I have used QuantLib Python to compute 1-month forward rates from zero rates as at 05 December 2019.
My codes can be found below:
import QuantLib as ql
calendar = ql.NullCalendar()
compounding = ql.Compounded
day_convention = ql.Actual360()
valuation_date = ql.Date(5, 12, 2019)
ql.Settings.instance().evaluationDate = valuation_date
dates = [calendar.advance(valuation_date, ql.Period(n, ql.Years)) for n in range(0, 4, 1)]
zero_rates = [0.01, 0.02, 0.03, 0.05]
zero_curve = ql.ZeroCurve(dates, zero_rates, day_convention)
forward_term_structure = ql.YieldTermStructureHandle(zero_curve)
forward_term_structure.enableExtrapolation()
forward_rates_quantlib = []
value_dates = []
maturity_dates = []
discount_factor_value_dates = []
discount_factor_maturity_dates = []
year_frac_value_maturity_dates = []
for date in dates:
value_date = date
value_dates.append(value_date)
maturity_date = date + ql.Period('1M')
maturity_dates.append(maturity_date)
forward_rate = forward_term_structure.forwardRate(value_date, maturity_date, day_convention, compounding).rate()
forward_rates_quantlib.append(forward_rate)
discount_factor_value_date = zero_curve.discount(value_date)
discount_factor_value_dates.append(discount_factor_value_date)
discount_factor_maturity_date = zero_curve.discount(maturity_date)
discount_factor_maturity_dates.append(discount_factor_maturity_date)
year_frac_value_maturity_date = day_convention.yearFraction(value_date, maturity_date)
year_frac_value_maturity_dates.append(year_frac_value_maturity_date)
import pandas as pd
manual_calculation = pd.DataFrame()
manual_calculation['Value_Date'] = value_dates
manual_calculation['Discount_Factor_Value_Date'] = discount_factor_value_dates
manual_calculation['Maturity_Date'] = maturity_dates
manual_calculation['Discount_Factor_Maturity_Date'] = discount_factor_maturity_dates
manual_calculation['Year_Frac_Value_Maturity'] = year_frac_value_maturity_dates
manual_calculation['Forward_Rate_QuantLib'] = forward_rates_quantlib
forward_rates_manual = []
for i in range(0, len(manual_calculation), 1):
df_value = manual_calculation.loc[i, 'Discount_Factor_Value_Date']
df_mat = manual_calculation.loc[i, 'Discount_Factor_Maturity_Date']
year_frac = manual_calculation.loc[i, 'Year_Frac_Value_Maturity']
forward_rates_manual.append(((df_value/df_mat) - 1) * (1/year_frac))
manual_calculation['Forward_Rate_Manual'] = forward_rates_manual
import matplotlib.pyplot as plt
plt.plot(zero_rates, 'o-', label = "Spot")
plt.plot(forward_rates, 'o-', label = "1M Forward (QuantLib)")
plt.plot(forward_rates_manual, 'o-', label = "1M Forward (Manual)")
plt.legend()
As can be seen from the list forward_rates_manual
, I have tried to recompute the 1-month forward rates manually using the following formula:
where
means discount factor from value date to valuation date
means discount factor from maturity date to valuation date, where maturity date is value date plus 1 month, and
means the year fraction between value date and maturity date.
However, when I compare forward_rates_quantlib
with forward_rates_manual
, I can see slight differences arising, and I cannot seem to understand where these come from.
Grateful for any clarification, thanks.
ql.Compounded
), but in my manual computation, my mathematical formula is following a simple rate calculation mode. $\endgroup$