Scenario You are working as a consultant to an accounting firm. One of your charges is the valuation of employee stock options. The question has been raised of the effect of stochastic volatility on valuation of the options granted to officers of the company.
Action You will be given a program that uses simulations to evaluate options when the volatility of the stock is random. You will use the program to evaluate some call options, and you will perform a statistical analysis of the resultant values to form an opinion of the accuracy of the simulation.
Concept Simulation is a powerful tool for computing option values. When a one-dimensional binomial model can be used, it is much quicker, but when there are multiple sources of uncertainty, simulation is easier to program and more flexible provided there are not any American features. Simulation is the only practical technique for many hard problems in practice, for example, the valuation of mortgage-backed securities.
Instructions
<HTML> <HEAD> <TITLE>Asset Allocation Simulation</TITLE> </HEAD> <BODY> <P> <APPLET CODE=SVPrice.class WIDTH=300 HEIGHT=50> </APPLET> </p> <p> WARNING: The number of simulations equals 100 for testing only! It takes many more draws (perhaps 100,000) to obtain an accurate value.</p> </BODY> </HTML>Exhibit B: SVPrice.java
import java.applet.*; import java.awt.*; public class SVPrice extends Applet { SVPriceFrame svpf; Button startASimu; public SVPrice() { setLayout(new GridLayout(1,1)); add(startASimu = new Button("Compute Option Prices Now")); svpf = new SVPriceFrame(); svpf.setTitle("Stochastic Volatility Option Pricing Simulation"); svpf.pack(); svpf.resize(500,400);} public boolean action(Event e, Object arg) { if(e.target == startASimu) { svpf.reset(); return true;} return false;}} class SVPriceFrame extends Frame { double[] initSigmas; Label[] opvals; TextField r,sigmabar,kappa,sigmasigma,ttm,s0,strike,nsimu,nper; Button newRandomDraws,resetInputs; SVPriceEngine vroom; int i; public SVPriceFrame() { setLayout(new BorderLayout()); Panel outputs = new Panel(); outputs.setLayout(new GridLayout(6,2)); outputs.add(new Label("Initial Sigma")); outputs.add(new Label("Call Price")); opvals = new Label[5]; initSigmas = new double[5]; for(i=0;i<5;i++) { initSigmas[i] = .3 + .05*((double) i); outputs.add(new Label(Double.toString(initSigmas[i]))); outputs.add(opvals[i] = new Label("**********")); opvals[i].setForeground(Color.yellow);} add("North",outputs); Panel inputs = new Panel(); inputs.setLayout(new GridLayout(8,3)); inputs.add(new Label("stock price")); inputs.add(new Label("strike price")); inputs.add(new Label("number of simus")); inputs.add(s0=new TextField("50",10)); inputs.add(strike=new TextField("60",10)); inputs.add(nsimu=new TextField("100",10)); inputs.add(new Label("interest (%/yr)")); inputs.add(new Label("avg sigma (%/yr)")); inputs.add(new Label("kappa (%/yr)")); inputs.add(r=new TextField("5",10)); inputs.add(sigmabar=new TextField("40",10)); inputs.add(kappa=new TextField("3.0",10)); inputs.add(new Label("vol of vol (%/yr)")); inputs.add(new Label("time to mat (yr)")); inputs.add(new Label("# subperiods")); inputs.add(sigmasigma=new TextField("10",10)); inputs.add(ttm=new TextField("5",10)); inputs.add(nper=new TextField("25",10)); inputs.add(newRandomDraws = new Button("Compute Prices")); inputs.add(new Label("")); inputs.add(new Label("")); inputs.add(resetInputs = new Button("Reset Parameters")); add("South",inputs); vroom = new SVPriceEngine();} public void startSimu() { newRandomDraws.setLabel("-- Computing --"); newRandomDraws.setForeground(Color.red); for(i=0;i<5;i++) { opvals[i].setForeground(Color.yellow);} for(i=0;i<5;i++) { vroom.newPars(text2double(ttm),(int) text2double(nper), text2double(r)/100.0,initSigmas[i],text2double(sigmabar)/100.0, text2double(kappa)/100.0,text2double(sigmasigma)/100.0); opvals[i].setText(String.valueOf((float) vroom.eurCall(text2double(s0),text2double(strike), (long) text2double(nsimu)))); opvals[i].setForeground(Color.black);} newRandomDraws.setLabel("Compute Prices"); newRandomDraws.setForeground(Color.black);} public void reset() { r.setText("5"); sigmabar.setText("40"); kappa.setText("3.0"); sigmasigma.setText("10"); ttm.setText("5"); nper.setText("25"); s0.setText("50"); strike.setText("60"); nsimu.setText("100"); show();} public boolean action(Event e, Object arg) { if(e.target == newRandomDraws) { startSimu(); return true;} if(e.target == resetInputs) { reset(); return true;} return false;} public boolean handleEvent(Event event) { if(event.id == Event.WINDOW_DESTROY) { dispose();} return super.handleEvent(event);} double text2double(TextField tf) { return Double.valueOf(tf.getText()).doubleValue();}}Exhibit B: SVPrice.java
public class SVPriceEngine { double npers, tinc, r1per, sigma0, meansigma, sigmasigma, kappa, c0, c1, c2, c3, c4; double stockP, sigma; public SVPriceEngine(){} public void newPars(double ttm,int nper,double r,double initstd, double meanstd, double k, double sigstd) { npers = nper; tinc = ttm/(double) nper; r1per = 1.0 + r*tinc; sigma0 = initstd; meansigma = meanstd; sigmasigma = sigstd; kappa = k; c0 = kappa * tinc * meansigma; c1 = 1.0 - kappa * tinc; c2 = 1.0 - sigmasigma * Math.sqrt(tinc)*0.5*Math.sqrt((double) 12); c3 = sigmasigma * Math.sqrt(tinc) * Math.sqrt((double) 12); c4 = Math.sqrt(tinc)*Math.sqrt((double) 12);} public double eurCall(double stock,double strike,long nsimu) { long i,n; double x; x=0.0; for(n=0;n<nsimu;n++) { stockP = stock; sigma = sigma0; for(i=0;i<npers;i++) { stockP *= stocktotret(); } x += Math.max(stockP-strike,0);} return(x/((double) nsimu * Math.pow(r1per,(double) npers)));} double stocktotret() { double stockret; // // The following straightforward computations are algebraically // the same as the ones used below but are much slower because // many more calculations are performed in each pass through the // nested for loops in eurCall. // // stockret = r1per + sigma * Math.sqrt(tinc) * // (Math.random()-0.5) * Math.sqrt((double) 12); // sigma = (kappa*tinc * meansigma + (1.0 - kappa * tinc) * sigma) * // (1 + sigmasigma * Math.sqrt(tinc) * // (Math.random()-0.5) * Math.sqrt((double) 12)); // return(stockret);} // stockret = r1per + sigma * c4 * (Math.random() - 0.5); sigma = (c0 + c1 * sigma) * (c2 + c3 * Math.random()); return(stockret);}}