HedgingSimulator.cpp
#include "HedgingSimulator.h"
#include "testing.h"
#include "matlib.h"
using namespace std;
HedgingSimulator::HedgingSimulator() {
// Choose default models and options
shared_ptr<BlackScholesModel> model(
new BlackScholesModel());
model->stockPrice = 1;
model->date = 0;
model->riskFreeRate = 0.05;
model->volatility = 0.2;
model->drift = 0.10;
shared_ptr<CallOption> option =
make_shared<CallOption>();
option->setStrike(model->stockPrice);
option->setMaturity(1);
setToHedge(option);
setSimulationModel(model);
setPricingModel(model);
nSteps = 10;
}
/* Runs a number of simulations and returns
a vector of the profit and loss */
std::vector<double>
HedgingSimulator::runSimulations(
int nSimulations) const {
std::vector<double> ret(nSimulations);
for (int i = 0; i < nSimulations; i++) {
ret[i] = runSimulation();
}
return ret;
}
/* Run a simulation and compute the profit and loss */
double HedgingSimulator::runSimulation() const {
double T = toHedge->getMaturity();
double S0 = simulationModel->stockPrice;
vector<double> pricePath =
simulationModel->generatePricePath(T,nSteps);
double dt = T / nSteps;
double charge = chooseCharge(S0);
double stockQuantity = selectStockQuantity(0,S0);
double bankBalance = charge - stockQuantity*S0;
for (int i = 0; i< nSteps-1; i++) {
double balanceWithInterest = bankBalance *
exp(simulationModel->riskFreeRate*dt);
double S = pricePath[i];
double date = dt*(i + 1);
double newStockQuantity =
selectStockQuantity(date, S);
double costs =
(newStockQuantity - stockQuantity)*S;
bankBalance = balanceWithInterest - costs;
stockQuantity = newStockQuantity;
}
double balanceWithInterest = bankBalance *
exp(simulationModel->riskFreeRate*dt);
double S = pricePath[nSteps - 1];
double stockValue = stockQuantity*S;
double payout = toHedge->payoff(S);
return balanceWithInterest + stockValue - payout;
}
/* How much should we charge the customer */
double HedgingSimulator::chooseCharge(
double stockPrice) const {
// create a copy of the pricing model
BlackScholesModel pm = *pricingModel;
pm.stockPrice = stockPrice;
return toHedge->price(pm);
}
/* How much stock should we hold */
double HedgingSimulator::selectStockQuantity(
double date,
double stockPrice) const {
// create a copy of the pricing model
BlackScholesModel pm = *pricingModel;
pm.stockPrice = stockPrice;
pm.date = date;
return toHedge->delta(pm);
}
//
//
// Tests
//
//
static void testDeltaHedgingMeanPayoff() {
rng("default");
HedgingSimulator simulator;
simulator.setNSteps(1000);
vector<double> result=simulator.runSimulations(1);
ASSERT_APPROX_EQUAL(result[0], 0.0, 0.01);
}
static void testPlotDeltaHedgingHistogram() {
rng("default");
HedgingSimulator simulator;
simulator.setNSteps(100);
vector<double> result =
simulator.runSimulations(10000);
hist("deltaHedgingPNL.html", result, 20);
}
void testHedgingSimulator() {
TEST(testDeltaHedgingMeanPayoff);
TEST(testPlotDeltaHedgingHistogram);
}