Created
January 12, 2018 17:31
-
-
Save thrasibule/f84d24c35dc845b4429e50e34dd07299 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-8)); | |
// 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; | |
CreditDefaultSwap trade(Protection::Buyer, nominal, 0., 0.01, | |
cdsSchedule, Following, Actual360(), true, true, | |
tradeDate + 1, WeekendsOnly().advance(tradeDate, 3 * Days), | |
boost::shared_ptr<Claim>(), | |
Actual360(true), true); | |
trade.setPricingEngine(isdaPricer); | |
std::cout << trade.fairUpfront() * nominal << 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