This example shows how to set up a term structure and then price some simple bonds. The last part is dedicated to peripherical computations such as yield-to-price or price-to-yield.
#if !defined(BOOST_ALL_NO_LIB) && defined(BOOST_MSVC)
#endif
#include <iostream>
#include <iomanip>
int main(int, char* []) {
try {
std::cout << std::endl;
Date settlementDate(18, September, 2008);
settlementDate = calendar.
adjust(settlementDate);
Date todaysDate = calendar.
advance(settlementDate, -fixingDays, Days);
Settings::instance().evaluationDate() = todaysDate;
std::cout <<
"Today: " << todaysDate.
weekday()
<< ", " << todaysDate << std::endl;
std::cout <<
"Settlement date: " << settlementDate.
weekday()
<< ", " << settlementDate << std::endl;
auto zc3mRate = ext::make_shared<SimpleQuote>(zc3mQuote);
auto zc6mRate = ext::make_shared<SimpleQuote>(zc6mQuote);
auto zc1yRate = ext::make_shared<SimpleQuote>(zc1yQuote);
auto zc3m = ext::make_shared<DepositRateHelper>(
3*Months, fixingDays,
calendar, ModifiedFollowing,
true, zcBondsDayCounter);
auto zc6m = ext::make_shared<DepositRateHelper>(
6*Months, fixingDays,
calendar, ModifiedFollowing,
true, zcBondsDayCounter);
auto zc1y = ext::make_shared<DepositRateHelper>(
1*Years, fixingDays,
calendar, ModifiedFollowing,
true, zcBondsDayCounter);
const Size numberOfBonds = 5;
Date (15, November, 2002),
};
};
0.02375,
0.04625,
0.03125,
0.04000,
0.04500
};
100.390625,
106.21875,
100.59375,
101.6875,
102.140625
};
std::vector<ext::shared_ptr<SimpleQuote>> quote;
for (
Real marketQuote : marketQuotes) {
quote.push_back(ext::make_shared<SimpleQuote>(marketQuote));
}
for (
Size i=0; i<numberOfBonds; i++) {
quoteHandle[i].
linkTo(quote[i]);
}
std::vector<ext::shared_ptr<BondHelper>> bondsHelpers;
for (
Size i=0; i<numberOfBonds; i++) {
Unadjusted, Unadjusted, DateGeneration::Backward, false);
auto bondHelper = ext::make_shared<FixedRateBondHelper>(
quoteHandle[i],
settlementDays,
100.0,
schedule,
std::vector<Rate>(1,couponRates[i]),
Unadjusted,
redemption,
issueDates[i]);
bondsHelpers.push_back(bondHelper);
}
std::vector<ext::shared_ptr<RateHelper>> bondInstruments;
bondInstruments.push_back(zc3m);
bondInstruments.push_back(zc6m);
bondInstruments.push_back(zc1y);
for (
Size i=0; i<numberOfBonds; i++) {
bondInstruments.push_back(bondsHelpers[i]);
}
auto bondDiscountingTermStructure = ext::make_shared<PiecewiseYieldCurve<Discount,LogLinear>>(
settlementDate, bondInstruments, termStructureDayCounter);
auto d1wRate = ext::make_shared<SimpleQuote>(d1wQuote);
auto d1mRate = ext::make_shared<SimpleQuote>(d1mQuote);
auto d3mRate = ext::make_shared<SimpleQuote>(d3mQuote);
auto d6mRate = ext::make_shared<SimpleQuote>(d6mQuote);
auto d9mRate = ext::make_shared<SimpleQuote>(d9mQuote);
auto d1yRate = ext::make_shared<SimpleQuote>(d1yQuote);
auto s2yRate = ext::make_shared<SimpleQuote>(s2yQuote);
auto s3yRate = ext::make_shared<SimpleQuote>(s3yQuote);
auto s5yRate = ext::make_shared<SimpleQuote>(s5yQuote);
auto s10yRate = ext::make_shared<SimpleQuote>(s10yQuote);
auto s15yRate = ext::make_shared<SimpleQuote>(s15yQuote);
auto d1w = ext::make_shared<DepositRateHelper>(
1*Weeks, fixingDays,
calendar, ModifiedFollowing,
true, depositDayCounter);
auto d1m = ext::make_shared<DepositRateHelper>(
1*Months, fixingDays,
calendar, ModifiedFollowing,
true, depositDayCounter);
auto d3m = ext::make_shared<DepositRateHelper>(
3*Months, fixingDays,
calendar, ModifiedFollowing,
true, depositDayCounter);
auto d6m = ext::make_shared<DepositRateHelper>(
6*Months, fixingDays,
calendar, ModifiedFollowing,
true, depositDayCounter);
auto d9m = ext::make_shared<DepositRateHelper>(
9*Months, fixingDays,
calendar, ModifiedFollowing,
true, depositDayCounter);
auto d1y = ext::make_shared<DepositRateHelper>(
1*Years, fixingDays,
calendar, ModifiedFollowing,
true, depositDayCounter);
auto swFixedLegFrequency = Annual;
auto swFixedLegConvention = Unadjusted;
auto swFixedLegDayCounter =
Thirty360(Thirty360::European);
auto swFloatingLegIndex = ext::make_shared<Euribor6M>();
const Period forwardStart(1*Days);
auto s2y = ext::make_shared<SwapRateHelper>(
calendar, swFixedLegFrequency,
swFixedLegConvention, swFixedLegDayCounter,
auto s3y = ext::make_shared<SwapRateHelper>(
calendar, swFixedLegFrequency,
swFixedLegConvention, swFixedLegDayCounter,
auto s5y = ext::make_shared<SwapRateHelper>(
calendar, swFixedLegFrequency,
swFixedLegConvention, swFixedLegDayCounter,
auto s10y = ext::make_shared<SwapRateHelper>(
calendar, swFixedLegFrequency,
swFixedLegConvention, swFixedLegDayCounter,
auto s15y = ext::make_shared<SwapRateHelper>(
calendar, swFixedLegFrequency,
swFixedLegConvention, swFixedLegDayCounter,
std::vector<ext::shared_ptr<RateHelper>> depoSwapInstruments;
depoSwapInstruments.push_back(d1w);
depoSwapInstruments.push_back(d1m);
depoSwapInstruments.push_back(d3m);
depoSwapInstruments.push_back(d6m);
depoSwapInstruments.push_back(d9m);
depoSwapInstruments.push_back(d1y);
depoSwapInstruments.push_back(s2y);
depoSwapInstruments.push_back(s3y);
depoSwapInstruments.push_back(s5y);
depoSwapInstruments.push_back(s10y);
depoSwapInstruments.push_back(s15y);
auto depoSwapTermStructure = ext::make_shared<PiecewiseYieldCurve<Discount, LogLinear>>(
settlementDate, depoSwapInstruments,
termStructureDayCounter);
auto bondEngine = ext::make_shared<DiscountingBondEngine>(discountingTermStructure);
settlementDays,
faceAmount,
Following,
Unadjusted, Unadjusted, DateGeneration::Backward, false);
settlementDays,
faceAmount,
fixedBondSchedule,
std::vector<Rate>(1, 0.045),
ModifiedFollowing,
100.0,
Date(15, May, 2007));
const auto libor3m = ext::make_shared<USDLibor>(
Period(3, Months), liborTermStructure);
libor3m->addFixing(
Date(17, July, 2008),0.0278625);
Unadjusted, Unadjusted, DateGeneration::Backward, true);
settlementDays,
faceAmount,
floatingBondSchedule,
libor3m,
ModifiedFollowing,
std::vector<Real>(1, 1.0),
std::vector<Rate>(1, 0.001),
std::vector<Rate>(),
std::vector<Rate>(),
true,
Date(21, October, 2005));
auto pricer = ext::make_shared<BlackIborCouponPricer>();
ext::make_shared<ConstantOptionletVolatility>(
settlementDays,
calendar,
ModifiedFollowing,
volatility,
pricer->setCapletVolatility(vol);
setCouponPricer(floatingRateBond.
cashflows(),pricer);
forecastingTermStructure.
linkTo(depoSwapTermStructure);
discountingTermStructure.linkTo(bondDiscountingTermStructure);
liborTermStructure.
linkTo(depoSwapTermStructure);
std::cout << std::endl;
Size widths[] = { 18, 10, 10, 10 };
std::cout << std::setw(widths[0]) << " "
<< std::setw(widths[1]) << "ZC"
<< std::setw(widths[2]) << "Fixed"
<< std::setw(widths[3]) << "Floating"
<< std::endl;
Size width = widths[0] + widths[1] + widths[2] + widths[3];
std::string rule(width, '-');
std::cout << rule << std::endl;
std::cout << std::fixed;
std::cout << std::setprecision(2);
std::cout << std::setw(widths[0]) << "Net present value"
<< std::setw(widths[1]) << zeroCouponBond.
NPV()
<< std::setw(widths[2]) << fixedRateBond.
NPV()
<< std::setw(widths[3]) << floatingRateBond.
NPV()
<< std::endl;
std::cout << std::setw(widths[0]) << "Clean price"
<< std::setw(widths[1]) << zeroCouponBond.
cleanPrice()
<< std::setw(widths[2]) << fixedRateBond.
cleanPrice()
<< std::setw(widths[3]) << floatingRateBond.
cleanPrice()
<< std::endl;
std::cout << std::setw(widths[0]) << "Dirty price"
<< std::setw(widths[1]) << zeroCouponBond.
dirtyPrice()
<< std::setw(widths[2]) << fixedRateBond.
dirtyPrice()
<< std::setw(widths[3]) << floatingRateBond.
dirtyPrice()
<< std::endl;
std::cout << std::setw(widths[0]) << "Accrued coupon"
<< std::endl;
std::cout << std::setw(widths[0]) << "Previous coupon"
<< std::setw(widths[1]) << "N/A"
<< std::endl;
std::cout << std::setw(widths[0]) << "Next coupon"
<< std::setw(widths[1]) << "N/A"
<< std::setw(widths[3]) << io::rate(floatingRateBond.
nextCouponRate())
<< std::endl;
std::cout << std::setw(widths[0]) << "Yield"
<< std::setw(widths[1])
<< std::setw(widths[2])
<< std::setw(widths[3])
<< std::endl;
std::cout << std::endl;
std::cout << "Sample indirect computations (for the floating rate bond): " << std::endl;
std::cout << rule << std::endl;
std::cout << "Yield to Clean Price: "
std::cout << "Clean Price to Yield: "
<< io::rate(floatingRateBond.
yield({floatingRateBond.cleanPrice(), Bond::Price::Clean},
Actual360(), Compounded, Annual, settlementDate))
<< 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.
Real cleanPrice() const
theoretical clean price
Rate previousCouponRate(Date d=Date()) const
Previous coupon already paid at a given date.
Rate yield(const DayCounter &dc, Compounding comp, Frequency freq, Real accuracy=1.0e-8, Size maxEvaluations=100, Real guess=0.05, Bond::Price::Type priceType=Bond::Price::Clean) const
theoretical bond yield
virtual Real accruedAmount(Date d=Date()) const
accrued amount at a given date
const Leg & cashflows() const
Real dirtyPrice() const
theoretical dirty price
virtual Rate nextCouponRate(Date d=Date()) const
Date adjust(const Date &, BusinessDayConvention convention=Following) const
Date advance(const Date &, Integer n, TimeUnit unit, BusinessDayConvention convention=Following, bool endOfMonth=false) const
floating-rate bond (possibly capped and/or floored)
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.
Relinkable handle to an observable.
void linkTo(const ext::shared_ptr< T > &h, bool registerAsObserver=true)
30/360 day count convention
Constant caplet/floorlet volatility.
unsigned QL_INTEGER Natural
positive integer
Real Volatility
volatility
QL_INTEGER Integer
integer number
std::size_t Size
size of a container
piecewise-interpolated term structure
Global definitions and compiler switches.