Part 5
c++ finance course
Monte-Carlo c++ – basket options
Objective
– price basket options
based on this you’ll be able to price Autocallable, Himalaya, Spread and similar basket options
Basket option
Here let’s see how to price an option on 2 stocks with payoff
$$ ( w_1S_1+w_2S_2-K)^+ $$
where $$ w_i $$ are basket weights
let’s consider zero interest rate environment and n non-dividend paying stocks with dynamics: (for interest rates and dividends just add $$(r-q)dt$$ terms to this dynamics
$$dS_1=S_1 \sigma_1 dW_1(t)$$
$$dS_2=S_2 \sigma_2 dW_2(t)$$
$$ dW_i dW_j=\rho_{i,j} dt$$
where $$\rho_{i,j}$$ is a stock correlation matrix
given the correlation matrix we’ll construct it’s Cholesky decomposition.
Cholesky decomposition can be done with boost but it’s easier to do it with QuantLib implementation.
to store correlation and cholesky matrices we’ll use QuantLib::Matrix class.
we’ll store vector of independent gaussians in the QuantLib::Array class.
we don’t store in std::vector
to obtain correlated gaussians we’ll generate vector of independent gaussians $$\vec{\epsilon}= (\epsilon_1, \epsilon_2)$$ first.
then vector of correlated gaussians is $$M_{cholesky} \vec{\epsilon}$$
here’s the code for wights =1
#include <boost/random/variate_generator.hpp> #include <boost/random/mersenne_twister.hpp> #include <boost/random/normal_distribution.hpp> #include <iostream> #include <ql/quantlib.hpp> double pp(double x) //positive part x+ { if(x>0) return x; return 0; } void main() { boost::mt19937 mt; boost::normal_distribution<> distribution; boost::variate_generator<boost::mt19937&,boost::normal_distribution<>>* normal(new boost::variate_generator<boost::mt19937&,boost::normal_distribution<>>(mt,distribution)); int numberSimulations=10000; std::vector<double> S0(2); S0[0]=100.0;// S1(0) - spot price of first stock S0[1]=100.0;//S2(0) - spot price of second stock std::vector<double> sigma(2); sigma[0]=0.2; //volatility of S1 sigma[1]=0.2;//volatility of S2 double T=1.0;//maturity in years double K=100.0;//strike of option double sum=0;//for monte-carlo averaging double payoff=0; double NT=100;//number of time intervals double dt=T/NT; QuantLib::Matrix rho(2,2);//correlation matrix rho[0][0]=1;rho[0][1]=0.5; rho[1][0]=0.5;rho[1][1]=1; QuantLib::Matrix cholesky=QuantLib::CholeskyDecomposition(rho); for(int iSim=0;iSim<numberSimulations;iSim++) //outer loop for simulations { std::vector<double> Sprev(S0); //create a vector equal to S0 with its values std::vector<double> Snext(2);//create vector with 2 elemens for(double t=0;t<T;t+=dt) //inner loop for constructing one stock price from time 0 to T { QuantLib::Array epsilon(2);//create a vector with 2 elements .we'll put here independent gaussians epsilon[0]=(*normal)(); epsilon[1]=(*normal)(); QuantLib::Array x(2); x=cholesky*epsilon; //correlated gaussians for(int iStock=0;iStock<2;iStock++) //loop over all stocks { Snext[iStock]=Sprev[iStock]*std::exp(-0.5*sigma[iStock]*sigma[iStock]*dt+sigma[iStock]*std::sqrt(dt)*x[iStock]); Sprev[iStock]=Snext[iStock]; } } payoff=pp(Snext[0]+Snext[1]-K); sum+=payoff; } std::cout<<"\nBasket Call="<<sum/numberSimulations<<std::endl; int dummy;std::cin>>dummy; }
Exercises
– modify the program to calculate asian basket payoff
– modify the program to N stocks
– modify program to include interest rates and dividend yield