Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
Functions
commodityapo.cpp File Reference
#include <oret/toplevelfixture.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/timer/timer.hpp>
#include <ql/currencies/america.hpp>
#include <ql/exercise.hpp>
#include <ql/math/interpolations/linearinterpolation.hpp>
#include <ql/termstructures/volatility/equityfx/blackconstantvol.hpp>
#include <ql/termstructures/yield/flatforward.hpp>
#include <ql/time/calendars/unitedstates.hpp>
#include <qle/instruments/commodityapo.hpp>
#include <qle/pricingengines/commodityapoengine.hpp>
#include <qle/termstructures/pricecurve.hpp>

Go to the source code of this file.

Functions

 BOOST_AUTO_TEST_CASE (testCommodityAPO)
 

Function Documentation

◆ BOOST_AUTO_TEST_CASE()

BOOST_AUTO_TEST_CASE ( testCommodityAPO  )

Definition at line 57 of file commodityapo.cpp.

57 {
58
59 BOOST_TEST_MESSAGE("Testing Commodity APO Analytical Approximation vs MC Pricing");
60
61 SavedSettings backup;
62
63 Date today(5, Feb, 2019);
64 Settings::instance().evaluationDate() = today;
65 Calendar cal = UnitedStates(UnitedStates::Settlement);
66
67 // Market - flat price curve
68 std::vector<Date> dates = {today + 1 * Years, today + 5 * Years, today + 10 * Years};
69 std::vector<Real> prices = {100.0, 100.0, 100.0};
70 DayCounter dc = Actual365Fixed();
71 Handle<QuantExt::PriceTermStructure> priceCurve(
72 QuantLib::ext::make_shared<InterpolatedPriceCurve<Linear>>(today, dates, prices, dc, USDCurrency()));
73 priceCurve->enableExtrapolation();
74
75 // Market - flat discount curve
76 Handle<Quote> rateQuote(QuantLib::ext::make_shared<SimpleQuote>(0.01));
77 Handle<YieldTermStructure> discountCurve(QuantLib::ext::make_shared<FlatForward>(today, rateQuote, dc, Compounded, Annual));
78
79 // Market - flat volatility structure
80 Handle<QuantLib::BlackVolTermStructure> vol(QuantLib::ext::make_shared<QuantLib::BlackConstantVol>(today, cal, 0.3, dc));
81
82 // Analytical engine
83 Real beta = 0.0;
84 QuantLib::ext::shared_ptr<PricingEngine> analyticalEngine =
85 QuantLib::ext::make_shared<CommodityAveragePriceOptionAnalyticalEngine>(discountCurve, vol, beta);
86
87 // Monte Carlo engine
88 Size samples = 10000;
89 QuantLib::ext::shared_ptr<PricingEngine> mcEngine =
90 QuantLib::ext::make_shared<CommodityAveragePriceOptionMonteCarloEngine>(discountCurve, vol, samples, beta);
91
92 // Instrument
93 Real quantity = 1.0;
94 std::string name = "CL";
95 Period term = 1 * Months;
96
97 // std::vector<ApoTestCase> cases = {{100.0, Option::Call}, {100.0, Option::Put}};
98 std::vector<ApoTestCase> cases = {{100.0, Option::Call}, {120.0, Option::Call}, {80.0, Option::Call},
99 {100.0, Option::Put}, {120.0, Option::Put}, {80.0, Option::Put}};
100
101 for (Size k = 0; k < cases.size(); ++k) {
102
103 Real strikePrice = cases[k].strikePrice;
104 QuantLib::Option::Type optionType = cases[k].optionType;
105 std::string optionTypeString = (optionType == Option::Call ? "Call" : "Put");
106
107 // Vary APO start dates
108 for (Size i = 1; i <= 10; ++i) {
109
110 // Instrument
111 Period startTerm = i * Years;
112 Date startDate = today + startTerm;
113 Date endDate = startDate + term;
114 Date payDate = endDate;
115 QuantLib::ext::shared_ptr<CommoditySpotIndex> index = QuantLib::ext::make_shared<CommoditySpotIndex>(name, cal, priceCurve);
116 QuantLib::ext::shared_ptr<CommodityIndexedAverageCashFlow> flow =
117 QuantLib::ext::make_shared<CommodityIndexedAverageCashFlow>(quantity, startDate, endDate, payDate, index);
118 QuantLib::ext::shared_ptr<Exercise> exercise = QuantLib::ext::make_shared<EuropeanExercise>(endDate);
119
120 QuantLib::ext::shared_ptr<CommodityAveragePriceOption> apo =
121 QuantLib::ext::make_shared<CommodityAveragePriceOption>(flow, exercise, quantity, strikePrice, optionType);
122
123 boost::timer::cpu_timer tan;
124 apo->setPricingEngine(analyticalEngine);
125 Real anPrice = apo->NPV();
126 tan.stop();
127 Real anTime = tan.elapsed().wall * 1e-6;
128
129 boost::timer::cpu_timer tmc;
130 apo->setPricingEngine(mcEngine);
131 Real mcPrice = apo->NPV();
132 Real mcTime = tmc.elapsed().wall * 1e-6;
133
134 Real error1 = 100.0 * fabs(mcPrice - anPrice) / mcPrice;
135 Real error2 = 100.0 * fabs(mcPrice - anPrice) / anPrice;
136
137 BOOST_TEST_MESSAGE(optionTypeString << " " << std::fixed << std::setprecision(2) << strikePrice << " "
138 << startTerm << " Analytical vs MC price: " << std::fixed
139 << std::setprecision(2) << anPrice << " vs " << mcPrice << " diff "
140 << anPrice - mcPrice << " error " << std::max(error1, error2) << "% ("
141 << anTime << " ms, " << mcTime << " ms)");
142 BOOST_CHECK_CLOSE(anPrice, mcPrice, 1.0); // accept 1% relative error
143 }
144 }
145}
string name