Skip to content

Instantly share code, notes, and snippets.

@thrasibule
Created January 12, 2018 17:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thrasibule/2123c9e524e2b8c50f0f75ebfffa3ae2 to your computer and use it in GitHub Desktop.
Save thrasibule/2123c9e524e2b8c50f0f75ebfffa3ae2 to your computer and use it in GitHub Desktop.
#include <ql/qldefines.hpp>
#include <ql/time/date.hpp>
#include <ql/instruments/creditdefaultswap.hpp>
#include <ql/pricingengines/credit/isdacdsengine.hpp>
#include <ql/termstructures/credit/piecewisedefaultcurve.hpp>
#include <ql/termstructures/credit/defaultprobabilityhelpers.hpp>
#include <ql/termstructures/yield/piecewiseyieldcurve.hpp>
#include <ql/termstructures/yield/ratehelpers.hpp>
#include <ql/time/calendars/weekendsonly.hpp>
#include <ql/time/daycounters/thirty360.hpp>
#include <ql/time/daycounters/actual365fixed.hpp>
#include <ql/time/daycounters/actual360.hpp>
#include <ql/currencies/america.hpp>
#include <ql/quotes/simplequote.hpp>
#include <boost/make_shared.hpp>
#include <iostream>
#include <iomanip>
using namespace QuantLib;
void example() {
// this is the example from Apdx E in pricing and risk management of CDS, OpenGamma
Date tradeDate(29, December, 2017);
Settings::instance().evaluationDate() = tradeDate;
std::vector<double> depositRates = {0.015678, 0.016219, 0.016947,
0.018436, 0.021063};
std::vector<int> tenors = {1, 2, 3, 6, 12};
std::vector<boost::shared_ptr<RateHelper> > isdaYieldHelpers;
int i = 0;
for(auto r: depositRates) {
isdaYieldHelpers.push_back(
boost::make_shared<DepositRateHelper>(r, tenors[i] * Months, 2,
WeekendsOnly(), ModifiedFollowing,
false, Actual360()));
i++;
}
// this index is probably not important since we are not using
// QL_USE_INDEXED_COUPON - define it "isda compliant" anyway
boost::shared_ptr<IborIndex> libor3m = boost::make_shared<IborIndex>(
"IsdaIbor", 3 * Months, 2, USDCurrency(), WeekendsOnly(),
ModifiedFollowing, false, Actual360());
std::vector<double> swapRates = {0.020825, 0.02176, 0.02227,
0.022625, 0.02298, 0.02335, 0.023555,
0.02385, 0.024145, 0.02452, 0.025025,
0.02536, 0.025455, 0.02546};
std::vector<int> swapTenors = {2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 15, 20, 25, 30};
i = 0;
for(auto r: swapRates) {
isdaYieldHelpers.push_back(boost::make_shared<SwapRateHelper>(
r, swapTenors[i] * Years, WeekendsOnly(), Semiannual,
ModifiedFollowing, Thirty360(), libor3m));
i++;
}
// build yield curve
Handle<YieldTermStructure> isdaYts = Handle<YieldTermStructure>(
boost::make_shared<PiecewiseYieldCurve<Discount, LogLinear> >(
0, WeekendsOnly(), isdaYieldHelpers, Actual365Fixed()));
isdaYts->enableExtrapolation();
CreditDefaultSwap::PricingModel model = CreditDefaultSwap::ISDA;
boost::shared_ptr<CdsHelper> cds6m(new SpreadCdsHelper(
0.0248, 6 * Months, 1, WeekendsOnly(), Quarterly, Following,
DateGeneration::CDS2015, Actual360(), 0.4, isdaYts, true, true, Date(),
Actual360(true), true, model));
boost::shared_ptr<CdsHelper> cds5y(new SpreadCdsHelper(
0.0248, 5 * Years, 1, WeekendsOnly(), Quarterly, Following,
DateGeneration::CDS2015, Actual360(), 0.4, isdaYts, true, true, Date(),
Actual360(true), true, model));
std::vector<boost::shared_ptr<DefaultProbabilityHelper> > isdaCdsHelpers;
//isdaCdsHelpers.push_back(cds6m);
isdaCdsHelpers.push_back(cds5y);
// build credit curve
Handle<DefaultProbabilityTermStructure> isdaCts =
Handle<DefaultProbabilityTermStructure>(boost::make_shared<
PiecewiseDefaultCurve<SurvivalProbability, LogLinear> >(
0, WeekendsOnly(), isdaCdsHelpers, Actual365Fixed(), 1e-12));
// set up isda engine
boost::shared_ptr<IsdaCdsEngine> isdaPricer =
boost::make_shared<IsdaCdsEngine>(
isdaCts, 0.4, isdaYts);
// check the curves
std::cout << "ISDA yield curve:" << std::endl;
std::cout << "date;time;zeroyield" << std::endl;
for (Size i = 0; i < isdaYieldHelpers.size(); i++) {
Date d = isdaYieldHelpers[i]->latestDate();
Real t = isdaYts->timeFromReference(d);
std::cout << d << ";" << t << ";"
<< isdaYts->zeroRate(d, Actual365Fixed(), Continuous).rate()
<< std::endl;
}
std::cout << "ISDA credit curve:" << std::endl;
std::cout << "date;time;survivalprob" << std::endl;
for (Size i = 0; i < isdaCdsHelpers.size(); i++) {
Date d = isdaCdsHelpers[i]->latestDate();
Real t = isdaCts->timeFromReference(d);
std::cout << d << ";" << t << ";" << isdaCts->survivalProbability(d)
<< std::endl;
}
Schedule cdsSchedule(tradeDate + 1, Date(20, December, 2022), 3 * Months, WeekendsOnly(), Following,
Unadjusted, DateGeneration::CDS, false, Date(), Date());
Real nominal = 10000000;
Date upfrontPaymentDate = WeekendsOnly().advance(tradeDate, 3 * Days);
CreditDefaultSwap trade(Protection::Buyer, nominal, 0., 0.01,
cdsSchedule, Following, Actual360(), true, true,
tradeDate + 1, upfrontPaymentDate,
boost::shared_ptr<Claim>(),
Actual360(true));
trade.setPricingEngine(isdaPricer);
std::cout << trade.fairUpfront() * nominal << std::endl;
std::cout << trade.NPV() / isdaYts->discount(upfrontPaymentDate) << std::endl;
}
int main() {
example();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment