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
![[<<] PriceDerivatives blog](https://www.pricederivatives.com/en/wp-content/uploads/2014/03/cropped-pricederivatives-blog-logo-Copy3.png)