Scenario You are working as a consultant in 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 the binomial model can be used, it is much quicker, but simulation is easier to program and more flexible and is the only practical technique for many hard problems in practice.
Instructions
// // simu2.h Stochastic Volatility Option Pricing Model // class svprice { public: svprice(double ttm=0.25,int nper=12,double r=.05,double initstd=.15, double meanstd=.2,double k=6.0,double sigstd=.5); double eurcall(double stock,double strike,long int nsimu=1000); private: int npers; double tinc, r1per, stockP, sigma0, sigma, meansigma, sigmasigma, kappa, c0, c1, c2, c3, c4, c5; double stocktotret();};Exhibit B: the test file simu2test.cc
// // simu2test.cc Stochastic Volatility Option Pricing Test File // #include <iostream.h> #include <math.h> #include "simu2.h" main() { long int i,nsimus; svprice sim2; for(nsimus=10;nsimus<=100000l;nsimus *= 10) cout << nsimus << " " << floor(sim2.eurcall((double) 100.0,(double) 100.0,nsimus)*100.0+0.5)/100.0 << endl; cout << endl; for(i=0;i<20;i++) cout << "100000 " << floor(sim2.eurcall((double) 100.0,(double) 100.0,(long int) 100000l)*100.0+0.5)/100.0 << endl; return(0);}Exhibit C: the implementation file simu2.cc
// // simu2.cc Stochastic Volatility Option Pricing Model // #include <math.h> #include <stdlib.h> #include <iostream.h> #include "simu2.h" #define unifrand() ((double) rand()/((double) RAND_MAX)) #define MAX(a,b) (((a) > (b)) ? (a) : (b)) svprice::svprice(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 * sqrt(tinc)*0.5*sqrt((double) 12); c3 = sigmasigma * sqrt(tinc) * sqrt((double) 12); c4 = sqrt(tinc)*sqrt((double) 12);} double svprice::eurcall(double stock,double strike,long int nsimu) { long int 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 += MAX(stockP-strike,0);} return(x/((double) nsimu * pow(r1per,(double) npers)));} double svprice::stocktotret() { // // 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 loop. // // sigma = (kappa*tinc * meansigma + (1.0 - kappa * tinc) * sigma) * // (1 + sigmasigma * sqrt(tinc) * (unifrand()-0.5) * sqrt((double) 12)); // return(r1per + sigma * sqrt(tinc) * (unifrand()-0.5) * sqrt((double) 12));} // sigma = (c0 + c1 * sigma) * (c2 + c3 * unifrand()); return(r1per + sigma * c4 * (unifrand()-0.5));}