Created
January 12, 2018 17:48
-
-
Save thrasibule/2123c9e524e2b8c50f0f75ebfffa3ae2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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