The implementation, in c++, of Black-Scholes pricer can be as followed:
Files
4 Header file
3 cpp file
Header file 1: BinModel02.h
#pragma once
class BinModel {
private:
double S0, U, D, R;
public:
double RiskNeutProb();
double S(int n, int i);
double GetR();
double GetS0();
double GetU();
double GetD();
BinModel(double S0_, double U_, double D_, double R_)
{
S0 = S0_; U = U_; D = D_; R = R_;
}
};
Header file 2: BinLattice02.h
#pragma once
#include <iostream>
#include <iomanip>
#include <vector>
using namespace std;
template<typename Type> class BinLattice {
private:
int N;
vector< vector<Type> > Lattice;
public:
void SetN(int N_) {
N = N_;
Lattice.resize(N + 1);
for (int n = 0; n <= N; n++) Lattice[n].resize(n + 1);
}
void SetNode(int n, int i, Type x) { Lattice[n][i] = x; }
Type GetNode(int n, int i) { return Lattice[n][i]; }
void Display(ostream& stream) {
stream << setiosflags(ios::fixed) << setprecision(6);
for (int n = 0; n <= N; n++) {
for (int i = 0; i <= n; i++)
stream << setw(15) << GetNode(n, i);
stream << endl;
}
stream << endl;
}
};
Header file 3: Options09.h
#pragma once
#include "BinLattice02.h"
#include "BinModel02.h"
class Option {
private:
int N; //steps to expiry
public:
void SetN(int N_) { N = N_; }
int GetN() { return N; }
virtual double Payoff(double z) = 0;
};
class EurOption : public virtual Option {
public:
//pricing European option
double PriceByCRR(BinModel Model);
};
class AmOption : public virtual Option {
public:
//pricing American option
double PriceBySnell(BinModel Model, BinLattice<double>& PriceTree, BinLattice<bool>& StoppingTree);
};
class Call : public EurOption, public AmOption {
private:
double K; //strike price
public:
Call(int N_, double K_) { SetN(N_); K = K_; }
double Payoff(double z);
};
class Put : public EurOption, public AmOption {
private:
double K; //strike price
public:
Put(int N_, double K_) { SetN(N_); K = K_; }
double Payoff(double z);
};
Header file 4: Blackschole.h
#pragma once
#include <cmath>
#include "BinModel02.h"
using namespace std;
class Blackschole {
private:
double S0, r, sigma;
public:
Blackschole(double S0_, double r_, double sigma_)
{
S0 = S0_; r = r_; sigma = sigma_;
}
BinModel ApproxBinModel(double h)
{
double U = exp( sigma * sqrt(h)) - 1;
double D = (1 / (1 + U)) - 1;
double R = exp(r * h) - 1;
BinModel ApproxModel(S0, U, D, R);
return ApproxModel;
}
};
Cpp file 1: BinModel02.cpp
#include "BinModel02.h"
#include <iostream>
#include <cmath>
using namespace std;
double BinModel::RiskNeutProb() {return (R - D) / (U - D);}
double BinModel::S(int n, int i) {return S0 * pow(1 + U, i) * pow(1 + D, n - i);}
double BinModel::GetR() {return R;}
double BinModel::GetS0() {return S0;}
double BinModel::GetU() {return U;}
double BinModel::GetD() {return D;}
Cpp file 2 : Options09.cpp
#include "Options09.h"
#include "BinModel02.h"
#include "BinLattice02.h"
#include <iostream>
#include <cmath>
using namespace std;
double EurOption::PriceByCRR(BinModel Model) {
double q = Model.RiskNeutProb();
int N = GetN();
vector<double> Price(N + 1);
for (int i = 0; i <= N; i++)
Price[i] = Payoff(Model.S(N, i));
for (int n = N - 1; n >= 0; n--) {
for (int i = 0; i <= n; i++)
Price[i] = (q * Price[i + 1] + (1 - q) * Price[i]) / (1 + Model.GetR());
}
return Price[0];
}
double AmOption::PriceBySnell(BinModel Model, BinLattice<double>& PriceTree, BinLattice<bool>& StoppingTree) {
double q = Model.RiskNeutProb();
int N = GetN();
PriceTree.SetN(N);
StoppingTree.SetN(N);
double ContVal;
for (int i = 0; i <= N; i++) {
PriceTree.SetNode(N, i, Payoff(Model.S(N, i)));
StoppingTree.SetNode(N, i, 1);
}
for (int n = N - 1; n >= 0; n--) {
for (int i = 0; i <= n; i++) {
ContVal = (q * PriceTree.GetNode(n + 1, i + 1) + (1 - q) * PriceTree.GetNode(n + 1, i)) / (1 + Model.GetR());
PriceTree.SetNode(n, i, Payoff(Model.S(n, i)));
StoppingTree.SetNode(n, i, 1);
if (ContVal > PriceTree.GetNode(n, i)) {
PriceTree.SetNode(n, i, ContVal);
StoppingTree.SetNode(n, i, 0);
}
else if (PriceTree.GetNode(n, i) == 0.0) {
StoppingTree.SetNode(n, i, 0);
}
}
}
return PriceTree.GetNode(0, 0);
}
double Call::Payoff(double z) {
if (z > K) return z - K;
return 0.0;
}
double Put::Payoff(double z) {
if (z < K) return K - z;
return 0.0;
}
Cpp file 3 : main.cpp
#include <iostream>
#include "BinModel02.h"
#include "Options09.h"
#include "Blackschole.h"
using namespace std;
int main() {
double S0 = 106.0;
double r = 0.058;
double sigma = 0.46;
double T = (double)9 / 12;
double K = 100.0;
int N = 8;
cout << setiosflags(ios::fixed) << setprecision(5);
cout << "S0 = " << S0 << endl;
cout << "r = " << r << endl;
cout << "sigma = " << sigma << endl;
cout << "T = " << T << endl;
cout << "K = " << K << endl;
cout << "N = " << N << endl;
cout << endl;
Blackschole Model(S0, r, sigma);
double h = T / N;
BinModel ApproxModel = Model.ApproxBinModel(h);
cout << "U = " << ApproxModel.GetU() << endl;
cout << "D = " << ApproxModel.GetD() << endl;
cout << "R = " << ApproxModel.GetR() << endl;
Call Option(N, K);
BinLattice<double> PriceTree;
BinLattice<bool> StoppingTree;
Option.PriceBySnell(ApproxModel, PriceTree, StoppingTree);
cout << "American call option price = "
<< PriceTree.GetNode(0, 0)
<< endl << endl;
return 0;
}
/*
S0 = 106.00000
r = 0.05800
sigma = 0.46000
T = 0.75000
K = 100.00000
N = 8
U = 0.15125
D = -0.13138
R = 0.00545
American call option price = 21.68171
*/




Leave a comment