The American option pricer in C++ can be written as below:

The American option pricer in C++ can be written as below:
Header file 1: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(3);
for (int n = 0; n <= N; n++)
{
for (int i = 0; i <= n; i++)
stream << setw(7) << GetNode(n, i);
stream << endl;
}
stream << endl;
}
};
Header file 2: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();
int GetInputData();
};
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);
double PriceByCRRHW6(BinModel Model, BinLattice<double>& PriceTree, BinLattice<double>& XTree, BinLattice<double>& YTree);
};
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:
void SetK(double K_) { K = K_; }
double GetK() { return K; }
int GetInputData();
double Payoff(double z);
};
class Put : public EurOption, public AmOption
{
private:
double K; //strike price
public:
void SetK(double K_) { K = K_; }
double GetK() { return K; }
int GetInputData();
double Payoff(double z);
};
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;
}
int BinModel::GetInputData()
{
//entering data
cout << "Enter S0: "; cin >> S0;
cout << "Enter U: "; cin >> U;
cout << "Enter D: "; cin >> D;
cout << "Enter R: "; cin >> R;
cout << endl;
//making sure that 0<S0, -1<D<U, -1<R
if (S0 <= 0.0 || U <= -1.0 || D <= -1.0 || U <= D ||
R <= -1.0)
{
cout << "Illegal data ranges" << endl;
cout << "Terminating program" << endl;
return 1;
}
//checking for arbitrage
if (R >= U || R <= D)
{
cout << "Arbitrage exists" << endl;
cout << "Terminating program" << endl;
return 1;
}
cout << "Input data checked" << endl;
cout << "There is no arbitrage" << endl << endl;
return 0;
}
cpp file 2: Options09.cpp
/*
#include "BinLattice02.h"
#include "BinModel02.h"
#include "Options09.h"
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
BinModel Model;
if (Model.GetInputData() == 1) return 1;
ofstream fout;
fout.open("Results.txt");
Call Option1;
Option1.GetInputData();
BinLattice<double> PriceTree;
BinLattice<double> XTree;
BinLattice<double> YTree;
fout << "S0 = " << Model.GetS0() << endl
<< "U = " << Model.GetU() << endl
<< "D = " << Model.GetD() << endl
<< "R = " << Model.GetR() << endl;
fout << "N = " << Option1.GetN() << endl
<< "K = " << Option1.GetK() << endl;
fout << "European call prices by PriceByCRR:・
<< Option1.PriceByCRR(Model) << endl << endl;
fout << "European call prices by PriceByCRRHW6:"
<< Option1.PriceByCRRHW6(Model, PriceTree, XTree, YTree)
<< endl << endl;
PriceTree.Display(fout);
fout << "Stock positions in replicating strategy:・<< endl << endl;
XTree.Display(fout);
fout << "Money market account positions in replicating strategy:・<< endl << endl;
YTree.Display(fout);
}
*/
#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 EurOption::PriceByCRRHW6(BinModel Model, BinLattice<double>& PriceTree, BinLattice<double>& XTree, BinLattice<double>& YTree)
{
double q = Model.RiskNeutProb();
int N = GetN();
PriceTree.SetN(N);
XTree.SetN(N);
YTree.SetN(N);
double EOVal;
double X_Node, Y_Node;
for (int i = 0; i <= N; i++) {
PriceTree.SetNode(N, i, Payoff(Model.S(N, i)));
}
for (int n = N-1 ; n >= 0; n--)
{
for (int i = 0; i <= n; i++)
{
EOVal = (q * PriceTree.GetNode(n + 1, i + 1) + (1 - q) * PriceTree.GetNode(n + 1, i)) / (1 + Model.GetR());
X_Node = (PriceTree.GetNode(n + 1, i + 1) - PriceTree.GetNode(n + 1, i)) / (Model.S(n + 1, i + 1) - Model.S(n + 1, i ));
Y_Node = (PriceTree.GetNode(n + 1, i) - ( X_Node * Model.S(n + 1, i))) / pow( (1 + Model.GetR() ), (1 + n) ) ;
PriceTree.SetNode(n, i, EOVal);
XTree.SetNode(n, i, X_Node);
YTree.SetNode(n, i, Y_Node);
}
}
return PriceTree.GetNode(0, 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++) //at expiration
{
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); // updated to calculated value
StoppingTree.SetNode(n, i, 0); // set not eligible for early exercise
}
else if (PriceTree.GetNode(n, i) == 0.0)
{
StoppingTree.SetNode(n, i, 0);
}
}
}
return PriceTree.GetNode(0, 0);
}
int Call::GetInputData()
{
cout << "Enter call option data:" << endl; int N;
cout << "Enter steps to expiry N: "; cin >> N;
SetN(N);
cout << "Enter strike price K: "; cin >> K;
cout << endl;
return 0;
}
double Call::Payoff(double z)
{
if (z > K) return z - K;
return 0.0;
}
int Put::GetInputData()
{
cout << "Enter put option data:" << endl; int N;
cout << "Enter steps to expiry N: "; cin >> N;
SetN(N);
cout << "Enter strike price K: "; cin >> K;
cout << endl;
return 0;
}
double Put::Payoff(double z)
{
if (z < K) return K - z;
return 0.0;
}
cpp file3 : main.cpp
#include "BinLattice02.h"
#include "BinModel02.h"
#include "Options09.h"
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
BinModel Model;
if (Model.GetInputData() == 1) return 1;
ofstream fout;
fout.open("Results.txt");
Call Option1;
Option1.GetInputData();
BinLattice<double> PriceTree;
BinLattice<double> XTree;
BinLattice<double> YTree;
fout << "S0 = " << Model.GetS0() << endl
<< "U = " << Model.GetU() << endl
<< "D = " << Model.GetD() << endl
<< "R = " << Model.GetR() << endl;
fout << "N = " << Option1.GetN() << endl
<< "K = " << Option1.GetK() << endl;
fout << "European call prices by PriceByCRR:"
<< Option1.PriceByCRR(Model) << endl << endl;
fout << "European call prices by PriceByCRRHW6:"
<< Option1.PriceByCRRHW6(Model, PriceTree, XTree, YTree)
<< endl << endl;
fout << "Stock positions in replicating strategy:" << endl << endl;
XTree.Display(fout);
fout << "Money market account positions in replicating strategy:" << endl << endl;
YTree.Display(fout);
Put Option2;
Option2.GetInputData();
BinLattice<double> PriceTree2;
BinLattice<double> XTree2;
BinLattice<double> YTree2;
fout << "N = " << Option2.GetN() << endl
<< "K = " << Option2.GetK() << endl;
fout << "European put prices by PriceByCRR:"
<< Option2.PriceByCRR(Model) << endl << endl;
fout << "European put prices by PriceByCRRHW6:"
<< Option2.PriceByCRRHW6(Model, PriceTree2, XTree2, YTree2)
<< endl << endl;
fout << "Stock positions in replicating strategy:" << endl << endl;
XTree2.Display(fout);
fout << "Money market account positions in replicating strategy:" << endl << endl;
YTree2.Display(fout);
fout.close();
return 0;
}
/*
Enter S0: 106
Enter U: 0.15125
Enter D: -0.13138
Enter R: 0.00545
Input data checked
There is no arbitrage
Enter call option data:
Enter steps to expiry N: 8
Enter strike price K: 100
Enter put option data:
Enter steps to expiry N: 8
Enter strike price K: 100
RESULT in Results.txt
*/
Result of the code are following
S0 = 106
U = 0.15125
D = -0.13138
R = 0.00545
N = 8
K = 100
European call prices by PriceByCRR:21.6811
European call prices by PriceByCRRHW6:21.6811
Stock positions in replicating strategy:
0.672
0.520 0.794
0.341 0.664 0.898
0.164 0.483 0.810 0.970
0.039 0.265 0.657 0.932 1.000
0.000 0.071 0.421 0.847 1.000 1.000
0.000 0.000 0.128 0.657 1.000 1.000 1.000
0.000 0.000 0.000 0.231 1.000 1.000 1.000 1.000
0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000
Money market account positions in replicating strategy:
-49.518
-35.611-64.336
-21.444-50.706-78.860
-9.393-34.285-68.204-90.215
-2.003-17.268-52.418-85.024-95.745
0.000 -4.138-31.259-74.963-95.745-95.745
0.000 0.000 -8.547-55.460-95.745-95.745-95.745
0.000 0.000 0.000-17.654-95.745-95.745-95.745-95.745
0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000
N = 8
K = 100.000
European put prices by PriceByCRR:11.426
European put prices by PriceByCRRHW6:11.426
Stock positions in replicating strategy:
-0.328
-0.480 -0.206
-0.659 -0.336 -0.102
-0.836 -0.517 -0.190 -0.030
-0.961 -0.735 -0.343 -0.068 0.000
-1.000 -0.929 -0.579 -0.153 0.000 0.000
-1.000 -1.000 -0.872 -0.343 0.000 0.000 0.000
-1.000 -1.000 -1.000 -0.769 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000
Money market account positions in replicating strategy:
46.227
60.134 31.409
74.301 45.039 16.885
86.352 61.460 27.541 5.530
93.742 78.477 43.327 10.721 0.000
95.745 91.607 64.486 20.782 0.000 0.000
95.745 95.745 87.198 40.285 0.000 0.000 0.000
95.745 95.745 95.745 78.091 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000




Leave a comment