# Zero Rates to Piecewise linear forward rates in Py QuantLib

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),
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.

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: 2. Build a floating rate leg and get to rate of the index:

    ql.Settings.instance().evaluationDate = curve_date
schedule = ql.MakeSchedule(start, end, ql.Period('1M'))
index = ql.USDLibor(ql.Period('1M'), forward_term_structure)
leg = ql.IborLeg(, 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: 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

• 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? Mar 4, 2020 at 15:02