1 /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3 /*
4 Copyright (C) 2008 Jose Aparicio
5 Copyright (C) 2014 Peter Caspers
6
7 This file is part of QuantLib, a free-software/open-source library
8 for financial quantitative analysts and developers - http://quantlib.org/
9
10 QuantLib is free software: you can redistribute it and/or modify it
11 under the terms of the QuantLib license. You should have received a
12 copy of the license along with this program; if not, please email
13 <quantlib-dev@lists.sf.net>. The license is also available online at
14 <http://quantlib.org/license.shtml>.
15
16 This program is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 FOR A PARTICULAR PURPOSE. See the license for more details.
19 */
20
21 #include <ql/qldefines.hpp>
22 #if !defined(BOOST_ALL_NO_LIB) && defined(BOOST_MSVC)
23 # include <ql/auto_link.hpp>
24 #endif
25 #include <ql/cashflows/fixedratecoupon.hpp>
26 #include <ql/cashflows/iborcoupon.hpp>
27 #include <ql/instruments/creditdefaultswap.hpp>
28 #include <ql/indexes/ibor/euribor.hpp>
29 #include <ql/pricingengines/credit/midpointcdsengine.hpp>
30 #include <ql/pricingengines/credit/isdacdsengine.hpp>
31 #include <ql/termstructures/credit/piecewisedefaultcurve.hpp>
32 #include <ql/termstructures/credit/defaultprobabilityhelpers.hpp>
33 #include <ql/termstructures/credit/flathazardrate.hpp>
34 #include <ql/termstructures/yield/flatforward.hpp>
35 #include <ql/termstructures/yield/piecewiseyieldcurve.hpp>
36 #include <ql/termstructures/yield/ratehelpers.hpp>
37 #include <ql/math/interpolations/backwardflatinterpolation.hpp>
38 #include <ql/time/calendars/target.hpp>
39 #include <ql/time/calendars/weekendsonly.hpp>
40 #include <ql/time/daycounters/thirty360.hpp>
41 #include <ql/time/daycounters/actual365fixed.hpp>
42 #include <ql/time/daycounters/actual360.hpp>
43 #include <ql/currencies/europe.hpp>
44 #include <ql/quotes/simplequote.hpp>
45
46 #include <iostream>
47 #include <iomanip>
48
49 using namespace std;
50 using namespace QuantLib;
51
52 void example01() {
53
54 std::cout << std::endl;
55
56 /*********************
57 *** MARKET DATA ***
58 *********************/
59
60 Calendar calendar = TARGET();
61 Date todaysDate(15, May, 2007);
62 // must be a business day
63 todaysDate = calendar.adjust(todaysDate);
64
65 Settings::instance().evaluationDate() = todaysDate;
66
67 // dummy curve
68 auto flatRate = ext::make_shared<SimpleQuote>(0.01);
69 Handle<YieldTermStructure> tsCurve(
70 ext::make_shared<FlatForward>(
71 todaysDate, Handle<Quote>(flatRate), Actual365Fixed()));
72
73 /*
74 In Lehmans Brothers "guide to exotic credit derivatives"
75 p. 32 there's a simple case, zero flat curve with a flat CDS
76 curve with constant market spreads of 150 bp and RR = 50%
77 corresponds to a flat 3% hazard rate. The implied 1-year
78 survival probability is 97.04% and the 2-years is 94.18%
79 */
80
81 // market
82 Natural settlementDays = 1;
83 Real recovery_rate = 0.5;
84 Real quoted_spreads[] = { 0.0150, 0.0150, 0.0150, 0.0150 };
85 vector<Period> tenors;
86 tenors.push_back(3 * Months);
87 tenors.push_back(6 * Months);
88 tenors.push_back(1 * Years);
89 tenors.push_back(2 * Years);
90
91 Date settlementDate = calendar.advance(todaysDate, settlementDays, Days);
92 vector<Date> maturities;
93 for (Size i = 0; i < 4; i++) {
94 maturities.push_back(
95 calendar.adjust(settlementDate + tenors[i], Following));
96 }
97
98 std::vector<ext::shared_ptr<DefaultProbabilityHelper>> instruments;
99 for (Size i = 0; i < 4; i++) {
100 instruments.push_back(ext::make_shared<SpreadCdsHelper>(
101 Handle<Quote>(ext::make_shared<SimpleQuote>(quoted_spreads[i])),
102 tenors[i], settlementDays, calendar, Quarterly, Following,
103 DateGeneration::TwentiethIMM, Actual365Fixed(),
104 recovery_rate, tsCurve));
105 }
106
107 // Bootstrap hazard rates
108 auto hazardRateStructure = ext::make_shared<PiecewiseDefaultCurve<HazardRate, BackwardFlat>>(
109 todaysDate, instruments, Actual365Fixed());
110 vector<pair<Date, Real>> hr_curve_data = hazardRateStructure->nodes();
111
112 cout << "Calibrated hazard rate values: " << endl;
113 for (auto& i : hr_curve_data) {
114 cout << "hazard rate on " << i.first << " is " << i.second << endl;
115 }
116 cout << endl;
117
118 cout << "Some survival probability values: " << endl;
119 cout << "1Y survival probability: "
120 << io::percent(hazardRateStructure->survivalProbability(todaysDate +
121 1 * Years))
122 << endl << " expected: " << io::percent(0.9704) << endl;
123 cout << "2Y survival probability: "
124 << io::percent(hazardRateStructure->survivalProbability(todaysDate +
125 2 * Years))
126 << endl << " expected: " << io::percent(0.9418) << endl;
127
128 cout << endl << endl;
129
130 // reprice instruments
131 Real nominal = 1000000.0;
132 Handle<DefaultProbabilityTermStructure> probability(hazardRateStructure);
133 auto engine = ext::make_shared<MidPointCdsEngine>(probability, recovery_rate, tsCurve);
134
135 Schedule cdsSchedule = MakeSchedule()
136 .from(settlementDate)
137 .to(maturities[0])
138 .withFrequency(Quarterly)
139 .withCalendar(calendar)
140 .withTerminationDateConvention(Unadjusted)
141 .withRule(DateGeneration::TwentiethIMM);
142 CreditDefaultSwap cds_3m(Protection::Seller, nominal, quoted_spreads[0],
143 cdsSchedule, Following, Actual365Fixed());
144
145 cdsSchedule = MakeSchedule()
146 .from(settlementDate)
147 .to(maturities[1])
148 .withFrequency(Quarterly)
149 .withCalendar(calendar)
150 .withTerminationDateConvention(Unadjusted)
151 .withRule(DateGeneration::TwentiethIMM);
152 CreditDefaultSwap cds_6m(Protection::Seller, nominal, quoted_spreads[1],
153 cdsSchedule, Following, Actual365Fixed());
154
155 cdsSchedule = MakeSchedule()
156 .from(settlementDate)
157 .to(maturities[2])
158 .withFrequency(Quarterly)
159 .withCalendar(calendar)
160 .withTerminationDateConvention(Unadjusted)
161 .withRule(DateGeneration::TwentiethIMM);
162 CreditDefaultSwap cds_1y(Protection::Seller, nominal, quoted_spreads[2],
163 cdsSchedule, Following, Actual365Fixed());
164
165 cdsSchedule = MakeSchedule()
166 .from(settlementDate)
167 .to(maturities[3])
168 .withFrequency(Quarterly)
169 .withCalendar(calendar)
170 .withTerminationDateConvention(Unadjusted)
171 .withRule(DateGeneration::TwentiethIMM);
172 CreditDefaultSwap cds_2y(Protection::Seller, nominal, quoted_spreads[3],
173 cdsSchedule, Following, Actual365Fixed());
174
175 cds_3m.setPricingEngine(engine);
176 cds_6m.setPricingEngine(engine);
177 cds_1y.setPricingEngine(engine);
178 cds_2y.setPricingEngine(engine);
179
180 cout << "Repricing of quoted CDSs employed for calibration: " << endl;
181 cout << "3M fair spread: " << io::rate(cds_3m.fairSpread()) << endl
182 << " NPV: " << cds_3m.NPV() << endl
183 << " default leg: " << cds_3m.defaultLegNPV() << endl
184 << " coupon leg: " << cds_3m.couponLegNPV() << endl << endl;
185
186 cout << "6M fair spread: " << io::rate(cds_6m.fairSpread()) << endl
187 << " NPV: " << cds_6m.NPV() << endl
188 << " default leg: " << cds_6m.defaultLegNPV() << endl
189 << " coupon leg: " << cds_6m.couponLegNPV() << endl << endl;
190
191 cout << "1Y fair spread: " << io::rate(cds_1y.fairSpread()) << endl
192 << " NPV: " << cds_1y.NPV() << endl
193 << " default leg: " << cds_1y.defaultLegNPV() << endl
194 << " coupon leg: " << cds_1y.couponLegNPV() << endl << endl;
195
196 cout << "2Y fair spread: " << io::rate(cds_2y.fairSpread()) << endl
197 << " NPV: " << cds_2y.NPV() << endl
198 << " default leg: " << cds_2y.defaultLegNPV() << endl
199 << " coupon leg: " << cds_2y.couponLegNPV() << endl << endl;
200
201 cout << endl << endl;
202
203 }
204
205 void example02() {
206
207 Date todaysDate(25, September, 2014);
208 Settings::instance().evaluationDate() = todaysDate;
209
210 Date termDate = TARGET().adjust(todaysDate+Period(2*Years), Following);
211
212 Schedule cdsSchedule =
213 MakeSchedule().from(todaysDate).to(termDate)
214 .withFrequency(Quarterly)
215 .withCalendar(WeekendsOnly())
216 .withConvention(ModifiedFollowing)
217 .withTerminationDateConvention(ModifiedFollowing)
218 .withRule(DateGeneration::CDS);
219
220 std::copy(cdsSchedule.begin(), cdsSchedule.end(),
221 std::ostream_iterator<Date>(cout, "\n"));
222
223 Date evaluationDate = Date(21, October, 2014);
224
225 Settings::instance().evaluationDate() = evaluationDate;
226
227 IborCoupon::Settings::instance().createAtParCoupons();
228
229 // set up ISDA IR curve helpers
230
231 auto dp1m = ext::make_shared<DepositRateHelper>(0.000060, 1 * Months, 2,
232 TARGET(), ModifiedFollowing,
233 false, Actual360());
234 auto dp2m = ext::make_shared<DepositRateHelper>(0.000450, 2 * Months, 2,
235 TARGET(), ModifiedFollowing,
236 false, Actual360());
237 auto dp3m = ext::make_shared<DepositRateHelper>(0.000810, 3 * Months, 2,
238 TARGET(), ModifiedFollowing,
239 false, Actual360());
240 auto dp6m = ext::make_shared<DepositRateHelper>(0.001840, 6 * Months, 2,
241 TARGET(), ModifiedFollowing,
242 false, Actual360());
243 auto dp9m = ext::make_shared<DepositRateHelper>(0.002560, 9 * Months, 2,
244 TARGET(), ModifiedFollowing,
245 false, Actual360());
246 auto dp12m = ext::make_shared<DepositRateHelper>(0.003370, 12 * Months, 2,
247 TARGET(), ModifiedFollowing,
248 false, Actual360());
249
250 // intentionally we do not provide a fixing for the euribor index used for
251 // bootstrapping in order to be compliant with the ISDA specification
252
253 auto euribor6m = ext::make_shared<Euribor>(Euribor(6 * Months));
254
255 DayCounter thirty360 = Thirty360(Thirty360::BondBasis);
256
257 auto sw2y = ext::make_shared<SwapRateHelper>(
258 0.002230, 2 * Years, TARGET(), Annual, ModifiedFollowing, thirty360,
259 euribor6m);
260 auto sw3y = ext::make_shared<SwapRateHelper>(
261 0.002760, 3 * Years, TARGET(), Annual, ModifiedFollowing, thirty360,
262 euribor6m);
263 auto sw4y = ext::make_shared<SwapRateHelper>(
264 0.003530, 4 * Years, TARGET(), Annual, ModifiedFollowing, thirty360,
265 euribor6m);
266 auto sw5y = ext::make_shared<SwapRateHelper>(
267 0.004520, 5 * Years, TARGET(), Annual, ModifiedFollowing, thirty360,
268 euribor6m);
269 auto sw6y = ext::make_shared<SwapRateHelper>(
270 0.005720, 6 * Years, TARGET(), Annual, ModifiedFollowing, thirty360,
271 euribor6m);
272 auto sw7y = ext::make_shared<SwapRateHelper>(
273 0.007050, 7 * Years, TARGET(), Annual, ModifiedFollowing, thirty360,
274 euribor6m);
275 auto sw8y = ext::make_shared<SwapRateHelper>(
276 0.008420, 8 * Years, TARGET(), Annual, ModifiedFollowing, thirty360,
277 euribor6m);
278 auto sw9y = ext::make_shared<SwapRateHelper>(
279 0.009720, 9 * Years, TARGET(), Annual, ModifiedFollowing, thirty360,
280 euribor6m);
281 auto sw10y = ext::make_shared<SwapRateHelper>(
282 0.010900, 10 * Years, TARGET(), Annual, ModifiedFollowing, thirty360,
283 euribor6m);
284 auto sw12y = ext::make_shared<SwapRateHelper>(
285 0.012870, 12 * Years, TARGET(), Annual, ModifiedFollowing, thirty360,
286 euribor6m);
287 auto sw15y = ext::make_shared<SwapRateHelper>(
288 0.014970, 15 * Years, TARGET(), Annual, ModifiedFollowing, thirty360,
289 euribor6m);
290 auto sw20y = ext::make_shared<SwapRateHelper>(
291 0.017000, 20 * Years, TARGET(), Annual, ModifiedFollowing, thirty360,
292 euribor6m);
293 auto sw30y = ext::make_shared<SwapRateHelper>(
294 0.018210, 30 * Years, TARGET(), Annual, ModifiedFollowing, thirty360,
295 euribor6m);
296
297 std::vector<ext::shared_ptr<RateHelper>> isdaRateHelper;
298
299 isdaRateHelper.push_back(dp1m);
300 isdaRateHelper.push_back(dp2m);
301 isdaRateHelper.push_back(dp3m);
302 isdaRateHelper.push_back(dp6m);
303 isdaRateHelper.push_back(dp9m);
304 isdaRateHelper.push_back(dp12m);
305 isdaRateHelper.push_back(sw2y);
306 isdaRateHelper.push_back(sw3y);
307 isdaRateHelper.push_back(sw4y);
308 isdaRateHelper.push_back(sw5y);
309 isdaRateHelper.push_back(sw6y);
310 isdaRateHelper.push_back(sw7y);
311 isdaRateHelper.push_back(sw8y);
312 isdaRateHelper.push_back(sw9y);
313 isdaRateHelper.push_back(sw10y);
314 isdaRateHelper.push_back(sw12y);
315 isdaRateHelper.push_back(sw15y);
316 isdaRateHelper.push_back(sw20y);
317 isdaRateHelper.push_back(sw30y);
318
319 Handle<YieldTermStructure> rateTs(
320 ext::make_shared<PiecewiseYieldCurve<Discount, LogLinear>>(
321 0, WeekendsOnly(), isdaRateHelper, Actual365Fixed()));
322 rateTs->enableExtrapolation();
323
324 // output rate curve
325 std::cout << "ISDA rate curve: " << std::endl;
326 for (auto& i : isdaRateHelper) {
327 Date d = i->latestDate();
328 std::cout << d << "\t" << setprecision(6) <<
329 rateTs->zeroRate(d,Actual365Fixed(),Continuous).rate() << "\t" <<
330 rateTs->discount(d) << std::endl;
331 }
332
333 // build reference credit curve (flat)
334 auto defaultTs0 = ext::make_shared<FlatHazardRate>(0, WeekendsOnly(), 0.016739207493630, Actual365Fixed());
335
336 // reference CDS
337 Schedule sched( Date(22,September,2014), Date(20,December,2019), 3*Months,
338 WeekendsOnly(), Following, Unadjusted, DateGeneration::CDS, false, Date(), Date() );
339 auto trade = ext::make_shared<CreditDefaultSwap>(
340 Protection::Buyer, 100000000.0, 0.01, sched,
341 Following, Actual360(), true, true,
342 Date(22,October,2014), ext::shared_ptr<Claim>(),
343 Actual360(true), true);
344
345 auto cp = ext::dynamic_pointer_cast<FixedRateCoupon>(trade->coupons()[0]);
346 std::cout << "first period = " << cp->accrualStartDate() << " to " << cp->accrualEndDate() <<
347 " accrued amount = " << cp->accruedAmount(Date(24,October,2014)) << std::endl;
348
349 // price with isda engine
350 auto engine = ext::make_shared<IsdaCdsEngine>(
351 Handle<DefaultProbabilityTermStructure>(defaultTs0), 0.4, rateTs,
352 false, IsdaCdsEngine::Taylor, IsdaCdsEngine::NoBias, IsdaCdsEngine::Piecewise);
353
354 trade->setPricingEngine(engine);
355
356 std::cout << "reference trade NPV = " << trade->NPV() << std::endl;
357
358
359 // build credit curve with one cds
360 std::vector<ext::shared_ptr<DefaultProbabilityHelper>> isdaCdsHelper;
361
362 auto cds5y = ext::make_shared<SpreadCdsHelper>(
363 0.00672658551, 4 * Years + 6 * Months, 1, WeekendsOnly(), Quarterly,
364 Following, DateGeneration::CDS, Actual360(), 0.4, rateTs, true, true,
365 Date(), Actual360(true), true, CreditDefaultSwap::ISDA);
366
367 isdaCdsHelper.push_back(cds5y);
368
369 Handle<DefaultProbabilityTermStructure> defaultTs(ext::make_shared<
370 PiecewiseDefaultCurve<SurvivalProbability, LogLinear>>(
371 0, WeekendsOnly(), isdaCdsHelper, Actual365Fixed()));
372
373 std::cout << "ISDA credit curve: " << std::endl;
374 for (auto& i : isdaCdsHelper) {
375 Date d = i->latestDate();
376 Real pd = defaultTs->defaultProbability(d);
377 Real t = defaultTs->timeFromReference(d);
378 std::cout << d << ";" << pd << ";" << 1.0 - pd << ";" <<
379 -std::log(1.0-pd)/t << std::endl;
380 }
381
382
383 // // set up sample CDS trade
384
385 // auto trade =
386 // MakeCreditDefaultSwap(5 * Years, 0.03);
387
388 // // set up isda engine
389
390 // // auto isdaPricer =
391 // // ext::make_shared<IsdaCdsEngine>(
392 // // isdaCdsHelper, 0.4, isdaRateHelper);
393 // auto isdaPricer =
394 // ext::make_shared<IsdaCdsEngine>(defaultTs,0.40,rateTs);
395
396 // // check the curves built by the engine
397
398 // Handle<YieldTermStructure> isdaYts = isdaPricer->isdaRateCurve();
399 // Handle<DefaultProbabilityTermStructure> isdaCts = isdaPricer->isdaCreditCurve();
400
401 // std::cout << "isda rate 1m " << dp1m->latestDate() << " "
402 // << isdaYts->zeroRate(dp1m->latestDate(), Actual365Fixed(),
403 // Continuous) << std::endl;
404 // std::cout << "isda rate 3m " << dp3m->latestDate() << " "
405 // << isdaYts->zeroRate(dp3m->latestDate(), Actual365Fixed(),
406 // Continuous) << std::endl;
407 // std::cout << "isda rate 6m " << dp6m->latestDate() << " "
408 // << isdaYts->zeroRate(dp6m->latestDate(), Actual365Fixed(),
409 // Continuous) << std::endl;
410
411 // std::cout << "isda hazard 5y " << cds5y->latestDate() << " "
412 // << isdaCts->hazardRate(cds5y->latestDate()) << std::endl;
413
414 // // price the trade
415
416 // trade->setPricingEngine(isdaPricer);
417
418 // Real npv = trade->NPV();
419
420 // std::cout << "Pricing of example trade with ISDA engine:" << std::endl;
421 // std::cout << "NPV = " << npv << std::endl;
422
423 }
424
425 void example03() {
426
427 // this is the example from Apdx E in pricing and risk management of CDS, OpenGamma
428
429 Date tradeDate(13,June,2011);
430
431 Settings::instance().evaluationDate() = tradeDate;
432
433 IborCoupon::Settings::instance().createAtParCoupons();
434
435 DayCounter actual360 = Actual360();
436 DayCounter thirty360 = Thirty360(Thirty360::BondBasis);
437
438 auto dp1m = ext::make_shared<DepositRateHelper>(0.00445, 1 * Months, 2,
439 WeekendsOnly(), ModifiedFollowing,
440 false, actual360);
441 auto dp2m = ext::make_shared<DepositRateHelper>(0.00949, 2 * Months, 2,
442 WeekendsOnly(), ModifiedFollowing,
443 false, actual360);
444 auto dp3m = ext::make_shared<DepositRateHelper>(0.01234, 3 * Months, 2,
445 WeekendsOnly(), ModifiedFollowing,
446 false, actual360);
447 auto dp6m = ext::make_shared<DepositRateHelper>(0.01776, 6 * Months, 2,
448 WeekendsOnly(), ModifiedFollowing,
449 false, actual360);
450 auto dp9m = ext::make_shared<DepositRateHelper>(0.01935, 9 * Months, 2,
451 WeekendsOnly(), ModifiedFollowing,
452 false, actual360);
453 auto dp1y = ext::make_shared<DepositRateHelper>(0.02084, 12 * Months, 2,
454 WeekendsOnly(), ModifiedFollowing,
455 false, actual360);
456
457 // this index is probably not important since we are not using
458 // IborCoupon::Settings::instance().usingAtParCoupons() == false
459 // - define it "isda compliant" anyway
460 auto euribor6m = ext::make_shared<IborIndex>(
461 "IsdaIbor", 6 * Months, 2, EURCurrency(), WeekendsOnly(),
462 ModifiedFollowing, false, actual360);
463
464 auto sw2y = ext::make_shared<SwapRateHelper>(
465 0.01652, 2 * Years, WeekendsOnly(), Annual, ModifiedFollowing, thirty360,
466 euribor6m);
467 auto sw3y = ext::make_shared<SwapRateHelper>(
468 0.02018, 3 * Years, WeekendsOnly(), Annual, ModifiedFollowing, thirty360,
469 euribor6m);
470 auto sw4y = ext::make_shared<SwapRateHelper>(
471 0.02303, 4 * Years, WeekendsOnly(), Annual, ModifiedFollowing, thirty360,
472 euribor6m);
473 auto sw5y = ext::make_shared<SwapRateHelper>(
474 0.02525, 5 * Years, WeekendsOnly(), Annual, ModifiedFollowing, thirty360,
475 euribor6m);
476 auto sw6y = ext::make_shared<SwapRateHelper>(
477 0.02696, 6 * Years, WeekendsOnly(), Annual, ModifiedFollowing, thirty360,
478 euribor6m);
479 auto sw7y = ext::make_shared<SwapRateHelper>(
480 0.02825, 7 * Years, WeekendsOnly(), Annual, ModifiedFollowing, thirty360,
481 euribor6m);
482 auto sw8y = ext::make_shared<SwapRateHelper>(
483 0.02931, 8 * Years, WeekendsOnly(), Annual, ModifiedFollowing, thirty360,
484 euribor6m);
485 auto sw9y = ext::make_shared<SwapRateHelper>(
486 0.03017, 9 * Years, WeekendsOnly(), Annual, ModifiedFollowing, thirty360,
487 euribor6m);
488 auto sw10y = ext::make_shared<SwapRateHelper>(
489 0.03092, 10 * Years, WeekendsOnly(), Annual, ModifiedFollowing, thirty360,
490 euribor6m);
491 auto sw11y = ext::make_shared<SwapRateHelper>(
492 0.03160, 11 * Years, WeekendsOnly(), Annual, ModifiedFollowing, thirty360,
493 euribor6m);
494 auto sw12y = ext::make_shared<SwapRateHelper>(
495 0.03231, 12 * Years, WeekendsOnly(), Annual, ModifiedFollowing, thirty360,
496 euribor6m);
497 auto sw15y = ext::make_shared<SwapRateHelper>(
498 0.03367, 15 * Years, WeekendsOnly(), Annual, ModifiedFollowing, thirty360,
499 euribor6m);
500 auto sw20y = ext::make_shared<SwapRateHelper>(
501 0.03419, 20 * Years, WeekendsOnly(), Annual, ModifiedFollowing, thirty360,
502 euribor6m);
503 auto sw25y = ext::make_shared<SwapRateHelper>(
504 0.03411, 25 * Years, WeekendsOnly(), Annual, ModifiedFollowing, thirty360,
505 euribor6m);
506 auto sw30y = ext::make_shared<SwapRateHelper>(
507 0.03412, 30 * Years, WeekendsOnly(), Annual, ModifiedFollowing, thirty360,
508 euribor6m);
509
510 std::vector<ext::shared_ptr<RateHelper>> isdaYieldHelpers;
511
512 isdaYieldHelpers.push_back(dp1m);
513 isdaYieldHelpers.push_back(dp2m);
514 isdaYieldHelpers.push_back(dp3m);
515 isdaYieldHelpers.push_back(dp6m);
516 isdaYieldHelpers.push_back(dp9m);
517 isdaYieldHelpers.push_back(dp1y);
518 isdaYieldHelpers.push_back(sw2y);
519 isdaYieldHelpers.push_back(sw3y);
520 isdaYieldHelpers.push_back(sw4y);
521 isdaYieldHelpers.push_back(sw5y);
522 isdaYieldHelpers.push_back(sw6y);
523 isdaYieldHelpers.push_back(sw7y);
524 isdaYieldHelpers.push_back(sw8y);
525 isdaYieldHelpers.push_back(sw9y);
526 isdaYieldHelpers.push_back(sw10y);
527 isdaYieldHelpers.push_back(sw11y);
528 isdaYieldHelpers.push_back(sw12y);
529 isdaYieldHelpers.push_back(sw15y);
530 isdaYieldHelpers.push_back(sw20y);
531 isdaYieldHelpers.push_back(sw25y);
532 isdaYieldHelpers.push_back(sw30y);
533
534 // build yield curve
535 Handle<YieldTermStructure> isdaYts = Handle<YieldTermStructure>(
536 ext::make_shared<PiecewiseYieldCurve<Discount, LogLinear>>(
537 0, WeekendsOnly(), isdaYieldHelpers, Actual365Fixed()));
538 isdaYts->enableExtrapolation();
539
540
541 CreditDefaultSwap::PricingModel model = CreditDefaultSwap::ISDA;
542 auto cds6m = ext::make_shared<SpreadCdsHelper>(
543 0.007927, 6 * Months, 1, WeekendsOnly(), Quarterly, Following,
544 DateGeneration::CDS, Actual360(), 0.4, isdaYts, true, true, Date(),
545 Actual360(true), true, model);
546 auto cds1y = ext::make_shared<SpreadCdsHelper>(
547 0.007927, 1 * Years, 1, WeekendsOnly(), Quarterly, Following,
548 DateGeneration::CDS, Actual360(), 0.4, isdaYts, true, true, Date(),
549 Actual360(true), true, model);
550 auto cds3y = ext::make_shared<SpreadCdsHelper>(
551 0.012239, 3 * Years, 1, WeekendsOnly(), Quarterly, Following,
552 DateGeneration::CDS, Actual360(), 0.4, isdaYts, true, true, Date(),
553 Actual360(true), true, model);
554 auto cds5y = ext::make_shared<SpreadCdsHelper>(
555 0.016979, 5 * Years, 1, WeekendsOnly(), Quarterly, Following,
556 DateGeneration::CDS, Actual360(), 0.4, isdaYts, true, true, Date(),
557 Actual360(true), true, model);
558 auto cds7y = ext::make_shared<SpreadCdsHelper>(
559 0.019271, 7 * Years, 1, WeekendsOnly(), Quarterly, Following,
560 DateGeneration::CDS, Actual360(), 0.4, isdaYts, true, true, Date(),
561 Actual360(true), true, model);
562 auto cds10y = ext::make_shared<SpreadCdsHelper>(
563 0.020860, 10 * Years, 1, WeekendsOnly(), Quarterly, Following,
564 DateGeneration::CDS, Actual360(), 0.4, isdaYts, true, true, Date(),
565 Actual360(true), true, model);
566
567 std::vector<ext::shared_ptr<DefaultProbabilityHelper>> isdaCdsHelpers;
568
569 isdaCdsHelpers.push_back(cds6m);
570 isdaCdsHelpers.push_back(cds1y);
571 isdaCdsHelpers.push_back(cds3y);
572 isdaCdsHelpers.push_back(cds5y);
573 isdaCdsHelpers.push_back(cds7y);
574 isdaCdsHelpers.push_back(cds10y);
575
576 // build credit curve
577 auto isdaCts =
578 Handle<DefaultProbabilityTermStructure>(ext::make_shared<
579 PiecewiseDefaultCurve<SurvivalProbability, LogLinear>>(
580 0, WeekendsOnly(), isdaCdsHelpers, Actual365Fixed()));
581
582 // set up isda engine
583 auto isdaPricer = ext::make_shared<IsdaCdsEngine>(isdaCts, 0.4, isdaYts);
584
585 // check the curves
586 std::cout << "ISDA yield curve:" << std::endl;
587 std::cout << "date;time;zeroyield" << std::endl;
588 for (auto& isdaYieldHelper : isdaYieldHelpers) {
589 Date d = isdaYieldHelper->latestDate();
590 Real t = isdaYts->timeFromReference(d);
591 std::cout << d << ";" << t << ";"
592 << isdaYts->zeroRate(d, Actual365Fixed(), Continuous).rate()
593 << std::endl;
594 }
595
596 std::cout << "ISDA credit curve:" << std::endl;
597 std::cout << "date;time;survivalprob" << std::endl;
598 for (auto& isdaCdsHelper : isdaCdsHelpers) {
599 Date d = isdaCdsHelper->latestDate();
600 Real t = isdaCts->timeFromReference(d);
601 std::cout << d << ";" << t << ";" << isdaCts->survivalProbability(d)
602 << std::endl;
603 }
604 }
605
606
607 int main(int argc, char *argv[]) {
608
609 try {
610 Size example = 0;
611 if (argc == 2)
612 example = std::atoi(argv[1]);
613
614 if (example == 0 || example == 1) {
615 std::cout << "***** Running example #1 *****" << std::endl;
616 example01();
617 }
618
619 if (example == 0 || example == 2) {
620 std::cout << "***** Running example #2 *****" << std::endl;
621 example02();
622 }
623
624 if (example == 0 || example == 3) {
625 std::cout << "***** Running example #3 *****" << std::endl;
626 example03();
627 }
628
629 return 0;
630 }
631 catch (exception &e) {
632 cerr << e.what() << endl;
633 return 1;
634 }
635 catch (...) {
636 cerr << "unknown error" << endl;
637 return 1;
638 }
639 }