Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
Macros | Functions
generalisedreplicatingvarianceswapengine.cpp File Reference
#include <qle/pricingengines/varianceswapgeneralreplicationengine.hpp>
#include <oret/toplevelfixture.hpp>
#include <boost/test/unit_test.hpp>
#include <qle/indexes/equityindex.hpp>
#include <qle/models/cdsoptionhelper.hpp>
#include <qle/models/cpicapfloorhelper.hpp>
#include <qle/models/crlgm1fparametrization.hpp>
#include <qle/models/crossassetanalytics.hpp>
#include <qle/models/crossassetanalyticsbase.hpp>
#include <qle/models/crossassetmodel.hpp>
#include <qle/models/crossassetmodelimpliedeqvoltermstructure.hpp>
#include <qle/models/crossassetmodelimpliedfxvoltermstructure.hpp>
#include <qle/models/dkimpliedyoyinflationtermstructure.hpp>
#include <qle/models/dkimpliedzeroinflationtermstructure.hpp>
#include <qle/models/eqbsconstantparametrization.hpp>
#include <qle/models/eqbsparametrization.hpp>
#include <qle/models/eqbspiecewiseconstantparametrization.hpp>
#include <qle/models/fxbsconstantparametrization.hpp>
#include <qle/models/fxbsparametrization.hpp>
#include <qle/models/fxbspiecewiseconstantparametrization.hpp>
#include <qle/models/fxeqoptionhelper.hpp>
#include <qle/models/gaussian1dcrossassetadaptor.hpp>
#include <qle/models/infdkparametrization.hpp>
#include <qle/models/irlgm1fconstantparametrization.hpp>
#include <qle/models/irlgm1fparametrization.hpp>
#include <qle/models/irlgm1fpiecewiseconstanthullwhiteadaptor.hpp>
#include <qle/models/irlgm1fpiecewiseconstantparametrization.hpp>
#include <qle/models/irlgm1fpiecewiselinearparametrization.hpp>
#include <qle/models/lgm.hpp>
#include <qle/models/lgmimplieddefaulttermstructure.hpp>
#include <qle/models/lgmimpliedyieldtermstructure.hpp>
#include <qle/models/linkablecalibratedmodel.hpp>
#include <qle/models/parametrization.hpp>
#include <qle/models/piecewiseconstanthelper.hpp>
#include <qle/models/pseudoparameter.hpp>
#include <qle/pricingengines/analyticcclgmfxoptionengine.hpp>
#include <qle/pricingengines/analyticdkcpicapfloorengine.hpp>
#include <qle/pricingengines/analyticlgmcdsoptionengine.hpp>
#include <qle/pricingengines/analyticlgmswaptionengine.hpp>
#include <qle/pricingengines/analyticxassetlgmeqoptionengine.hpp>
#include <qle/pricingengines/blackcdsoptionengine.hpp>
#include <qle/pricingengines/crossccyswapengine.hpp>
#include <qle/pricingengines/depositengine.hpp>
#include <qle/pricingengines/discountingcommodityforwardengine.hpp>
#include <qle/pricingengines/discountingcurrencyswapengine.hpp>
#include <qle/pricingengines/discountingequityforwardengine.hpp>
#include <qle/pricingengines/discountingfxforwardengine.hpp>
#include <qle/pricingengines/discountingriskybondengine.hpp>
#include <qle/pricingengines/discountingswapenginemulticurve.hpp>
#include <qle/pricingengines/numericlgmmultilegoptionengine.hpp>
#include <qle/pricingengines/oiccbasisswapengine.hpp>
#include <qle/pricingengines/paymentdiscountingengine.hpp>
#include <ql/pricingengines/credit/midpointcdsengine.hpp>
#include <ql/pricingengines/forward/replicatingvarianceswapengine.hpp>
#include <ql/processes/blackscholesprocess.hpp>
#include <ql/termstructures/volatility/equityfx/blackvariancesurface.hpp>
#include <ql/math/array.hpp>
#include <ql/math/comparison.hpp>
#include <ql/quotes/simplequote.hpp>
#include <ql/termstructures/yield/flatforward.hpp>
#include <ql/time/calendars/nullcalendar.hpp>
#include <ql/time/calendars/target.hpp>
#include <ql/time/daycounters/actualactual.hpp>
#include <boost/make_shared.hpp>

Go to the source code of this file.

Macros

#define LENGTH(a)   (sizeof(a) / sizeof(a[0]))
 

Functions

 BOOST_AUTO_TEST_CASE (testT0Pricing)
 
 BOOST_AUTO_TEST_CASE (testSeasonedSwapPricing)
 
 BOOST_AUTO_TEST_CASE (testForwardStartPricing)
 
 BOOST_AUTO_TEST_CASE (testReplicatingVarianceSwap)
 

Macro Definition Documentation

◆ LENGTH

#define LENGTH (   a)    (sizeof(a) / sizeof(a[0]))

Definition at line 93 of file generalisedreplicatingvarianceswapengine.cpp.

Function Documentation

◆ BOOST_AUTO_TEST_CASE() [1/4]

BOOST_AUTO_TEST_CASE ( testT0Pricing  )

Definition at line 127 of file generalisedreplicatingvarianceswapengine.cpp.

127 {
128
129 SavedSettings backup;
130 Date today = Date(3, Oct, 2019);
131 Settings::instance().evaluationDate() = today;
132 Calendar cal = TARGET();
133 DayCounter dc = Actual365Fixed();
134 Date exDate = today + Integer(0.246575 * 365 + 0.5);
135 std::vector<Date> dates(1, exDate);
136 Real volatilityStrike = 0.2;
137 Real varianceStrike = volatilityStrike * volatilityStrike;
138 Real vegaNotional = 50000.0;
139 Real varianceNotional = vegaNotional / (2.0 * 100.0 * volatilityStrike);
140
141 // add strikes in C++98 compatible way
142 Real arrStrikes[] = {50.0, 55.0, 60.0, 65.0, 70.0, 75.0, 80.0, 85.0, 90.0, 95.0, 100.0, // Put Strikes
143 105.0, 110.0, 115.0, 120.0, 125.0, 130.0, 135.0}; // Call Strikes
144 std::vector<Real> strikes(arrStrikes, arrStrikes + sizeof(arrStrikes) / sizeof(Real));
145 // add vols in C++98 compatible way
146 Real arrVols[] = {0.3, 0.29, 0.28, 0.27, 0.26, 0.25, 0.24, 0.23, 0.22, 0.21, 0.2, // Put Vols
147 0.19, 0.18, 0.17, 0.16, 0.15, 0.14, 0.13}; // Call Vols
148 std::vector<Real> volsVector(arrVols, arrVols + sizeof(arrVols) / sizeof(Real));
149 Matrix vols(18, 1, volsVector.begin(), volsVector.end());
150
151 BOOST_TEST_MESSAGE("Testing t0 pricing of the QuantExt VarSwap engine, as per Demeterfi et. al (1999).");
152 std::string equityName = "STE";
153 QuantLib::ext::shared_ptr<SimpleQuote> spot(new SimpleQuote(0.0));
154 Handle<Quote> equityPrice = Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(100.0));
155 Handle<YieldTermStructure> yieldTS =
156 Handle<YieldTermStructure>(QuantLib::ext::make_shared<FlatForward>(0, NullCalendar(), 0.05, dc));
157 Handle<YieldTermStructure> dividendTS =
158 Handle<YieldTermStructure>(QuantLib::ext::make_shared<FlatForward>(0, NullCalendar(), 0.0, dc));
159 Handle<BlackVolTermStructure> volTS = Handle<BlackVolTermStructure>(
160 QuantLib::ext::make_shared<BlackVarianceSurface>(today, NullCalendar(), dates, strikes, vols, dc));
161 Handle<YieldTermStructure> discountingTS =
162 Handle<YieldTermStructure>(QuantLib::ext::make_shared<FlatForward>(0, NullCalendar(), 0.05, dc));
163 QuantLib::ext::shared_ptr<Index> eqIndex =
164 QuantLib::ext::make_shared<EquityIndex2>(equityName, cal, EURCurrency(), equityPrice, yieldTS, dividendTS);
165
166 QuantLib::ext::shared_ptr<GeneralizedBlackScholesProcess> stochProcess(
167 new BlackScholesMertonProcess(equityPrice, dividendTS, discountingTS, volTS));
168
169 QuantLib::ext::shared_ptr<PricingEngine> engine(new GeneralisedReplicatingVarianceSwapEngine(
170 eqIndex, stochProcess, discountingTS, GeneralisedReplicatingVarianceSwapEngine::VarSwapSettings()));
171
172 QuantExt::VarianceSwap2 varianceSwap(Position::Long, varianceStrike, varianceNotional, today, exDate, cal, false);
173 varianceSwap.setPricingEngine(engine);
174
175 Real result = varianceSwap.variance();
176 Real expected = 0.040203605175062058;
177 Real tol = 1.0e-4;
178 BOOST_CHECK_CLOSE(result, expected, tol);
179 result = varianceSwap.NPV();
180 expected = 2513.8798089810457;
181 BOOST_CHECK_CLOSE(result, expected, tol);
182}
vector< Real > strikes

◆ BOOST_AUTO_TEST_CASE() [2/4]

BOOST_AUTO_TEST_CASE ( testSeasonedSwapPricing  )

Definition at line 184 of file generalisedreplicatingvarianceswapengine.cpp.

184 {
185
186 SavedSettings backup;
187 Date today = Date(30, April, 2018);
188 Settings::instance().evaluationDate() = today;
189 DayCounter dc = Actual365Fixed();
190 Date startDate = today - Integer(0.019178 * 365 + 0.5); // started 7 calendar days ago
191 Date exDate = today + Integer(0.246575 * 365 + 0.5);
192 std::string equityName = "STE";
193 Calendar cal = TARGET();
194 std::vector<Date> pastDates;
195 std::vector<Date> dates(1, exDate);
196 Real volatilityStrike = 0.2;
197 Real varianceStrike = volatilityStrike * volatilityStrike;
198 Real vegaNotional = 50000.0;
199 Real varianceNotional = vegaNotional / (2.0 * 100.0 * volatilityStrike);
200
201 for (Date day = cal.adjust(cal.advance(startDate, -1, Days)); day < today; day = cal.advance(day, 1, Days)) {
202 pastDates.push_back(day);
203 }
204
205 // add fixings in C++98 compatible way
206 Real arrFixings[] = {98.5, 98.0, 99.0, 100.2, 99.4, 98.2};
207 std::vector<Real> fixings(arrFixings, arrFixings + sizeof(arrFixings) / sizeof(Real));
208 TimeSeries<Real> fixingHistory(pastDates.begin(), pastDates.end(), fixings.begin());
209 IndexManager::instance().setHistory(equityName, fixingHistory);
210
211 // add strikes in C++98 compatible way
212 Real arrStrikes[] = {50.0, 55.0, 60.0, 65.0, 70.0, 75.0, 80.0, 85.0, 90.0, 95.0, 100.0, // Put Strikes
213 105.0, 110.0, 115.0, 120.0, 125.0, 130.0, 135.0}; // Call Strikes
214 std::vector<Real> strikes(arrStrikes, arrStrikes + sizeof(arrStrikes) / sizeof(Real));
215 // add vols in C++98 compatible way
216 Real arrVols[] = {0.3, 0.29, 0.28, 0.27, 0.26, 0.25, 0.24, 0.23, 0.22, 0.21, 0.2, // Put Vols
217 0.19, 0.18, 0.17, 0.16, 0.15, 0.14, 0.13}; // Call Vols
218 std::vector<Real> volsVector(arrVols, arrVols + sizeof(arrVols) / sizeof(Real));
219 Matrix vols(18, 1, volsVector.begin(), volsVector.end());
220
221 BOOST_TEST_MESSAGE("Testing seasoned swap pricing of the QuantExt VarSwap engine.");
222 QuantLib::ext::shared_ptr<SimpleQuote> spot(new SimpleQuote(0.0));
223 Handle<Quote> equityPrice = Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(100.0));
224 Handle<YieldTermStructure> yieldTS = Handle<YieldTermStructure>(QuantLib::ext::make_shared<FlatForward>(0, cal, 0.05, dc));
225 Handle<YieldTermStructure> dividendTS =
226 Handle<YieldTermStructure>(QuantLib::ext::make_shared<FlatForward>(0, cal, 0.0, dc));
227 Handle<BlackVolTermStructure> volTS =
228 Handle<BlackVolTermStructure>(QuantLib::ext::make_shared<BlackVarianceSurface>(today, cal, dates, strikes, vols, dc));
229 Handle<YieldTermStructure> discountingTS =
230 Handle<YieldTermStructure>(QuantLib::ext::make_shared<FlatForward>(0, cal, 0.05, dc));
231 QuantLib::ext::shared_ptr<Index> eqIndex =
232 QuantLib::ext::make_shared<EquityIndex2>(equityName, cal, EURCurrency(), equityPrice, yieldTS, dividendTS);
233
234 QuantLib::ext::shared_ptr<GeneralizedBlackScholesProcess> stochProcess(
235 new BlackScholesMertonProcess(equityPrice, dividendTS, yieldTS, volTS));
236
237 QuantLib::ext::shared_ptr<PricingEngine> engine(new GeneralisedReplicatingVarianceSwapEngine(
238 eqIndex, stochProcess, discountingTS, GeneralisedReplicatingVarianceSwapEngine::VarSwapSettings()));
239
240 QuantExt::VarianceSwap2 varianceSwap(Position::Long, varianceStrike, varianceNotional, startDate, exDate, cal,
241 false);
242 varianceSwap.setPricingEngine(engine);
243
244 Real result = varianceSwap.variance();
245 Real expected = 0.040169651620750264;
246 Real tol = 1.0e-4;
247 BOOST_CHECK_CLOSE(result, expected, tol);
248 result = varianceSwap.NPV();
249 expected = 2094.6608249765977;
250 BOOST_CHECK_CLOSE(result, expected, tol);
251
252 // A little clean up of the environment.
253 IndexManager::instance().clearHistory("EQ/" + equityName);
254}

◆ BOOST_AUTO_TEST_CASE() [3/4]

BOOST_AUTO_TEST_CASE ( testForwardStartPricing  )

Definition at line 256 of file generalisedreplicatingvarianceswapengine.cpp.

256 {
257
258 SavedSettings backup;
259 Date today(2, Jul, 2018);
260 Settings::instance().evaluationDate() = today;
261 Calendar cal = TARGET();
262 DayCounter dc = Actual365Fixed();
263 Date exDate = today + Integer(0.246575 * 365 + 0.5);
264 std::vector<Date> dates(1, exDate);
265 Real volatilityStrike = 0.2;
266 Real varianceStrike = volatilityStrike * volatilityStrike;
267 Real vegaNotional = 50000.0;
268 Real varianceNotional = vegaNotional / (2.0 * 100.0 * volatilityStrike);
269
270 // add strikes in C++98 compatible way
271 Real arrStrikes[] = {50.0, 55.0, 60.0, 65.0, 70.0, 75.0, 80.0, 85.0, 90.0, 95.0, 100.0, // Put Strikes
272 105.0, 110.0, 115.0, 120.0, 125.0, 130.0, 135.0}; // Call Strikes
273 std::vector<Real> strikes(arrStrikes, arrStrikes + sizeof(arrStrikes) / sizeof(Real));
274 // add vols in C++98 compatible way
275 Real arrVols[] = {0.3, 0.29, 0.28, 0.27, 0.26, 0.25, 0.24, 0.23, 0.22, 0.21, 0.2, // Put Vols
276 0.19, 0.18, 0.17, 0.16, 0.15, 0.14, 0.13}; // Call Vols
277 std::vector<Real> volsVector(arrVols, arrVols + sizeof(arrVols) / sizeof(Real));
278 Matrix vols(18, 1, volsVector.begin(), volsVector.end());
279
280 BOOST_TEST_MESSAGE(
281 "Testing future starting pricing of the QuantExt VarSwap engine, as per Demeterfi et. al (1999).");
282 std::string equityName = "STE";
283 QuantLib::ext::shared_ptr<SimpleQuote> spot(new SimpleQuote(0.0));
284 Handle<Quote> equityPrice = Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(100.0));
285 Handle<YieldTermStructure> yieldTS =
286 Handle<YieldTermStructure>(QuantLib::ext::make_shared<FlatForward>(0, NullCalendar(), 0.05, dc));
287 Handle<YieldTermStructure> dividendTS =
288 Handle<YieldTermStructure>(QuantLib::ext::make_shared<FlatForward>(0, NullCalendar(), 0.0, dc));
289 Handle<BlackVolTermStructure> volTS = Handle<BlackVolTermStructure>(
290 QuantLib::ext::make_shared<BlackVarianceSurface>(today, NullCalendar(), dates, strikes, vols, dc));
291 Handle<YieldTermStructure> discountingTS =
292 Handle<YieldTermStructure>(QuantLib::ext::make_shared<FlatForward>(0, NullCalendar(), 0.05, dc));
293 QuantLib::ext::shared_ptr<Index> eqIndex =
294 QuantLib::ext::make_shared<EquityIndex2>(equityName, cal, EURCurrency(), equityPrice, yieldTS, dividendTS);
295
296 QuantLib::ext::shared_ptr<GeneralizedBlackScholesProcess> stochProcess(
297 new BlackScholesMertonProcess(equityPrice, dividendTS, discountingTS, volTS));
298
299 QuantLib::ext::shared_ptr<PricingEngine> engine(new GeneralisedReplicatingVarianceSwapEngine(
300 eqIndex, stochProcess, discountingTS, GeneralisedReplicatingVarianceSwapEngine::VarSwapSettings()));
301
302 QuantExt::VarianceSwap2 varianceSwap(Position::Long, varianceStrike, varianceNotional, today + 7, exDate, cal,
303 false);
304 varianceSwap.setPricingEngine(engine);
305
306 Real result = varianceSwap.variance();
307 Real expected = 0.038880652347511133;
308 Real tol = 1.0e-4;
309 BOOST_CHECK_CLOSE(result, expected, tol);
310 result = varianceSwap.NPV();
311 expected = -13820.40246258254;
312 BOOST_CHECK_CLOSE(result, expected, tol);
313}

◆ BOOST_AUTO_TEST_CASE() [4/4]

BOOST_AUTO_TEST_CASE ( testReplicatingVarianceSwap  )

Definition at line 315 of file generalisedreplicatingvarianceswapengine.cpp.

315 {
316
317 BOOST_TEST_MESSAGE("Testing variance swap with replicating cost engine...");
318
319 ReplicatingVarianceSwapData values[] = {
320
321 // data from "A Guide to Volatility and Variance Swaps",
322 // Derman, Kamal & Zou, 1999
323 // with maturity t corrected from 0.25 to 0.246575
324 // corresponding to Jan 1, 1999 to Apr 1, 1999
325
326 // type, varStrike, nominal, s, q, r, t, v, result, tol
327 {Position::Long, 0.04, 50000, 100.0, 0.00, 0.05, 0.246575, 0.20, 0.041888574, 1.0e-4}
328
329 };
330
331 Datum replicatingOptionData[] = {
332
333 // data from "A Guide to Volatility and Variance Swaps",
334 // Derman, Kamal & Zou, 1999
335
336 // Option::Type, strike, v
337 {Option::Put, 50, 0.30}, {Option::Put, 55, 0.29}, {Option::Put, 60, 0.28}, {Option::Put, 65, 0.27},
338 {Option::Put, 70, 0.26}, {Option::Put, 75, 0.25}, {Option::Put, 80, 0.24}, {Option::Put, 85, 0.23},
339 {Option::Put, 90, 0.22}, {Option::Put, 95, 0.21}, {Option::Put, 100, 0.20}, {Option::Call, 100, 0.20},
340 {Option::Call, 105, 0.19}, {Option::Call, 110, 0.18}, {Option::Call, 115, 0.17}, {Option::Call, 120, 0.16},
341 {Option::Call, 125, 0.15}, {Option::Call, 130, 0.14}, {Option::Call, 135, 0.13}};
342
343 SavedSettings backup;
344 DayCounter dc = Actual365Fixed();
345 Date today = Date::todaysDate();
346 Settings::instance().evaluationDate() = today;
347
348 QuantLib::ext::shared_ptr<SimpleQuote> spot(new SimpleQuote(0.0));
349 QuantLib::ext::shared_ptr<SimpleQuote> qRate(new SimpleQuote(0.0));
350 QuantLib::ext::shared_ptr<YieldTermStructure> qTS =
351 QuantLib::ext::shared_ptr<YieldTermStructure>(new FlatForward(today, Handle<Quote>(qRate), dc));
352 QuantLib::ext::shared_ptr<SimpleQuote> rRate(new SimpleQuote(0.0));
353 QuantLib::ext::shared_ptr<YieldTermStructure> rTS =
354 QuantLib::ext::shared_ptr<YieldTermStructure>(new FlatForward(today, Handle<Quote>(rRate), dc));
355
356 for (Size i = 0; i < LENGTH(values); i++) {
357 Date exDate = today + Integer(values[i].t * 365 + 0.5);
358 std::vector<Date> dates(1);
359 dates[0] = exDate;
360
361 spot->setValue(values[i].s);
362 qRate->setValue(values[i].q);
363 rRate->setValue(values[i].r);
364
365 Size options = LENGTH(replicatingOptionData);
366 std::vector<Real> callStrikes, putStrikes, callVols, putVols;
367
368 // Assumes ascending strikes and same min call and max put strikes
369 Size j;
370 for (j = 0; j < options; j++) {
371 if (replicatingOptionData[j].type == Option::Call) {
372 callStrikes.push_back(replicatingOptionData[j].strike);
373 callVols.push_back(replicatingOptionData[j].v);
374 } else if (replicatingOptionData[j].type == Option::Put) {
375 putStrikes.push_back(replicatingOptionData[j].strike);
376 putVols.push_back(replicatingOptionData[j].v);
377 } else {
378 QL_FAIL("unknown option type");
379 }
380 }
381
382 Matrix vols(options - 1, 1);
383 std::vector<Real> strikes;
384 for (j = 0; j < putVols.size(); j++) {
385 vols[j][0] = putVols[j];
386 strikes.push_back(putStrikes[j]);
387 }
388
389 for (Size k = 1; k < callVols.size(); k++) {
390 Size j = putVols.size() - 1;
391 vols[j + k][0] = callVols[k];
392 strikes.push_back(callStrikes[k]);
393 }
394
395 QuantLib::ext::shared_ptr<BlackVolTermStructure> volTS(
396 new BlackVarianceSurface(today, NullCalendar(), dates, strikes, vols, dc));
397
398 QuantLib::ext::shared_ptr<GeneralizedBlackScholesProcess> stochProcess(
399 new BlackScholesMertonProcess(Handle<Quote>(spot), Handle<YieldTermStructure>(qTS),
400 Handle<YieldTermStructure>(rTS), Handle<BlackVolTermStructure>(volTS)));
401
402 QuantLib::ext::shared_ptr<PricingEngine> engine(
403 new ReplicatingVarianceSwapEngine(stochProcess, 5.0, callStrikes, putStrikes));
404
405 QuantLib::VarianceSwap varianceSwap(values[i].type, values[i].varStrike, values[i].nominal, today, exDate);
406 varianceSwap.setPricingEngine(engine);
407
408 Real calculated = varianceSwap.variance();
409 Real expected = values[i].result;
410 Real tol = 1.0e-4;
411 BOOST_CHECK_CLOSE(calculated, expected, tol);
412 }
413}