C++:实现量化Jump-diffusion跳跃扩散过程测试实例

#include "jumpdiffusion.hpp"
#include "utilities.hpp"
#include <ql/time/daycounters/actual360.hpp>
#include <ql/instruments/europeanoption.hpp>
#include <ql/pricingengines/vanilla/analyticeuropeanengine.hpp>
#include <ql/pricingengines/vanilla/jumpdiffusionengine.hpp>
#include <ql/processes/merton76process.hpp>
#include <ql/termstructures/yield/flatforward.hpp>
#include <ql/termstructures/volatility/equityfx/blackconstantvol.hpp>
#include <ql/utilities/dataformatters.hpp>
#include <map>using namespace QuantLib;
using namespace boost::unit_test_framework;#undef REPORT_FAILURE_1
#define REPORT_FAILURE_1(greekName, payoff, exercise, s, q, r, today, v, \intensity, meanLogJump, jumpVol, expected, \calculated, error, tolerance) \BOOST_FAIL(exerciseTypeToString(exercise) << " " \<< payoff->optionType() << " option with " \<< payoffTypeToString(payoff) << " payoff:\n" \<< "    underlying value: " << s << "\n" \<< "    strike:           " << payoff->strike() <<"\n" \<< "    dividend yield:   " << io::rate(q) << "\n" \<< "    risk-free rate:   " << io::rate(r) << "\n" \<< "    reference date:   " << today << "\n" \<< "    maturity:         " << exercise->lastDate() << "\n" \<< "    volatility:       " << io::volatility(v) << "\n\n" \<< "    intensity:        " << intensity << "\n" \<< "    mean log-jump:    " << meanLogJump << "\n" \<< "    jump volatility:  " << jumpVol << "\n\n" \<< "    expected   " << greekName << ": " << expected << "\n" \<< "    calculated " << greekName << ": " << calculated << "\n"\<< "    error:            " << error << "\n" \<< "    tolerance:        "  << tolerance);#undef REPORT_FAILURE_2
#define REPORT_FAILURE_2(greekName, payoff, exercise, s, q, r, today, v, \intensity, gamma, expected, calculated, \error, tolerance) \BOOST_FAIL(exerciseTypeToString(exercise) << " " \<< payoff->optionType() << " option with " \<< payoffTypeToString(payoff) << " payoff:\n" \<< "    underlying value: " << s << "\n" \<< "    strike:           " << payoff->strike() <<"\n" \<< "    dividend yield:   " << io::rate(q) << "\n" \<< "    risk-free rate:   " << io::rate(r) << "\n" \<< "    reference date:   " << today << "\n" \<< "    maturity:         " << exercise->lastDate() << "\n" \<< "    volatility:       " << io::volatility(v) << "\n" \<< "    intensity:        " << intensity << "\n" \<< "    gamma:            " << gamma << "\n\n" \<< "    expected   " << greekName << ": " << expected << "\n" \<< "    calculated " << greekName << ": " << calculated << "\n"\<< "    error:            " << error << "\n" \<< "    tolerance:        " << tolerance);namespace {struct HaugMertonData {Option::Type type;Real strike;Real s;        // spotRate q;        // dividendRate r;        // risk-free rateTime t;        // time to maturityVolatility v;  // volatilityReal jumpIntensity;Real gamma;Real result;   // resultReal tol;      // tolerance};}void JumpDiffusionTest::testMerton76() {BOOST_TEST_MESSAGE("Testing Merton 76 jump-diffusion model ""for European options...");SavedSettings backup;/* The data below are from"Option pricing formulas", E.G. Haug, McGraw-Hill 1998, pag 9Haug use the arbitrary truncation criterium of 11 terms in the sum,which doesn't guarantee convergence up to 1e-2.Using Haug's criterium Haug's values have been correctly reproduced.the following values have the right 1e-2 accuracy: any value differentfrom Haug has been noted.*/HaugMertonData values[] = {//        type, strike,   spot,    q,    r,    t,  vol, int, gamma, value, tol// gamma = 0.25, strike = 80{ Option::Call,  80.00, 100.00, 0.00, 0.08, 0.10, 0.25, 1.0,  0.25, 20.67, 1e-2 },{ Option::Call,  80.00, 100.00, 0.00, 0.08, 0.25, 0.25, 1.0,  0.25, 21.74, 1e-2 },{ Option::Call,  80.00, 100.00, 0.00, 0.08, 0.50, 0.25, 1.0,  0.25, 23.63, 1e-2 },{ Option::Call,  80.00, 100.00, 0.00, 0.08, 0.10, 0.25, 5.0,  0.25, 20.65, 1e-2 },{ Option::Call,  80.00, 100.00, 0.00, 0.08, 0.25, 0.25, 5.0,  0.25, 21.70, 1e-2 },{ Option::Call,  80.00, 100.00, 0.00, 0.08, 0.50, 0.25, 5.0,  0.25, 23.61, 1e-2 },{ Option::Call,  80.00, 100.00, 0.00, 0.08, 0.10, 0.25,10.0,  0.25, 20.64, 1e-2 },{ Option::Call,  80.00, 100.00, 0.00, 0.08, 0.25, 0.25,10.0,  0.25, 21.70, 1e-2 },{ Option::Call,  80.00, 100.00, 0.00, 0.08, 0.50, 0.25,10.0,  0.25, 23.61, 1e-2 }, // Haug 23.28// gamma = 0.25, strike = 90{ Option::Call,  90.00, 100.00, 0.00, 0.08, 0.10, 0.25, 1.0,  0.25, 11.00, 1e-2 },{ Option::Call,  90.00, 100.00, 0.00, 0.08, 0.25, 0.25, 1.0,  0.25, 12.74, 1e-2 },{ Option::Call,  90.00, 100.00, 0.00, 0.08, 0.50, 0.25, 1.0,  0.25, 15.40, 1e-2 },{ Option::Call,  90.00, 100.00, 0.00, 0.08, 0.10, 0.25, 5.0,  0.25, 10.98, 1e-2 },{ Option::Call,  90.00, 100.00, 0.00, 0.08, 0.25, 0.25, 5.0,  0.25, 12.75, 1e-2 },{ Option::Call,  90.00, 100.00, 0.00, 0.08, 0.50, 0.25, 5.0,  0.25, 15.42, 1e-2 },{ Option::Call,  90.00, 100.00, 0.00, 0.08, 0.10, 0.25,10.0,  0.25, 10.98, 1e-2 },{ Option::Call,  90.00, 100.00, 0.00, 0.08, 0.25, 0.25,10.0,  0.25, 12.75, 1e-2 },{ Option::Call,  90.00, 100.00, 0.00, 0.08, 0.50, 0.25,10.0,  0.25, 15.42, 1e-2 }, // Haug 15.20// gamma = 0.25, strike = 100{ Option::Call, 100.00, 100.00, 0.00, 0.08, 0.10, 0.25, 1.0,  0.25,  3.42, 1e-2 },{ Option::Call, 100.00, 100.00, 0.00, 0.08, 0.25, 0.25, 1.0,  0.25,  5.88, 1e-2 },{ Option::Call, 100.00, 100.00, 0.00, 0.08, 0.50, 0.25, 1.0,  0.25,  8.95, 1e-2 },{ Option::Call, 100.00, 100.00, 0.00, 0.08, 0.10, 0.25, 5.0,  0.25,  3.51, 1e-2 },{ Option::Call, 100.00, 100.00, 0.00, 0.08, 0.25, 0.25, 5.0,  0.25,  5.96, 1e-2 },{ Option::Call, 100.00, 100.00, 0.00, 0.08, 0.50, 0.25, 5.0,  0.25,  9.02, 1e-2 },{ Option::Call, 100.00, 100.00, 0.00, 0.08, 0.10, 0.25,10.0,  0.25,  3.53, 1e-2 },{ Option::Call, 100.00, 100.00, 0.00, 0.08, 0.25, 0.25,10.0,  0.25,  5.97, 1e-2 },{ Option::Call, 100.00, 100.00, 0.00, 0.08, 0.50, 0.25,10.0,  0.25,  9.03, 1e-2 }, // Haug 8.89// gamma = 0.25, strike = 110{ Option::Call, 110.00, 100.00, 0.00, 0.08, 0.10, 0.25, 1.0,  0.25,  0.55, 1e-2 },{ Option::Call, 110.00, 100.00, 0.00, 0.08, 0.25, 0.25, 1.0,  0.25,  2.11, 1e-2 },{ Option::Call, 110.00, 100.00, 0.00, 0.08, 0.50, 0.25, 1.0,  0.25,  4.67, 1e-2 },{ Option::Call, 110.00, 100.00, 0.00, 0.08, 0.10, 0.25, 5.0,  0.25,  0.56, 1e-2 },{ Option::Call, 110.00, 100.00, 0.00, 0.08, 0.25, 0.25, 5.0,  0.25,  2.16, 1e-2 },{ Option::Call, 110.00, 100.00, 0.00, 0.08, 0.50, 0.25, 5.0,  0.25,  4.73, 1e-2 },{ Option::Call, 110.00, 100.00, 0.00, 0.08, 0.10, 0.25,10.0,  0.25,  0.56, 1e-2 },{ Option::Call, 110.00, 100.00, 0.00, 0.08, 0.25, 0.25,10.0,  0.25,  2.17, 1e-2 },{ Option::Call, 110.00, 100.00, 0.00, 0.08, 0.50, 0.25,10.0,  0.25,  4.74, 1e-2 }, // Haug 4.66// gamma = 0.25, strike = 120{ Option::Call, 120.00, 100.00, 0.00, 0.08, 0.10, 0.25, 1.0,  0.25,  0.10, 1e-2 },{ Option::Call, 120.00, 100.00, 0.00, 0.08, 0.25, 0.25, 1.0,  0.25,  0.64, 1e-2 },{ Option::Call, 120.00, 100.00, 0.00, 0.08, 0.50, 0.25, 1.0,  0.25,  2.23, 1e-2 },{ Option::Call, 120.00, 100.00, 0.00, 0.08, 0.10, 0.25, 5.0,  0.25,  0.06, 1e-2 },{ Option::Call, 120.00, 100.00, 0.00, 0.08, 0.25, 0.25, 5.0,  0.25,  0.63, 1e-2 },{ Option::Call, 120.00, 100.00, 0.00, 0.08, 0.50, 0.25, 5.0,  0.25,  2.25, 1e-2 },{ Option::Call, 120.00, 100.00, 0.00, 0.08, 0.10, 0.25,10.0,  0.25,  0.05, 1e-2 },{ Option::Call, 120.00, 100.00, 0.00, 0.08, 0.25, 0.25,10.0,  0.25,  0.62, 1e-2 },{ Option::Call, 120.00, 100.00, 0.00, 0.08, 0.50, 0.25,10.0,  0.25,  2.25, 1e-2 }, // Haug 2.21// gamma = 0.50, strike = 80{ Option::Call,  80.00, 100.00, 0.00, 0.08, 0.10, 0.25, 1.0,  0.50, 20.72, 1e-2 },{ Option::Call,  80.00, 100.00, 0.00, 0.08, 0.25, 0.25, 1.0,  0.50, 21.83, 1e-2 },{ Option::Call,  80.00, 100.00, 0.00, 0.08, 0.50, 0.25, 1.0,  0.50, 23.71, 1e-2 },{ Option::Call,  80.00, 100.00, 0.00, 0.08, 0.10, 0.25, 5.0,  0.50, 20.66, 1e-2 },{ Option::Call,  80.00, 100.00, 0.00, 0.08, 0.25, 0.25, 5.0,  0.50, 21.73, 1e-2 },{ Option::Call,  80.00, 100.00, 0.00, 0.08, 0.50, 0.25, 5.0,  0.50, 23.63, 1e-2 },{ Option::Call,  80.00, 100.00, 0.00, 0.08, 0.10, 0.25,10.0,  0.50, 20.65, 1e-2 },{ Option::Call,  80.00, 100.00, 0.00, 0.08, 0.25, 0.25,10.0,  0.50, 21.71, 1e-2 },{ Option::Call,  80.00, 100.00, 0.00, 0.08, 0.50, 0.25,10.0,  0.50, 23.61, 1e-2 }, // Haug 23.28// gamma = 0.50, strike = 90{ Option::Call,  90.00, 100.00, 0.00, 0.08, 0.10, 0.25, 1.0,  0.50, 11.04, 1e-2 },{ Option::Call,  90.00, 100.00, 0.00, 0.08, 0.25, 0.25, 1.0,  0.50, 12.72, 1e-2 },{ Option::Call,  90.00, 100.00, 0.00, 0.08, 0.50, 0.25, 1.0,  0.50, 15.34, 1e-2 },{ Option::Call,  90.00, 100.00, 0.00, 0.08, 0.10, 0.25, 5.0,  0.50, 11.02, 1e-2 },{ Option::Call,  90.00, 100.00, 0.00, 0.08, 0.25, 0.25, 5.0,  0.50, 12.76, 1e-2 },{ Option::Call,  90.00, 100.00, 0.00, 0.08, 0.50, 0.25, 5.0,  0.50, 15.41, 1e-2 },{ Option::Call,  90.00, 100.00, 0.00, 0.08, 0.10, 0.25,10.0,  0.50, 11.00, 1e-2 },{ Option::Call,  90.00, 100.00, 0.00, 0.08, 0.25, 0.25,10.0,  0.50, 12.75, 1e-2 },{ Option::Call,  90.00, 100.00, 0.00, 0.08, 0.50, 0.25,10.0,  0.50, 15.41, 1e-2 }, // Haug 15.18// gamma = 0.50, strike = 100{ Option::Call, 100.00, 100.00, 0.00, 0.08, 0.10, 0.25, 1.0,  0.50,  3.14, 1e-2 },{ Option::Call, 100.00, 100.00, 0.00, 0.08, 0.25, 0.25, 1.0,  0.50,  5.58, 1e-2 },{ Option::Call, 100.00, 100.00, 0.00, 0.08, 0.50, 0.25, 1.0,  0.50,  8.71, 1e-2 },{ Option::Call, 100.00, 100.00, 0.00, 0.08, 0.10, 0.25, 5.0,  0.50,  3.39, 1e-2 },{ Option::Call, 100.00, 100.00, 0.00, 0.08, 0.25, 0.25, 5.0,  0.50,  5.87, 1e-2 },{ Option::Call, 100.00, 100.00, 0.00, 0.08, 0.50, 0.25, 5.0,  0.50,  8.96, 1e-2 },{ Option::Call, 100.00, 100.00, 0.00, 0.08, 0.10, 0.25,10.0,  0.50,  3.46, 1e-2 },{ Option::Call, 100.00, 100.00, 0.00, 0.08, 0.25, 0.25,10.0,  0.50,  5.93, 1e-2 },{ Option::Call, 100.00, 100.00, 0.00, 0.08, 0.50, 0.25,10.0,  0.50,  9.00, 1e-2 }, // Haug 8.85// gamma = 0.50, strike = 110{ Option::Call, 110.00, 100.00, 0.00, 0.08, 0.10, 0.25, 1.0,  0.50,  0.53, 1e-2 },{ Option::Call, 110.00, 100.00, 0.00, 0.08, 0.25, 0.25, 1.0,  0.50,  1.93, 1e-2 },{ Option::Call, 110.00, 100.00, 0.00, 0.08, 0.50, 0.25, 1.0,  0.50,  4.42, 1e-2 },{ Option::Call, 110.00, 100.00, 0.00, 0.08, 0.10, 0.25, 5.0,  0.50,  0.58, 1e-2 },{ Option::Call, 110.00, 100.00, 0.00, 0.08, 0.25, 0.25, 5.0,  0.50,  2.11, 1e-2 },{ Option::Call, 110.00, 100.00, 0.00, 0.08, 0.50, 0.25, 5.0,  0.50,  4.67, 1e-2 },{ Option::Call, 110.00, 100.00, 0.00, 0.08, 0.10, 0.25,10.0,  0.50,  0.57, 1e-2 },{ Option::Call, 110.00, 100.00, 0.00, 0.08, 0.25, 0.25,10.0,  0.50,  2.14, 1e-2 },{ Option::Call, 110.00, 100.00, 0.00, 0.08, 0.50, 0.25,10.0,  0.50,  4.71, 1e-2 }, // Haug 4.62// gamma = 0.50, strike = 120{ Option::Call, 120.00, 100.00, 0.00, 0.08, 0.10, 0.25, 1.0,  0.50,  0.19, 1e-2 },{ Option::Call, 120.00, 100.00, 0.00, 0.08, 0.25, 0.25, 1.0,  0.50,  0.71, 1e-2 },{ Option::Call, 120.00, 100.00, 0.00, 0.08, 0.50, 0.25, 1.0,  0.50,  2.15, 1e-2 },{ Option::Call, 120.00, 100.00, 0.00, 0.08, 0.10, 0.25, 5.0,  0.50,  0.10, 1e-2 },{ Option::Call, 120.00, 100.00, 0.00, 0.08, 0.25, 0.25, 5.0,  0.50,  0.66, 1e-2 },{ Option::Call, 120.00, 100.00, 0.00, 0.08, 0.50, 0.25, 5.0,  0.50,  2.23, 1e-2 },{ Option::Call, 120.00, 100.00, 0.00, 0.08, 0.10, 0.25,10.0,  0.50,  0.07, 1e-2 },{ Option::Call, 120.00, 100.00, 0.00, 0.08, 0.25, 0.25,10.0,  0.50,  0.64, 1e-2 },{ Option::Call, 120.00, 100.00, 0.00, 0.08, 0.50, 0.25,10.0,  0.50,  2.24, 1e-2 }, // Haug 2.19// gamma = 0.75, strike = 80{ Option::Call,  80.00, 100.00, 0.00, 0.08, 0.10, 0.25, 1.0,  0.75, 20.79, 1e-2 },{ Option::Call,  80.00, 100.00, 0.00, 0.08, 0.25, 0.25, 1.0,  0.75, 21.96, 1e-2 },{ Option::Call,  80.00, 100.00, 0.00, 0.08, 0.50, 0.25, 1.0,  0.75, 23.86, 1e-2 },{ Option::Call,  80.00, 100.00, 0.00, 0.08, 0.10, 0.25, 5.0,  0.75, 20.68, 1e-2 },{ Option::Call,  80.00, 100.00, 0.00, 0.08, 0.25, 0.25, 5.0,  0.75, 21.78, 1e-2 },{ Option::Call,  80.00, 100.00, 0.00, 0.08, 0.50, 0.25, 5.0,  0.75, 23.67, 1e-2 },{ Option::Call,  80.00, 100.00, 0.00, 0.08, 0.10, 0.25,10.0,  0.75, 20.66, 1e-2 },{ Option::Call,  80.00, 100.00, 0.00, 0.08, 0.25, 0.25,10.0,  0.75, 21.74, 1e-2 },{ Option::Call,  80.00, 100.00, 0.00, 0.08, 0.50, 0.25,10.0,  0.75, 23.64, 1e-2 }, // Haug 23.30// gamma = 0.75, strike = 90{ Option::Call,  90.00, 100.00, 0.00, 0.08, 0.10, 0.25, 1.0,  0.75, 11.11, 1e-2 },{ Option::Call,  90.00, 100.00, 0.00, 0.08, 0.25, 0.25, 1.0,  0.75, 12.75, 1e-2 },{ Option::Call,  90.00, 100.00, 0.00, 0.08, 0.50, 0.25, 1.0,  0.75, 15.30, 1e-2 },{ Option::Call,  90.00, 100.00, 0.00, 0.08, 0.10, 0.25, 5.0,  0.75, 11.09, 1e-2 },{ Option::Call,  90.00, 100.00, 0.00, 0.08, 0.25, 0.25, 5.0,  0.75, 12.78, 1e-2 },{ Option::Call,  90.00, 100.00, 0.00, 0.08, 0.50, 0.25, 5.0,  0.75, 15.39, 1e-2 },{ Option::Call,  90.00, 100.00, 0.00, 0.08, 0.10, 0.25,10.0,  0.75, 11.04, 1e-2 },{ Option::Call,  90.00, 100.00, 0.00, 0.08, 0.25, 0.25,10.0,  0.75, 12.76, 1e-2 },{ Option::Call,  90.00, 100.00, 0.00, 0.08, 0.50, 0.25,10.0,  0.75, 15.40, 1e-2 }, // Haug 15.17// gamma = 0.75, strike = 100{ Option::Call, 100.00, 100.00, 0.00, 0.08, 0.10, 0.25, 1.0,  0.75,  2.70, 1e-2 },{ Option::Call, 100.00, 100.00, 0.00, 0.08, 0.25, 0.25, 1.0,  0.75,  5.08, 1e-2 },{ Option::Call, 100.00, 100.00, 0.00, 0.08, 0.50, 0.25, 1.0,  0.75,  8.24, 1e-2 },{ Option::Call, 100.00, 100.00, 0.00, 0.08, 0.10, 0.25, 5.0,  0.75,  3.16, 1e-2 },{ Option::Call, 100.00, 100.00, 0.00, 0.08, 0.25, 0.25, 5.0,  0.75,  5.71, 1e-2 },{ Option::Call, 100.00, 100.00, 0.00, 0.08, 0.50, 0.25, 5.0,  0.75,  8.85, 1e-2 },{ Option::Call, 100.00, 100.00, 0.00, 0.08, 0.10, 0.25,10.0,  0.75,  3.33, 1e-2 },{ Option::Call, 100.00, 100.00, 0.00, 0.08, 0.25, 0.25,10.0,  0.75,  5.85, 1e-2 },{ Option::Call, 100.00, 100.00, 0.00, 0.08, 0.50, 0.25,10.0,  0.75,  8.95, 1e-2 }, // Haug 8.79// gamma = 0.75, strike = 110{ Option::Call, 110.00, 100.00, 0.00, 0.08, 0.10, 0.25, 1.0,  0.75,  0.54, 1e-2 },{ Option::Call, 110.00, 100.00, 0.00, 0.08, 0.25, 0.25, 1.0,  0.75,  1.69, 1e-2 },{ Option::Call, 110.00, 100.00, 0.00, 0.08, 0.50, 0.25, 1.0,  0.75,  3.99, 1e-2 },{ Option::Call, 110.00, 100.00, 0.00, 0.08, 0.10, 0.25, 5.0,  0.75,  0.62, 1e-2 },{ Option::Call, 110.00, 100.00, 0.00, 0.08, 0.25, 0.25, 5.0,  0.75,  2.05, 1e-2 },{ Option::Call, 110.00, 100.00, 0.00, 0.08, 0.50, 0.25, 5.0,  0.75,  4.57, 1e-2 },{ Option::Call, 110.00, 100.00, 0.00, 0.08, 0.10, 0.25,10.0,  0.75,  0.60, 1e-2 },{ Option::Call, 110.00, 100.00, 0.00, 0.08, 0.25, 0.25,10.0,  0.75,  2.11, 1e-2 },{ Option::Call, 110.00, 100.00, 0.00, 0.08, 0.50, 0.25,10.0,  0.75,  4.66, 1e-2 }, // Haug 4.56// gamma = 0.75, strike = 120{ Option::Call, 120.00, 100.00, 0.00, 0.08, 0.10, 0.25, 1.0,  0.75,  0.29, 1e-2 },{ Option::Call, 120.00, 100.00, 0.00, 0.08, 0.25, 0.25, 1.0,  0.75,  0.84, 1e-2 },{ Option::Call, 120.00, 100.00, 0.00, 0.08, 0.50, 0.25, 1.0,  0.75,  2.09, 1e-2 },{ Option::Call, 120.00, 100.00, 0.00, 0.08, 0.10, 0.25, 5.0,  0.75,  0.15, 1e-2 },{ Option::Call, 120.00, 100.00, 0.00, 0.08, 0.25, 0.25, 5.0,  0.75,  0.71, 1e-2 },{ Option::Call, 120.00, 100.00, 0.00, 0.08, 0.50, 0.25, 5.0,  0.75,  2.21, 1e-2 },{ Option::Call, 120.00, 100.00, 0.00, 0.08, 0.10, 0.25,10.0,  0.75,  0.11, 1e-2 },{ Option::Call, 120.00, 100.00, 0.00, 0.08, 0.25, 0.25,10.0,  0.75,  0.67, 1e-2 },{ Option::Call, 120.00, 100.00, 0.00, 0.08, 0.50, 0.25,10.0,  0.75,  2.23, 1e-2 }  // Haug 2.17
};DayCounter dc = Actual360();Date today = Date::todaysDate();ext::shared_ptr<SimpleQuote> spot(new SimpleQuote(0.0));ext::shared_ptr<SimpleQuote> qRate(new SimpleQuote(0.0));ext::shared_ptr<YieldTermStructure> qTS = flatRate(today, qRate, dc);ext::shared_ptr<SimpleQuote> rRate(new SimpleQuote(0.0));ext::shared_ptr<YieldTermStructure> rTS = flatRate(today, rRate, dc);ext::shared_ptr<SimpleQuote> vol(new SimpleQuote(0.0));ext::shared_ptr<BlackVolTermStructure> volTS = flatVol(today, vol, dc);ext::shared_ptr<SimpleQuote> jumpIntensity(new SimpleQuote(0.0));ext::shared_ptr<SimpleQuote> meanLogJump(new SimpleQuote(0.0));ext::shared_ptr<SimpleQuote> jumpVol(new SimpleQuote(0.0));ext::shared_ptr<Merton76Process> stochProcess(new Merton76Process(Handle<Quote>(spot),Handle<YieldTermStructure>(qTS),Handle<YieldTermStructure>(rTS),Handle<BlackVolTermStructure>(volTS),Handle<Quote>(jumpIntensity),Handle<Quote>(meanLogJump),Handle<Quote>(jumpVol)));ext::shared_ptr<PricingEngine> engine(new JumpDiffusionEngine(stochProcess));for (auto& value : values) {ext::shared_ptr<StrikedTypePayoff> payoff(new PlainVanillaPayoff(value.type, value.strike));Date exDate = today + timeToDays(value.t);ext::shared_ptr<Exercise> exercise(new EuropeanExercise(exDate));spot->setValue(value.s);qRate->setValue(value.q);rRate->setValue(value.r);jumpIntensity->setValue(value.jumpIntensity);// delta in Haug's notationReal jVol = value.v * std::sqrt(value.gamma / value.jumpIntensity);jumpVol->setValue(jVol);// z in Haug's notationReal diffusionVol = value.v * std::sqrt(1.0 - value.gamma);vol  ->setValue(diffusionVol);// Haug is assuming zero meanJumpReal meanJump = 0.0;meanLogJump->setValue(std::log(1.0+meanJump)-0.5*jVol*jVol);Volatility totalVol =std::sqrt(value.jumpIntensity * jVol * jVol + diffusionVol * diffusionVol);Volatility volError = std::fabs(totalVol - value.v);QL_REQUIRE(volError<1e-13,volError << " mismatch");EuropeanOption option(payoff, exercise);option.setPricingEngine(engine);Real calculated = option.NPV();Real error = std::fabs(calculated - value.result);if (error > value.tol) {REPORT_FAILURE_2("value", payoff, exercise, value.s, value.q, value.r, today, value.v,value.jumpIntensity, value.gamma, value.result, calculated, error,value.tol);}}
}void JumpDiffusionTest::testGreeks() {BOOST_TEST_MESSAGE("Testing jump-diffusion option greeks...");SavedSettings backup;std::map<std::string,Real> calculated, expected, tolerance;tolerance["delta"]  = 1.0e-4;tolerance["gamma"]  = 1.0e-4;tolerance["theta"]  = 1.1e-4;tolerance["rho"]    = 1.0e-4;tolerance["divRho"] = 1.0e-4;tolerance["vega"]   = 1.0e-4;Option::Type types[] = { Option::Put, Option::Call };Real strikes[] = { 50.0, 100.0, 150.0 };Real underlyings[] = { 100.0 };Rate qRates[] = { -0.05, 0.0, 0.05 };Rate rRates[] = { 0.0, 0.01, 0.2 };// The testsuite check fails if a too short maturity is chosen(i.e. 1 year).// The problem is in the theta calculation. With the finite difference(fd) method// we might get values too close to the jump steps, invalidating the fd methodology// for calculating greeks.Time residualTimes[] = { 5.0 };Volatility vols[] = { 0.11 };Real jInt[] = { 1.0, 5.0 };Real mLJ[] = { -0.20, 0.0, 0.20 };Volatility jV[] = { 0.01, 0.25 };DayCounter dc = Actual360();Date today = Date::todaysDate();Settings::instance().evaluationDate() = today;ext::shared_ptr<SimpleQuote> spot(new SimpleQuote(0.0));ext::shared_ptr<SimpleQuote> qRate(new SimpleQuote(0.0));Handle<YieldTermStructure> qTS(flatRate(qRate, dc));ext::shared_ptr<SimpleQuote> rRate(new SimpleQuote(0.0));Handle<YieldTermStructure> rTS(flatRate(rRate, dc));ext::shared_ptr<SimpleQuote> vol(new SimpleQuote(0.0));Handle<BlackVolTermStructure> volTS(flatVol(vol, dc));ext::shared_ptr<SimpleQuote> jumpIntensity(new SimpleQuote(0.0));ext::shared_ptr<SimpleQuote> meanLogJump(new SimpleQuote(0.0));ext::shared_ptr<SimpleQuote> jumpVol(new SimpleQuote(0.0));ext::shared_ptr<Merton76Process> stochProcess(new Merton76Process(Handle<Quote>(spot), qTS, rTS, volTS,Handle<Quote>(jumpIntensity),Handle<Quote>(meanLogJump),Handle<Quote>(jumpVol)));ext::shared_ptr<StrikedTypePayoff> payoff;// The jumpdiffusionengine greeks are very sensitive to the// convergence level.  A tolerance of 1.0e-08 is usually// sufficient to get reasonable resultsext::shared_ptr<PricingEngine> engine(new JumpDiffusionEngine(stochProcess,1e-08));for (auto& type : types) {for (Real strike : strikes) {for (Real& jj1 : jInt) {jumpIntensity->setValue(jj1);for (Real& jj2 : mLJ) {meanLogJump->setValue(jj2);for (Real& jj3 : jV) {jumpVol->setValue(jj3);for (Real residualTime : residualTimes) {Date exDate = today + timeToDays(residualTime);ext::shared_ptr<Exercise> exercise(new EuropeanExercise(exDate));for (Size kk = 0; kk < 1; kk++) {// option to checkif (kk == 0) {payoff = ext::shared_ptr<StrikedTypePayoff>(new PlainVanillaPayoff(type, strike));} else if (kk == 1) {payoff = ext::shared_ptr<StrikedTypePayoff>(new CashOrNothingPayoff(type, strike, 100.0));}EuropeanOption option(payoff, exercise);option.setPricingEngine(engine);for (Real u : underlyings) {for (Real q : qRates) {for (Real r : rRates) {for (Real v : vols) {spot->setValue(u);qRate->setValue(q);rRate->setValue(r);vol->setValue(v);Real value = option.NPV();calculated["delta"] = option.delta();calculated["gamma"] = option.gamma();calculated["theta"] = option.theta();calculated["rho"] = option.rho();calculated["divRho"] = option.dividendRho();calculated["vega"] = option.vega();if (value > spot->value() * 1.0e-5) {// perturb spot and get delta and gammaReal du = u * 1.0e-5;spot->setValue(u + du);Real value_p = option.NPV(),delta_p = option.delta();spot->setValue(u - du);Real value_m = option.NPV(),delta_m = option.delta();spot->setValue(u);expected["delta"] =(value_p - value_m) / (2 * du);expected["gamma"] =(delta_p - delta_m) / (2 * du);// perturb rates and get rho and dividend rhoSpread dr = 1.0e-5;rRate->setValue(r + dr);value_p = option.NPV();rRate->setValue(r - dr);value_m = option.NPV();rRate->setValue(r);expected["rho"] =(value_p - value_m) / (2 * dr);Spread dq = 1.0e-5;qRate->setValue(q + dq);value_p = option.NPV();qRate->setValue(q - dq);value_m = option.NPV();qRate->setValue(q);expected["divRho"] =(value_p - value_m) / (2 * dq);// perturb volatility and get vegaVolatility dv = v * 1.0e-4;vol->setValue(v + dv);value_p = option.NPV();vol->setValue(v - dv);value_m = option.NPV();vol->setValue(v);expected["vega"] =(value_p - value_m) / (2 * dv);// get theta from time-shifted optionsTime dT = dc.yearFraction(today - 1, today + 1);Settings::instance().evaluationDate() =today - 1;value_m = option.NPV();Settings::instance().evaluationDate() =today + 1;value_p = option.NPV();Settings::instance().evaluationDate() = today;expected["theta"] = (value_p - value_m) / dT;// comparestd::map<std::string, Real>::iterator it;for (it = expected.begin();it != expected.end(); ++it) {std::string greek = it->first;Real expct = expected[greek],calcl = calculated[greek],tol = tolerance[greek];Real error = std::fabs(expct - calcl);if (error > tol) {REPORT_FAILURE_1(greek, payoff, exercise, u, q, r,today, v, jj1, jj2, jj3, expct,calcl, error, tol);}}}}}}}}}} // strike loop}}}} // type loop
}test_suite* JumpDiffusionTest::suite() {auto* suite = BOOST_TEST_SUITE("Jump-diffusion tests");suite->add(QUANTLIB_TEST_CASE(&JumpDiffusionTest::testMerton76));suite->add(QUANTLIB_TEST_CASE(&JumpDiffusionTest::testGreeks));return suite;
}

该博文为原创文章,未经博主同意不得转。
本文章博客地址:https://cplusplus.blog.csdn.net/article/details/128364255

C++:实现量化Jump-diffusion跳跃扩散过程测试实例相关推荐

  1. C++:实现量化SMM Caplet均匀校准测试实例

    C++:实现量化SMM Caplet均匀校准测试实例 #include "markovfunctional.hpp" #include "utilities.hpp&qu ...

  2. C++:实现量化相关的Interpolation插值测试实例

    C++:实现量化相关的Interpolation插值测试实例 #include "interpolations.hpp" #include "utilities.hpp& ...

  3. C++:实现量化dividend option股息期权 测试实例

    C++:实现量化dividend option股息期权 测试实例 #include "dividendoption.hpp" #include "utilities.hp ...

  4. C++:实现量化compound option复合期权测试实例

    C++:实现量化compound option复合期权测试实例 #include "compoundoption.hpp" #include "utilities.hpp ...

  5. C++:实现量化Path generation路径生成测试实例

    C++:实现量化Path generation路径生成测试实例 #include "pathgenerator.hpp" #include "utilities.hpp& ...

  6. C++:实现量化cliquet option棘轮期权测试实例

    C++:实现量化cliquet option棘轮期权测试实例 #include "cliquetoption.hpp" #include "utilities.hpp&q ...

  7. C++:实现量化期权定价理论方法之一Bates模型测试实例

    C++:实现量化期权定价理论方法之一Bates模型测试实例 #include "batesmodel.hpp" #include "utilities.hpp" ...

  8. C++:实现量化Piecewise yield曲线测试实例

    C++:实现量化Piecewise yield曲线测试实例 #include "piecewiseyieldcurve.hpp" #include "utilities. ...

  9. C++jump game跳跃游戏的算法(附完整源码)

    C++jump game跳跃游戏的算法 C++实现jump game跳跃游戏的算法完整源码(定义,实现,main函数测试) C++实现jump game跳跃游戏的算法完整源码(定义,实现,main函数 ...

最新文章

  1. PyTorch学习之六个学习率调整策略
  2. Vim 删除不包含指定字符串的行及统计匹配个数
  3. qt槽函数如何传递多个参数_Qt:在发出信号后尝试将多个引用传递给槽函数
  4. 利用cross join 构造大量测试数据
  5. 【人体姿态估计2】Real-time Multi-person 2d pose estimation using part affinity fields_2017
  6. Java——设计模式(工厂方法模式)
  7. 《Android开发艺术探索》读书笔记 (10) 第10章 Android的消息机制
  8. cloud 异步远程调用_异步远程工作的意外好处-以及如何拥抱它们
  9. 05-按钮的基本使用-开发步骤
  10. oracle 数据库 字符串函数
  11. AOS编排语言系列教程(三):创建子网Subnet
  12. android 标题栏进度圈使用方法,Android 标题栏显示进度条
  13. linux 备份iphone,用linux搭建Mac备份服务器,伪TimeCapsule
  14. NHibernate的缓存管理机制
  15. Mac Android studio 修改历史查看
  16. Chrome 离线下载最佳方法
  17. java 文档比较功能_java 实现在线比较两个版本的Word文档的功能
  18. 视觉SLAM和激光SLAM的实现
  19. java中laber字体颜色设置,重写jxl中可用的颜色实现自定义颜色
  20. 共享充电宝PCBA方案开发设计

热门文章

  1. PC硬件之我见——CPU篇
  2. Android 用Groovy实现扇贝阅读APP的自动阅读功能
  3. 拼多多 2020校园招聘 二维表第k大数(二分)
  4. 垃圾分类微信小程序——云开发+CMS+微应用+百度智能云图片识别
  5. 用 canvas 操作图片像素
  6. 云服务器的概念(云服务器年度最低价来了,就要抓住双11)
  7. 国内云服务器怎么选配置?如何低价购买国内云主机?
  8. 解决Intellij idea 修改控制台的字体样式问题
  9. PHP规范PSR13(链接定义接口)介绍
  10. 西装证件照如何制作?快速制作教程来啦