Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
digitalcms.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2017 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/make_shared.hpp>
20#include <boost/test/unit_test.hpp>
30#include <oret/toplevelfixture.hpp>
31#include <ql/cashflows/digitalcoupon.hpp>
32#include <ql/termstructures/volatility/swaption/swaptionconstantvol.hpp>
33#include <ql/termstructures/yield/flatforward.hpp>
34#include <ql/time/calendars/target.hpp>
35#include <ql/time/daycounters/actualactual.hpp>
37
38#include <iostream>
39
40using namespace QuantLib;
41using namespace boost::unit_test_framework;
42using namespace std;
43using namespace ore::data;
44
45// CMS Swap test
46
47namespace {
48
49class TestMarket : public MarketImpl {
50public:
51 TestMarket() : MarketImpl(false) {
52 asof_ = Date(3, Feb, 2016);
53
54 // build discount
55 yieldCurves_[make_tuple(Market::defaultConfiguration, YieldCurveType::Discount, "EUR")] = flatRateYts(0.02);
56
57 // build swaption vols
58 swaptionCurves_[make_pair(Market::defaultConfiguration, "EUR")] = flatRateSvs(0.1);
59
60 // build ibor index
61 Handle<IborIndex> hEUR(ore::data::parseIborIndex(
62 "EUR-EURIBOR-6M", yieldCurves_[make_tuple(Market::defaultConfiguration, YieldCurveType::Discount, "EUR")]));
63 iborIndices_[make_pair(Market::defaultConfiguration, "EUR-EURIBOR-6M")] = hEUR;
64
65 QuantLib::ext::shared_ptr<Conventions> conventions = QuantLib::ext::make_shared<Conventions>();
66
67 // add swap index
68 QuantLib::ext::shared_ptr<ore::data::Convention> swapEURConv(new ore::data::IRSwapConvention(
69 "EUR-6M-SWAP-CONVENTIONS", "TARGET", "Annual", "MF", "30/360", "EUR-EURIBOR-6M"));
70 conventions->add(swapEURConv);
71 QuantLib::ext::shared_ptr<ore::data::Convention> swapIndexEURLongConv1(
72 new ore::data::SwapIndexConvention("EUR-CMS-2Y", "EUR-6M-SWAP-CONVENTIONS"));
73 QuantLib::ext::shared_ptr<ore::data::Convention> swapIndexEURLongConv2(
74 new ore::data::SwapIndexConvention("EUR-CMS-30Y", "EUR-6M-SWAP-CONVENTIONS"));
75 conventions->add(swapIndexEURLongConv1);
76 conventions->add(swapIndexEURLongConv2);
77
78 InstrumentConventions::instance().setConventions(conventions);
79
80 addSwapIndex("EUR-CMS-2Y", "EUR-EURIBOR-6M", Market::defaultConfiguration);
81 addSwapIndex("EUR-CMS-30Y", "EUR-EURIBOR-6M", Market::defaultConfiguration);
82
83 correlationCurves_[make_tuple(Market::defaultConfiguration, "EUR-CMS-30Y", "EUR-CMS-2Y")] = flatCorr(0.8);
84 }
85
86private:
87 Handle<YieldTermStructure> flatRateYts(Real forward) {
88 QuantLib::ext::shared_ptr<YieldTermStructure> yts(new FlatForward(0, NullCalendar(), forward, ActualActual(ActualActual::ISDA)));
89 return Handle<YieldTermStructure>(yts);
90 }
91 Handle<SwaptionVolatilityStructure> flatRateSvs(Volatility forward) {
92 QuantLib::ext::shared_ptr<SwaptionVolatilityStructure> Svs(
93 new ConstantSwaptionVolatility(0, NullCalendar(), ModifiedFollowing, forward, ActualActual(ActualActual::ISDA)));
94 return Handle<SwaptionVolatilityStructure>(Svs);
95 }
96 Handle<QuantExt::CorrelationTermStructure> flatCorr(Real corr) {
97 QuantLib::ext::shared_ptr<QuantExt::CorrelationTermStructure> cs(
98 new QuantExt::FlatCorrelation(0, NullCalendar(), corr, ActualActual(ActualActual::ISDA)));
99
100 return Handle<QuantExt::CorrelationTermStructure>(cs);
101 }
102};
103
104struct CommonVars {
105 // global data
106 string ccy;
107 bool isPayer;
108 string start;
109 string end;
110 string fixtenor;
111 string cmstenor;
112 Calendar cal;
113 string calStr;
114 string conv;
115 string rule;
116 Size days;
117 string fixDC;
118 Real fixedRate;
119 string index1;
120 string index2;
121 int fixingdays;
122 bool isinarrears;
123 double notional;
124 string longShort;
125 vector<double> notionals;
126
127 QuantLib::ext::shared_ptr<ore::data::Swap> makeDigitalCmsSpreadOption(bool call, vector<double> strikes,
128 vector<double> payoffs) {
129 ScheduleData cmsSchedule(ScheduleRules(start, end, cmstenor, calStr, conv, conv, rule));
130
131 vector<LegData> legData;
132 QuantLib::ext::shared_ptr<DigitalCMSSpreadLegData> cmsLegData;
133 if (call) {
134 cmsLegData = QuantLib::ext::make_shared<DigitalCMSSpreadLegData>(
135 QuantLib::ext::make_shared<CMSSpreadLegData>(
136 index1, index2, fixingdays, isinarrears, vector<double>(), vector<string>(), vector<double>(),
137 vector<string>(), vector<double>(), vector<string>(), vector<double>(), vector<string>(), false),
138 Position::Long, false, strikes, vector<string>(), payoffs, vector<string>());
139 } else {
140 cmsLegData = QuantLib::ext::make_shared<DigitalCMSSpreadLegData>(
141 QuantLib::ext::make_shared<CMSSpreadLegData>(
142 index1, index2, fixingdays, isinarrears, vector<double>(), vector<string>(), vector<double>(),
143 vector<string>(), vector<double>(), vector<string>(), vector<double>(), vector<string>(), false),
144 Position::Long, false, vector<double>(), vector<string>(), vector<double>(), vector<string>(),
145 Position::Long, false, strikes, vector<string>(), payoffs);
146 }
147
148 LegData leg(cmsLegData, isPayer, ccy, cmsSchedule, fixDC, notionals);
149 legData.push_back(leg);
150
151 Envelope env("CP1");
152 QuantLib::ext::shared_ptr<ore::data::Swap> swap(new ore::data::Swap(env, legData));
153 return swap;
154 }
155
156 QuantLib::ext::shared_ptr<ore::data::Swap> makeCmsSpreadOption(vector<double> spreads) {
157 ScheduleData cmsSchedule(ScheduleRules(start, end, cmstenor, calStr, conv, conv, rule));
158
159 vector<LegData> legData;
160 CMSSpreadLegData cmsLegData(index1, index2, fixingdays, isinarrears, spreads, vector<string>(),
161 vector<double>(), vector<string>(), vector<double>(), vector<string>(),
162 vector<double>(), vector<string>(), false);
163
164 LegData leg(QuantLib::ext::make_shared<CMSSpreadLegData>(cmsLegData), isPayer, ccy, cmsSchedule, fixDC, notionals);
165 legData.push_back(leg);
166
167 Envelope env("CP1");
168 QuantLib::ext::shared_ptr<ore::data::Swap> swap(new ore::data::Swap(env, legData));
169 return swap;
170 }
171
172 QuantLib::ext::shared_ptr<ore::data::Swap> makeCmsSpreadFloor(vector<double> floors) {
173 ScheduleData cmsSchedule(ScheduleRules(start, end, cmstenor, calStr, conv, conv, rule));
174
175 vector<LegData> legData;
176 CMSSpreadLegData cmsLegData(index1, index2, fixingdays, isinarrears, vector<double>(), vector<string>(),
177 vector<double>(), vector<string>(), floors, vector<string>(), vector<double>(),
178 vector<string>(), false);
179
180 LegData leg(QuantLib::ext::make_shared<CMSSpreadLegData>(cmsLegData), isPayer, ccy, cmsSchedule, fixDC, notionals);
181 legData.push_back(leg);
182
183 Envelope env("CP1");
184 QuantLib::ext::shared_ptr<ore::data::Swap> swap(new ore::data::Swap(env, legData));
185 return swap;
186 }
187
188 QuantLib::ext::shared_ptr<ore::data::Swap> makeCmsSpreadCap(vector<double> caps) {
189 ScheduleData cmsSchedule(ScheduleRules(start, end, cmstenor, calStr, conv, conv, rule));
190
191 vector<LegData> legData;
192 CMSSpreadLegData cmsLegData(index1, index2, fixingdays, isinarrears, vector<double>(), vector<string>(), caps,
193 vector<string>(), vector<double>(), vector<string>(), vector<double>(),
194 vector<string>(), false);
195
196 LegData leg(QuantLib::ext::make_shared<CMSSpreadLegData>(cmsLegData), isPayer, ccy, cmsSchedule, fixDC, notionals);
197 legData.push_back(leg);
198
199 Envelope env("CP1");
200 QuantLib::ext::shared_ptr<ore::data::Swap> swap(new ore::data::Swap(env, legData));
201 return swap;
202 }
203
204 CommonVars() : ccy("EUR"), isPayer(false), start("20160301"), end("20360301"), fixtenor("1Y"), cmstenor("6M") {
205
206 longShort = isPayer ? "Short" : "Long";
207 cal = TARGET();
208 calStr = "TARGET";
209 conv = "MF";
210 rule = "Forward";
211 fixDC = "ACT/360";
212 fixedRate = 0.0;
213 index1 = "EUR-CMS-30Y";
214 index2 = "EUR-CMS-2Y";
215 fixingdays = 2;
216 isinarrears = false;
217 notional = 10000000;
218 notionals.push_back(10000000);
219 }
220};
221
222void outputCoupons(QuantLib::ext::shared_ptr<ore::data::Swap> cmsSwap) {
223 Leg leg = cmsSwap->legs().at(0);
224 for (auto cf : leg) {
225 QuantLib::ext::shared_ptr<FloatingRateCoupon> frc = QuantLib::ext::dynamic_pointer_cast<FloatingRateCoupon>(cf);
226 if (frc) {
227 BOOST_TEST_MESSAGE("Coupon Date: " << frc->date() << "; Rate: " << frc->rate()
228 << "; DayCount: " << frc->dayCounter());
229 } else {
230 BOOST_TEST_MESSAGE("Coupon Date: " << cf->date() << " - not a floating rate coupon!");
231 }
232 }
233};
234} // namespace
235
236BOOST_FIXTURE_TEST_SUITE(OREDataTestSuite, ore::test::TopLevelFixture)
237
238BOOST_AUTO_TEST_SUITE(DigitalCmsTests)
239
240// TODO FIXME
241BOOST_AUTO_TEST_CASE(testDigitalCMSSpreadCoupon) {
242 BOOST_TEST_MESSAGE("Testing CMS Digital CMS Spread coupon...");
243
244 // build market
245 QuantLib::ext::shared_ptr<Market> market = QuantLib::ext::make_shared<TestMarket>();
246 Settings::instance().evaluationDate() = market->asofDate();
247 CommonVars vars;
248
249 // Build and price
250 QuantLib::ext::shared_ptr<EngineData> engineData = QuantLib::ext::make_shared<EngineData>();
251 engineData->model("CMS") = "LinearTSR";
252 engineData->engine("CMS") = "LinearTSRPricer";
253
254 map<string, string> engineparams1;
255 engineparams1["MeanReversion"] = "0.0";
256 engineparams1["Policy"] = "RateBound";
257 engineparams1["LowerRateBoundLogNormal"] = "0.0001";
258 engineparams1["UpperRateBoundLogNormal"] = "2";
259 engineparams1["LowerRateBoundNormal"] = "-2";
260 engineparams1["UpperRateBoundNormal"] = "2";
261 engineparams1["VegaRatio"] = "0.01";
262 engineparams1["PriceThreshold"] = "0.0000001";
263 engineparams1["BsStdDev"] = "3";
264 engineData->engineParameters("CMS") = engineparams1;
265
266 engineData->model("CMSSpread") = "BrigoMercurio";
267 engineData->engine("CMSSpread") = "Analytic";
268 map<string, string> engineparams2;
269 engineparams2["IntegrationPoints"] = "16";
270 engineData->engineParameters("CMSSpread") = engineparams2;
271 engineData->model("Swap") = "DiscountedCashflows";
272 engineData->engine("Swap") = "DiscountingSwapEngineOptimised";
273
274 QuantLib::ext::shared_ptr<EngineFactory> engineFactory = QuantLib::ext::make_shared<EngineFactory>(engineData, market);
275
276 // test edge cases
277 // If strike >> rate then NPV(digital call option) == NPV(option with spread = 0)
278 // and NPV(digital put option == NPV(option with spread = payoff)
279
280 {
281 double strike = 1.0;
282 double pay = 0.0001;
283 QuantLib::ext::shared_ptr<ore::data::Swap> cmsDigitalSwapCall =
284 vars.makeDigitalCmsSpreadOption(true, vector<double>(1, strike), vector<double>(1, pay));
285 QuantLib::ext::shared_ptr<ore::data::Swap> cmsDigitalSwapPut =
286 vars.makeDigitalCmsSpreadOption(false, vector<double>(1, strike), vector<double>(1, pay));
287 QuantLib::ext::shared_ptr<ore::data::Swap> cmsSwap1 = vars.makeCmsSpreadOption(vector<double>(1, pay));
288 QuantLib::ext::shared_ptr<ore::data::Swap> cmsSwap2 = vars.makeCmsSpreadOption(vector<double>(1, 0.0));
289 cmsDigitalSwapCall->build(engineFactory);
290 cmsDigitalSwapPut->build(engineFactory);
291 cmsSwap1->build(engineFactory);
292 cmsSwap2->build(engineFactory);
293
294 BOOST_TEST_MESSAGE("digital call coupons");
295 outputCoupons(cmsDigitalSwapCall);
296 BOOST_TEST_MESSAGE("digital put coupons");
297 outputCoupons(cmsDigitalSwapPut);
298 BOOST_TEST_MESSAGE("coupon 1");
299 outputCoupons(cmsSwap1);
300 BOOST_TEST_MESSAGE("coupon 2");
301 outputCoupons(cmsSwap2);
302
303 BOOST_TEST_MESSAGE("NPV Call = " << cmsDigitalSwapCall->instrument()->NPV());
304 BOOST_TEST_MESSAGE("NPV Put = " << cmsDigitalSwapPut->instrument()->NPV());
305 BOOST_TEST_MESSAGE("NPV1 = " << cmsSwap1->instrument()->NPV());
306 BOOST_TEST_MESSAGE("NPV2 = " << cmsSwap2->instrument()->NPV());
307
308 BOOST_CHECK_CLOSE(cmsDigitalSwapCall->instrument()->NPV(), cmsSwap2->instrument()->NPV(), 0.1);
309 BOOST_CHECK_CLOSE(cmsDigitalSwapPut->instrument()->NPV(), cmsSwap1->instrument()->NPV(), 0.1);
310 }
311
312 // check put cash-or-nothing payoffs
313 {
314 double strike = 0.0001;
315 double pay = 0.0001;
316 double eps = 1e-4;
317 QuantLib::ext::shared_ptr<ore::data::Swap> cmsDigitalSwapPut =
318 vars.makeDigitalCmsSpreadOption(false, vector<double>(1, strike), vector<double>(1, pay));
319 QuantLib::ext::shared_ptr<ore::data::Swap> cmsSwap1 = vars.makeCmsSpreadFloor(vector<double>(1, strike + eps / 2));
320 QuantLib::ext::shared_ptr<ore::data::Swap> cmsSwap2 = vars.makeCmsSpreadFloor(vector<double>(1, strike - eps / 2));
321 cmsDigitalSwapPut->build(engineFactory);
322 cmsSwap1->build(engineFactory);
323 cmsSwap2->build(engineFactory);
324
325 Leg leg = cmsDigitalSwapPut->legs().at(0);
326 Leg leg1 = cmsSwap1->legs().at(0);
327 Leg leg2 = cmsSwap2->legs().at(0);
328
329 for (Size i = 0; i < leg.size(); i++) {
330 QuantLib::ext::shared_ptr<DigitalCoupon> dc = QuantLib::ext::dynamic_pointer_cast<DigitalCoupon>(leg[i]);
331 QuantLib::ext::shared_ptr<FloatingRateCoupon> frc1 = QuantLib::ext::dynamic_pointer_cast<FloatingRateCoupon>(leg1[i]);
332 QuantLib::ext::shared_ptr<FloatingRateCoupon> frc2 = QuantLib::ext::dynamic_pointer_cast<FloatingRateCoupon>(leg2[i]);
333
334 double r = pay * (frc1->rate() - frc2->rate()) / eps;
335
336 BOOST_CHECK_CLOSE(r, dc->putOptionRate(), 0.1);
337 }
338 }
339
340 // check call cash-or-nothing payoffs
341 {
342 double strike = 0.0001;
343 double pay = 0.0001;
344 double eps = 1e-4;
345 QuantLib::ext::shared_ptr<ore::data::Swap> cmsDigitalSwapCall =
346 vars.makeDigitalCmsSpreadOption(true, vector<double>(1, strike), vector<double>(1, pay));
347 QuantLib::ext::shared_ptr<ore::data::Swap> cmsSwap1 = vars.makeCmsSpreadCap(vector<double>(1, strike + eps / 2));
348 QuantLib::ext::shared_ptr<ore::data::Swap> cmsSwap2 = vars.makeCmsSpreadCap(vector<double>(1, strike - eps / 2));
349 cmsDigitalSwapCall->build(engineFactory);
350 cmsSwap1->build(engineFactory);
351 cmsSwap2->build(engineFactory);
352
353 Leg leg = cmsDigitalSwapCall->legs().at(0);
354 Leg leg1 = cmsSwap1->legs().at(0);
355 Leg leg2 = cmsSwap2->legs().at(0);
356
357 for (Size i = 0; i < leg.size(); i++) {
358 QuantLib::ext::shared_ptr<DigitalCoupon> dc = QuantLib::ext::dynamic_pointer_cast<DigitalCoupon>(leg[i]);
359 QuantLib::ext::shared_ptr<FloatingRateCoupon> frc1 = QuantLib::ext::dynamic_pointer_cast<FloatingRateCoupon>(leg1[i]);
360 QuantLib::ext::shared_ptr<FloatingRateCoupon> frc2 = QuantLib::ext::dynamic_pointer_cast<FloatingRateCoupon>(leg2[i]);
361
362 double r = pay * (frc1->rate() - frc2->rate()) / eps;
363
364 BOOST_CHECK_CLOSE(r, dc->callOptionRate(), 0.1);
365 }
366 }
367 // check put asset-or-nothing payoffs
368 {
369 double strike = 0.0001;
370 double eps = 1e-4;
371 QuantLib::ext::shared_ptr<ore::data::Swap> cmsDigitalSwapPut =
372 vars.makeDigitalCmsSpreadOption(false, vector<double>(1, strike), vector<double>());
373 QuantLib::ext::shared_ptr<ore::data::Swap> cmsSwap1 = vars.makeCmsSpreadFloor(vector<double>(1, strike + eps / 2));
374 QuantLib::ext::shared_ptr<ore::data::Swap> cmsSwap2 = vars.makeCmsSpreadFloor(vector<double>(1, strike - eps / 2));
375 QuantLib::ext::shared_ptr<ore::data::Swap> cmsSwap3 = vars.makeCmsSpreadFloor(vector<double>(1, strike));
376 QuantLib::ext::shared_ptr<ore::data::Swap> cmsSwap4 = vars.makeCmsSpreadFloor(vector<double>());
377 cmsDigitalSwapPut->build(engineFactory);
378 cmsSwap1->build(engineFactory);
379 cmsSwap2->build(engineFactory);
380 cmsSwap3->build(engineFactory);
381 cmsSwap4->build(engineFactory);
382
383 Leg leg = cmsDigitalSwapPut->legs().at(0);
384 Leg leg1 = cmsSwap1->legs().at(0);
385 Leg leg2 = cmsSwap2->legs().at(0);
386 Leg leg3 = cmsSwap3->legs().at(0);
387 Leg leg4 = cmsSwap4->legs().at(0);
388
389 for (Size i = 0; i < leg.size(); i++) {
390 QuantLib::ext::shared_ptr<DigitalCoupon> dc = QuantLib::ext::dynamic_pointer_cast<DigitalCoupon>(leg[i]);
391 QuantLib::ext::shared_ptr<FloatingRateCoupon> frc1 = QuantLib::ext::dynamic_pointer_cast<FloatingRateCoupon>(leg1[i]);
392 QuantLib::ext::shared_ptr<FloatingRateCoupon> frc2 = QuantLib::ext::dynamic_pointer_cast<FloatingRateCoupon>(leg2[i]);
393 QuantLib::ext::shared_ptr<FloatingRateCoupon> frc3 = QuantLib::ext::dynamic_pointer_cast<FloatingRateCoupon>(leg3[i]);
394 QuantLib::ext::shared_ptr<FloatingRateCoupon> frc4 = QuantLib::ext::dynamic_pointer_cast<FloatingRateCoupon>(leg4[i]);
395
396 double r = strike * (frc1->rate() - frc2->rate()) / eps;
397 double put = -frc4->rate() + frc3->rate();
398 BOOST_TEST_MESSAGE(frc4->rate() << " " << frc3->rate() << " " << r << " " << put);
399
400 BOOST_CHECK_CLOSE(r - put, dc->putOptionRate(), 0.1);
401 }
402 }
403
404 // check call asset-or-nothing payoffs
405 {
406 double strike = 0.0001;
407 double eps = 1e-4;
408 QuantLib::ext::shared_ptr<ore::data::Swap> cmsDigitalSwapCall =
409 vars.makeDigitalCmsSpreadOption(true, vector<double>(1, strike), vector<double>());
410 QuantLib::ext::shared_ptr<ore::data::Swap> cmsSwap1 = vars.makeCmsSpreadCap(vector<double>(1, strike + eps / 2));
411 QuantLib::ext::shared_ptr<ore::data::Swap> cmsSwap2 = vars.makeCmsSpreadCap(vector<double>(1, strike - eps / 2));
412 QuantLib::ext::shared_ptr<ore::data::Swap> cmsSwap3 = vars.makeCmsSpreadCap(vector<double>(1, strike));
413 QuantLib::ext::shared_ptr<ore::data::Swap> cmsSwap4 = vars.makeCmsSpreadCap(vector<double>());
414 cmsDigitalSwapCall->build(engineFactory);
415 cmsSwap1->build(engineFactory);
416 cmsSwap2->build(engineFactory);
417 cmsSwap3->build(engineFactory);
418 cmsSwap4->build(engineFactory);
419
420 Leg leg = cmsDigitalSwapCall->legs().at(0);
421 Leg leg1 = cmsSwap1->legs().at(0);
422 Leg leg2 = cmsSwap2->legs().at(0);
423 Leg leg3 = cmsSwap3->legs().at(0);
424 Leg leg4 = cmsSwap4->legs().at(0);
425
426 for (Size i = 0; i < leg.size(); i++) {
427 QuantLib::ext::shared_ptr<DigitalCoupon> dc = QuantLib::ext::dynamic_pointer_cast<DigitalCoupon>(leg[i]);
428 QuantLib::ext::shared_ptr<FloatingRateCoupon> frc1 = QuantLib::ext::dynamic_pointer_cast<FloatingRateCoupon>(leg1[i]);
429 QuantLib::ext::shared_ptr<FloatingRateCoupon> frc2 = QuantLib::ext::dynamic_pointer_cast<FloatingRateCoupon>(leg2[i]);
430 QuantLib::ext::shared_ptr<FloatingRateCoupon> frc3 = QuantLib::ext::dynamic_pointer_cast<FloatingRateCoupon>(leg3[i]);
431 QuantLib::ext::shared_ptr<FloatingRateCoupon> frc4 = QuantLib::ext::dynamic_pointer_cast<FloatingRateCoupon>(leg4[i]);
432
433 double r = strike * (frc1->rate() - frc2->rate()) / eps;
434 double call = frc4->rate() - frc3->rate();
435
436 BOOST_CHECK_CLOSE(r + call, dc->callOptionRate(), 0.1);
437 }
438 }
439}
440
441BOOST_AUTO_TEST_SUITE_END()
442
443BOOST_AUTO_TEST_SUITE_END()
Ibor cap, floor or collar trade data model and serialization.
Serializable CMS Spread Leg Data.
Definition: legdata.hpp:548
Serializable object holding generic trade data, reporting dimensions.
Definition: envelope.hpp:51
Container for storing Interest Rate Swap conventions.
Serializable object holding leg data.
Definition: legdata.hpp:844
static const string defaultConfiguration
Default configuration label.
Definition: market.hpp:296
Market Implementation.
Definition: marketimpl.hpp:53
map< tuple< string, string, string >, Handle< QuantExt::CorrelationTermStructure > > correlationCurves_
Definition: marketimpl.hpp:229
map< tuple< string, YieldCurveType, string >, Handle< YieldTermStructure > > yieldCurves_
Definition: marketimpl.hpp:208
map< pair< string, string >, Handle< IborIndex > > iborIndices_
Definition: marketimpl.hpp:209
map< pair< string, string >, Handle< QuantLib::SwaptionVolatilityStructure > > swaptionCurves_
Definition: marketimpl.hpp:211
void addSwapIndex(const string &swapindex, const string &discountIndex, const string &configuration=Market::defaultConfiguration) const
add a swap index to the market
Definition: marketimpl.cpp:473
Serializable schedule data.
Definition: schedule.hpp:202
Serializable object holding schedule Rules data.
Definition: schedule.hpp:37
Serializable Swap, Single and Cross Currency.
Definition: swap.hpp:36
Container for storing Swap Index conventions.
builder that returns an engine to price capped floored ibor legs
BOOST_AUTO_TEST_CASE(testDigitalCMSSpreadCoupon)
Definition: digitalcms.cpp:241
A class to hold pricing engine parameters.
trade envelope data model and serialization
QuantLib::ext::shared_ptr< IborIndex > parseIborIndex(const string &s, const Handle< YieldTermStructure > &h)
Convert std::string to QuantLib::IborIndex.
Map text representations to QuantLib/QuantExt types.
leg data model and serialization
An implementation of the Market class that stores the required objects in maps.
trade schedule data model and serialization
Swap trade data model and serialization.