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

Trending