In the last post of this series, I began talking about QuantLib’s support for representing the term structure of interest rates, which is typically referred to by finance practitioners as the ‘yield curve’. Under normal economic conditions, the yield curve slopes upward – long term interest rates are higher than short-term interest rates. The following chart graphically depicts the relationship between interest rates and time to maturity.

The level, slope and shape of the yield curve are intrinsic to the pricing and risk management of bonds and bond portfolios. To price a bond accurately, or, more generally, to compute the present value of future cash flows accurately, the interest rate at the time the cash flow occurs must be inferred from the yield curve.

So let’s revisit our earlier bond pricing example to see how one would go about building a yield curve and pricing a bond with it using QuantLib’s YieldTermStructure class. Consider a 3 year fixed rate bond with a face value of 100 and an interest rate of 3% with annual coupons that pay 5% compounded annually. We’ve already seen that the bond’s price is 105.66. The code below shows how to reproduce this price using an explicit yield curve rather than a single, constant rate. One thing to note is that a constant interest rate is the same as a flat yield curve, one where the rate is the same at all maturities. So that we calculate the same price as before, 105.66, the example uses QuantLib’s FlatForward class to represent the yield ‘curve’.

#include <cstdlib>

#include <iostream>

#define BOOST_AUTO_TEST_MAIN

#include <boost/test/unit_test.hpp>

#include <boost/detail/lightweight_test.hpp>

#include <ql/quantlib.hpp>

#include <vector>

#include <ql/instruments/bonds/fixedratebond.hpp>

`BOOST_AUTO_TEST_CASE(testPriceBondWithFlatTermStructure) {`

Calendar calendar = UnitedStates(UnitedStates::GovernmentBond);

const Natural settlementDays = 3;

Date today = Date::todaysDate();

Date issueDate = today;

Date terminationDate = issueDate + Period(3, Years);

Rate rate = .03;

InterestRate couponRate(.05, ActualActual(ActualActual::Bond), Compounded, Annual);

Real faceValue = 100.0;

std::vector<InterestRate> coupons(3, couponRate);

Schedule schedule(issueDate, terminationDate, Period(Annual), calendar,

Unadjusted, Unadjusted, DateGeneration::Backward, false);

FixedRateBond fixedRateBond(settlementDays, faceValue, schedule, coupons);

boost::shared_ptr<YieldTermStructure> flatForward(new FlatForward(issueDate, rate, ActualActual(ActualActual::Bond), Compounded, Annual));

Handle<YieldTermStructure> flatTermStructure(flatForward);

boost::shared_ptr<PricingEngine> bondEngine(new DiscountingBondEngine(flatTermStructure));

fixedRateBond.setPricingEngine(bondEngine);

Real npv = fixedRateBond.NPV();

std::cout << "NPV of bond is: " << npv << std::endl;

}

A key feature of this code is the use of a pricing engine, DiscountingBondEngine. A pricing engine is a common QuantLib abstraction which effectively encapsulates instrument-specific valuation logic. The constructor of the DiscountingBondEngine takes the yield curve as an argument, from which the engine extracts the interest rates required to discount the bond’s coupons. Of note also is that the coupon payment dates are generated by QuantLib’s Schedule class, which takes into account a supplied calendar for determining business days and holidays. Overall, this code illustrates what is required to price a bond in the real world, with the obvious caveat that the term structure is flat. To redress this last remaining deficiency, the FittedBondDiscountCurve class can be substituted for the FlatForward class. On the QuantLib Web site you can find a complete example, FittedBondCurve.cpp, that shows how to use the FittedBondDiscountCurve to ‘bootstrap’ a yield curve given market rate quotes. I encourage you to check it out.

That’s it for now. In my next post, I’ll back out the interest rate for a sequence of cash flows using a QuantLib solver. See you then!