Term Structure with QuantLib

Interest Rate Term Structure With QuantLib - Part 1

The Basic Curve

In this exercise, the author will use QuantLib to construct a curve based on short term rates and par bond yields. Lets assume we have the following curve represented as python dictionary:

These two curves have to be defined. At the very minimum, we need to know the day count convention and the accrual convention for each curve. Let defined them using QuantLib. For st_curve, we will need to use ql.DepositRateHelper, while the lt_curve will be using qlFixedRateHelper. Before using these classes we need to import QuantLib.

We also need to define the value date of these curves. Lets assumed a single value date of June 17, 2020. In the python module add the following:

Note: ql.Date is overloaded as most other classes in QuantLib. ql.Date is documented here.

Transforming A Curve To QuantLib Object

Lets generate our discount factor curve from the short term curve prior to combining the two curves. To do so, we need to use ql.DepositRateHelper (documentation is here) which requires several parameters namely:

  1. quote - is a ql.QuoteHandle object
  2. tenor - is a ql.Period object
  3. fixingDays - an integer reflecting number of days from our value date or ql.Settings.instance().evaluationDate
  4. calendar - a ql.Calendar object. For the list of countries supported by the calendar please refer to . Unfortunately, Malaysian calendar is not currently supported. The workaround is using ql.BespokeCalendar() and joining the calendar with ql.WeekendsOnly(). This will be illustrated in future tutorial. For our purpose, we will use ql.Singapore() without adding or removing holidays.
  5. convention - business day convention. Options are ql.Following, ql.ModifiedFollowing, ql.Preceeding, ql.ModifiedPreceeding and ql.Unadjutsed
  6. endOfMonth - end of month rule. Accept a boolean value - True or False
  7. dayCounter - day count convention. A ql.DayCounter class. The list of acceptable values are here.
ql.DepositRateHelper basically defines a point on the short term curve with information listed above. Since we have 4 points in our st_curve, we will need to create a list.

The above code is a list comprehension which iterates through our dictionary to create a new list called st_helpers. ql.SimpleQuote(st_curve[key]/100.0) convert our rate which was in percentage to a simple float while ql.Period(key) convert the key of our st_curve dictionary to a ql.Period object. The iteration is done by for key in st_curve.

Now we have all that we need to transform our data to QuantLib Yield Term Structure object generally called Piecewise. There are several method available (documentation is here) and for our exercise we will be using ql.PiecewiseLogCubicDiscount which requires:

  1. referenceDate - our value date
  2. helpers - our st_helpers
  3. dayCounter - day count convention. A ql.DayCounter class in QuantLib

Unfortunately, that is not the end of it. We cant actually see the result and we are interested in seeing the discount factors it generated. Dont worry. ql.PiecewiseLogCubicDiscount returns a ql.YieldTermStructure class which has several public member functions including:

  1. discount - the discount factor
  2. date
  3. zeroRate - zero rate
  4. forwardRate - function to calculate forward rate
Take note that these functions are not described in the python documentations but can be found
here. The information can therefore be retrieved/calculated from ql_stcurve object. Here is how to create list of dictionary containing date and discount factor from ql_stcurve.

Take not of "date": x.ISO() in the above code. .ISO() is used to convert ql.Date to ISO standard date string ('yyyy-mm-dd' format). This allow passing of the value as JSON.

Now we can use pandas to see the result in DataFrame, print to your console/terminal or send as JSON as a response to a request. For interpolation purposes, however, a list of dictionary with string type date is not the best format. Instead, we have to create two lists containing time as a fraction of year and the discount factors. Conversion of dates to time as a fraction of a year is available but not documented in the python version but available in the C++ version. It is a public member function of ql.DayCounter class named as 'yearFraction'.

The following codes use the ql.DayCounter class to calculate time as fraction of a year (yearfrac in the code) and retrieve the discount factors from the ql.YieldTermStructure class:

Now suppose we want to find the discount factor for November 25, 2020. We should convert the date to time as a fraction of a year. The interpolation can be done using either python or QuantLib library. There several methods in QuantLib and the references are here. For illustartion we use ql.LogCubicNaturalSpline as shown below:

Using QuantLib's interpolation is similar to interpolation in scipy.interpolate packages. ql.LogCubicNaturalSpline returns a class or function which we assigned a variable named ipolate. ipolate is then fed with the relevant parameters - itime, the time for the rate to be interpolated and allowExtrapolation which is self explanatory. You can print irate to the console/terminal to see the result.

Summary

We have only worked with st_curve which is our short term rates. The long term rates lt_curve will need to be merged with st_curve - an endeavour we will undertake in the next part of our exercise.