Write DigitalCallOption and DigitalPutOption classes. Refactor PutOption so it extends PathIndependentOption.
这个题目的要求看起来并不算特别难。但是编写的时候也遇到了一些问题:c++ 错误提示:不能使用抽象类对象,这是因为基类的虚函数需要重构,但是PutOption的函数和基类不一致,这个需要改成一致才行。参考代码如下:
DigitalCallOption.h
#pragma once #include "stdafx.h" #include "BlackScholesModel.h" #include "PathIndependentOption.h" #include "testing.h" #include "MonteCarloPricer.h" class DigitalCallOption : public PathIndependentOption { public: /* Calculate the payoff of the option given a history of prices */ double payoff(double endStockPrice) const; double payoff( const std::vector<double>& stockPrices ) const; double price(const BlackScholesModel& bsm) const; bool isPathDependent() const { return false; }; }; void testDigitalCallOption();
DigitalCallOption.cpp
#include "DigitalCallOption.h" double DigitalCallOption::payoff(double endStockPrice) const { if (endStockPrice > getStrike()) { return 1.0; } else { return 0.0; } } double DigitalCallOption::payoff(const std::vector<double>& stockPrices) const { double stockAtMaturity = stockPrices.back(); return payoff(stockAtMaturity); } double DigitalCallOption::price( const BlackScholesModel& bsm) const { MonteCarloPricer pricer; return pricer.price(*this, bsm); } ////////////////////////// // // Test the call option class // // ////////////////////////// static void testDigitalCallOptionPayoff() { DigitalCallOption dc; dc.setStrike(105.0); dc.setMaturity(2.0); std::vector<double> d; d.push_back(110.0); ASSERT_APPROX_EQUAL(dc.payoff(d), 1.0, 0.001); d[0] = 100.0; ASSERT_APPROX_EQUAL(dc.payoff(d), 0.0, 0.001); } static void testDigitalCallOptionPrice() { DigitalCallOption dc; dc.setStrike(105.0); dc.setMaturity(2.0); BlackScholesModel bsm; bsm.date = 1.0; bsm.volatility = 0.0001; bsm.riskFreeRate = 0.0001; bsm.stockPrice = 100000.0; double price = dc.price(bsm); ASSERT_APPROX_EQUAL(price, 1.0, 0.01); } void testDigitalCallOption() { TEST(testDigitalCallOptionPrice); TEST(testDigitalCallOptionPayoff); }
DigitalPutOption.h
#pragma once #include "stdafx.h" #include "matlib.h" #include "BlackScholesModel.h" #include "PathIndependentOption.h" #include "testing.h" #include "MonteCarloPricer.h" class DigitalPutOption : public PathIndependentOption { public: /* Calculate the payoff of the option given a history of prices */ double payoff(double endStockPrice) const; double payoff( const std::vector<double>& stockPrices ) const; double price(const BlackScholesModel& bsm) const; bool isPathDependent() const { return false; }; }; void testDigitalPutOption();
DigitalPutOption.cpp
#include "DigitalPutOption.h" double DigitalPutOption::payoff(double endStockPrice) const { if (endStockPrice >= getStrike()) { return 0.0; } else { return 1.0; } } double DigitalPutOption::payoff(const std::vector<double>& stockPrices) const { double stockAtMaturity = stockPrices.back(); return payoff(stockAtMaturity); } double DigitalPutOption::price( const BlackScholesModel& bsm) const { MonteCarloPricer pricer; return pricer.price(*this, bsm); } ////////////////////////// // // Test the call option class // // ////////////////////////// static void testDigitalPutOptionPayoff() { DigitalPutOption pc; pc.setStrike(105.0); pc.setMaturity(2.0); std::vector<double> d; d.push_back(110.0); ASSERT_APPROX_EQUAL(pc.payoff(d), 0.0, 0.001); d[0] = 100.0; ASSERT_APPROX_EQUAL(pc.payoff(d), 1.0, 0.001); } static void testDigitalPutOptionPrice() { DigitalPutOption pc; pc.setStrike(105.0); pc.setMaturity(2.0); BlackScholesModel bsm; bsm.date = 1.0; bsm.volatility = 0.001; bsm.riskFreeRate = 0.05; bsm.stockPrice = 100000.0; double price = pc.price(bsm); ASSERT_APPROX_EQUAL(price, 0.0, 0.01); } void testDigitalPutOption() { TEST(testDigitalPutOptionPrice); TEST(testDigitalPutOptionPayoff); }