0
$\begingroup$

How can I extract the piecewise linear forward rates given a term structure of zero rates for a given trade date in Py QuantLib. This is used to price an ir swap.

My attempt is to create a ZeroCurve object with the dates, rates, and day count convention, pass this to a YieldTermStructureHandle, pass this to USDLibor object, and lastly pass it to NonstandardSwap object.

This is what I did for the zero rates.

import QuantLib as ql

calendar = ql.UnitedKingdom()    
curve_date = ql.Date(5, 12, 2019)
zcr = [ (calendar.advance(curve_date, 365, ql.Days), 0.02),
        (calendar.advance(curve_date, 730, ql.Days), 0.03),
        (calendar.advance(curve_date, 365, ql.Days), 0.05) ]
dates, rates = zip(*zcr)
forward_term_structure = ql.YieldTermStructureHandle(ql.ZeroCurve(dates, rates, ql.Actual360()))
libor_index = ql.USDLibor(ql.Period(1, ql.Months), forward_term_structure)

Is this correct way to do it? Note that there are more nodes in the zcr but for illustration I made up three coordinates. Thank you.

$\endgroup$

1 Answer 1

0
$\begingroup$

There is probably a typo in your code because you have two nodes for 365 days, but solving that (and also giving the curve a shorter tenor node):

calendar = ql.UnitedKingdom()    
curve_date = ql.Date(5, 12, 2019)
dates = [calendar.advance(curve_date, ql.Period(n, ql.Years)) for n in range(0,4)]
rates = [0.01, 0.02, 0.03, 0.05]
forward_term_structure = ql.YieldTermStructureHandle(ql.ZeroCurve(dates, rates, ql.Actual360()))
forward_term_structure.enableExtrapolation()

there are several ways you can go about doing what you want.

1. Get the forward rates directly from the YieldTermStructure

    import matplotlib.pyplot as plt
    fwds = [forward_term_structure.forwardRate(date, date + ql.Period('1M'), ql.Actual360(), ql.Simple).rate() for date in dates]     
    plt.plot(rates, 'o-', label="Spot")
    plt.plot(fwds, 'o-', label="1M Forward")
    plt.legend()

Here you are extracting the simple 1M forward rate Actual360:

enter image description here

2. Build a floating rate leg and get to rate of the index:

    ql.Settings.instance().evaluationDate = curve_date
    start = calendar.advance(curve_date, 2, ql.Days)
    end = calendar.advance(start, 3, ql.Years)
    schedule = ql.MakeSchedule(start, end, ql.Period('1M'))
    index = ql.USDLibor(ql.Period('1M'), forward_term_structure)
    leg = ql.IborLeg([100], schedule, index)
    fwds = [cf.rate() for cf in map(ql.as_coupon, leg)]
    plt.plot(rates, 'o-', label="Spot")
    times = [ql.Actual360().yearFraction(curve_date, cf.date()) for cf in leg]
    plt.plot(times, fwds, 'o-', label="1M Forward")
    plt.legend()

This would give you:

enter image description here

Notice that in the case of ql.ZeroCurve you are applying linear interpolation to the spot rate which has the known drawback of exhibiting discontinuities in the forwards

$\endgroup$
1
  • $\begingroup$ Thank you very much. Yes, you're correct; there is a typo in my code. Also, I'm aware that linear interpolation does create discontinuities in generating the forwards. Please, I have one follow up question. In ql.ZeroCurve object, can I change the interpolation method to say cubic via ql.ZeroCurve(dates, rates, ql.Actual360(), ql.Cubic()) or use ql.CubicZeroCurve object? $\endgroup$
    – AnonymousJ
    Mar 4, 2020 at 15:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.