Skip to content

Commit

Permalink
Add files via upload
Browse files Browse the repository at this point in the history
  • Loading branch information
ShashankSureshRotti authored May 20, 2023
1 parent 61b2537 commit 3dba4c8
Show file tree
Hide file tree
Showing 11 changed files with 364 additions and 2 deletions.
44 changes: 44 additions & 0 deletions EurCall.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#include "EurCall.h"
#include <cmath>
namespace fre {
double N(double x)
{
double gamma = 0.2316419; double a1 = 0.319381530;
double a2 = -0.356563782; double a3 = 1.781477937;
double a4 = -1.821255978; double a5 = 1.330274429;
double pi = 4.0 * atan(1.0); double k = 1.0 / (1.0 + gamma * x);
if (x >= 0.0)
{
return 1.0 - ((((a5 * k + a4) * k + a3) * k + a2) * k + a1) * k * exp(-x * x / 2.0) / sqrt(2.0 * pi);
}
else return 1.0 - N(-x);
}

double EurCall::d_plus(double S0, double sigma, double r)
{
return (log(S0 / K) + (r + 0.5 * pow(sigma, 2.0)) * T) / (sigma * sqrt(T));
}

double EurCall::d_minus(double S0, double sigma, double r)
{
return d_plus(S0, sigma, r) - sigma * sqrt(T);
}

double EurCall::PriceByBSFormula(double S0, double sigma, double r)
{
return S0 * N(d_plus(S0, sigma, r)) - K * exp(-r * T) * N(d_minus(S0, sigma, r));
}

double EurCall::VegaByBSFormula(double S0, double sigma, double r)
{
double pi = 4.0 * atan(1.0);
return S0 * exp(-d_plus(S0, sigma, r) * d_plus(S0, sigma, r) / 2) * sqrt(T) / sqrt(2.0 * pi);
}

double EurCall::DeltaByBSFormula(double S0, double sigma, double r)
{
return N(d_plus(S0, sigma, r));
}
}


17 changes: 17 additions & 0 deletions EurCall.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#pragma once
namespace fre {
class EurCall
{
private:
double T, K;
double d_plus(double S0, double sigma, double r);
double d_minus(double S0, double sigma, double r);
public:
EurCall(double T_, double K_) : T(T_), K(K_) {}
double PriceByBSFormula(double S0, double sigma, double r);
double VegaByBSFormula(double S0, double sigma, double r);
double DeltaByBSFormula(double S0, double sigma, double r);
};
}


49 changes: 49 additions & 0 deletions GmtrAsianCall.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#include "GmtrAsianCall.h"
#include "EurCall.h"
#include <cmath>
//using namespace std;
namespace fre {

double N_gauss(double x)
{
double gamma = 0.2316419; double a1 = 0.319381530;
double a2 = -0.356563782; double a3 = 1.781477937;
double a4 = -1.821255978; double a5 = 1.330274429;
double pi = 4.0 * atan(1.0); double k = 1.0 / (1.0 + gamma * x);
if (x >= 0.0)
{
return 1.0 - ((((a5 * k + a4) * k + a3) * k + a2) * k + a1) * k * exp(-x * x / 2.0) / sqrt(2.0 * pi);
}
else return 1.0 - N_gauss(-x);
}

double GmtrAsianCall::Payoff(const SamplePath& S) const
{
double Prod = 1.0;
for (int i = 0; i < m; i++)
{
Prod = Prod * S[i];
}
if (pow(Prod, 1.0 / m) < K) return 0.0;
return pow(Prod, 1.0 / m) - K;
}

double GmtrAsianCall::PriceByBSFormula(const MCModel& Model)
{
double a = exp(-Model.GetR() * T) * Model.GetS0() * exp((m + 1.0) * T / (2.0 * m) * (Model.GetR() + Model.GetSigma() * Model.GetSigma() * ((2.0 * m + 1.0) / (3.0 * m) - 1.0) / 2.0));
double b = Model.GetSigma() * sqrt((m + 1.0) * (2.0 * m + 1.0) / (6.0 * m * m));
EurCall G(T, K);
Price = G.PriceByBSFormula(a, b, Model.GetR());
return Price;
}

double GmtrAsianCall::DeltaByBSFormula(const MCModel& Model)
{
double a = exp(-Model.GetR() * T) * Model.GetS0() * exp((m + 1.0) * T / (2.0 * m) * (Model.GetR() + Model.GetSigma() * Model.GetSigma() * ((2.0 * m + 1.0) / (3.0 * m) - 1.0) / 2.0));
double b = Model.GetSigma() * sqrt((m + 1.0) * (2.0 * m + 1.0) / (6.0 * m * m));
double d_delta_plus = ((log(a/K) + (Model.GetR() + 0.5 * pow(b,2))* T) / (b * sqrt(T)));
double BS_delta = N_gauss(d_delta_plus);
//cout<< "BS_delta: "<<BS_delta<<endl;
return BS_delta;
}
}
12 changes: 12 additions & 0 deletions GmtrAsianCall.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#pragma once
#include "PathDepOption.h"
namespace fre {
class GmtrAsianCall : public PathDepOption
{
public:
GmtrAsianCall(double T_, double K_, int m_) : PathDepOption(T_, K_, m_) {}
double Payoff(const SamplePath& S) const;
double PriceByBSFormula(const MCModel& Model);
double DeltaByBSFormula(const MCModel& Model);
};
}
22 changes: 22 additions & 0 deletions MCModel.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#include "MCModel.h"
#include <cmath>

namespace fre {
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 MCModel::GenerateSamplePath(double T, int m, SamplePath& S) const
{
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];
}
}
}
28 changes: 28 additions & 0 deletions MCModel.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#pragma once
#include <vector>
#include <cstdlib>
#include <ctime>

using namespace std;

namespace fre {
typedef vector<double> SamplePath;
class MCModel
{
private:
double S0, r, sigma;
public:
MCModel() :S0(0.0), r(0.0), sigma(0.0) {}
MCModel(double S0_, double r_, double sigma_) :S0(S0_), r(r_), sigma(sigma_)
{
srand((unsigned)time(NULL));
}
void GenerateSamplePath(double T, int m, SamplePath& S) const;
double GetS0() const { return S0; }
double GetR() const { return r; }
double GetSigma() const { return sigma; }
void SetS0(double S0_) { S0 = S0_; }
void SetR(double r_) { r = r_; }
void SetSigma(double sigma_) { sigma = sigma_; }
};
}
43 changes: 43 additions & 0 deletions Main04.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#include <iostream>
#include "PathDepOption.h"
#include "GmtrAsianCall.h"

using namespace std;
using namespace fre;

int main()
{
double S0=100.0, r=0.03, sigma=0.2;
MCModel Model(S0,r,sigma);

double T =1.0/12.0, K=100.0;
int m=30;

ArthmAsianCall Option(T,K,m);
GmtrAsianCall CVOption(T,K,m);

long N=30000;
double epsilon =0.001;
Option.PriceByVarRedMC(Model,N,CVOption,epsilon);
cout << "Arithmetic call price = " << Option.GetPrice() << endl
<< "Error = " << Option.GetPricingError() << endl
<< "Delta = " << Option.GetDelta() << endl << endl;

Option.PriceByMC(Model,N,epsilon);
cout << "Price by direct MC = " << Option.GetPrice() << endl
<< "Error = " << Option.GetPricingError() << endl
<< "Delta = " << Option.GetDelta() << endl << endl;

return 0;
}
/*
Arithmetic call price = 1.42615
Error = 0.000139644
Delta = 0.518651
Price by direct MC = 1.43208
Error = 0.0121643
Delta = 0.524516
*/

26 changes: 26 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
CC = g++
CFLAGS = -Wall -ggdb3 -std=c++11

HW11: Main04.o GmtrAsianCall.o EurCall.o MCModel.o PathDepOption.o
$(CC) $(CFLAGS) -o HW11 Main04.o GmtrAsianCall.o EurCall.o MCModel.o PathDepOption.o

Main04.o: Main04.cpp GmtrAsianCall.h PathDepOption.h
$(CC) $(CFLAGS) -c Main04.cpp

GmtrAsianCall.o: EurCall.h PathDepOption.h GmtrAsianCall.h GmtrAsianCall.cpp
$(CC) $(CFLAGS) -c GmtrAsianCall.cpp

PathDepOption.o: EurCall.h PathDepOption.h PathDepOption.cpp
$(CC) $(CFLAGS) -c PathDepOption.cpp

EurCall.o: EurCall.h EurCall.cpp
$(CC) $(CFLAGS) -c EurCall.cpp

MCModel.o: MCModel.h MCModel.cpp
$(CC) $(CFLAGS) -c MCModel.cpp

clean:
rm -rf HW11 *.o



50 changes: 50 additions & 0 deletions PathDepOption.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#include "PathDepOption.h"
#include "EurCall.h"
#include <cmath>

namespace fre {
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(const MCModel& Model, long N, double epsilon)
{
double H = 0.0, Hsq = 0.0, Heps = 0.0;
SamplePath S(m);
for (long i = 0; i < N; i++)
{
Model.GenerateSamplePath(T, m, S);
H = (i * H + Payoff(S)) / (i + 1.0);
Hsq = (i * Hsq + pow(Payoff(S), 2.0)) / (i + 1.0);
Rescale(S, 1.0 + epsilon);
Heps = (i * Heps + Payoff(S)) / (i + 1.0);
}
Price = exp(-Model.GetR() * T) * H;
PricingError = exp(-Model.GetR() * T) * sqrt(Hsq - H * H) / sqrt(N - 1.0);
delta = exp(-Model.GetR() * T) * (Heps - H) / (Model.GetS0() * epsilon);
return Price;
}

double PathDepOption::PriceByVarRedMC(const MCModel& Model, long N, PathDepOption& CVOption, double epsilon)
{
DifferenceOfOptions VarRedOpt(T, K, m, this, &CVOption);

Price = VarRedOpt.PriceByMC(Model, N, epsilon) + CVOption.PriceByBSFormula(Model);

PricingError = VarRedOpt.PricingError;

delta += CVOption.DeltaByBSFormula(Model);

return Price;
}

double ArthmAsianCall::Payoff(const SamplePath& S) const
{
double Ave = 0.0;
for (int k = 0; k < m; k++) Ave = (k * Ave + S[k]) / (k + 1.0);
if (Ave < K) return 0.0;
return Ave - K;
}
}
51 changes: 51 additions & 0 deletions PathDepOption.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#pragma once
#include "MCModel.h"
namespace fre {
class PathDepOption
{
protected:
double Price, PricingError, delta;
int m;
double K, T;
public:
PathDepOption(double T_, double K_, int m_) :Price(0.0), PricingError(0.0), delta(0.0), m(m_), K(K_), T(T_)
{}
virtual ~PathDepOption() {}
virtual double Payoff(const SamplePath& S) const = 0;
double PriceByMC(const MCModel& Model, long N, double epsilon);
double PriceByVarRedMC(const MCModel& Model, long N, PathDepOption& CVOption, double epsilon);
virtual double PriceByBSFormula(const MCModel& Model) { return 0.0; }
virtual double DeltaByBSFormula(const MCModel& Model) { return 0.0; }
double GetPrice() { return Price; }
double GetPricingError() { return PricingError; }
double GetDelta() { return delta; }
};


class DifferenceOfOptions : public PathDepOption
{
private:
PathDepOption* Ptr1;
PathDepOption* Ptr2;
public:
DifferenceOfOptions(double T_, double K_, int m_, PathDepOption* Ptr1_, PathDepOption* Ptr2_) : PathDepOption(T_, K_, m_), Ptr1(Ptr1_), Ptr2(Ptr2_)
{ }
double Payoff(const SamplePath& S) const
{
return Ptr1->Payoff(S) - Ptr2->Payoff(S);
}
};

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

}





24 changes: 22 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,22 @@
# Path-Dependent-Option-Pricing
Leveraged C++ OOPs to price path-dependent options using Monte Carlo Simulation. Incorporated the Control Variate technique for error reduction, enhancing accuracy and precision.
[![Review Assignment Due Date](https://classroom.github.com/assets/deadline-readme-button-24ddc0f5d75046c5622901739e7c5dd533143b0c8e959d652212380cedb1ea36.svg)](https://classroom.github.com/a/vqE6laHJ)
# Homework_Assignment_11

Please refer to Topic 9 Slide # 58 for the details of HW11. The followings are the inputs and outputs for HW11. Your outputs could be different, but should be around these numbers:

Input:

   double S0=100.0, r=0.03, sigma=0.2;
   double T =1.0/12.0, K=100.0;
   int m=30;
   long N=30000;
   double epsilon =0.001;

Output:

Arithmetic call price = 1.42609
Error = 0.000138491
delta = 0.520246

Price by direct MC = 1.41326
Error = 0.0119483
delta = 0.525525

0 comments on commit 3dba4c8

Please sign in to comment.