#include "Put.h" #include #include #include #include #include "normal.h" #include "util.h" Put::~Put() { } Put::Put(double spot, double exercise, double r, double volatility, double timeToExpiry) { Put::spot = spot; Put::exercise = exercise; Put::r = r; Put::volatility = volatility; Put::timeToExpiry = timeToExpiry; timeSqrt = sqrt(timeToExpiry); d1 = getD1(); d2 = getD2(); delta = calcDelta(); gamma = calcGamma(d1, spot, volatility, timeSqrt);; theta = calcTheta(); rho = calcRho(); vega = calcVega(d1, spot, timeSqrt); } double Put::priceEuropeanBlackScholes() { return priceEuropeanBlackScholes(spot, exercise, r, volatility, timeToExpiry); } double Put::priceEuropeanBlackScholes(double spot, double exercise, double r, double volatility, double t) { double value = (exercise * exp(-r * t) * nc(-d2)) - (spot * nc(-d1)); if (value > 0) return value; else return 0; } double Put::priceEuropeanBinomial(int steps){ if (steps <= 0) steps = 16; return priceEuropeanBinomial(spot, exercise, r, volatility, timeToExpiry, steps); } double Put::priceEuropeanBinomial(double spot, double exercise, double r, double volatility, double t, int steps) { double deltaT = t/steps; // risklessRate = exp(r(At)) double risklessRate = exp(r * deltaT); double discountRate = 1/risklessRate; double u = exp(volatility * sqrt(deltaT)); // u = exp(vol * sqrt((At))) double d = 1/u; // d = exp-(vol * sqrt((At))) // //double d = exp(-volatility * sqrt(deltaT)); double probabilityUp = (risklessRate-d)/(u-d); double probabilityDown = 1 - probabilityUp; vector stockPrices(steps + 1); // Set prices of underlying at maturity stockPrices[0] = spot * pow(d, steps); double uu = u*u; for (int i = 1; i <= steps; i++) { stockPrices[i] = uu * stockPrices[i - 1]; } vector putValues(steps + 1); // Set call payoffs at maturity for (int i = 0; i <= steps; i++) { //putValues.add(Math.max(0.0, (stockPrices.get(i) - exercise))); putValues[i] = max(exercise - stockPrices[i], 0.0); } for (int step = steps - 1; step >= 0; --step) { for (int i = 0; i <= step; ++i) { double putValue = ((probabilityUp * putValues[i + 1]) + (probabilityDown * putValues[i])) * discountRate; putValues[i] = putValue; } } return putValues[0]; } double Put::priceEuropeanMonteCarlo(int numEstimates) { if (numEstimates <= 0) numEstimates = 100; return priceEuropeanMonteCarlo(spot, exercise, r, volatility, timeToExpiry, numEstimates); } double Put::priceEuropeanMonteCarlo(double spot, double exercise, double r, double volatility, double t, int numEstimates) { // double callValue, price, callValueTotal = 0; // // for (int i = 0; i < numEstimates; i++) { // callValue = getSimulatedValue(spot, exercise, r, volatility); // callValueTotal += callValue; // } // // price = exp(-r * timeToExpiry) * (callValueTotal/numEstimates); // return price; return 1.0; } double Put::getSimulatedValue(double spot, double exercise, double r, double volatility) { util u = util(); double randomNormal = u.getRandomFromStandardNormal(0, 1); double rMean = (r - (0.5 * pow(volatility,2))) * timeToExpiry; double sd = volatility * timeSqrt; double exponentTerm = rMean + (sd * randomNormal); double simulatedStockValue = spot * exp(exponentTerm); double simulatedCallValue = max(simulatedStockValue - exercise, 0); //cout << simulatedCallValue << endl; return simulatedCallValue; } double Put::calcDelta(){ return nc(d1); } double Put::calcTheta() { double theta =- (spot*volatility*ndf(d1)) / (2*timeSqrt) + r*exercise * exp(-r*timeToExpiry) * nc(-d2); return theta/365; } double Put::calcRho() { double rho = -exercise * timeToExpiry * exp(-r * timeToExpiry) * nc(-d2); return 0.01 * rho; }