Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
representativeswaption.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2019 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 <boost/test/unit_test.hpp>
20
21#include <oret/toplevelfixture.hpp>
22
24
27#include <qle/models/lgm.hpp>
29
30#include <ql/cashflows/couponpricer.hpp>
31#include <ql/cashflows/iborcoupon.hpp>
32#include <ql/currencies/europe.hpp>
33#include <ql/exercise.hpp>
34#include <ql/indexes/iborindex.hpp>
35#include <ql/indexes/swap/euriborswap.hpp>
36#include <ql/instruments/makevanillaswap.hpp>
37#include <ql/instruments/nonstandardswap.hpp>
38#include <ql/math/optimization/levenbergmarquardt.hpp>
39#include <ql/models/shortrate/calibrationhelpers/swaptionhelper.hpp>
40#include <ql/pricingengines/swaption/blackswaptionengine.hpp>
41#include <ql/termstructures/volatility/swaption/swaptionconstantvol.hpp>
42#include <ql/termstructures/yield/flatforward.hpp>
43#include <ql/time/calendars/target.hpp>
44#include <ql/time/daycounters/actualactual.hpp>
45#include <ql/timegrid.hpp>
46
47#include <boost/accumulators/accumulators.hpp>
48#include <boost/accumulators/statistics/mean.hpp>
49#include <boost/accumulators/statistics/stats.hpp>
50
51#include <boost/timer/timer.hpp>
52
53using namespace QuantLib;
54using namespace QuantExt;
55using namespace boost::accumulators;
56
57using namespace boost::unit_test_framework;
58using std::vector;
59
60BOOST_FIXTURE_TEST_SUITE(OREDataTestSuite, ore::test::TopLevelFixture)
61
62BOOST_AUTO_TEST_SUITE(RepresentativeSwaptionTest)
63
64BOOST_AUTO_TEST_CASE(testStandardUnderlying) {
65
66 Date today(6, Jun, 2019);
67 Settings::instance().evaluationDate() = today;
68
69 auto dsc = Handle<YieldTermStructure>(QuantLib::ext::make_shared<FlatForward>(today, 0.01, ActualActual(ActualActual::ISDA)));
70 auto fwd = Handle<YieldTermStructure>(QuantLib::ext::make_shared<FlatForward>(today, 0.02, ActualActual(ActualActual::ISDA)));
71
72 auto swapIndexBase = QuantLib::ext::make_shared<EuriborSwapIsdaFixA>(10 * Years, fwd, dsc);
73
74 for (Size i = 1; i <= 19; ++i) {
75
76 Date exerciseDate = TARGET().advance(today, i * Years);
77 Date valueDate = swapIndexBase->iborIndex()->valueDate(exerciseDate);
78 VanillaSwap underlying = MakeVanillaSwap((20 - i) * Years, swapIndexBase->iborIndex(), 0.03)
79 .withNominal(10000.0)
80 .withEffectiveDate(valueDate);
81
82 RepresentativeSwaptionMatcher matcher({underlying.leg(0), underlying.leg(1)}, {true, false}, swapIndexBase,
83 false, dsc, 0.01);
84
85 static constexpr Real tol = 1E-6;
86
87 auto w = matcher.representativeSwaption(
88 exerciseDate, RepresentativeSwaptionMatcher::InclusionCriterion::AccrualStartGeqExercise);
89
90 BOOST_REQUIRE_EQUAL(w->exercise()->dates().size(), 1);
91 BOOST_CHECK_EQUAL(w->exercise()->date(0), exerciseDate);
92 auto s = w->underlyingSwap();
93 BOOST_CHECK_EQUAL(s->type(), VanillaSwap::Payer);
94 BOOST_CHECK_CLOSE(s->nominal(), 10000.0, tol);
95 BOOST_CHECK_CLOSE(s->fixedRate(), 0.03, tol);
96 BOOST_REQUIRE(!s->fixedSchedule().dates().empty());
97 BOOST_CHECK_EQUAL(s->fixedSchedule().dates().front(), valueDate);
98 BOOST_CHECK_EQUAL(s->fixedSchedule().dates().back(), underlying.maturityDate());
99 BOOST_REQUIRE(!s->floatingSchedule().dates().empty());
100 BOOST_CHECK_EQUAL(s->floatingSchedule().dates().front(), valueDate);
101 BOOST_CHECK_EQUAL(s->floatingSchedule().dates().back(), underlying.maturityDate());
102 BOOST_CHECK_EQUAL(s->iborIndex()->name(), swapIndexBase->iborIndex()->name());
103 BOOST_CHECK_CLOSE(s->spread(), 0.0, tol);
104 }
105}
106
107namespace {
108void runTest(const std::vector<Real>& nominals, const bool isPayer, const Real errorTol,
109 const std::vector<Real> cachedSimResults = {}) {
110
111 Date today(6, Jun, 2019);
112 Settings::instance().evaluationDate() = today;
113
114 auto dsc = Handle<YieldTermStructure>(QuantLib::ext::make_shared<FlatForward>(today, 0.01, ActualActual(ActualActual::ISDA)));
115 auto fwd = Handle<YieldTermStructure>(QuantLib::ext::make_shared<FlatForward>(today, 0.02, ActualActual(ActualActual::ISDA)));
116 auto blackVol = Handle<SwaptionVolatilityStructure>(
117 QuantLib::ext::make_shared<ConstantSwaptionVolatility>(today, TARGET(), Following, 0.0050, ActualActual(ActualActual::ISDA), Normal));
118 auto blackEngine = QuantLib::ext::make_shared<BachelierSwaptionEngine>(dsc, blackVol);
119
120 auto swapIndexBase = QuantLib::ext::make_shared<EuriborSwapIsdaFixA>(10 * Years, fwd, dsc);
121
122 // create swap
123
124 std::vector<Real> fixedNominals(nominals);
125 fixedNominals.resize(20, nominals.back());
126 std::vector<Real> fixedRates(20, 0.03);
127 std::vector<Real> floatNominals;
128 for (auto const& n : fixedNominals) {
129 floatNominals.push_back(n);
130 floatNominals.push_back(n);
131 }
132
133 QuantLib::ext::shared_ptr<VanillaSwap> tmp = MakeVanillaSwap(20 * Years, swapIndexBase->iborIndex(), 0.03);
134 QuantLib::ext::shared_ptr<Swap> underlying = QuantLib::ext::make_shared<NonstandardSwap>(
135 isPayer ? VanillaSwap::Payer : VanillaSwap::Receiver, fixedNominals, floatNominals, tmp->fixedSchedule(),
136 fixedRates, tmp->fixedDayCount(), tmp->floatingSchedule(), tmp->iborIndex(), std::vector<Real>(40, 1.0),
137 std::vector<Real>(40, 0.0), tmp->floatingDayCount());
138
139 // set evaluation dates / times
140
141 std::vector<Date> evalDates;
142 std::vector<Real> evalTimes;
143 for (Size i = 1; i < 250; ++i) {
144 evalDates.push_back(today + i * Months);
145 evalTimes.push_back(dsc->timeFromReference(evalDates.back()));
146 }
147 Size nTimes = evalDates.size();
148 std::vector<Real> epe_repr(nTimes), epe_sim(nTimes);
149
150 // generate EPE by pricing representative swaptions
151
152 boost::timer::cpu_timer timer;
153 for (Size i = 0; i < nTimes; ++i) {
154 evalTimes[i] = dsc->timeFromReference(evalDates[i]);
155
156 RepresentativeSwaptionMatcher matcher({underlying->leg(0), underlying->leg(1)}, {isPayer, !isPayer},
157 swapIndexBase, false, dsc, 0.0);
158
159 Real npv = 0.0;
160 auto w = matcher.representativeSwaption(evalDates[i],
161 RepresentativeSwaptionMatcher::InclusionCriterion::PayDateGtExercise);
162 if (w) {
163 w->setPricingEngine(blackEngine);
164 npv = w->NPV();
165 }
166 epe_repr[i] = npv;
167 }
168 timer.stop();
169 BOOST_TEST_MESSAGE("EPE calculation via representative swaptions took " << timer.elapsed().wall * 1e-6 << "ms");
170
171 // generate EPE with full simulation (reversion = 0, so LGM vol = black vol)
172
173 if (cachedSimResults.empty()) {
174 Size nPaths = 10000;
175 TimeGrid grid(evalTimes.begin(), evalTimes.end());
176
177 std::vector<QuantLib::ext::shared_ptr<BlackCalibrationHelper>> basket;
178 std::vector<Date> expiryDates;
179 for (Size i = 1; i < 20; ++i) {
180 QuantLib::ext::shared_ptr<BlackCalibrationHelper> helper = QuantLib::ext::make_shared<SwaptionHelper>(
181 i * Years, (20 - i) * Years, Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(0.0050)),
182 swapIndexBase->iborIndex(), 1 * Years, swapIndexBase->dayCounter(),
183 swapIndexBase->iborIndex()->dayCounter(), dsc, BlackCalibrationHelper::RelativePriceError,
184 fixedRates.front(), 1.0, Normal);
185 basket.push_back(helper);
186 expiryDates.push_back(
187 QuantLib::ext::static_pointer_cast<SwaptionHelper>(helper)->swaption()->exercise()->dates().back());
188 }
189 std::vector<Date> stepDates(expiryDates.begin(), expiryDates.end() - 1);
190 Array stepTimes(stepDates.size());
191 for (Size i = 0; i < stepDates.size(); ++i) {
192 stepTimes[i] = dsc->timeFromReference(stepDates[i]);
193 }
194 auto lgm_p = QuantLib::ext::make_shared<IrLgm1fPiecewiseConstantHullWhiteAdaptor>(
195 EURCurrency(), dsc, stepTimes, Array(stepTimes.size() + 1, 0.0050), stepTimes,
196 Array(stepTimes.size() + 1, 0.0));
197 lgm_p->shift() = -lgm_p->H(20.0);
198 auto lgm = QuantLib::ext::make_shared<LGM>(lgm_p);
199 auto swaptionEngineLgm = QuantLib::ext::make_shared<AnalyticLgmSwaptionEngine>(lgm);
200 for (Size i = 0; i < basket.size(); ++i) {
201 basket[i]->setPricingEngine(swaptionEngineLgm);
202 }
203 LevenbergMarquardt lm(1E-8, 1E-8, 1E-8);
204 EndCriteria ec(1000, 500, 1E-8, 1E-8, 1E-8);
205 lgm->calibrateVolatilitiesIterative(basket, lm, ec);
206
207 MultiPathGeneratorSobolBrownianBridge pgen(lgm->stateProcess(), grid);
208
209 auto lgm_dsc = QuantLib::ext::make_shared<LgmImpliedYtsFwdFwdCorrected>(lgm, dsc);
210 auto lgm_fwd = QuantLib::ext::make_shared<LgmImpliedYtsFwdFwdCorrected>(lgm, fwd);
211
212 auto lgmEuribor = swapIndexBase->iborIndex()->clone(Handle<YieldTermStructure>(lgm_fwd));
213
214 std::vector<Leg> lgmLinkedUnderlying(2);
215 std::set<Date> requiredFixings;
216 for (Size i = 0; i < 2; ++i) {
217 for (auto const& c : underlying->leg(i)) {
218 auto f = QuantLib::ext::dynamic_pointer_cast<IborCoupon>(c);
219 if (f) {
220 requiredFixings.insert(f->fixingDate());
221 auto ic = QuantLib::ext::make_shared<IborCoupon>(
222 f->date(), f->nominal(), f->accrualStartDate(), f->accrualEndDate(), f->fixingDays(),
223 lgmEuribor, f->gearing(), f->spread(), f->referencePeriodStart(), f->referencePeriodEnd(),
224 f->dayCounter(), f->isInArrears());
225 ic->setPricer(QuantLib::ext::make_shared<BlackIborCouponPricer>());
226 lgmLinkedUnderlying[i].push_back(ic);
227 } else
228 lgmLinkedUnderlying[i].push_back(c);
229 }
230 }
231
232 Swap lgmUnderlying(lgmLinkedUnderlying, {isPayer, !isPayer});
233
234 timer.start();
235 auto lgmSwapEngine = QuantLib::ext::make_shared<DiscountingSwapEngine>(Handle<YieldTermStructure>(lgm_dsc));
236 lgmUnderlying.setPricingEngine(lgmSwapEngine);
237 std::vector<accumulator_set<double, stats<tag::mean>>> acc(nTimes);
238 for (Size p = 0; p < nPaths; ++p) {
239 auto currentFixing = requiredFixings.begin();
240 MultiPath path = pgen.next().value;
241 for (Size i = 0; i < nTimes; ++i) {
242 lgm_dsc->move(evalDates[i], path[0][i + 1]);
243 lgm_fwd->move(evalDates[i], path[0][i + 1]);
244 Settings::instance().evaluationDate() = evalDates[i];
245 while (currentFixing != requiredFixings.end() && evalDates[i] >= *currentFixing) {
246 Date evalDateAdj =
247 lgmEuribor->fixingCalendar().adjust(evalDates[i]); // for today's fixing generation
248 lgmEuribor->addFixing(*currentFixing, lgmEuribor->fixing(evalDateAdj), false);
249 ++currentFixing;
250 }
251 acc[i](std::max(lgmUnderlying.NPV(), 0.0) / lgm->numeraire(evalTimes[i], path[0][i + 1]));
252 }
253 Settings::instance().evaluationDate() = today;
254 IndexManager::instance().clearHistory(lgmEuribor->name());
255 }
256 for (Size i = 0; i < nTimes; ++i) {
257 epe_sim[i] = mean(acc[i]);
258 BOOST_TEST_MESSAGE(epe_sim[i] << (i < nTimes - 1 ? "," : ""));
259 }
260 timer.stop();
261 BOOST_TEST_MESSAGE("EPE calculation via full simulation took " << timer.elapsed().wall * 1e-6 << "ms");
262 } else {
263 BOOST_REQUIRE(cachedSimResults.size() == nTimes);
264 for (Size i = 0; i < nTimes; ++i)
265 epe_sim[i] = cachedSimResults[i];
266 }
267
268 // compare results
269
270 BOOST_TEST_MESSAGE("date t EPE_repr EPE_sim");
271 for (Size i = 0; i < nTimes; ++i) {
272 BOOST_TEST_MESSAGE(QuantLib::io::iso_date(evalDates[i])
273 << " " << evalTimes[i] << " " << epe_repr[i] << " " << epe_sim[i]);
274 BOOST_CHECK_SMALL(epe_repr[i] - epe_sim[i], errorTol);
275 }
276}
277} // namespace
278
279BOOST_AUTO_TEST_CASE(testEPEStandardPayerSwap) {
280 runTest({10000.0}, true, 5.0,
281 {0, 0, 0, 0.00476312, 0.141555, 0.229646, 0.285095, 0.750794, 1.43698, 2.23473, 3.12387,
282 4.08822, 10.1648, 11.9295, 15.377, 18.4359, 21.1733, 23.829, 18.5224, 21.1229, 24.0598, 26.4625,
283 28.777, 31.1131, 46.7003, 50.1594, 53.5407, 57.2505, 60.4863, 64.6806, 51.473, 54.8708, 57.7915,
284 60.302, 62.9418, 65.1625, 86.3816, 89.7665, 93.488, 97.5451, 101.403, 105.314, 84.7002, 88.0465,
285 90.626, 94.0729, 97.6903, 100.334, 125.85, 129.309, 131.478, 133.738, 139.173, 143.482, 116.766,
286 119.195, 121.608, 124.51, 127.738, 130.716, 157.044, 160.824, 163.489, 166.715, 169.565, 172.198,
287 140.408, 143.187, 145.431, 148.512, 151.258, 154.147, 182.893, 186.55, 188.204, 190.143, 193.236,
288 196.31, 161.458, 163.681, 165.816, 167.875, 170.316, 172.51, 201.745, 204.853, 206.583, 208.683,
289 211.533, 213.877, 174.826, 177.235, 178.714, 180.611, 183.115, 185.117, 214.554, 216.786, 218.909,
290 221.963, 223.604, 225.513, 182.987, 184.414, 186.651, 188.521, 190.39, 192.539, 221.357, 223.192,
291 225.106, 226.645, 227.932, 230.81, 186.467, 188.049, 189.68, 191.836, 193.588, 195.276, 224.057,
292 225.636, 226.516, 228.609, 230.082, 231.878, 184.733, 186.123, 187.525, 189.293, 190.731, 191.882,
293 219.822, 221.445, 222.857, 223.791, 224.945, 226.246, 177.87, 179.055, 180.006, 181.366, 182.334,
294 183.467, 209.987, 211.417, 212.994, 214.195, 215.049, 216.597, 166.943, 168.152, 169.01, 169.767,
295 170.732, 171.77, 198.04, 199.156, 200.184, 201.36, 201.983, 202.727, 151.235, 152.127, 152.92,
296 153.78, 154.52, 155.813, 181.015, 181.805, 182.547, 183.035, 183.925, 184.402, 131.595, 132.355,
297 133.101, 134.118, 134.54, 134.86, 159.379, 160.045, 160.721, 161.29, 161.831, 162.648, 110.028,
298 110.509, 110.892, 111.467, 111.937, 112.641, 134.687, 135.165, 135.463, 136.04, 136.535, 136.947,
299 84.0783, 84.501, 84.9166, 85.1605, 85.5312, 85.9006, 105.707, 106.004, 106.191, 106.522, 106.961,
300 107.167, 55.3124, 55.482, 55.6544, 55.9519, 56.2398, 56.4192, 73.8899, 74.0573, 74.2138, 74.3796,
301 74.547, 74.6136, 25.2369, 25.2908, 25.3794, 25.4661, 25.5298, 25.5784, 38.5024, 38.5559, 38.5982,
302 38.6212, 38.6586, 38.7142, 1.25658, 1.25658, 1.25658, 1.25658, 1.25658, 1.25658, 0, 0,
303 0, 0, 0, 0, 0, 0, 0});
304}
305
306BOOST_AUTO_TEST_CASE(testEPEStandardReceiverSwap) {
307 runTest({10000.0}, false, 5.0,
308 {1776.1, 1776.16, 1776.27, 1776.39, 1776.42, 1776.58, 1876.93, 1877.36, 1878.17, 1878.88, 1879.66, 1880.74,
309 1689.31, 1691.07, 1694.48, 1697.55, 1700.31, 1703.1, 1796.8, 1799.45, 1802.44, 1804.92, 1807.18, 1809.65,
310 1629.45, 1632.97, 1636.23, 1640, 1643.18, 1647.31, 1732.38, 1735.85, 1738.74, 1741.2, 1743.84, 1746.11,
311 1573.39, 1576.8, 1580.64, 1584.57, 1588.55, 1592.54, 1670.29, 1673.64, 1676.17, 1679.7, 1683.49, 1686.24,
312 1518.25, 1521.77, 1524.01, 1526.41, 1531.78, 1535.98, 1604.98, 1607.35, 1609.64, 1612.66, 1615.93, 1618.91,
313 1456.63, 1460.35, 1463.11, 1466.31, 1469.16, 1471.81, 1535.16, 1538.05, 1540.22, 1543.35, 1545.96, 1549.03,
314 1389.55, 1393.3, 1395.02, 1397, 1400.06, 1403.08, 1462.55, 1464.82, 1466.93, 1468.96, 1471.46, 1473.84,
315 1316.64, 1319.69, 1321.4, 1323.64, 1326.29, 1328.68, 1383.02, 1385.55, 1387.06, 1389.04, 1391.56, 1393.56,
316 1238.64, 1240.94, 1243.11, 1246.07, 1247.79, 1249.73, 1299.71, 1301.09, 1303.37, 1305.24, 1307, 1309.24,
317 1155.17, 1157.04, 1158.95, 1160.47, 1161.84, 1164.64, 1211.03, 1212.48, 1214.12, 1216.31, 1218.07, 1219.78,
318 1068.44, 1069.98, 1070.92, 1072.97, 1074.54, 1076.37, 1119.5, 1120.92, 1122.32, 1123.97, 1125.53, 1126.69,
319 976.39, 978.009, 979.414, 980.4, 981.515, 982.851, 1024.18, 1025.38, 1026.36, 1027.75, 1028.67, 1029.81,
320 879.091, 880.557, 882.126, 883.351, 884.23, 885.776, 924.896, 926.077, 926.923, 927.62, 928.595, 929.658,
321 780.719, 781.807, 782.875, 784.059, 784.728, 785.429, 821.668, 822.593, 823.351, 824.199, 825.001, 826.25,
322 677.732, 678.55, 679.337, 679.897, 680.778, 681.247, 716.469, 717.211, 717.967, 718.95, 719.399, 719.747,
323 570.817, 571.447, 572.099, 572.637, 573.167, 573.963, 607.066, 607.543, 607.927, 608.494, 608.939, 609.607,
324 462.062, 462.526, 462.861, 463.412, 463.919, 464.334, 496.515, 496.929, 497.349, 497.577, 497.939, 498.317,
325 350.516, 350.807, 350.997, 351.318, 351.743, 351.953, 384.239, 384.402, 384.575, 384.872, 385.161, 385.345,
326 235.92, 236.085, 236.247, 236.417, 236.582, 236.647, 270.98, 271.032, 271.119, 271.205, 271.265, 271.319,
327 119.009, 119.059, 119.098, 119.124, 119.161, 119.217, 164.655, 164.655, 164.655, 164.655, 164.655, 164.655,
328 0, 0, 0, 0, 0, 0, 0, 0, 0});
329}
330
331BOOST_AUTO_TEST_CASE(testEPEAmortisingPayerSwap) {
332 runTest({10000.0, 9500.0, 9000.0, 8500.0, 8000.0, 7500.0, 7000.0, 6500.0, 6000.0, 5500.0, 5000.0,
333 4500.0, 4000.0, 3500.0, 3000.0, 2500.0, 2000.0, 1500.0, 1000.0, 500.0, 0.0},
334 true, 5.0,
335 {0, 0, 0, 0, 0.0635402, 0.0996111, 0.035936, 0.166171, 0.388186, 0.634441,
336 0.903261, 1.16444, 5.22218, 6.0652, 7.75181, 9.2517, 10.602, 11.8243, 6.61368, 7.63869,
337 8.68031, 9.73107, 10.5444, 11.5449, 22.8357, 24.4621, 25.9824, 27.7498, 29.2149, 31.165,
338 19.2384, 20.6274, 21.7167, 22.7248, 23.7752, 24.4396, 39.8875, 41.3704, 42.9692, 44.7158,
339 46.4326, 48.1301, 30.8631, 32.1783, 33.1271, 34.4257, 35.8597, 36.958, 54.8657, 56.2677,
340 57.103, 57.9756, 60.2837, 62.0728, 41.1482, 42.0981, 43.0602, 44.1488, 45.2792, 46.4176,
341 64.2242, 65.7178, 66.695, 67.9049, 69.0142, 69.9904, 46.9911, 48.0362, 48.8651, 49.8856,
342 50.7845, 51.6657, 70.0341, 71.3877, 72.0085, 72.6884, 73.7758, 74.8804, 51.3413, 51.997,
343 52.6139, 53.2466, 53.9994, 54.6788, 72.1067, 73.1625, 73.7329, 74.4325, 75.3778, 76.1421,
344 51.6972, 52.403, 52.8399, 53.3164, 54.0852, 54.6213, 71.0502, 71.7524, 72.3968, 73.3006,
345 73.83, 74.4205, 49.8508, 50.2944, 50.8843, 51.4477, 52.029, 52.7141, 67.5214, 68.0293,
346 68.5529, 68.9871, 69.3272, 70.1703, 46.8175, 47.2749, 47.6874, 48.1455, 48.5909, 48.9994,
347 62.5804, 62.9791, 63.1859, 63.7347, 64.1205, 64.5542, 42.0059, 42.3223, 42.6418, 43.0848,
348 43.3828, 43.6137, 55.6927, 56.082, 56.3962, 56.5947, 56.8809, 57.1763, 36.3262, 36.5648,
349 36.7741, 37.0445, 37.2607, 37.4808, 47.8274, 48.1118, 48.4317, 48.6837, 48.8367, 49.1609,
350 30.1894, 30.3809, 30.5203, 30.6408, 30.8201, 30.9834, 40.0044, 40.2067, 40.3934, 40.6031,
351 40.7129, 40.843, 23.7438, 23.8644, 23.9791, 24.1195, 24.2254, 24.4208, 31.9716, 32.0886,
352 32.1989, 32.2737, 32.4059, 32.4767, 17.4688, 17.573, 17.6864, 17.8163, 17.8776, 17.9241,
353 24.0637, 24.1502, 24.2402, 24.3139, 24.3819, 24.4917, 12.1097, 12.1592, 12.2033, 12.2612,
354 12.3094, 12.3633, 16.9255, 16.9758, 17.0046, 17.0663, 17.1174, 17.161, 7.27119, 7.30655,
355 7.33206, 7.3495, 7.382, 7.40213, 10.5911, 10.6146, 10.6292, 10.6574, 10.6943, 10.7102,
356 3.50722, 3.51497, 3.52593, 3.53726, 3.55108, 3.56092, 5.55212, 5.5622, 5.57099, 5.58081,
357 5.59027, 5.59405, 1.0627, 1.06533, 1.06692, 1.06874, 1.06958, 1.07202, 1.92512, 1.92779,
358 1.92991, 1.93106, 1.93293, 1.93571, 0.0628288, 0.0628288, 0.0628288, 0.0628288, 0.0628288, 0.0628289,
359 0, 0, 0, 0, 0, 0, 0, 0, 0});
360}
361
362BOOST_AUTO_TEST_CASE(testEPEAmortisingReceiverSwap) {
363 runTest({10000.0, 9500.0, 9000.0, 8500.0, 8000.0, 7500.0, 7000.0, 6500.0, 6000.0, 5500.0, 5000.0,
364 4500.0, 4000.0, 3500.0, 3000.0, 2500.0, 2000.0, 1500.0, 1000.0, 500.0, 0.0},
365 false, 10.0,
366 {961.998, 962.037, 962.093, 962.152, 962.166, 962.237, 1062.45, 1062.55, 1062.85, 1063.06, 1063.27, 1063.59,
367 870.155, 870.999, 872.661, 874.169, 875.532, 876.831, 965.656, 966.707, 967.782, 968.878, 969.664, 970.75,
368 796.03, 797.683, 799.142, 800.936, 802.374, 804.28, 880.794, 882.224, 883.305, 884.29, 885.348, 886.051,
369 726.982, 728.478, 730.147, 731.837, 733.62, 735.345, 801.657, 802.972, 803.892, 805.221, 806.744, 807.896,
370 661.313, 662.726, 663.603, 664.556, 666.834, 668.564, 724.232, 725.157, 726.057, 727.194, 728.346, 729.481,
371 596.371, 597.825, 598.856, 600.059, 601.174, 602.158, 650.48, 651.571, 652.373, 653.42, 654.263, 655.219,
372 532.429, 533.819, 534.461, 535.156, 536.233, 537.315, 579.784, 580.467, 581.072, 581.694, 582.468, 583.218,
373 470.182, 471.213, 471.776, 472.542, 473.394, 474.18, 510.442, 511.19, 511.636, 512.148, 512.923, 513.461,
374 410.043, 410.763, 411.425, 412.296, 412.855, 413.461, 444.386, 444.818, 445.418, 445.977, 446.516, 447.238,
375 352.314, 352.837, 353.361, 353.789, 354.161, 354.972, 381.526, 381.944, 382.361, 382.829, 383.274, 383.688,
376 298.222, 298.614, 298.844, 299.368, 299.784, 300.23, 322.807, 323.135, 323.454, 323.857, 324.194, 324.43,
377 247.386, 247.777, 248.087, 248.301, 248.576, 248.88, 268.402, 268.647, 268.865, 269.143, 269.347, 269.569,
378 200.161, 200.452, 200.77, 201.032, 201.188, 201.512, 218.047, 218.234, 218.371, 218.477, 218.657, 218.826,
379 157.762, 157.958, 158.155, 158.366, 158.485, 158.606, 172.207, 172.335, 172.442, 172.582, 172.699, 172.885,
380 119.639, 119.76, 119.878, 119.966, 120.097, 120.166, 131.566, 131.667, 131.782, 131.905, 131.971, 132.022,
381 86.1339, 86.2152, 86.302, 86.3712, 86.4373, 86.5439, 95.5948, 95.6435, 95.688, 95.7448, 95.7896, 95.839,
382 58.0129, 58.0613, 58.095, 58.1534, 58.2064, 58.2508, 65.3708, 65.4053, 65.4312, 65.4474, 65.4788, 65.4999,
383 35.1676, 35.1909, 35.2061, 35.2332, 35.2684, 35.2847, 40.7032, 40.7105, 40.7214, 40.7327, 40.7466, 40.7568,
384 17.7212, 17.7311, 17.7403, 17.7504, 17.7597, 17.7634, 21.6034, 21.6059, 21.6075, 21.6092, 21.6099, 21.6126,
385 5.95044, 5.95296, 5.95492, 5.95619, 5.95805, 5.96085, 8.23275, 8.23275, 8.23275, 8.23275, 8.23275, 8.23275,
386 0, 0, 0, 0, 0, 0, 0, 0, 0});
387}
388
389BOOST_AUTO_TEST_CASE(testEPEAccretingPayerSwap) {
390 runTest({10000.0, 11000.0, 12000.0, 13000.0, 14000.0, 15000.0, 16000.0, 17000.0, 18000.0, 19000.0,
391 20000.0, 21000.0, 22000.0, 23000.0, 24000.0, 25000.0, 26000.0, 27000.0, 28000.0, 29000.0},
392 true, 10.0,
393 {0, 0, 0, 0.0201268, 0.303151, 0.492128, 0.996429, 2.34557, 3.95999, 6.21514, 8.50881,
394 10.8789, 20.0638, 23.6787, 30.6577, 36.8466, 42.3846, 47.9246, 44.0161, 49.9686, 56.4549, 61.9091,
395 67.2612, 72.4536, 94.4797, 101.627, 108.739, 116.334, 123.174, 131.838, 118.332, 125.834, 132.444,
396 138.029, 143.965, 149.348, 179.48, 186.679, 194.639, 203.367, 211.48, 219.84, 194.913, 202.513,
397 208.166, 216.025, 224.238, 230.37, 267.965, 275.567, 280.404, 285.421, 297.124, 306.53, 270.392,
398 276.072, 281.611, 287.977, 295.193, 302.139, 342.83, 351.21, 357.283, 364.517, 370.867, 376.839,
399 329.971, 336.168, 341.369, 348.435, 354.896, 361.73, 408.801, 417.062, 420.807, 425.29, 432.412,
400 439.367, 384.213, 389.783, 394.784, 399.9, 405.539, 410.878, 461.195, 468.37, 472.436, 477.354,
401 484.027, 489.531, 423.175, 429.096, 432.727, 437.811, 443.607, 448.655, 501.693, 506.981, 512.066,
402 519.459, 523.331, 527.855, 451.411, 454.973, 460.204, 465.019, 469.408, 474.516, 529.141, 533.641,
403 538.364, 542.097, 545.255, 552.239, 467.676, 471.477, 475.712, 480.977, 485.523, 489.821, 547.096,
404 551.04, 553.258, 558.449, 562.113, 566.617, 471.922, 475.411, 478.939, 483.373, 487.003, 490.123,
405 548.138, 552.224, 555.849, 558.254, 561.161, 564.46, 462.237, 465.516, 467.838, 471.329, 473.883,
406 476.937, 534.355, 538.071, 542.18, 545.286, 547.528, 551.54, 441.736, 444.906, 447.21, 449.377,
407 451.856, 454.677, 514.14, 517.086, 519.79, 522.9, 524.555, 526.529, 407.306, 409.76, 411.966,
408 414.283, 416.297, 419.716, 479.117, 481.257, 483.262, 484.575, 486.981, 488.28, 360.88, 362.938,
409 364.905, 367.684, 368.849, 369.822, 430.016, 431.843, 433.689, 435.253, 436.746, 438.971, 306.661,
410 307.983, 309.111, 310.686, 312.051, 314.024, 370.213, 371.546, 372.385, 373.993, 375.38, 376.525,
411 238.345, 239.511, 240.697, 241.412, 242.45, 243.555, 295.939, 296.785, 297.316, 298.253, 299.496,
412 300.087, 159.434, 159.911, 160.415, 161.286, 162.106, 162.602, 210.565, 211.048, 211.5, 211.978,
413 212.462, 212.654, 73.8598, 74.0193, 74.2862, 74.5391, 74.7318, 74.8647, 111.657, 111.812, 111.935,
414 112.002, 112.11, 112.271, 3.64407, 3.64407, 3.64407, 3.64407, 3.64407, 3.64407, 0, 0,
415 0, 0, 0, 0, 0, 0, 0});
416}
417
418BOOST_AUTO_TEST_CASE(testEPEAccretingReceiverSwap) {
419 runTest({10000.0, 11000.0, 12000.0, 13000.0, 14000.0, 15000.0, 16000.0, 17000.0, 18000.0, 19000.0,
420 20000.0, 21000.0, 22000.0, 23000.0, 24000.0, 25000.0, 26000.0, 27000.0, 28000.0, 29000.0},
421 false, 10.0,
422 {3404.31, 3404.42, 3404.64, 3404.86, 3404.94, 3405.25, 3506.11, 3507.41, 3509.22, 3511.31, 3513.38, 3515.98,
423 3327.63, 3331.23, 3338.16, 3344.34, 3349.95, 3355.74, 3460.75, 3466.82, 3473.4, 3478.98, 3484.22, 3489.64,
424 3296.33, 3303.63, 3310.49, 3318.2, 3324.93, 3333.48, 3437.95, 3445.57, 3452.12, 3457.58, 3463.5, 3468.97,
425 3266.31, 3273.56, 3281.74, 3290.2, 3298.54, 3307.08, 3410.11, 3417.72, 3423.28, 3431.31, 3439.86, 3446.21,
426 3232.28, 3240.03, 3244.99, 3250.28, 3261.86, 3271.03, 3368.87, 3374.43, 3379.72, 3386.34, 3393.63, 3400.6,
427 3177.29, 3185.58, 3191.84, 3199, 3205.33, 3211.35, 3307.24, 3313.69, 3318.71, 3325.88, 3332.06, 3339.26,
428 3103.98, 3112.46, 3116.36, 3120.92, 3127.98, 3134.82, 3230.59, 3236.27, 3241.21, 3246.27, 3252.05, 3257.8,
429 3009.72, 3016.78, 3020.79, 3025.99, 3032.27, 3037.86, 3130.27, 3136.46, 3140.16, 3145.44, 3151.27, 3156.31,
430 2895.98, 2901.43, 2906.62, 2913.77, 2917.83, 2922.44, 3012.5, 3015.96, 3021.3, 3026.12, 3030.27, 3035.58,
431 2760.99, 2765.57, 2770.28, 2773.96, 2777.31, 2784.13, 2871.94, 2875.44, 2879.7, 2885.02, 2889.59, 2893.95,
432 2608.95, 2612.81, 2615.15, 2620.26, 2624.16, 2628.75, 2714.6, 2718.19, 2721.71, 2725.87, 2729.77, 2732.93,
433 2434.45, 2438.53, 2442.14, 2444.67, 2447.48, 2450.87, 2537.02, 2540.33, 2542.72, 2546.29, 2548.73, 2551.79,
434 2237, 2240.81, 2244.9, 2248.06, 2250.37, 2254.37, 2339.88, 2342.98, 2345.25, 2347.26, 2349.77, 2352.66,
435 2026.66, 2029.53, 2032.34, 2035.47, 2037.25, 2039.11, 2121.68, 2124.22, 2126.33, 2128.61, 2130.79, 2134.1,
436 1793.93, 1796.15, 1798.27, 1799.78, 1802.16, 1803.44, 1887.31, 1889.32, 1891.31, 1894, 1895.24, 1896.29,
437 1540.19, 1541.92, 1543.7, 1545.18, 1546.64, 1548.81, 1630.81, 1632.12, 1633.25, 1634.8, 1636.1, 1637.97,
438 1270.16, 1271.46, 1272.4, 1273.93, 1275.35, 1276.51, 1359.46, 1360.6, 1361.8, 1362.47, 1363.48, 1364.61,
439 981.213, 982.04, 982.58, 983.491, 984.696, 985.296, 1071.82, 1072.28, 1072.79, 1073.65, 1074.48, 1074.99,
440 672.318, 672.794, 673.262, 673.752, 674.228, 674.414, 770.008, 770.161, 770.425, 770.674, 770.856, 771.005,
441 345.125, 345.272, 345.386, 345.459, 345.567, 345.729, 477.499, 477.499, 477.499, 477.499, 477.499, 477.499,
442 0, 0, 0, 0, 0, 0, 0, 0, 0});
443}
444
445BOOST_AUTO_TEST_SUITE_END()
446
447BOOST_AUTO_TEST_SUITE_END()
boost::shared_ptr< Swaption > representativeSwaption(Date exerciseDate, const InclusionCriterion criterion=InclusionCriterion::AccrualStartGeqExercise)
QuantLib::BootstrapHelper< QuantLib::OptionletVolatilityStructure > helper
BOOST_AUTO_TEST_CASE(testStandardUnderlying)