I have used QuantLib Python to construct a zero curve from deposits and bonds.
Below are my codes:
import QuantLib as ql
valuationDate = ql.Date(30, 6, 2021)
ql.Settings.instance().evaluationDate = valuationDate
calendar = ql.NullCalendar()
dayConvention = ql.Actual360()
businessConvention = ql.Following
couponFrequency = ql.Semiannual
depositRates = [1.03, 1.13, 1.43]
depositMaturities = ['91D', '182D', '364D']
depositHelpers = [ql.DepositRateHelper(ql.QuoteHandle(ql.SimpleQuote(r/100.0)),
ql.Period(m),
2,
calendar,
businessConvention,
True,
dayConvention) for r, m in zip(depositRates, depositMaturities)]
bondPrices = [98.452, 99.955, 100.68, 94.251, 89.1395]
bondMaturities = ['3Y', '5Y', '10Y', '15Y', '20Y']
bondCoupons = [1.85, 3.10, 4.45, 4.17, 4.17]
bondHelpers = []
for r, m, z in zip(bondPrices, bondMaturities, bondCoupons):
terminationDate = valuationDate + ql.Period(m)
schedule = ql.Schedule(valuationDate, terminationDate, ql.Period(couponFrequency), calendar, businessConvention, businessConvention, ql.DateGeneration.Forward, True)
bondHelper = ql.FixedRateBondHelper(ql.QuoteHandle(ql.SimpleQuote(r)), 2, 100, schedule, [z/100], dayConvention, businessConvention)
bondHelpers.append(bondHelper)
rateHelpers = depositHelpers + bondHelpers
yieldCurve = ql.PiecewiseLogCubicDiscount(valuationDate, rateHelpers, dayConvention)
yieldCurve.enableExtrapolation()
dates = [date for date in yieldCurve.dates()]
zeroRates = []
for d in dates[1:]:
years = dayConvention.yearFraction(valuationDate, d)
zeroRate = yieldCurve.zeroRate(d, dayConvention, ql.Compounded, couponFrequency).rate()
zeroRates.append(zeroRate * 100)
However, for the deposits, since these are already zero-coupon, I would expect the zero rates to be exactly equal to the par rates inserted in the depositHelpers
list.
Unfortunately, this is not the case, as can be seen below:
for i in range(0, 3, 1):
print('Par rate:', depositRates[i], '; Zero rate:', zeroRates[i])
The results are as follows:
Par rate: 1.03 ; Zero rate: 1.0305594755884773
Par rate: 1.13 ; Zero rate: 1.1285118046763465
Par rate: 1.43 ; Zero rate: 1.4224679299821297
Can someone please explain what I'm doing wrong? Thanks a lot.