Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
Functions
discountingcommodityforwardengine.cpp File Reference
#include "toplevelfixture.hpp"
#include <boost/make_shared.hpp>
#include <boost/test/unit_test.hpp>
#include <ql/currencies/america.hpp>
#include <ql/settings.hpp>
#include <ql/termstructures/yield/discountcurve.hpp>
#include <qle/pricingengines/discountingcommodityforwardengine.hpp>
#include <qle/termstructures/pricecurve.hpp>

Go to the source code of this file.

Functions

 BOOST_AUTO_TEST_CASE (testPricing)
 

Function Documentation

◆ BOOST_AUTO_TEST_CASE()

BOOST_AUTO_TEST_CASE ( testPricing  )

Definition at line 38 of file discountingcommodityforwardengine.cpp.

38 {
39
40 BOOST_TEST_MESSAGE("Testing discounting commodity forward engine pricing");
41
42 SavedSettings backup;
43
44 // Tolerance for npv comparison
45 Real tolerance = 1e-10;
46
47 // Commodity forward base data
48 Date asof(19, Feb, 2018);
49 string name("GOLD_USD");
50 USDCurrency currency;
51 Date maturity(19, Feb, 2019);
52
53 // Day counter for time
54 Actual365Fixed dayCounter;
55
56 // Discount curve
57 vector<Date> dates(2);
58 vector<DiscountFactor> dfs(2);
59 dates[0] = asof;
60 dfs[0] = 1.0;
61 dates[1] = maturity;
62 dfs[1] = 0.85;
63 Handle<YieldTermStructure> discountCurve(QuantLib::ext::make_shared<InterpolatedDiscountCurve<LogLinear> >(
64 InterpolatedDiscountCurve<LogLinear>(dates, dfs, dayCounter)));
65
66 // Commodity Price curve
67 vector<Real> prices(2);
68 prices[0] = 1346.0;
69 prices[1] = 1384.0;
70 Handle<PriceTermStructure> priceCurve(
71 QuantLib::ext::make_shared<InterpolatedPriceCurve<Linear> >(asof, dates, prices, dayCounter, USDCurrency()));
72
73 // Create the engine
74 QuantLib::ext::shared_ptr<DiscountingCommodityForwardEngine> engine =
75 QuantLib::ext::make_shared<DiscountingCommodityForwardEngine>(discountCurve);
76
77 // Set evaluation date
78 Settings::instance().evaluationDate() = asof;
79
80 // Long 100 units with strike 1380.0
81 QuantLib::ext::shared_ptr<CommodityIndex> index = QuantLib::ext::make_shared<CommoditySpotIndex>(
82 name, NullCalendar(), priceCurve);
83 Position::Type position = Position::Long;
84 Real quantity = 100;
85 Real strike = 1380.0;
86 QuantLib::ext::shared_ptr<CommodityForward> forward =
87 QuantLib::ext::make_shared<CommodityForward>(index, currency, position, quantity, maturity, strike);
88 forward->setPricingEngine(engine);
89 BOOST_CHECK_CLOSE(forward->NPV(), quantity * (prices[1] - strike) * dfs[1], tolerance);
90
91 // Short 100 units with strike 1380.0
92 position = Position::Short;
93 forward = QuantLib::ext::make_shared<CommodityForward>(index, currency, position, quantity, maturity, strike);
94 forward->setPricingEngine(engine);
95 BOOST_CHECK_CLOSE(forward->NPV(), -quantity * (prices[1] - strike) * dfs[1], tolerance);
96
97 // Short 50 units with strike 1380.0
98 quantity = 50.0;
99 forward = QuantLib::ext::make_shared<CommodityForward>(index, currency, position, quantity, maturity, strike);
100 forward->setPricingEngine(engine);
101 BOOST_CHECK_CLOSE(forward->NPV(), -quantity * (prices[1] - strike) * dfs[1], tolerance);
102
103 // Short 50 units with strike 1375.0
104 strike = 1375.0;
105 forward = QuantLib::ext::make_shared<CommodityForward>(index, currency, position, quantity, maturity, strike);
106 forward->setPricingEngine(engine);
107 BOOST_CHECK_CLOSE(forward->NPV(), -quantity * (prices[1] - strike) * dfs[1], tolerance);
108
109 // Bring maturity of forward in 6 months
110 maturity = Date(19, Aug, 2018);
111 forward = QuantLib::ext::make_shared<CommodityForward>(index, currency, position, quantity, maturity, strike);
112 forward->setPricingEngine(engine);
113 BOOST_CHECK_CLOSE(forward->NPV(),
114 -quantity * (priceCurve->price(maturity) - strike) * discountCurve->discount(maturity),
115 tolerance);
116
117 // Make maturity of forward equal to today
118 forward = QuantLib::ext::make_shared<CommodityForward>(index, currency, position, quantity, asof, strike);
119 // includeReferenceDateEvents_ of Settings is false by default => value should equal 0
120 forward->setPricingEngine(engine);
121 BOOST_CHECK_CLOSE(forward->NPV(), 0.0, tolerance);
122 // Set includeReferenceDateEvents_ of Settings to true => value should be today's price - strike
123 Settings::instance().includeReferenceDateEvents() = true;
124 forward->recalculate();
125 BOOST_CHECK_CLOSE(forward->NPV(), -quantity * (prices[0] - strike), tolerance);
126 // Override behaviour in engine i.e. don't include flows on reference date even when
127 // Settings::instance().includeReferenceDateEvents() is true
128 engine = QuantLib::ext::make_shared<DiscountingCommodityForwardEngine>(discountCurve, false);
129 forward->setPricingEngine(engine);
130 BOOST_CHECK_CLOSE(forward->NPV(), 0.0, tolerance);
131 // Trying the other way around should not work as the trade is marked as expired
132 Settings::instance().includeReferenceDateEvents() = false;
133 engine = QuantLib::ext::make_shared<DiscountingCommodityForwardEngine>(discountCurve, true);
134 forward->setPricingEngine(engine);
135 BOOST_CHECK_CLOSE(forward->NPV(), 0.0, tolerance);
136
137 // Reinstate original maturity and change the npv date in the engine to 2 days after asof
138 maturity = Date(19, Feb, 2019);
139 forward = QuantLib::ext::make_shared<CommodityForward>(index, currency, position, quantity, maturity, strike);
140 Date npvDate = asof + 2 * Days;
141 engine = QuantLib::ext::make_shared<DiscountingCommodityForwardEngine>(discountCurve, boost::none, npvDate);
142 forward->setPricingEngine(engine);
143 DiscountFactor npvDateDiscount = discountCurve->discount(npvDate);
144 BOOST_CHECK_CLOSE(forward->NPV(), -quantity * (prices[1] - strike) * dfs[1] / npvDateDiscount, tolerance);
145}
InterpolatedDiscountCurve based on loglinear interpolation of DiscountFactors.
Interpolated price curve.
Definition: pricecurve.hpp:50