Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
discountingcurrencyswapenginedeltagamma.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2016 Quaternion Risk Management Ltd
3 All rights reserved.
4
5 This file is part of ORE, a free-software/open-source library
6 for transparent pricing and risk analysis - http://opensourcerisk.org
7
8 ORE is free software: you can redistribute it and/or modify it
9 under the terms of the Modified BSD License. You should have received a
10 copy of the license along with this program.
11 The license is also available online at <http://opensourcerisk.org>
12
13 This program is distributed on the basis that it will form a useful
14 contribution to risk analytics and model standardisation, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the license for more details.
17*/
18
19#include "toplevelfixture.hpp"
20#include <boost/test/unit_test.hpp>
21
24
25#include <ql/cashflows/iborcoupon.hpp>
26#include <ql/indexes/ibor/euribor.hpp>
27#include <ql/indexes/ibor/usdlibor.hpp>
28#include <ql/math/matrix.hpp>
29#include <ql/quotes/simplequote.hpp>
30#include <ql/termstructures/yield/flatforward.hpp>
31#include <ql/termstructures/yield/piecewisezerospreadedtermstructure.hpp>
32#include <ql/time/calendars/target.hpp>
33#include <ql/time/calendars/unitedstates.hpp>
34
35#include <boost/make_shared.hpp>
36
37using namespace QuantLib;
38using namespace QuantExt;
39
40using namespace boost::unit_test_framework;
41using std::vector;
42
43namespace {
44struct TestData {
45 TestData() : refDate(Date(22, Aug, 2016)) {
46 Settings::instance().evaluationDate() = refDate;
47 baseDiscount = Handle<YieldTermStructure>(QuantLib::ext::make_shared<FlatForward>(
48 refDate, Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(0.02)), Actual365Fixed()));
49 baseForward = Handle<YieldTermStructure>(QuantLib::ext::make_shared<FlatForward>(
50 refDate, Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(0.03)), Actual365Fixed()));
51 baseDiscountFor = Handle<YieldTermStructure>(QuantLib::ext::make_shared<FlatForward>(
52 refDate, Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(0.04)), Actual365Fixed()));
53 baseForwardFor = Handle<YieldTermStructure>(QuantLib::ext::make_shared<FlatForward>(
54 refDate, Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(0.05)), Actual365Fixed()));
55 fxQuote = QuantLib::ext::make_shared<SimpleQuote>(0.90);
56 pillarDates.push_back(refDate + 1 * Years);
57 pillarDates.push_back(refDate + 2 * Years);
58 pillarDates.push_back(refDate + 3 * Years);
59 pillarDates.push_back(refDate + 4 * Years);
60 pillarDates.push_back(refDate + 5 * Years);
61 pillarDates.push_back(refDate + 7 * Years);
62 pillarDates.push_back(refDate + 10 * Years);
63 std::vector<Handle<Quote>> tmpDiscSpr, tmpFwdSpr, tmpDiscSprFor, tmpFwdSprFor;
64 for (Size i = 0; i < pillarDates.size(); ++i) {
65 QuantLib::ext::shared_ptr<SimpleQuote> qd = QuantLib::ext::make_shared<SimpleQuote>(0.0);
66 QuantLib::ext::shared_ptr<SimpleQuote> qf = QuantLib::ext::make_shared<SimpleQuote>(0.0);
67 QuantLib::ext::shared_ptr<SimpleQuote> qdf = QuantLib::ext::make_shared<SimpleQuote>(0.0);
68 QuantLib::ext::shared_ptr<SimpleQuote> qff = QuantLib::ext::make_shared<SimpleQuote>(0.0);
69 discountSpreads.push_back(qd);
70 forwardSpreads.push_back(qf);
71 discountSpreadsFor.push_back(qdf);
72 forwardSpreadsFor.push_back(qff);
73 tmpDiscSpr.push_back(Handle<Quote>(qd));
74 tmpFwdSpr.push_back(Handle<Quote>(qf));
75 tmpDiscSprFor.push_back(Handle<Quote>(qdf));
76 tmpFwdSprFor.push_back(Handle<Quote>(qff));
77 pillarTimes.push_back(baseDiscount->timeFromReference(pillarDates[i]));
78 }
79 discountCurve =
80 Handle<YieldTermStructure>(QuantLib::ext::make_shared<InterpolatedPiecewiseZeroSpreadedTermStructure<Linear>>(
81 baseDiscount, tmpDiscSpr, pillarDates));
82 forwardCurve =
83 Handle<YieldTermStructure>(QuantLib::ext::make_shared<InterpolatedPiecewiseZeroSpreadedTermStructure<Linear>>(
84 baseForward, tmpFwdSpr, pillarDates));
85 discountCurveFor =
86 Handle<YieldTermStructure>(QuantLib::ext::make_shared<InterpolatedPiecewiseZeroSpreadedTermStructure<Linear>>(
87 baseDiscountFor, tmpDiscSprFor, pillarDates));
88 forwardCurveFor =
89 Handle<YieldTermStructure>(QuantLib::ext::make_shared<InterpolatedPiecewiseZeroSpreadedTermStructure<Linear>>(
90 baseForwardFor, tmpFwdSprFor, pillarDates));
91 discountCurve->enableExtrapolation();
92 forwardCurve->enableExtrapolation();
93 discountCurveFor->enableExtrapolation();
94 forwardCurveFor->enableExtrapolation();
95 forwardIndex = QuantLib::ext::make_shared<Euribor>(6 * Months, forwardCurve);
96 forwardIndexFor = QuantLib::ext::make_shared<USDLibor>(3 * Months, forwardCurveFor);
97 }
98 Date refDate;
99 Handle<YieldTermStructure> baseDiscount, baseForward, discountCurve, forwardCurve;
100 Handle<YieldTermStructure> baseDiscountFor, baseForwardFor, discountCurveFor, forwardCurveFor;
101 QuantLib::ext::shared_ptr<IborIndex> forwardIndex, forwardIndexFor;
102 QuantLib::ext::shared_ptr<SimpleQuote> fxQuote;
103 std::vector<Date> pillarDates;
104 std::vector<QuantLib::ext::shared_ptr<SimpleQuote>> discountSpreads, forwardSpreads;
105 std::vector<QuantLib::ext::shared_ptr<SimpleQuote>> discountSpreadsFor, forwardSpreadsFor;
106 std::vector<Real> pillarTimes;
107}; // TestData
108
109bool check(const Real reference, const Real value) {
110 if (std::fabs(reference) >= 1E-4) {
111 return std::fabs((reference - value) / reference) < 1E-3;
112 } else {
113 return std::fabs(reference - value) < 5E-5;
114 }
115}
116
117void performTest(const TestData& d, const QuantLib::ext::shared_ptr<PricingEngine>& engine0,
118 const QuantLib::ext::shared_ptr<PricingEngine>& engine, const bool receive, const Real spread,
119 const std::string& config) {
120
121 BOOST_TEST_MESSAGE("Testing npv calculation in DiscountingCurrencySwapEngineDeltaGamma against QuantExt engine ("
122 << config << ")...");
123
124 Date settlement = d.refDate + 2;
125 Schedule scheduleEur(settlement, TARGET().advance(settlement, 10 * Years), 6 * Months, TARGET(), ModifiedFollowing,
126 ModifiedFollowing, DateGeneration::Forward, false);
127 Schedule scheduleUsd(settlement, UnitedStates(UnitedStates::Settlement).advance(settlement, 10 * Years), 3 * Months, UnitedStates(UnitedStates::Settlement),
128 ModifiedFollowing, ModifiedFollowing, DateGeneration::Forward, false);
129 Leg eurLeg = IborLeg(scheduleEur, d.forwardIndex).withNotionals(10.0);
130 Leg usdLeg = IborLeg(scheduleUsd, d.forwardIndexFor).withNotionals(10.0).withSpreads(spread);
131 std::vector<Leg> legs;
132 legs.push_back(eurLeg);
133 legs.push_back(usdLeg);
134 std::vector<Currency> currencies;
135 currencies.push_back(EURCurrency());
136 currencies.push_back(USDCurrency());
137 std::vector<bool> payer;
138 payer.push_back(receive);
139 payer.push_back(!receive);
140 CurrencySwap swap(legs, payer, currencies);
141
142 std::vector<Handle<YieldTermStructure>> discountCurves;
143 discountCurves.push_back(d.discountCurve);
144 discountCurves.push_back(d.discountCurveFor);
145
146 std::vector<Handle<Quote>> fx;
147 fx.push_back(Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(1.00)));
148 fx.push_back(Handle<Quote>(d.fxQuote));
149
150 swap.setPricingEngine(engine0);
151 Real npvRef = swap.NPV();
152
153 swap.setPricingEngine(engine);
154 Real npv = swap.NPV();
155
156 const Real tol = 1E-7;
157 if (std::fabs(npv - npvRef) > tol)
158 BOOST_ERROR("npv (" << npv << ") is inconsistent to expected value (" << npvRef << "), difference is "
159 << npv - npvRef << ", tolerance is " << tol);
160
161 std::vector<Real> resultDeltaDsc =
162 swap.result<DiscountingCurrencySwapEngineDeltaGamma::result_type_vector>("deltaDiscount")[EURCurrency()];
163 std::vector<Real> resultDeltaFwd =
164 swap.result<DiscountingCurrencySwapEngineDeltaGamma::result_type_vector>("deltaForward")[EURCurrency()];
165 std::vector<Real> resultDeltaDscFor =
166 swap.result<DiscountingCurrencySwapEngineDeltaGamma::result_type_vector>("deltaDiscount")[USDCurrency()];
167 std::vector<Real> resultDeltaFwdFor =
168 swap.result<DiscountingCurrencySwapEngineDeltaGamma::result_type_vector>("deltaForward")[USDCurrency()];
169
170 Matrix resultGamma =
171 swap.result<DiscountingCurrencySwapEngineDeltaGamma::result_type_matrix>("gamma")[EURCurrency()];
172 Matrix resultGammaFor =
173 swap.result<DiscountingCurrencySwapEngineDeltaGamma::result_type_matrix>("gamma")[USDCurrency()];
174
175 Real resultDeltaFxSpot =
176 swap.result<DiscountingCurrencySwapEngineDeltaGamma::result_type_scalar>("deltaFxSpot")[USDCurrency()];
177 Real resultFxSpot =
178 swap.result<DiscountingCurrencySwapEngineDeltaGamma::result_type_scalar>("fxSpot")[USDCurrency()];
179
180 if (std::fabs(resultFxSpot - d.fxQuote->value()) > tol)
181 BOOST_ERROR("fxSpot (" << resultFxSpot << ") is inconsistent to expected value (" << d.fxQuote->value()
182 << "), difference is " << resultFxSpot - d.fxQuote->value() << ", tolerance is " << tol);
183
184 BOOST_TEST_MESSAGE(
185 "Testing delta calculation in DiscountingCurrencySwapEngineDeltaGamma against bump and revalue results ("
186 << config << ")...");
187
188 // bump and revalue
189
190 // use QLE engine to compute reference bump and revalue results
191 swap.setPricingEngine(engine0);
192
193 const Size n = d.pillarDates.size();
194
195 // check results for correct dimension
196 if (resultDeltaDsc.size() != n)
197 BOOST_ERROR("deltaDiscount (EUR) has a wrong dimension (" << resultDeltaDsc.size() << "), expected " << n);
198 if (resultDeltaFwd.size() != n)
199 BOOST_ERROR("deltaForward (EUR) has a wrong dimension (" << resultDeltaFwd.size() << "), expected " << n);
200 if (resultDeltaDscFor.size() != n)
201 BOOST_ERROR("deltaDiscount (USD) has a wrong dimension (" << resultDeltaDsc.size() << "), expected " << n);
202 if (resultDeltaFwdFor.size() != n)
203 BOOST_ERROR("deltaForward (USD) has a wrong dimension (" << resultDeltaFwd.size() << "), expected " << n);
204 if (resultGamma.rows() != 2 * n || resultGamma.columns() != 2 * n)
205 BOOST_ERROR("gamma result matrix (EUR) has wrong dimensions ("
206 << resultGamma.rows() << "x" << resultGamma.columns() << "), expected " << 2 * n << "x" << 2 * n);
207 if (resultGammaFor.rows() != 2 * n || resultGamma.columns() != 2 * n)
208 BOOST_ERROR("gamma result matrix (EUR) has wrong dimensions ("
209 << resultGamma.rows() << "x" << resultGamma.columns() << "), expected " << 2 * n << "x" << 2 * n);
210
211 // delta (npv)
212
213 const Real bump = 1E-7;
214 Real npv0 = swap.NPV();
215 for (Size i = 0; i < d.pillarDates.size(); ++i) {
216 d.discountSpreads[i]->setValue(bump);
217 Real deltaDsc = (swap.NPV() - npv0) / bump;
218 d.discountSpreads[i]->setValue(0.0);
219 d.forwardSpreads[i]->setValue(bump);
220 Real deltaFwd = (swap.NPV() - npv0) / bump;
221 d.forwardSpreads[i]->setValue(0.0);
222 d.discountSpreadsFor[i]->setValue(bump);
223 // pricing engine results are in original currency
224 Real deltaDscFor = (swap.NPV() - npv0) / bump / d.fxQuote->value();
225 d.discountSpreadsFor[i]->setValue(0.0);
226 d.forwardSpreadsFor[i]->setValue(bump);
227 Real deltaFwdFor = (swap.NPV() - npv0) / bump / d.fxQuote->value();
228 d.forwardSpreadsFor[i]->setValue(0.0);
229 if (!check(deltaDsc, resultDeltaDsc[i]))
230 BOOST_ERROR("delta on pillar " << d.pillarTimes[i]
231 << " (discount curve, EUR) could not be verified, analytical: "
232 << resultDeltaDsc[i] << ", bump and revalue: " << deltaDsc);
233 if (!check(deltaFwd, resultDeltaFwd[i]))
234 BOOST_ERROR("delta on pillar " << d.pillarTimes[i]
235 << " (forward curve, EUR) could not be verified, analytical: "
236 << resultDeltaFwd[i] << ", bump and revalue: " << deltaFwd);
237 if (!check(deltaDscFor, resultDeltaDscFor[i]))
238 BOOST_ERROR("delta on pillar " << d.pillarTimes[i]
239 << " (discount curve, USD) could not be verified, analytical: "
240 << resultDeltaDscFor[i] << ", bump and revalue: " << deltaDscFor);
241 if (!check(deltaFwdFor, resultDeltaFwdFor[i]))
242 BOOST_ERROR("delta on pillar " << d.pillarTimes[i]
243 << " (forward curve, USD) could not be verified, analytical: "
244 << resultDeltaFwdFor[i] << ", bump and revalue: " << deltaFwdFor);
245 }
246
247 d.fxQuote->setValue(d.fxQuote->value() + bump);
248 Real deltaFxSpot = (swap.NPV() - npv0) / bump;
249 d.fxQuote->setValue(d.fxQuote->value() - bump);
250 if (!check(deltaFxSpot, resultDeltaFxSpot))
251 BOOST_ERROR("FXSpot delta could not be verified, analytical: " << resultDeltaFxSpot
252 << ", bump and revalue: " << deltaFxSpot);
253
254 // gamma
255
256 BOOST_TEST_MESSAGE(
257 "Testing gamma calculation in DiscountingCurrencySwapEngineDeltaGamma against bump and revalue results ("
258 << config << ")...");
259
260 const Real bump2 = 1E-5;
261 Matrix bumpGamma(n * 2, n * 2, 0.0), bumpGammaFor(n * 2, n * 2, 0.0);
262
263 // dsc-dsc (EUR)
264 for (Size i = 0; i < n; ++i) {
265 // j < i
266 for (Size j = 0; j < i; ++j) {
267 d.discountSpreads[i]->setValue(bump2);
268 d.discountSpreads[j]->setValue(bump2);
269 Real npvpp = swap.NPV();
270 d.discountSpreads[j]->setValue(0.0);
271 Real npvp0 = swap.NPV();
272 d.discountSpreads[i]->setValue(0.0);
273 d.discountSpreads[j]->setValue(bump2);
274 Real npv0p = swap.NPV();
275 d.discountSpreads[j]->setValue(0.0);
276 Real gamma = (npvpp - npvp0 - npv0p + npv0) / (bump2 * bump2);
277 bumpGamma[i][j] = bumpGamma[j][i] = gamma;
278 }
279 // j == i
280 d.discountSpreads[i]->setValue(2.0 * bump2);
281 Real npvpp = swap.NPV();
282 d.discountSpreads[i]->setValue(bump2);
283 Real npvp = swap.NPV();
284 d.discountSpreads[i]->setValue(0.0);
285 Real gamma = (npvpp - 2.0 * npvp + npv0) / (bump2 * bump2);
286 bumpGamma[i][i] = gamma;
287 }
288
289 // dsc-fwd (EUR)
290 for (Size i = 0; i < n; ++i) {
291 // j <= i
292 for (Size j = 0; j < n; ++j) {
293 d.discountSpreads[i]->setValue(bump2);
294 d.forwardSpreads[j]->setValue(bump2);
295 Real npvpp = swap.NPV();
296 d.forwardSpreads[j]->setValue(0.0);
297 Real npvp0 = swap.NPV();
298 d.discountSpreads[i]->setValue(0.0);
299 d.forwardSpreads[j]->setValue(bump2);
300 Real npv0p = swap.NPV();
301 d.forwardSpreads[j]->setValue(0.0);
302 Real gamma = (npvpp - npvp0 - npv0p + npv0) / (bump2 * bump2);
303 bumpGamma[i][n + j] = bumpGamma[n + j][i] = gamma;
304 }
305 }
306
307 // fwd-fwd (EUR)
308 for (Size i = 0; i < n; ++i) {
309 // j < i
310 for (Size j = 0; j < i; ++j) {
311 d.forwardSpreads[i]->setValue(bump2);
312 d.forwardSpreads[j]->setValue(bump2);
313 Real npvpp = swap.NPV();
314 d.forwardSpreads[j]->setValue(0.0);
315 Real npvp0 = swap.NPV();
316 d.forwardSpreads[i]->setValue(0.0);
317 d.forwardSpreads[j]->setValue(bump2);
318 Real npv0p = swap.NPV();
319 d.forwardSpreads[j]->setValue(0.0);
320 Real gamma = (npvpp - npvp0 - npv0p + npv0) / (bump2 * bump2);
321 bumpGamma[n + i][n + j] = bumpGamma[n + j][n + i] = gamma;
322 }
323 // j == i
324 d.forwardSpreads[i]->setValue(2.0 * bump2);
325 Real npvpp = swap.NPV();
326 d.forwardSpreads[i]->setValue(bump2);
327 Real npvp = swap.NPV();
328 d.forwardSpreads[i]->setValue(0.0);
329 Real gamma = (npvpp - 2.0 * npvp + npv0) / (bump2 * bump2);
330 bumpGamma[n + i][n + i] = gamma;
331 }
332
333 // dsc-dsc (USD)
334 for (Size i = 0; i < n; ++i) {
335 // j < i
336 for (Size j = 0; j < i; ++j) {
337 d.discountSpreadsFor[i]->setValue(bump2);
338 d.discountSpreadsFor[j]->setValue(bump2);
339 Real npvpp = swap.NPV();
340 d.discountSpreadsFor[j]->setValue(0.0);
341 Real npvp0 = swap.NPV();
342 d.discountSpreadsFor[i]->setValue(0.0);
343 d.discountSpreadsFor[j]->setValue(bump2);
344 Real npv0p = swap.NPV();
345 d.discountSpreadsFor[j]->setValue(0.0);
346 Real gamma = (npvpp - npvp0 - npv0p + npv0) / (bump2 * bump2);
347 bumpGammaFor[i][j] = bumpGammaFor[j][i] = gamma / d.fxQuote->value();
348 }
349 // j == i
350 d.discountSpreadsFor[i]->setValue(2.0 * bump2);
351 Real npvpp = swap.NPV();
352 d.discountSpreadsFor[i]->setValue(bump2);
353 Real npvp = swap.NPV();
354 d.discountSpreadsFor[i]->setValue(0.0);
355 Real gamma = (npvpp - 2.0 * npvp + npv0) / (bump2 * bump2);
356 bumpGammaFor[i][i] = gamma / d.fxQuote->value();
357 }
358
359 // dsc-fwd (USD)
360 for (Size i = 0; i < n; ++i) {
361 // j <= i
362 for (Size j = 0; j < n; ++j) {
363 d.discountSpreadsFor[i]->setValue(bump2);
364 d.forwardSpreadsFor[j]->setValue(bump2);
365 Real npvpp = swap.NPV();
366 d.forwardSpreadsFor[j]->setValue(0.0);
367 Real npvp0 = swap.NPV();
368 d.discountSpreadsFor[i]->setValue(0.0);
369 d.forwardSpreadsFor[j]->setValue(bump2);
370 Real npv0p = swap.NPV();
371 d.forwardSpreadsFor[j]->setValue(0.0);
372 Real gamma = (npvpp - npvp0 - npv0p + npv0) / (bump2 * bump2);
373 bumpGammaFor[i][n + j] = bumpGammaFor[n + j][i] = gamma / d.fxQuote->value();
374 }
375 }
376
377 // fwd-fwd (USD)
378 for (Size i = 0; i < n; ++i) {
379 // j < i
380 for (Size j = 0; j < i; ++j) {
381 d.forwardSpreadsFor[i]->setValue(bump2);
382 d.forwardSpreadsFor[j]->setValue(bump2);
383 Real npvpp = swap.NPV();
384 d.forwardSpreadsFor[j]->setValue(0.0);
385 Real npvp0 = swap.NPV();
386 d.forwardSpreadsFor[i]->setValue(0.0);
387 d.forwardSpreadsFor[j]->setValue(bump2);
388 Real npv0p = swap.NPV();
389 d.forwardSpreadsFor[j]->setValue(0.0);
390 Real gamma = (npvpp - npvp0 - npv0p + npv0) / (bump2 * bump2);
391 bumpGammaFor[n + i][n + j] = bumpGammaFor[n + j][n + i] = gamma / d.fxQuote->value();
392 }
393 // j == i
394 d.forwardSpreadsFor[i]->setValue(2.0 * bump2);
395 Real npvpp = swap.NPV();
396 d.forwardSpreadsFor[i]->setValue(bump2);
397 Real npvp = swap.NPV();
398 d.forwardSpreadsFor[i]->setValue(0.0);
399 Real gamma = (npvpp - 2.0 * npvp + npv0) / (bump2 * bump2);
400 bumpGammaFor[n + i][n + i] = gamma / d.fxQuote->value();
401 }
402
403 // check gamma (EUR)
404 for (Size i = 0; i < 2 * n; ++i) {
405 for (Size j = 0; j < 2 * n; ++j) {
406 if (!check(resultGamma[i][j], bumpGamma[i][j]))
407 BOOST_ERROR("gamma (EUR) entry (" << i << "," << j << ") is " << resultGamma[i][j]
408 << ", bump and revalue result is " << bumpGamma[i][j]);
409 }
410 }
411
412 // check gamma (USD)
413 for (Size i = 0; i < 2 * n; ++i) {
414 for (Size j = 0; j < 2 * n; ++j) {
415 if (!check(resultGammaFor[i][j], bumpGammaFor[i][j]))
416 BOOST_ERROR("gamma (USD) entry (" << i << "," << j << ") is " << resultGammaFor[i][j]
417 << ", bump and revalue result is " << bumpGammaFor[i][j]);
418 }
419 }
420} // performTests
421
422} // anonymous namespace
423
424BOOST_FIXTURE_TEST_SUITE(QuantExtTestSuite, qle::test::TopLevelFixture)
425
426BOOST_AUTO_TEST_SUITE(DiscountingCurrencySwapEngineDeltaGammaTest)
427
428BOOST_AUTO_TEST_CASE(testNpvDeltasGammas) {
429
430 TestData d;
431
432 std::vector<Handle<YieldTermStructure>> discountCurves;
433 discountCurves.push_back(d.discountCurve);
434 discountCurves.push_back(d.discountCurveFor);
435 std::vector<Handle<Quote>> fx;
436 fx.push_back(Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(1.00)));
437 fx.push_back(Handle<Quote>(d.fxQuote));
438 std::vector<Currency> currencies;
439 currencies.push_back(EURCurrency());
440 currencies.push_back(USDCurrency());
441
442 QuantLib::ext::shared_ptr<PricingEngine> engine0 =
443 QuantLib::ext::make_shared<DiscountingCurrencySwapEngine>(discountCurves, fx, currencies, EURCurrency());
444 QuantLib::ext::shared_ptr<PricingEngine> engine = QuantLib::ext::make_shared<DiscountingCurrencySwapEngineDeltaGamma>(
445 discountCurves, fx, currencies, EURCurrency(), d.pillarTimes, true, true);
446
447 performTest(d, engine0, engine, false, 0.0, "payer, zero spread");
448 performTest(d, engine0, engine, true, 0.0, "receiver, zero spread");
449 performTest(d, engine0, engine, false, 0.01, "payer, positive spread");
450 performTest(d, engine0, engine, true, 0.01, "receiver, positive spread");
451 performTest(d, engine0, engine, false, -0.01, "payer, negative spread");
452 performTest(d, engine0, engine, true, -0.01, "receiver, negative spread");
453
454 BOOST_CHECK(true);
455}
456
457BOOST_AUTO_TEST_SUITE_END()
458
459BOOST_AUTO_TEST_SUITE_END()
Currency Interest Rate Swap
std::map< Currency, std::vector< Real >, CurrencyComparator > result_type_vector
std::map< Currency, Real, CurrencyComparator > result_type_scalar
std::map< Currency, Matrix, CurrencyComparator > result_type_matrix
discounting currency swap engine
discounting currency swap engine providing analytical deltas and gammas for vanilla swaps
BOOST_AUTO_TEST_CASE(testNpvDeltasGammas)
Fixture that can be used at top level.