Skip to content
All library documents

Generating Daily Forward Rates from a QuantLib OIS Curve

Article Quant Q&A · Author: Tomás Carrera de Souza

Summary

The note explains how to obtain a daily grid of forward rates from an interpolated overnight indexed swap curve in QuantLib. The original approach queried forward rates only at the curve’s node dates, so it returned a sparse set of values. The proposed method instead creates a daily schedule spanning the curve’s reference date through its maximum date, then requests a one-day forward rate from the curve for each schedule date.

This approach uses the curve’s existing interpolation when evaluating between nodes, avoiding a separate interpolation of the sampled forward rates. The example is built around an EONIA curve and a particular calendar and day-count convention, so users must preserve the conventions appropriate to their market and ensure the date schedule advances as intended. The discussion demonstrates the implementation idea but does not compare alternative interpolation schemes or address curve construction, calibration quality, or numerical validation.

Key ideas

  • Querying forward rates only at curve nodes yields a sparse series rather than a daily curve.
  • Create a daily date schedule across the curve’s available range and evaluate one-day forwards at each date.
  • The curve’s interpolation supplies values between input nodes, so a second interpolation of sampled forwards is unnecessary.
  • Calendar and day-count choices affect the daily forward-rate calculations.

Tags

Full text
# Getting a daily forward OIS rate curve with QuantLib in Python


# Getting a daily forward OIS rate curve with QuantLib in Python












I am trying to build a 1-day EONIA forward curve with QuantLib giving OIS yields from 1mo to 50yr as input.

My current approach consists on (i) obtaining the yield curve with `ql.PiecewiseLogCubicDiscount`; (ii) getting the forward rates with `yield_curve.forwardRate`; and (iii) interpolating the forward rates to get a daily curve (I'm using `scipy.interpolate` cubic for this).

However, I guess I might be doing something wrong, because I don't see the need to interpolate twice (first the `ql.PiecewiseLogCubicDiscount` for the yield curve and then the cubic interpolation of the forward rates). I think that there might be a way to get a daily forward curve instead of getting the forward rates at the tenors I provided in my input to then interpolate.

Does anyone know how to do something like this? I'm thinking that maybe getting daily data for the yield curve obtained from `ql.PiecewiseLogCubicDiscount` could work, but I don't know if it is possible to do that.

My code looks like this:

```
OIS_rate = [-0.474, -0.476, -0.4824, -0.486, -0.489, -0.4925, -0.5039, -0.514, -0.531, -0.5415, -0.548, -0.5375, -0.517, -0.4871, -0.4501, -0.4075, -0.363, -0.3156, -0.227, -0.12, -0.0353, -0.029, -0.052, -0.093, -0.1293]
terms = [1, 2, 3, 4, 5, 6, 9, 12, 18, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 15, 20, 25, 30, 40, 50]

calendar = ql.TARGET()
bussiness_convention = ql.ModifiedFollowing
day_count = ql.Actual360()
settlement_days_EONIA = 2
EONIA = ql.OvernightIndex("EONIA", settlement_days_EONIA, ql.EURCurrency(), calendar, day_count)

# Deposit Helper
depo_facility = -0.50
depo_helper = [ql.DepositRateHelper(ql.QuoteHandle(ql.SimpleQuote(depo_facility/100)), ql.Period(1,ql.Days), 1, calendar, ql.Unadjusted, False, day_count)]

# OIS Helper
OIS_helpers = []
for i in range(len(terms)):
    if i < 9:
        tenor = ql.Period(terms[i],ql.Months)
        rate = OIS_rate[i]
        OIS_helpers.append(ql.OISRateHelper(settlement_days_EONIA, tenor, ql.QuoteHandle(ql.SimpleQuote(rate/100)), EONIA))
    else:
        tenor = ql.Period(terms[i],ql.Years)
        rate = OIS_rate[i]
        OIS_helpers.append(ql.OISRateHelper(settlement_days_EONIA, tenor, ql.QuoteHandle(ql.SimpleQuote(rate/100)), EONIA))

rate_helpers = depo_helper + OIS_helpers

eonia_curve_c = ql.PiecewiseLogCubicDiscount(0, ql.TARGET(), rate_helpers, day_count)
#This doesn't give me a daily grid of rates, but only the rates at the tenors of my input

eonia_curve_c.enableExtrapolation()

rates_fwd = [eonia_curve_c.forwardRate(d, ql.TARGET().advance(d,1,ql.Days), day_count, ql.Simple).rate()*100 for d in eonia_curve_c.dates()]
rates_fwd

[-0.5013205348687322,
 -0.49759625549583575,
 -0.46846454432847295,
 -0.4893274862465269,
 -0.497305638893053,
 -0.49938936415339086,
 -0.5072289896701498,
 -0.5161230287393792,
 -0.5385846400502992,
 -0.5544383645075257,
 -0.5733276029449286,
 -0.5751842558616715,
 -0.5396298224269458,
 -0.47530380873128664,
 -0.39194197619440985,
 -0.28725299520226955,
 -0.17226686231897048,
 -0.06337764882502483,
 0.05217469101559402,
 0.15310894226860938,
 0.2696636782033579,
 0.3087449981915569,
 0.11321403246888906,
 -0.10714449333359966,
 -0.1991592137913223,
 -0.24303965144012452,
 -0.2836656308087271]

#This gives me only len(terms) forward rates, and I would like to get a daily grid.
```

After this, I do a cubic interpolation of the rates from `rates_fwd `, which I consider redundant since I already interpolated with the `ql.PiecewiseLogCubicDiscount`!!

Does anyone have an idea on how I can get around this?

## Answer by David Duarte (score 1)

https://quant.stackexchange.com/a/58952

The problem is that in the first step, you are only fetching the forwards for the curve nodes. You could make a daily schedule and get forwards directly from the curve for each date.

```
all_days = ql.MakeSchedule(
    eonia_curve_c.referenceDate(),
    eonia_curve_c.maxDate(),
    ql.Period('1D')
)

rates_fwd = [
    eonia_curve_c.forwardRate(d, calendar.advance(d,1,ql.Days), day_count, ql.Simple).rate()*100
    for d in all_days
]
```

Shown in full with attribution under the source's licence. Licence: CC BY-SA 4.0 (Stack Exchange)

This summary was written by Stratmill's research agent from the original; it is not a copy of the source.