The implementation, in c++, of bull spread and bear spread option pricer can be as followed:

Files
2 Header file
3 cpp file

Header file 1: BSModel01.h

#pragma once
using namespace std;
#include <vector>
#include <cstdlib>
#include <ctime>// for srand()
using namespace std;

typedef vector<double> SamplePath;
class BSModel {
public:
    double S0, r, sigma;
    BSModel(double S0_, double r_, double sigma_) {
        S0 = S0_; r = r_; sigma = sigma_;
        srand(time(NULL));
    }
    void GenerateSamplePath(double T, int m, SamplePath& S);
};

Header file 2: PathDepOption03v2.h

#pragma once


#include "BSModel01.h"

class PathDepOption {
public:
    double T, Price, PricingError, delta, gamma;
    int m;
    virtual double Payoff(SamplePath& S) = 0;
    double PriceByMC(BSModel Model, long N, double epsilon);
};

class ArthmAsianCall : public PathDepOption {
public:
    double K;
    ArthmAsianCall(double T_, double K_, int m_) { T = T_; K = K_; m = m_; }
    double Payoff(SamplePath& S);
};

Cpp file 1: BSModel01.cpp

#include "BSModel01.h"
#include <iostream>
#include <cmath>

const double pi = 4.0 * atan(1.0);

double Gauss() {
    double U1 = (rand() + 1.0) / (RAND_MAX + 1.0);
    double U2 = (rand() + 1.0) / (RAND_MAX + 1.0);
    return sqrt(-2.0 * log(U1)) * cos(2.0 * pi * U2);
}

void BSModel::GenerateSamplePath(double T, int m, SamplePath& S) {
    double St = S0;
    for (int k = 0; k < m; k++) {
        S[k] = St * exp((r - sigma * sigma * 0.5) * (T / m) + sigma * sqrt(T / m) * Gauss());
        St = S[k];
    }
}


Cpp file 2: PathDepOption03v2.cpp

#include "PathDepOption03v2.h"
#include <cmath>

void Rescale(SamplePath& S, double x) {
    int m = S.size();
    for (int j = 0; j < m; j++) S[j] = x * S[j];
}

double PathDepOption::PriceByMC(BSModel Model, long N, double epsilon) {
    double H = 0.0, Hsq = 0.0, Heps = 0.0, Hgam = 0.0;
    SamplePath S(m);
    for (long i = 0; i < N; i++) {
        Model.GenerateSamplePath(T, m, S);
        H = (i / (i + 1.0)) * H + Payoff(S) / (i + 1.0);
        Hsq = (i / (i + 1.0)) * Hsq + pow(Payoff(S), 2.0) / (i + 1.0);
        Rescale(S, 1.0 + epsilon);
        Heps = (i / (i + 1.0)) * Heps + Payoff(S) / (i + 1.0);
        Rescale(S, (1.0 - epsilon) / (1.0 + epsilon));
        Hgam = (i / (i + 1.0)) * Hgam + Payoff(S) / (i + 1.0);
    }
    Price = exp(-Model.r * T) * H;
    PricingError = exp(-Model.r * T) * sqrt(Hsq - H * H) / sqrt(N - 1.0);
    delta = exp(-Model.r * T) * (Heps - H) / (Model.S0 * epsilon);
    gamma = exp(-Model.r * T) * (Heps + Hgam - 2 * H) / pow(Model.S0 * epsilon, 2);
    return Price;
}

double ArthmAsianCall::Payoff(SamplePath& S) {
    double Ave = 0.0;
    for (int k = 0; k < m; k++) Ave = (k / (k + 1.0)) * Ave + S[k] / (k + 1.0);
    if (Ave < K) return 0.0;
    return Ave - K;
}

cpp file 3 : Main.cpp



#include <iostream>
#include "PathDepOption03v2.h"

using namespace std;
int main() {
	double S0 = 100., r = 0.03, sigma = 0.2;
	BSModel Model(S0, r, sigma);

	double T = 1.0 / 12.0, K = 100.0;
	int m = 30;
	ArthmAsianCall Option(T, K, m);

	long N = 30000;
	double epsilon = 0.001;
	Option.PriceByMC(Model, N, epsilon);
	cout << "Asian Call Price = " << Option.Price << endl
		<< "   Pricing Error = " << Option.PricingError << endl
		<< "           delta = " << Option.delta << endl
		<< "           gamma = " << Option.gamma << endl;
	return 0;
}



/*

Asian Call Price = 1.43056
   Pricing Error = 0.0120874
		   delta = 0.524821
		   gamma = 0.119194


*/

Leave a comment

Trending