I am trying to calculate the zero rate for a piecewise linear zero curve. I have the following deposit on the short end
- STIBOR 1D, is identified as a tomorrow next deposit: 0.02416
- STIBOR 3 Month: 0.02701
I then use the very nice package QuantLib to find the continuous zero rates:
from datetime import datetime, date, timedelta
import pandas as pd
date_today = datetime(2022,12,30)
# Set the date today
ql_date_today = ql.Date(date_today.strftime("%Y-%m-%d"), "%Y-%m-%d") #
ql.Settings.instance().evaluationDate = ql_date_today
helpers = []
depositRates = [0.02416, 0.02701]
depositMaturities = ['1D', '3M']
calendar = ql.Sweden()
fixingDays = 2
endOfMonth = False
convention = ql.ModifiedFollowing
dayCounter = ql.Actual360()
for r,m in zip(depositRates, depositMaturities):
if m == '1D':
fixingDays = 1
convention = ql.Following
elif m == '3M':
convention = ql.Following
fixingDays = 2
helpers.append(ql.DepositRateHelper(ql.QuoteHandle(ql.SimpleQuote(r)),
ql.Period(m),
fixingDays,
calendar,
convention,
endOfMonth,
dayCounter))
curve1 = ql.PiecewiseLinearZero(0, ql.TARGET(), helpers, ql.Actual365Fixed())
curve1.enableExtrapolation()
def ql_to_datetime(d):
return datetime(d.year(), d.month(), d.dayOfMonth())
def calc_days(maturity, date_now = date_today):
return (maturity-date_now).days
dates, rates = zip(*curve1.nodes())
dates = list(map(ql_to_datetime, dates))
days = list(map(calc_days, dates))
df = pd.DataFrame(dict({"Date": dates, "Rate": rates, "Days" : days}))
df
The result from QuantLib is:
Date | Rate | Days | |
---|---|---|---|
0 | 2022-12-30 00:00:00 | 0.0244947 | 0 |
1 | 2023-01-03 00:00:00 | 0.0244947 | 4 |
2 | 2023-04-03 00:00:00 | 0.027174 | 94 |
Now I wish to recreate the values that Quantlib produces, given that the curve is bootstrapped with actual 365. For the first deposit I use the simple rate, $DF = \frac{1}{1+RT}$, to calculate the discount factor (I also find it interesting that the daycount convention that gives the matching result to Quantlib is given by 1/360, when my intuition tells me it should be 4/360 given the maturity date):
$$ DF_1 = \frac{1}{1+0.02416 \cdot \frac{1}{360}} \approx 0.999932893 . $$
Then the continuous zero rate becomes:
$$ r_1 = -365/1 \cdot \ln (DF_1) \approx 0.02449473. $$
Moreover, if we continue with the second rate we obtain the following discount factor:
$$ DF_2 = \frac{0.999932893 }{1+0.02701 \cdot \frac{94}{360}} \approx 0.99293014. $$
At last the continuous zero rate for the second deposit is
$$ r_1 = -365/94 \cdot \ln (DF_2) \approx 0,02754960 . $$
Thus, the results that I get by calculating the zero rates manually for the second deposit does not really match QuantLib's result so I know I am doing my calculations wrong. I have tried to dig in the c++ source code in Quantlib with no success. I have also tried to change the maturity dates in the calculations but still I have not found a matching value for the deposits. I would be glad for any help or pointers.