Valuation of Fixed Rate Bond using Spread with QuantLib

Valuation of Fixed Rate Bond using Spread with QuantLib

Introduction

In the last article we made a brief introduction on fixed rate bond using QuantLib. In this article we will extend the discussion by using QuantLib's bond pricing engine to price a bond based on a spread. Pricing will be done base on a yield term structure which may not necessarily flat.

The Yield Term Structure

For our purpose we will use the term structure created in previous exercises - 'Interest Rate Term Structure With QuantLib - Part 1 and 2' with minor changes to the conventions and a notable change in the calendar. In the event that a country's calendar is not in the list supported by QuantLib, a customs calendar can be created using ql.BespokeCalendar(country_name). This will create a calendar with all dates considered as business days. For standard weekends we can join the newly created calendar with ql.WeekendsOnly() using ql.JoinCalendar(calendar1, calendar2). Then we can add the country's holidays using addHoliday(). This will gives us a custom calendar with holidays including weekends.

The following should look familiar apart from the new created custom calendar and a single public holiday added as an example. After joining the calendars any holiday update via cal will affect mycal but not vice versa.

We will assume that the curve generated above is a risk free curve generated from Government issued securities. Now let us contruct a 10-year corporate bond with 5.00% semi-annual coupon. The following snippet should still look familiar, albeit minor changes, to those who read my previous article.

Revaluing A Bond Using Curve

In practice, revaluation of a bond should be done at its own credit curve, or at its last traded price. Instead of using the internal rate of return in valuing the bond, we will revalue the bond at the risk free curve to see how it is done using QuantLib.

ql.YieldTermStructureHandle, ql.DiscountingBondEngine and ql.setPricingEngine will be the three new classes we will use in this article. ql.YieldTermStructureHandle is required for ql.DiscountingBondEngine which in turn is required by ql.setPricingEngine as shown in the snippet below. Once we have set the pricing engine, the bond can be revalued using bond.NPV(). Note that the coupon of the bond is at 5.00% while the curve is generally below 3.00%. The price therefore will be a lot more than 100.

A function that we purposely left out in our previous article is BondFunctions.zSpread(). For the definition or description of z-spread please visit Wikipedia. In the snippet we used the result of bond.NPV(), to calculate z-spread, which will of course led to an answer of 0.00%. The market price of the bond should instead be used to derived the appropriate z-spread. Try changing bond_npv in the paramater of ql.BondFunctions.zSpread to 103, assuming that it is the market price of the bond. The z-spread is calculated is 1.7349%. We will use this number in the following section.

We can create variations to the above method used. For instance, we can use ql.FlatForward to create the risk free curve and the flat spread curve simply becomes spread above the risk free curve which is akin to quoting the bond as $$10Y_{\text{riskfree}} + \text{spread}$$.