26#include <ql/cashflows/floatingratecoupon.hpp>
27#include <ql/currencies/europe.hpp>
28#include <ql/indexes/ibor/euribor.hpp>
29#include <ql/models/shortrate/onefactormodels/gsr.hpp>
30#include <ql/pricingengines/swap/discountingswapengine.hpp>
31#include <ql/pricingengines/swaption/gaussian1dswaptionengine.hpp>
32#include <ql/termstructures/yield/flatforward.hpp>
33#include <ql/time/all.hpp>
35#include <boost/assign/std/vector.hpp>
36#include <boost/timer/timer.hpp>
37#include <boost/test/unit_test.hpp>
41using namespace boost::assign;
44using namespace boost::unit_test_framework;
50 TestData() :
qle::test::TopLevelFixture() {
52 evalDate = Date(5, February, 2016);
53 Settings::instance().evaluationDate() = evalDate;
54 effectiveDate = Date(cal.advance(evalDate, 2 * Days));
55 maturityDate = Date(cal.advance(effectiveDate, 10 * Years));
56 fixedSchedule = Schedule(effectiveDate, maturityDate, 1 * Years, cal, ModifiedFollowing, ModifiedFollowing,
57 DateGeneration::Forward,
false);
58 floatingSchedule = Schedule(effectiveDate, maturityDate, 6 * Months, cal, ModifiedFollowing, ModifiedFollowing,
59 DateGeneration::Forward,
false);
63 yts = Handle<YieldTermStructure>(QuantLib::ext::make_shared<FlatForward>(evalDate, rateLevel, Actual365Fixed()));
64 euribor6m = QuantLib::ext::make_shared<Euribor>(6 * Months, yts);
65 vanillaSwap = QuantLib::ext::make_shared<VanillaSwap>(VanillaSwap::Receiver, nominal, fixedSchedule, strike,
66 Thirty360(Thirty360::BondBasis), floatingSchedule, euribor6m, 0.0, Actual360());
67 for (Size i = 0; i < vanillaSwap->floatingLeg().size(); ++i) {
68 auto cpn = QuantLib::ext::dynamic_pointer_cast<FloatingRateCoupon>(vanillaSwap->floatingLeg()[i]);
69 BOOST_REQUIRE(cpn !=
nullptr);
70 if (cpn->fixingDate() > evalDate && i % 2 == 0)
71 exerciseDates.push_back(cpn->fixingDate());
73 stepDates = std::vector<Date>(exerciseDates.begin(), exerciseDates.end() - 1);
74 stepTimes = Array(stepDates.size());
75 for (Size i = 0; i < stepDates.size(); ++i) {
76 stepTimes[i] = yts->timeFromReference(stepDates[i]);
78 sigmas = Array(stepDates.size() + 1);
79 for (Size i = 0; i < sigmas.size(); ++i) {
80 sigmas[i] = 0.0050 + (0.0080 - 0.0050) * std::exp(-0.2 *
static_cast<double>(i));
83 lgmParam = QuantLib::ext::make_shared<IrLgm1fPiecewiseConstantHullWhiteAdaptor>(
84 EURCurrency(), yts, stepTimes, Array(sigmas.begin(), sigmas.end()), stepTimes,
85 Array(sigmas.size(), reversion));
86 lgm = QuantLib::ext::make_shared<LinearGaussMarkovModel>(lgmParam);
87 dscSwapEngine = QuantLib::ext::make_shared<DiscountingSwapEngine>(yts);
88 vanillaSwap->setPricingEngine(dscSwapEngine);
92 Date evalDate, effectiveDate, maturityDate;
93 Schedule fixedSchedule, floatingSchedule;
94 Real rateLevel, strike, nominal;
95 Handle<YieldTermStructure> yts;
96 QuantLib::ext::shared_ptr<IborIndex> euribor6m;
97 QuantLib::ext::shared_ptr<VanillaSwap> vanillaSwap;
98 std::vector<Date> exerciseDates, stepDates;
99 Array stepTimes, sigmas;
101 QuantLib::ext::shared_ptr<IrLgm1fParametrization> lgmParam;
102 QuantLib::ext::shared_ptr<LinearGaussMarkovModel> lgm;
103 QuantLib::ext::shared_ptr<DiscountingSwapEngine> dscSwapEngine;
110BOOST_FIXTURE_TEST_SUITE(LgmFlexiSwapEngineTest, TestData)
114 BOOST_TEST_MESSAGE(
"Testing LGM Flexi-Swap engine in single swaption case...");
118 QuantLib::ext::shared_ptr<Exercise> exercise = QuantLib::ext::make_shared<BermudanExercise>(exerciseDates,
false);
119 QuantLib::ext::shared_ptr<Swaption> swaption = QuantLib::ext::make_shared<Swaption>(vanillaSwap, exercise);
121 QuantLib::ext::shared_ptr<PricingEngine> swaptionEngine =
122 QuantLib::ext::make_shared<NumericLgmSwaptionEngine>(lgm, 7.0, 16, 7.0, 32);
124 swaption->setPricingEngine(swaptionEngine);
125 boost::timer::cpu_timer timer;
126 Real swaptionNpv = swaption->NPV();
129 Real swapNpv = vanillaSwap->NPV();
131 BOOST_TEST_MESSAGE(
"swaption npv = " << swaptionNpv <<
" swap npv = " << swapNpv
132 <<
" fix = " << vanillaSwap->legNPV(0) <<
" float =" << vanillaSwap->legNPV(1)
133 <<
" timing = " << timer.elapsed().wall * 1e-6 <<
" ms");
137 Size nFixed = fixedSchedule.size() - 1, nFloat = floatingSchedule.size() - 1;
138 QuantLib::ext::shared_ptr<FlexiSwap> flexiSwap = QuantLib::ext::make_shared<FlexiSwap>(
139 VanillaSwap::Payer, std::vector<Real>(nFixed, nominal), std::vector<Real>(nFloat, nominal), fixedSchedule,
140 std::vector<Real>(nFixed, strike), Thirty360(Thirty360::BondBasis), floatingSchedule, euribor6m, std::vector<Real>(nFloat, 1.0),
141 std::vector<Real>(nFloat, 0.0), std::vector<Real>(nFloat, Null<Real>()),
142 std::vector<Real>(nFloat, Null<Real>()), Actual360(), std::vector<Real>(nFixed, 0.0), Position::Long);
143 QuantLib::ext::shared_ptr<FlexiSwap> flexiSwap2 = QuantLib::ext::make_shared<FlexiSwap>(
144 VanillaSwap::Receiver, std::vector<Real>(nFixed, nominal), std::vector<Real>(nFloat, nominal), fixedSchedule,
145 std::vector<Real>(nFixed, strike), Thirty360(Thirty360::BondBasis), floatingSchedule, euribor6m, std::vector<Real>(nFloat, 1.0),
146 std::vector<Real>(nFloat, 0.0), std::vector<Real>(nFloat, Null<Real>()),
147 std::vector<Real>(nFloat, Null<Real>()), Actual360(), std::vector<Real>(nFixed, 0.0), Position::Short);
149 auto flexiEngine = QuantLib::ext::make_shared<NumericLgmFlexiSwapEngine>(
151 auto flexiEngine2 = QuantLib::ext::make_shared<NumericLgmFlexiSwapEngine>(
154 flexiSwap->setPricingEngine(dscSwapEngine);
155 flexiSwap2->setPricingEngine(dscSwapEngine);
156 Real flexiUnderlyingNpvAnalytical = flexiSwap->NPV();
157 Real flexiUnderlyingNpvAnalytical2 = flexiSwap2->NPV();
159 flexiSwap->setPricingEngine(flexiEngine);
160 flexiSwap2->setPricingEngine(flexiEngine);
162 Real flexiNpv = flexiSwap->NPV();
164 Real timing2 = timer.elapsed().wall * 1e-6;
165 Real flexiUnderlyingNpv = flexiSwap->underlyingValue();
166 Real flexiOptionNpv = flexiNpv - flexiUnderlyingNpv;
167 Real flexiNpv2 = flexiSwap2->NPV();
168 Real flexiUnderlyingNpv2 = flexiSwap2->underlyingValue();
169 Real flexiOptionNpv2 = flexiNpv2 - flexiUnderlyingNpv2;
171 flexiSwap->setPricingEngine(flexiEngine2);
172 flexiSwap2->setPricingEngine(flexiEngine2);
174 Real flexiNpvb = flexiSwap->NPV();
176 Real timing3 = timer.elapsed().wall * 1e-6;
177 Real flexiUnderlyingNpvb = flexiSwap->underlyingValue();
178 Real flexiOptionNpvb = flexiNpv - flexiUnderlyingNpv;
179 Real flexiNpvb2 = flexiSwap2->NPV();
180 Real flexiUnderlyingNpvb2 = flexiSwap2->underlyingValue();
181 Real flexiOptionNpvb2 = flexiNpv2 - flexiUnderlyingNpv2;
183 BOOST_TEST_MESSAGE(
"A1 flexi npv = " << flexiNpv <<
" flexi underlying npv = " << flexiUnderlyingNpv
184 <<
" flexi option npv = " << flexiOptionNpv
185 <<
" flexi analytical underlying npv = " << flexiUnderlyingNpvAnalytical
186 <<
" timing = " << timing2 <<
" ms (method=SwaptionArray)");
187 BOOST_TEST_MESSAGE(
"A2 flexi npv = " << flexiNpv2 <<
" flexi underlying npv = " << flexiUnderlyingNpv2
188 <<
" flexi option npv = " << flexiOptionNpv2
189 <<
" flexi analytical underlying npv = " << flexiUnderlyingNpvAnalytical2);
191 BOOST_TEST_MESSAGE(
"B1 flexi npv = " << flexiNpvb <<
" flexi underlying npv = " << flexiUnderlyingNpvb
192 <<
" flexi option npv = " << flexiOptionNpvb
193 <<
" flexi analytical underlying npv = " << flexiUnderlyingNpvAnalytical
194 <<
" timing = " << timing3 <<
" ms (method=SingleSwaptions)");
195 BOOST_TEST_MESSAGE(
"B2 flexi npv = " << flexiNpvb2 <<
" flexi underlying npv = " << flexiUnderlyingNpvb2
196 <<
" flexi option npv = " << flexiOptionNpvb2
197 <<
" flexi analytical underlying npv = " << flexiUnderlyingNpvAnalytical2);
201 Real tol = 3E-5 * nominal;
203 BOOST_CHECK_SMALL(std::abs(flexiUnderlyingNpv + swapNpv), tol);
204 BOOST_CHECK_SMALL(std::abs(flexiOptionNpv - swaptionNpv), tol);
206 BOOST_CHECK_SMALL(std::abs(flexiUnderlyingNpv2 - swapNpv), tol);
207 BOOST_CHECK_SMALL(std::abs(flexiOptionNpv2 + swaptionNpv), tol);
209 BOOST_CHECK_SMALL(std::abs(flexiUnderlyingNpvAnalytical + swapNpv), tol);
210 BOOST_CHECK_SMALL(std::abs(flexiUnderlyingNpvAnalytical2 - swapNpv), tol);
212 BOOST_CHECK_SMALL(std::abs(flexiUnderlyingNpvb + swapNpv), tol);
213 BOOST_CHECK_SMALL(std::abs(flexiOptionNpvb - swaptionNpv), tol);
215 BOOST_CHECK_SMALL(std::abs(flexiUnderlyingNpvb2 - swapNpv), tol);
216 BOOST_CHECK_SMALL(std::abs(flexiOptionNpvb2 + swaptionNpv), tol);
218 BOOST_CHECK_SMALL(std::abs(flexiUnderlyingNpvAnalytical + swapNpv), tol);
219 BOOST_CHECK_SMALL(std::abs(flexiUnderlyingNpvAnalytical2 - swapNpv), tol);
225 BOOST_TEST_MESSAGE(
"Testing LGM Flexi-Swap engine in multiple swaption case...");
229 Size nFixed = fixedSchedule.size() - 1, nFloat = floatingSchedule.size() - 1;
230 std::vector<Real> fixedNotionals{900.0, 1000.0, 1000.0, 800.0, 500.0, 500.0, 500.0, 500.0, 500.0, 500.0};
231 std::vector<Real> floatNotionals{900.0, 900.0, 1000.0, 1000.0, 1000.0, 1000.0, 800.0, 800.0, 500.0, 500.0,
232 500.0, 500.0, 500.0, 500.0, 500.0, 500.0, 500.0, 500.0, 500.0, 500.0};
233 std::vector<Real> lowerNotionals{900.0, 1000.0, 750.0, 600.0, 250.0, 0.0, 0.0, 0.0, 0.0, 0.0};
235 QuantLib::ext::shared_ptr<FlexiSwap> flexiSwap = QuantLib::ext::make_shared<FlexiSwap>(
236 VanillaSwap::Payer, fixedNotionals, floatNotionals, fixedSchedule, std::vector<Real>(nFixed, strike),
237 Thirty360(Thirty360::BondBasis), floatingSchedule, euribor6m, std::vector<Real>(nFloat, 1.0), std::vector<Real>(nFloat, 0.0),
238 std::vector<Real>(nFloat, Null<Real>()), std::vector<Real>(nFloat, Null<Real>()), Actual360(), lowerNotionals,
241 auto flexiEngine = QuantLib::ext::make_shared<NumericLgmFlexiSwapEngine>(
243 auto flexiEngine2 = QuantLib::ext::make_shared<NumericLgmFlexiSwapEngine>(
246 flexiSwap->setPricingEngine(flexiEngine);
247 boost::timer::cpu_timer timer;
248 Real flexiNpv = flexiSwap->NPV();
250 Real timing1 = timer.elapsed().wall * 1e-6;
251 Real flexiUnderlyingNpv = flexiSwap->underlyingValue();
252 Real flexiOptionNpv = flexiNpv - flexiUnderlyingNpv;
254 flexiSwap->setPricingEngine(flexiEngine2);
256 Real flexiNpv2 = flexiSwap->NPV();
258 Real timing3 = timer.elapsed().wall * 1e-6;
259 Real flexiUnderlyingNpv2 = flexiSwap->underlyingValue();
260 Real flexiOptionNpv2 = flexiNpv2 - flexiUnderlyingNpv2;
262 flexiSwap->setPricingEngine(dscSwapEngine);
263 Real flexiUnderlyingNpvAnalytical = flexiSwap->NPV();
268 Schedule fixedSchedule1(fixedSchedule[2], fixedSchedule[3], 1 * Years, cal, ModifiedFollowing, ModifiedFollowing,
269 DateGeneration::Forward,
false);
270 Schedule floatingSchedule1(floatingSchedule[4], floatingSchedule[6], 6 * Months, cal, ModifiedFollowing,
271 ModifiedFollowing, DateGeneration::Forward,
false);
272 auto swap1 = QuantLib::ext::make_shared<VanillaSwap>(VanillaSwap::Receiver, 200.0, fixedSchedule1, strike, Thirty360(Thirty360::BondBasis),
273 floatingSchedule1, euribor6m, 0.0, Actual360());
274 std::vector<Date> exerciseDates1(exerciseDates.begin() + 1, exerciseDates.begin() + 2);
275 auto exercise1 = QuantLib::ext::make_shared<BermudanExercise>(exerciseDates1,
false);
276 auto swaption1 = QuantLib::ext::make_shared<Swaption>(swap1, exercise1);
279 Schedule fixedSchedule2(fixedSchedule[2], fixedSchedule[4], 1 * Years, cal, ModifiedFollowing, ModifiedFollowing,
280 DateGeneration::Forward,
false);
281 Schedule floatingSchedule2(floatingSchedule[4], floatingSchedule[8], 6 * Months, cal, ModifiedFollowing,
282 ModifiedFollowing, DateGeneration::Forward,
false);
283 auto swap2 = QuantLib::ext::make_shared<VanillaSwap>(VanillaSwap::Receiver, 50.0, fixedSchedule2, strike, Thirty360(Thirty360::BondBasis),
284 floatingSchedule2, euribor6m, 0.0, Actual360());
285 std::vector<Date> exerciseDates2(exerciseDates.begin() + 1, exerciseDates.begin() + 3);
286 auto exercise2 = QuantLib::ext::make_shared<BermudanExercise>(exerciseDates2,
false);
287 auto swaption2 = QuantLib::ext::make_shared<Swaption>(swap2, exercise2);
290 Schedule fixedSchedule3(fixedSchedule[3], fixedSchedule[4], 1 * Years, cal, ModifiedFollowing, ModifiedFollowing,
291 DateGeneration::Forward,
false);
292 Schedule floatingSchedule3(floatingSchedule[6], floatingSchedule[8], 6 * Months, cal, ModifiedFollowing,
293 ModifiedFollowing, DateGeneration::Forward,
false);
294 auto swap3 = QuantLib::ext::make_shared<VanillaSwap>(VanillaSwap::Receiver, 150.0, fixedSchedule3, strike, Thirty360(Thirty360::BondBasis),
295 floatingSchedule3, euribor6m, 0.0, Actual360());
296 std::vector<Date> exerciseDates3(exerciseDates.begin() + 2, exerciseDates.begin() + 3);
297 auto exercise3 = QuantLib::ext::make_shared<BermudanExercise>(exerciseDates3,
false);
298 auto swaption3 = QuantLib::ext::make_shared<Swaption>(swap3, exercise3);
301 Schedule fixedSchedule4(fixedSchedule[4], fixedSchedule[10], 1 * Years, cal, ModifiedFollowing, ModifiedFollowing,
302 DateGeneration::Forward,
false);
303 Schedule floatingSchedule4(floatingSchedule[8], floatingSchedule[20], 6 * Months, cal, ModifiedFollowing,
304 ModifiedFollowing, DateGeneration::Forward,
false);
305 auto swap4 = QuantLib::ext::make_shared<VanillaSwap>(VanillaSwap::Receiver, 250.0, fixedSchedule4, strike, Thirty360(Thirty360::BondBasis),
306 floatingSchedule4, euribor6m, 0.0, Actual360());
307 std::vector<Date> exerciseDates4(exerciseDates.begin() + 3, exerciseDates.begin() + 9);
308 auto exercise4 = QuantLib::ext::make_shared<BermudanExercise>(exerciseDates4,
false);
309 auto swaption4 = QuantLib::ext::make_shared<Swaption>(swap4, exercise4);
312 Schedule fixedSchedule5(fixedSchedule[5], fixedSchedule[10], 1 * Years, cal, ModifiedFollowing, ModifiedFollowing,
313 DateGeneration::Forward,
false);
314 Schedule floatingSchedule5(floatingSchedule[10], floatingSchedule[20], 6 * Months, cal, ModifiedFollowing,
315 ModifiedFollowing, DateGeneration::Forward,
false);
316 auto swap5 = QuantLib::ext::make_shared<VanillaSwap>(VanillaSwap::Receiver, 250.0, fixedSchedule5, strike, Thirty360(Thirty360::BondBasis),
317 floatingSchedule5, euribor6m, 0.0, Actual360());
318 std::vector<Date> exerciseDates5(exerciseDates.begin() + 4, exerciseDates.begin() + 9);
319 auto exercise5 = QuantLib::ext::make_shared<BermudanExercise>(exerciseDates5,
false);
320 auto swaption5 = QuantLib::ext::make_shared<Swaption>(swap5, exercise5);
322 QuantLib::ext::shared_ptr<PricingEngine> swaptionEngine =
323 QuantLib::ext::make_shared<NumericLgmSwaptionEngine>(lgm, 7.0, 16, 7.0, 32);
324 swaption1->setPricingEngine(swaptionEngine);
325 swaption2->setPricingEngine(swaptionEngine);
326 swaption3->setPricingEngine(swaptionEngine);
327 swaption4->setPricingEngine(swaptionEngine);
328 swaption5->setPricingEngine(swaptionEngine);
330 Real swaptionNpv = swaption1->NPV() + swaption2->NPV() + swaption3->NPV() + swaption4->NPV() + swaption5->NPV();
332 Real timing2 = timer.elapsed().wall * 1e-6;
334 BOOST_TEST_MESSAGE(
"swaption basket npv =" << swaptionNpv <<
" timing = " << timing2 <<
" ms");
335 BOOST_TEST_MESSAGE(
"A flexi npv = " << flexiNpv <<
" flexi underlying npv = " << flexiUnderlyingNpv
336 <<
" flexi option npv = " << flexiOptionNpv
337 <<
" flexi analytical underlying npv = " << flexiUnderlyingNpvAnalytical
338 <<
" timing = " << timing1 <<
" ms (method=SwaptionArray)");
339 BOOST_TEST_MESSAGE(
"B flexi npv = " << flexiNpv2 <<
" flexi underlying npv = " << flexiUnderlyingNpv2
340 <<
" flexi option npv = " << flexiOptionNpv2
341 <<
" flexi analytical underlying npv = " << flexiUnderlyingNpvAnalytical
342 <<
" timing = " << timing3 <<
" ms (method=SingleSwaptions)");
345 Real tol = 3E-5 * nominal;
347 BOOST_CHECK_SMALL(std::abs(flexiOptionNpv - swaptionNpv), tol);
348 BOOST_CHECK_SMALL(std::abs(flexiUnderlyingNpv - flexiUnderlyingNpvAnalytical), tol);
349 BOOST_CHECK_SMALL(std::abs(flexiNpv - flexiUnderlyingNpv - flexiOptionNpv), 1E-10);
351 BOOST_CHECK_SMALL(std::abs(flexiOptionNpv2 - swaptionNpv), tol);
352 BOOST_CHECK_SMALL(std::abs(flexiUnderlyingNpv2 - flexiUnderlyingNpvAnalytical), tol);
353 BOOST_CHECK_SMALL(std::abs(flexiNpv2 - flexiUnderlyingNpv2 - flexiOptionNpv2), 1E-10);
358 BOOST_TEST_MESSAGE(
"Testing LGM Flexi-Swap engine in deterministic case (zero swaptions)...");
362 Real swapNpv = vanillaSwap->NPV();
363 BOOST_TEST_MESSAGE(
"swap npv = " << swapNpv <<
" fix = " << vanillaSwap->legNPV(0)
364 <<
" float =" << vanillaSwap->legNPV(1));
368 Size nFixed = fixedSchedule.size() - 1, nFloat = floatingSchedule.size() - 1;
369 QuantLib::ext::shared_ptr<FlexiSwap> flexiSwap = QuantLib::ext::make_shared<FlexiSwap>(
370 VanillaSwap::Payer, std::vector<Real>(nFixed, nominal), std::vector<Real>(nFloat, nominal), fixedSchedule,
371 std::vector<Real>(nFixed, strike), Thirty360(Thirty360::BondBasis), floatingSchedule, euribor6m, std::vector<Real>(nFloat, 1.0),
372 std::vector<Real>(nFloat, 0.0), std::vector<Real>(nFloat, Null<Real>()),
373 std::vector<Real>(nFloat, Null<Real>()), Actual360(), std::vector<Real>(nFixed, nominal), Position::Long);
375 auto flexiEngine = QuantLib::ext::make_shared<NumericLgmFlexiSwapEngine>(
377 auto flexiEngine2 = QuantLib::ext::make_shared<NumericLgmFlexiSwapEngine>(
379 auto flexiEngine3 = QuantLib::ext::make_shared<NumericLgmFlexiSwapEngine>(
382 flexiSwap->setPricingEngine(flexiEngine);
383 Real flexiNpv = flexiSwap->NPV();
384 Real flexiUnderlyingNpv = flexiSwap->underlyingValue();
385 Real flexiOptionNpv = flexiNpv - flexiUnderlyingNpv;
386 flexiSwap->setPricingEngine(flexiEngine2);
387 Real flexiNpv2 = flexiSwap->NPV();
388 Real flexiUnderlyingNpv2 = flexiSwap->underlyingValue();
389 Real flexiOptionNpv2 = flexiNpv2 - flexiUnderlyingNpv2;
390 flexiSwap->setPricingEngine(flexiEngine3);
391 Real flexiNpv3 = flexiSwap->NPV();
392 Real flexiUnderlyingNpv3 = flexiSwap->underlyingValue();
393 Real flexiOptionNpv3 = flexiNpv3 - flexiUnderlyingNpv3;
395 BOOST_TEST_MESSAGE(
"1 flexi npv = " << flexiNpv <<
" flexi underlying npv = " << flexiUnderlyingNpv
396 <<
" flexi option npv = " << flexiOptionNpv <<
" (method=SwaptionArray)");
397 BOOST_TEST_MESSAGE(
"2 flexi npv = " << flexiNpv2 <<
" flexi underlying npv = " << flexiUnderlyingNpv2
398 <<
" flexi option npv = " << flexiOptionNpv2 <<
" (method=SwaptionArray)");
399 BOOST_TEST_MESSAGE(
"3 flexi npv = " << flexiNpv3 <<
" flexi underlying npv = " << flexiUnderlyingNpv3
400 <<
" flexi option npv = " << flexiOptionNpv3 <<
" (method=SwaptionArray)");
404 Real tol = 3E-5 * nominal;
406 BOOST_CHECK_SMALL(std::abs(flexiUnderlyingNpv + swapNpv), tol);
407 BOOST_CHECK_SMALL(std::abs(flexiOptionNpv), tol);
408 BOOST_CHECK_SMALL(std::abs(flexiUnderlyingNpv2 + swapNpv), tol);
409 BOOST_CHECK_SMALL(std::abs(flexiOptionNpv2), tol);
410 BOOST_CHECK_SMALL(std::abs(flexiUnderlyingNpv3 + swapNpv), tol);
411 BOOST_CHECK_SMALL(std::abs(flexiOptionNpv3), tol);
415BOOST_AUTO_TEST_SUITE_END()
417BOOST_AUTO_TEST_SUITE_END()
adaptor to emulate piecewise constant Hull White parameters
BOOST_AUTO_TEST_CASE(testSingleSwaption)
numeric engine for flexi swaps in the LGM model
Fixture that can be used at top level.