This example prices an interest rate swap over a term structure and calculates its fair fixed rate and floating spread.
#include <ql/qldefines.hpp>
#ifdef BOOST_MSVC
# include <ql/auto_link.hpp>
#endif
#include <ql/termstructures/yield/piecewiseyieldcurve.hpp>
#include <ql/termstructures/yieldtermstructure.hpp>
#include <ql/termstructures/yield/ratehelpers.hpp>
#include <ql/termstructures/yield/oisratehelper.hpp>
#include <ql/pricingengines/swap/discountingswapengine.hpp>
#include <ql/indexes/ibor/eonia.hpp>
#include <ql/indexes/ibor/euribor.hpp>
#include <ql/time/imm.hpp>
#include <ql/time/calendars/target.hpp>
#include <ql/time/daycounters/actual360.hpp>
#include <ql/time/daycounters/thirty360.hpp>
#include <ql/time/daycounters/actualactual.hpp>
#include <ql/math/interpolations/cubicinterpolation.hpp>
#include <ql/math/interpolations/loginterpolation.hpp>
#include <iostream>
#include <iomanip>
#if defined(QL_ENABLE_SESSIONS)
ThreadKey sessionId() { return 0; }
}
#endif
int main(int, char* []) {
try {
std::cout << std::endl;
Date todaysDate(11, December, 2012);
Date settlementDate = calendar.
advance(todaysDate, fixingDays, Days);
settlementDate = calendar.
adjust(settlementDate);
std::cout <<
"Today: " << todaysDate.
weekday()
<< ", " << todaysDate << std::endl;
std::cout << "Settlement date: " << settlementDate.weekday()
<< ", " << settlementDate << std::endl;
ext::shared_ptr<Quote> dONRate(
new SimpleQuote(0.0004));
ext::shared_ptr<Quote> dTNRate(
new SimpleQuote(0.0004));
ext::shared_ptr<Quote> dSNRate(
new SimpleQuote(0.0004));
ext::shared_ptr<Quote> ois1WRate(
new SimpleQuote(0.00070));
ext::shared_ptr<Quote> ois2WRate(
new SimpleQuote(0.00069));
ext::shared_ptr<Quote> ois3WRate(
new SimpleQuote(0.00078));
ext::shared_ptr<Quote> ois1MRate(
new SimpleQuote(0.00074));
ext::shared_ptr<Quote> oisDated1Rate(
new SimpleQuote( 0.000460));
ext::shared_ptr<Quote> oisDated2Rate(
new SimpleQuote( 0.000160));
ext::shared_ptr<Quote> oisDated3Rate(
new SimpleQuote(-0.000070));
ext::shared_ptr<Quote> oisDated4Rate(
new SimpleQuote(-0.000130));
ext::shared_ptr<Quote> oisDated5Rate(
new SimpleQuote(-0.000140));
ext::shared_ptr<Quote> ois15MRate(
new SimpleQuote(0.00002));
ext::shared_ptr<Quote> ois18MRate(
new SimpleQuote(0.00008));
ext::shared_ptr<Quote> ois21MRate(
new SimpleQuote(0.00021));
ext::shared_ptr<Quote> ois2YRate(
new SimpleQuote(0.00036));
ext::shared_ptr<Quote> ois3YRate(
new SimpleQuote(0.00127));
ext::shared_ptr<Quote> ois4YRate(
new SimpleQuote(0.00274));
ext::shared_ptr<Quote> ois5YRate(
new SimpleQuote(0.00456));
ext::shared_ptr<Quote> ois6YRate(
new SimpleQuote(0.00647));
ext::shared_ptr<Quote> ois7YRate(
new SimpleQuote(0.00827));
ext::shared_ptr<Quote> ois8YRate(
new SimpleQuote(0.00996));
ext::shared_ptr<Quote> ois9YRate(
new SimpleQuote(0.01147));
ext::shared_ptr<Quote> ois10YRate(
new SimpleQuote(0.0128));
ext::shared_ptr<Quote> ois11YRate(
new SimpleQuote(0.01404));
ext::shared_ptr<Quote> ois12YRate(
new SimpleQuote(0.01516));
ext::shared_ptr<Quote> ois15YRate(
new SimpleQuote(0.01764));
ext::shared_ptr<Quote> ois20YRate(
new SimpleQuote(0.01939));
ext::shared_ptr<Quote> ois25YRate(
new SimpleQuote(0.02003));
ext::shared_ptr<Quote> ois30YRate(
new SimpleQuote(0.02038));
1 * Days, 0,
false, depositDayCounter));
1 * Days, 1,
false, depositDayCounter));
1 * Days, 2,
false, depositDayCounter));
ext::shared_ptr<Eonia> eonia(
new Eonia);
2, 1 * Weeks,
2, 2 * Weeks,
2, 3 * Weeks,
2, 1 * Months,
Date(16, January, 2013),
Date(13, February, 2013),
Date(13, February, 2013),
Date(13, March, 2013),
Date(13, March, 2013),
Date(10, April, 2013),
Date(10, April, 2013),
Date(8, May, 2013),
Date(8, May, 2013),
Date(12, June, 2013),
2, 15*Months,
2, 18*Months,
2, 21*Months,
2, 2*Years,
2, 3*Years,
2, 4*Years,
2, 5*Years,
2, 6*Years,
2, 7*Years,
2, 8*Years,
2, 9*Years,
2, 10*Years,
2, 11*Years,
2, 12*Years,
2, 15*Years,
2, 20*Years,
2, 25*Years,
2, 30*Years,
std::vector<ext::shared_ptr<RateHelper> > eoniaInstruments;
eoniaInstruments.push_back(dON);
eoniaInstruments.push_back(dTN);
eoniaInstruments.push_back(dSN);
eoniaInstruments.push_back(ois1W);
eoniaInstruments.push_back(ois2W);
eoniaInstruments.push_back(ois3W);
eoniaInstruments.push_back(ois1M);
eoniaInstruments.push_back(oisDated1);
eoniaInstruments.push_back(oisDated2);
eoniaInstruments.push_back(oisDated3);
eoniaInstruments.push_back(oisDated4);
eoniaInstruments.push_back(oisDated5);
eoniaInstruments.push_back(ois15M);
eoniaInstruments.push_back(ois18M);
eoniaInstruments.push_back(ois21M);
eoniaInstruments.push_back(ois2Y);
eoniaInstruments.push_back(ois3Y);
eoniaInstruments.push_back(ois4Y);
eoniaInstruments.push_back(ois5Y);
eoniaInstruments.push_back(ois6Y);
eoniaInstruments.push_back(ois7Y);
eoniaInstruments.push_back(ois8Y);
eoniaInstruments.push_back(ois9Y);
eoniaInstruments.push_back(ois10Y);
eoniaInstruments.push_back(ois11Y);
eoniaInstruments.push_back(ois12Y);
eoniaInstruments.push_back(ois15Y);
eoniaInstruments.push_back(ois20Y);
eoniaInstruments.push_back(ois25Y);
eoniaInstruments.push_back(ois30Y);
ext::shared_ptr<YieldTermStructure> eoniaTermStructure(
todaysDate, eoniaInstruments,
termStructureDayCounter) );
eoniaTermStructure->enableExtrapolation();
discountingTermStructure.
linkTo(eoniaTermStructure);
ext::shared_ptr<IborIndex> euribor6M(
new Euribor6M);
ext::shared_ptr<Quote> d6MRate(
new SimpleQuote(0.00312));
ext::shared_ptr<Quote> fra1Rate(
new SimpleQuote(0.002930));
ext::shared_ptr<Quote> fra2Rate(
new SimpleQuote(0.002720));
ext::shared_ptr<Quote> fra3Rate(
new SimpleQuote(0.002600));
ext::shared_ptr<Quote> fra4Rate(
new SimpleQuote(0.002560));
ext::shared_ptr<Quote> fra5Rate(
new SimpleQuote(0.002520));
ext::shared_ptr<Quote> fra6Rate(
new SimpleQuote(0.002480));
ext::shared_ptr<Quote> fra7Rate(
new SimpleQuote(0.002540));
ext::shared_ptr<Quote> fra8Rate(
new SimpleQuote(0.002610));
ext::shared_ptr<Quote> fra9Rate(
new SimpleQuote(0.002670));
ext::shared_ptr<Quote> fra10Rate(
new SimpleQuote(0.002790));
ext::shared_ptr<Quote> fra11Rate(
new SimpleQuote(0.002910));
ext::shared_ptr<Quote> fra12Rate(
new SimpleQuote(0.003030));
ext::shared_ptr<Quote> fra13Rate(
new SimpleQuote(0.003180));
ext::shared_ptr<Quote> fra14Rate(
new SimpleQuote(0.003350));
ext::shared_ptr<Quote> fra15Rate(
new SimpleQuote(0.003520));
ext::shared_ptr<Quote> fra16Rate(
new SimpleQuote(0.003710));
ext::shared_ptr<Quote> fra17Rate(
new SimpleQuote(0.003890));
ext::shared_ptr<Quote> fra18Rate(
new SimpleQuote(0.004090));
ext::shared_ptr<Quote> s3yRate(
new SimpleQuote(0.004240));
ext::shared_ptr<Quote> s4yRate(
new SimpleQuote(0.005760));
ext::shared_ptr<Quote> s5yRate(
new SimpleQuote(0.007620));
ext::shared_ptr<Quote> s6yRate(
new SimpleQuote(0.009540));
ext::shared_ptr<Quote> s7yRate(
new SimpleQuote(0.011350));
ext::shared_ptr<Quote> s8yRate(
new SimpleQuote(0.013030));
ext::shared_ptr<Quote> s9yRate(
new SimpleQuote(0.014520));
ext::shared_ptr<Quote> s10yRate(
new SimpleQuote(0.015840));
ext::shared_ptr<Quote> s12yRate(
new SimpleQuote(0.018090));
ext::shared_ptr<Quote> s15yRate(
new SimpleQuote(0.020370));
ext::shared_ptr<Quote> s20yRate(
new SimpleQuote(0.021870));
ext::shared_ptr<Quote> s25yRate(
new SimpleQuote(0.022340));
ext::shared_ptr<Quote> s30yRate(
new SimpleQuote(0.022560));
ext::shared_ptr<Quote> s35yRate(
new SimpleQuote(0.022950));
ext::shared_ptr<Quote> s40yRate(
new SimpleQuote(0.023480));
ext::shared_ptr<Quote> s50yRate(
new SimpleQuote(0.024210));
ext::shared_ptr<Quote> s60yRate(
new SimpleQuote(0.024630));
6 * Months, 3,
false, depositDayCounter));
1, euribor6M));
2, euribor6M));
3, euribor6M));
4, euribor6M));
5, euribor6M));
6, euribor6M));
7, euribor6M));
8, euribor6M));
9, euribor6M));
10, euribor6M));
11, euribor6M));
12, euribor6M));
13, euribor6M));
14, euribor6M));
15, euribor6M));
16, euribor6M));
17, euribor6M));
18, euribor6M));
ext::shared_ptr<IborIndex> swFloatingLegIndex(
new Euribor6M);
calendar, swFixedLegFrequency,
swFixedLegConvention, swFixedLegDayCounter,
swFloatingLegIndex,
calendar, swFixedLegFrequency,
swFixedLegConvention, swFixedLegDayCounter,
swFloatingLegIndex,
calendar, swFixedLegFrequency,
swFixedLegConvention, swFixedLegDayCounter,
swFloatingLegIndex,
calendar, swFixedLegFrequency,
swFixedLegConvention, swFixedLegDayCounter,
swFloatingLegIndex,
calendar, swFixedLegFrequency,
swFixedLegConvention, swFixedLegDayCounter,
swFloatingLegIndex,
calendar, swFixedLegFrequency,
swFixedLegConvention, swFixedLegDayCounter,
swFloatingLegIndex,
calendar, swFixedLegFrequency,
swFixedLegConvention, swFixedLegDayCounter,
swFloatingLegIndex,
calendar, swFixedLegFrequency,
swFixedLegConvention, swFixedLegDayCounter,
swFloatingLegIndex,
calendar, swFixedLegFrequency,
swFixedLegConvention, swFixedLegDayCounter,
swFloatingLegIndex,
calendar, swFixedLegFrequency,
swFixedLegConvention, swFixedLegDayCounter,
swFloatingLegIndex,
calendar, swFixedLegFrequency,
swFixedLegConvention, swFixedLegDayCounter,
swFloatingLegIndex,
calendar, swFixedLegFrequency,
swFixedLegConvention, swFixedLegDayCounter,
swFloatingLegIndex,
calendar, swFixedLegFrequency,
swFixedLegConvention, swFixedLegDayCounter,
swFloatingLegIndex,
calendar, swFixedLegFrequency,
swFixedLegConvention, swFixedLegDayCounter,
swFloatingLegIndex,
calendar, swFixedLegFrequency,
swFixedLegConvention, swFixedLegDayCounter,
swFloatingLegIndex,
calendar, swFixedLegFrequency,
swFixedLegConvention, swFixedLegDayCounter,
swFloatingLegIndex,
calendar, swFixedLegFrequency,
swFixedLegConvention, swFixedLegDayCounter,
swFloatingLegIndex,
std::vector<ext::shared_ptr<RateHelper> > euribor6MInstruments;
euribor6MInstruments.push_back(d6M);
euribor6MInstruments.push_back(fra1);
euribor6MInstruments.push_back(fra2);
euribor6MInstruments.push_back(fra3);
euribor6MInstruments.push_back(fra4);
euribor6MInstruments.push_back(fra5);
euribor6MInstruments.push_back(fra6);
euribor6MInstruments.push_back(fra7);
euribor6MInstruments.push_back(fra8);
euribor6MInstruments.push_back(fra9);
euribor6MInstruments.push_back(fra10);
euribor6MInstruments.push_back(fra11);
euribor6MInstruments.push_back(fra12);
euribor6MInstruments.push_back(fra13);
euribor6MInstruments.push_back(fra14);
euribor6MInstruments.push_back(fra15);
euribor6MInstruments.push_back(fra16);
euribor6MInstruments.push_back(fra17);
euribor6MInstruments.push_back(fra18);
euribor6MInstruments.push_back(s3y);
euribor6MInstruments.push_back(s4y);
euribor6MInstruments.push_back(s5y);
euribor6MInstruments.push_back(s6y);
euribor6MInstruments.push_back(s7y);
euribor6MInstruments.push_back(s8y);
euribor6MInstruments.push_back(s9y);
euribor6MInstruments.push_back(s10y);
euribor6MInstruments.push_back(s12y);
euribor6MInstruments.push_back(s15y);
euribor6MInstruments.push_back(s20y);
euribor6MInstruments.push_back(s25y);
euribor6MInstruments.push_back(s30y);
euribor6MInstruments.push_back(s35y);
euribor6MInstruments.push_back(s40y);
euribor6MInstruments.push_back(s50y);
euribor6MInstruments.push_back(s60y);
double tolerance = 1.0e-15;
ext::shared_ptr<YieldTermStructure> euribor6MTermStructure(
settlementDate, euribor6MInstruments,
termStructureDayCounter,
Real nominal = 1000000.0;
ext::shared_ptr<IborIndex> euriborIndex(
VanillaSwap::Type swapType = VanillaSwap::Payer;
Date maturity = settlementDate + lengthInYears*Years;
Schedule fixedSchedule(settlementDate, maturity,
calendar, fixedLegConvention,
fixedLegConvention,
Schedule floatSchedule(settlementDate, maturity,
calendar, floatingLegConvention,
floatingLegConvention,
fixedSchedule, fixedRate, fixedLegDayCounter,
floatSchedule, euriborIndex, spread,
floatingLegDayCounter);
Date fwdStart = calendar.
advance(settlementDate, 1, Years);
Date fwdMaturity = fwdStart + lengthInYears*Years;
Schedule fwdFixedSchedule(fwdStart, fwdMaturity,
calendar, fixedLegConvention,
fixedLegConvention,
Schedule fwdFloatSchedule(fwdStart, fwdMaturity,
calendar, floatingLegConvention,
floatingLegConvention,
fwdFixedSchedule, fixedRate, fixedLegDayCounter,
fwdFloatSchedule, euriborIndex, spread,
floatingLegDayCounter);
std::vector<std::string> headers(4);
headers[0] = "term structure";
headers[1] = "net present value";
headers[2] = "fair spread";
headers[3] = "fair fixed rate";
std::string separator = " | ";
Size width = headers[0].size() + separator.size()
+ headers[1].size() + separator.size()
+ headers[2].size() + separator.size()
+ headers[3].size() + separator.size() - 1;
std::string rule(width, '-'), dblrule(width, '=');
std::string tab(8, ' ');
std::cout << dblrule << std::endl;
std::cout << "5-year market swap-rate = "
<< std::setprecision(2) <<
io::rate(s5yRate->value())
<< std::endl;
std::cout << dblrule << std::endl;
std::cout << tab << "5-years swap paying "
std::cout << headers[0] << separator
<< headers[1] << separator
<< headers[2] << separator
<< headers[3] << separator << std::endl;
std::cout << rule << std::endl;
ext::shared_ptr<PricingEngine> swapEngine(
new DiscountingSwapEngine(discountingTermStructure));
spot5YearSwap.setPricingEngine(swapEngine);
oneYearForward5YearSwap.setPricingEngine(swapEngine);
forecastingTermStructure.linkTo(euribor6MTermStructure);
discountingTermStructure.linkTo(eoniaTermStructure);
NPV = spot5YearSwap.NPV();
fairSpread = spot5YearSwap.fairSpread();
fairRate = spot5YearSwap.fairRate();
std::cout << std::setw(headers[0].size())
<< "eonia disc" << separator;
std::cout << std::setw(headers[1].size())
<< std::fixed << std::setprecision(2) << NPV << separator;
std::cout << std::setw(headers[2].size())
std::cout << std::setw(headers[3].size())
std::cout << std::endl;
QL_REQUIRE(std::fabs(fairRate-s5yRate->value())<1e-8,
"5-years swap mispriced by "
<<
io::rate(std::fabs(fairRate-s5yRate->value())));
forecastingTermStructure.linkTo(euribor6MTermStructure);
discountingTermStructure.linkTo(euribor6MTermStructure);
NPV = spot5YearSwap.NPV();
fairSpread = spot5YearSwap.fairSpread();
fairRate = spot5YearSwap.fairRate();
std::cout << std::setw(headers[0].size())
<< "euribor disc" << separator;
std::cout << std::setw(headers[1].size())
<< std::fixed << std::setprecision(2) << NPV << separator;
std::cout << std::setw(headers[2].size())
std::cout << std::setw(headers[3].size())
std::cout << std::endl;
QL_REQUIRE(std::fabs(fairRate-s5yRate->value())<1e-8,
"5-years swap mispriced!");
std::cout << rule << std::endl;
std::cout << tab << "5-years, 1-year forward swap paying "
std::cout << headers[0] << separator
<< headers[1] << separator
<< headers[2] << separator
<< headers[3] << separator << std::endl;
std::cout << rule << std::endl;
forecastingTermStructure.linkTo(euribor6MTermStructure);
discountingTermStructure.linkTo(eoniaTermStructure);
NPV = oneYearForward5YearSwap.NPV();
fairSpread = oneYearForward5YearSwap.fairSpread();
fairRate = oneYearForward5YearSwap.fairRate();
std::cout << std::setw(headers[0].size())
<< "eonia disc" << separator;
std::cout << std::setw(headers[1].size())
<< std::fixed << std::setprecision(2) << NPV << separator;
std::cout << std::setw(headers[2].size())
std::cout << std::setw(headers[3].size())
std::cout << std::endl;
forecastingTermStructure.linkTo(euribor6MTermStructure);
discountingTermStructure.linkTo(euribor6MTermStructure);
NPV = oneYearForward5YearSwap.NPV();
fairSpread = oneYearForward5YearSwap.fairSpread();
fairRate = oneYearForward5YearSwap.fairRate();
std::cout << std::setw(headers[0].size())
<< "euribor disc" << separator;
std::cout << std::setw(headers[1].size())
<< std::fixed << std::setprecision(2) << NPV << separator;
std::cout << std::setw(headers[2].size())
std::cout << std::setw(headers[3].size())
std::cout << std::endl;
ext::shared_ptr<SimpleQuote> fiveYearsRate =
ext::dynamic_pointer_cast<SimpleQuote>(s5yRate);
fiveYearsRate->setValue(0.0090);
std::cout << dblrule << std::endl;
std::cout << "5-year market swap-rate = "
<<
io::rate(s5yRate->value()) << std::endl;
std::cout << dblrule << std::endl;
std::cout << tab << "5-years swap paying "
std::cout << headers[0] << separator
<< headers[1] << separator
<< headers[2] << separator
<< headers[3] << separator << std::endl;
std::cout << rule << std::endl;
forecastingTermStructure.linkTo(euribor6MTermStructure);
discountingTermStructure.linkTo(eoniaTermStructure);
NPV = spot5YearSwap.NPV();
fairSpread = spot5YearSwap.fairSpread();
fairRate = spot5YearSwap.fairRate();
std::cout << std::setw(headers[0].size())
<< "eonia disc" << separator;
std::cout << std::setw(headers[1].size())
<< std::fixed << std::setprecision(2) << NPV << separator;
std::cout << std::setw(headers[2].size())
std::cout << std::setw(headers[3].size())
std::cout << std::endl;
QL_REQUIRE(std::fabs(fairRate-s5yRate->value())<1e-8,
"5-years swap mispriced!");
forecastingTermStructure.linkTo(euribor6MTermStructure);
discountingTermStructure.linkTo(euribor6MTermStructure);
NPV = spot5YearSwap.NPV();
fairSpread = spot5YearSwap.fairSpread();
fairRate = spot5YearSwap.fairRate();
std::cout << std::setw(headers[0].size())
<< "euribor disc" << separator;
std::cout << std::setw(headers[1].size())
<< std::fixed << std::setprecision(2) << NPV << separator;
std::cout << std::setw(headers[2].size())
std::cout << std::setw(headers[3].size())
std::cout << std::endl;
QL_REQUIRE(std::fabs(fairRate-s5yRate->value())<1e-8,
"5-years swap mispriced!");
std::cout << rule << std::endl;
std::cout << tab << "5-years, 1-year forward swap paying "
std::cout << headers[0] << separator
<< headers[1] << separator
<< headers[2] << separator
<< headers[3] << separator << std::endl;
std::cout << rule << std::endl;
forecastingTermStructure.linkTo(euribor6MTermStructure);
discountingTermStructure.linkTo(eoniaTermStructure);
NPV = oneYearForward5YearSwap.NPV();
fairSpread = oneYearForward5YearSwap.fairSpread();
fairRate = oneYearForward5YearSwap.fairRate();
std::cout << std::setw(headers[0].size())
<< "eonia disc" << separator;
std::cout << std::setw(headers[1].size())
<< std::fixed << std::setprecision(2) << NPV << separator;
std::cout << std::setw(headers[2].size())
std::cout << std::setw(headers[3].size())
std::cout << std::endl;
forecastingTermStructure.linkTo(euribor6MTermStructure);
discountingTermStructure.linkTo(euribor6MTermStructure);
NPV = oneYearForward5YearSwap.NPV();
fairSpread = oneYearForward5YearSwap.fairSpread();
fairRate = oneYearForward5YearSwap.fairRate();
std::cout << std::setw(headers[0].size())
<< "euribor disc" << separator;
std::cout << std::setw(headers[1].size())
<< std::fixed << std::setprecision(2) << NPV << separator;
std::cout << std::setw(headers[2].size())
std::cout << std::setw(headers[3].size())
std::cout << std::endl;
return 0;
} catch (std::exception& e) {
std::cerr << e.what() << std::endl;
return 1;
} catch (...) {
std::cerr << "unknown error" << std::endl;
return 1;
}
}