0
$\begingroup$

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?

$\endgroup$

1 Answer 1

1
$\begingroup$

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
]
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.