This example prices an interest rate swap over a term structure and calculates its fair fixed rate and floating spread.
#if !defined(BOOST_ALL_NO_LIB) && defined(BOOST_MSVC)
#endif
#include <iostream>
#include <iomanip>
int main(int, char* []) {
try {
std::cout << std::endl;
Date todaysDate(11, December, 2012);
Settings::instance().evaluationDate() = todaysDate;
todaysDate = Settings::instance().evaluationDate();
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;
std::vector<ext::shared_ptr<RateHelper>> eoniaInstruments;
auto eonia = ext::make_shared<Eonia>();
std::map<Natural, ext::shared_ptr<Quote>> depoQuotes = {
{0, ext::make_shared<SimpleQuote>(0.0004)},
{1, ext::make_shared<SimpleQuote>(0.0004)},
{2, ext::make_shared<SimpleQuote>(0.0004)}
};
for (
const auto&
q : depoQuotes) {
auto settlementDays =
q.first;
auto helper = ext::make_shared<DepositRateHelper>(
1 * Days, settlementDays,
calendar, Following,
false, depositDayCounter);
eoniaInstruments.push_back(helper);
}
std::map<Period, ext::shared_ptr<Quote>> shortOisQuotes = {
{1 * Weeks, ext::make_shared<SimpleQuote>(0.00070)},
{2 * Weeks, ext::make_shared<SimpleQuote>(0.00069)},
{3 * Weeks, ext::make_shared<SimpleQuote>(0.00078)},
{1 * Months, ext::make_shared<SimpleQuote>(0.00074)}
};
for (
const auto&
q : shortOisQuotes) {
auto helper = ext::make_shared<OISRateHelper>(
eoniaInstruments.push_back(helper);
}
std::map<std::pair<Date, Date>, ext::shared_ptr<Quote>> datedOisQuotes = {
{{
Date(16, January, 2013),
Date(13, February, 2013)}, ext::make_shared<SimpleQuote>( 0.000460)},
{{
Date(13, February, 2013),
Date(13, March, 2013)}, ext::make_shared<SimpleQuote>( 0.000160)},
{{
Date(13, March, 2013),
Date(10, April, 2013)}, ext::make_shared<SimpleQuote>(-0.000070)},
{{
Date(10, April, 2013),
Date(8, May, 2013)}, ext::make_shared<SimpleQuote>(-0.000130)},
{{
Date(8, May, 2013),
Date(12, June, 2013)}, ext::make_shared<SimpleQuote>(-0.000140)},
};
for (
const auto&
q : datedOisQuotes) {
auto startDate =
q.first.first;
auto endDate =
q.first.second;
auto helper = ext::make_shared<DatedOISRateHelper>(
eoniaInstruments.push_back(helper);
}
std::map<Period, ext::shared_ptr<Quote>> longOisQuotes = {
{15 * Months, ext::make_shared<SimpleQuote>(0.00002)},
{18 * Months, ext::make_shared<SimpleQuote>(0.00008)},
{21 * Months, ext::make_shared<SimpleQuote>(0.00021)},
{2 * Years, ext::make_shared<SimpleQuote>(0.00036)},
{3 * Years, ext::make_shared<SimpleQuote>(0.00127)},
{4 * Years, ext::make_shared<SimpleQuote>(0.00274)},
{5 * Years, ext::make_shared<SimpleQuote>(0.00456)},
{6 * Years, ext::make_shared<SimpleQuote>(0.00647)},
{7 * Years, ext::make_shared<SimpleQuote>(0.00827)},
{8 * Years, ext::make_shared<SimpleQuote>(0.00996)},
{9 * Years, ext::make_shared<SimpleQuote>(0.01147)},
{10 * Years, ext::make_shared<SimpleQuote>(0.0128)},
{11 * Years, ext::make_shared<SimpleQuote>(0.01404)},
{12 * Years, ext::make_shared<SimpleQuote>(0.01516)},
{15 * Years, ext::make_shared<SimpleQuote>(0.01764)},
{20 * Years, ext::make_shared<SimpleQuote>(0.01939)},
{25 * Years, ext::make_shared<SimpleQuote>(0.02003)},
{30 * Years, ext::make_shared<SimpleQuote>(0.02038)}
};
for (
const auto&
q : longOisQuotes) {
auto helper = ext::make_shared<OISRateHelper>(
eoniaInstruments.push_back(helper);
}
auto eoniaTermStructure = ext::make_shared<PiecewiseYieldCurve<Discount, Cubic>>(
todaysDate, eoniaInstruments, termStructureDayCounter);
eoniaTermStructure->enableExtrapolation();
discountingTermStructure.
linkTo(eoniaTermStructure);
std::vector<ext::shared_ptr<RateHelper>> euribor6MInstruments;
auto euribor6M = ext::make_shared<Euribor6M>();
auto d6MRate = ext::make_shared<SimpleQuote>(0.00312);
auto d6M = ext::make_shared<DepositRateHelper>(
6 * Months, 3,
calendar, Following,
false, depositDayCounter);
euribor6MInstruments.push_back(d6M);
std::map<Natural, ext::shared_ptr<Quote>> fraQuotes = {
{1, ext::make_shared<SimpleQuote>(0.002930)},
{2, ext::make_shared<SimpleQuote>(0.002720)},
{3, ext::make_shared<SimpleQuote>(0.002600)},
{4, ext::make_shared<SimpleQuote>(0.002560)},
{5, ext::make_shared<SimpleQuote>(0.002520)},
{6, ext::make_shared<SimpleQuote>(0.002480)},
{7, ext::make_shared<SimpleQuote>(0.002540)},
{8, ext::make_shared<SimpleQuote>(0.002610)},
{9, ext::make_shared<SimpleQuote>(0.002670)},
{10, ext::make_shared<SimpleQuote>(0.002790)},
{11, ext::make_shared<SimpleQuote>(0.002910)},
{12, ext::make_shared<SimpleQuote>(0.003030)},
{13, ext::make_shared<SimpleQuote>(0.003180)},
{14, ext::make_shared<SimpleQuote>(0.003350)},
{15, ext::make_shared<SimpleQuote>(0.003520)},
{16, ext::make_shared<SimpleQuote>(0.003710)},
{17, ext::make_shared<SimpleQuote>(0.003890)},
{18, ext::make_shared<SimpleQuote>(0.004090)}
};
for (
const auto&
q : fraQuotes) {
auto monthsToStart =
q.first;
auto helper = ext::make_shared<FraRateHelper>(
monthsToStart, euribor6M);
euribor6MInstruments.push_back(helper);
}
std::map<Period, ext::shared_ptr<Quote>> swapQuotes = {
{3 * Years, ext::make_shared<SimpleQuote>(0.004240)},
{4 * Years, ext::make_shared<SimpleQuote>(0.005760)},
{5 * Years, ext::make_shared<SimpleQuote>(0.007620)},
{6 * Years, ext::make_shared<SimpleQuote>(0.009540)},
{7 * Years, ext::make_shared<SimpleQuote>(0.011350)},
{8 * Years, ext::make_shared<SimpleQuote>(0.013030)},
{9 * Years, ext::make_shared<SimpleQuote>(0.014520)},
{10 * Years, ext::make_shared<SimpleQuote>(0.015840)},
{12 * Years, ext::make_shared<SimpleQuote>(0.018090)},
{15 * Years, ext::make_shared<SimpleQuote>(0.020370)},
{20 * Years, ext::make_shared<SimpleQuote>(0.021870)},
{25 * Years, ext::make_shared<SimpleQuote>(0.022340)},
{30 * Years, ext::make_shared<SimpleQuote>(0.022560)},
{35 * Years, ext::make_shared<SimpleQuote>(0.022950)},
{40 * Years, ext::make_shared<SimpleQuote>(0.023480)},
{50 * Years, ext::make_shared<SimpleQuote>(0.024210)},
{60 * Years, ext::make_shared<SimpleQuote>(0.024630)}
};
for (
const auto&
q : swapQuotes) {
auto helper = ext::make_shared<SwapRateHelper>(
calendar, swFixedLegFrequency,
swFixedLegConvention, swFixedLegDayCounter,
euribor6M,
discountingTermStructure);
euribor6MInstruments.push_back(helper);
}
double tolerance = 1.0e-15;
auto euribor6MTermStructure = ext::make_shared<PiecewiseYieldCurve<Discount, Cubic>>(
settlementDate, euribor6MInstruments,
termStructureDayCounter,
forecastingTermStructure.
linkTo(euribor6MTermStructure);
Real nominal = 1000000.0;
auto euriborIndex = ext::make_shared<Euribor6M>(forecastingTermStructure);
Date maturity = settlementDate + lengthInYears*Years;
Schedule fixedSchedule(settlementDate, maturity,
calendar, fixedLegConvention,
fixedLegConvention,
DateGeneration::Forward, false);
Schedule floatSchedule(settlementDate, maturity,
calendar, floatingLegConvention,
floatingLegConvention,
DateGeneration::Forward, false);
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,
DateGeneration::Forward, false);
Schedule fwdFloatSchedule(fwdStart, fwdMaturity,
calendar, floatingLegConvention,
floatingLegConvention,
DateGeneration::Forward, false);
fwdFixedSchedule, fixedRate, fixedLegDayCounter,
fwdFloatSchedule, euriborIndex, spread,
floatingLegDayCounter);
std::ostringstream s1;
s1 << "5-years swap paying " << std::setprecision(2) << io::rate(fixedRate);
std::string case1 = s1.str();
std::ostringstream s2;
s2 << "5-years, 1-year forward swap paying " << std::setprecision(2) << io::rate(fixedRate);
std::string case2 = s2.str();
std::vector<std::string> headers(4);
headers[0] = std::string(std::max(case1.size(), case2.size()) + 1, ' ');
headers[1] = "net present value";
headers[2] = "fair spread";
headers[3] = "fair fixed rate";
std::string separator = " | ";
std::string header = headers[0] + separator + headers[1] + separator + headers[2] + separator + headers[3];
Size width = header.size();
std::string rule(width, '-'), dblrule(width, '=');
auto s5yRate = swapQuotes[5 * Years];
std::cout << dblrule << std::endl;
std::cout << " With 5-year market swap-rate = "
<< std::setprecision(2) << io::rate(s5yRate->value())
<< std::endl;
std::cout << rule << std::endl;
std::cout << header << std::endl;
std::cout << rule << std::endl;
auto swapEngine = ext::make_shared<DiscountingSwapEngine>(discountingTermStructure);
NPV = spot5YearSwap.
NPV();
std::cout << std::setw(headers[0].size())
<< case1 << separator;
std::cout << std::setw(headers[1].size())
<< std::fixed << std::setprecision(2) << NPV << separator;
std::cout << std::setw(headers[2].size())
<< io::rate(fairSpread) << separator;
std::cout << std::setw(headers[3].size())
<< io::rate(fairRate);
std::cout << std::endl;
std::cout << rule << std::endl;
QL_REQUIRE(std::fabs(fairRate-s5yRate->value())<1e-8,
"5-years swap mispriced by "
<< io::rate(std::fabs(fairRate-s5yRate->value())));
NPV = oneYearForward5YearSwap.
NPV();
fairSpread = oneYearForward5YearSwap.
fairSpread();
fairRate = oneYearForward5YearSwap.
fairRate();
std::cout << std::setw(headers[0].size())
<< case2 << separator;
std::cout << std::setw(headers[1].size())
<< std::fixed << std::setprecision(2) << NPV << separator;
std::cout << std::setw(headers[2].size())
<< io::rate(fairSpread) << separator;
std::cout << std::setw(headers[3].size())
<< io::rate(fairRate);
std::cout << std::endl;
auto fiveYearsRate = ext::dynamic_pointer_cast<SimpleQuote>(s5yRate);
fiveYearsRate->setValue(0.0090);
std::cout << dblrule << std::endl;
std::cout << " With 5-year market swap-rate = "
<< io::rate(s5yRate->value()) << std::endl;
std::cout << rule << std::endl;
std::cout << header << std::endl;
std::cout << rule << std::endl;
NPV = spot5YearSwap.
NPV();
std::cout << std::setw(headers[0].size())
<< case1 << separator;
std::cout << std::setw(headers[1].size())
<< std::fixed << std::setprecision(2) << NPV << separator;
std::cout << std::setw(headers[2].size())
<< io::rate(fairSpread) << separator;
std::cout << std::setw(headers[3].size())
<< io::rate(fairRate);
std::cout << std::endl;
QL_REQUIRE(std::fabs(fairRate-s5yRate->value())<1e-8,
"5-years swap mispriced!");
std::cout << rule << std::endl;
NPV = oneYearForward5YearSwap.
NPV();
fairSpread = oneYearForward5YearSwap.
fairSpread();
fairRate = oneYearForward5YearSwap.
fairRate();
std::cout << std::setw(headers[0].size())
<< case2 << separator;
std::cout << std::setw(headers[1].size())
<< std::fixed << std::setprecision(2) << NPV << separator;
std::cout << std::setw(headers[2].size())
<< io::rate(fairSpread) << separator;
std::cout << std::setw(headers[3].size())
<< io::rate(fairRate);
std::cout << std::endl;
std::cout << dblrule << 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;
}
}
Actual/360 day count convention.
Actual/365 (Fixed) day count convention.
Date adjust(const Date &, BusinessDayConvention convention=Following) const
Date advance(const Date &, Integer n, TimeUnit unit, BusinessDayConvention convention=Following, bool endOfMonth=false) const
Spread fairSpread() const
Shared handle to an observable.
Real NPV() const
returns the net present value of the instrument.
void setPricingEngine(const ext::shared_ptr< PricingEngine > &)
set the pricing engine to be used.
Bootstrap< this_curve > bootstrap_type
Relinkable handle to an observable.
void linkTo(const ext::shared_ptr< T > &h, bool registerAsObserver=true)
30/360 day count convention
Plain-vanilla swap: fix vs ibor leg.
cubic interpolation between discrete points
#define QL_REQUIRE(condition, message)
throw an error if the given pre-condition is not verified
Frequency
Frequency of events.
BusinessDayConvention
Business Day conventions.
QL_INTEGER Integer
integer number
Real Spread
spreads on interest rates
std::size_t Size
size of a container
IMM-related date functions.
log-linear and log-cubic interpolation between discrete points
Overnight Indexed Swap (aka OIS) rate helpers.
ext::shared_ptr< YieldTermStructure > q
piecewise-interpolated term structure
Global definitions and compiler switches.
deposit, FRA, futures, and various swap rate helpers
Interest-rate term structure.