QuantLib icon indicating copy to clipboard operation
QuantLib copied to clipboard

Errors / FuturesRateHelper Convexity Adjustment Yield Curve bootstrapping issue

Open is-source opened this issue 5 months ago • 1 comments

Hi all,

I am facing an issue with bootstrapping my Bbsw3M curve. I have sourced market quotes from LSEG Refinitiv for 3M deposit, futures, and swap rates.

In using the FuturesRateHelper, specifically the convexity adjustment I receive the error:

RuntimeError: 1st iteration: failed at 5th alive instrument, pillar March 17th, 2026, maturity March 17th, 2026, reference date September 13th, 2024: root not bracketed: f[-1,1] -> [1.670495e+01,2.187378e+02]

Note that I have no issues with getting my aonia curve.

Thanks in advance for your help with these issues.

My complete code is as follows: import QuantLib as ql import refinitiv.data as rd import os import matplotlib.pyplot as plt from matplotlib.ticker import PercentFormatter

today = ql.Date(11, ql.September, 2024) ql.Settings.instance().evaluationDate = today

os.environ["RD_LIB_CONFIG_PATH"] = "./Configuration" rd.open_session()

depo_data = rd.get_data(universe = ["AUDOND=", "AUDSND=", "AUDTND=", "AUDSWD=", "AUD2WD=","AUD3WD=", "AUD3MD="], fields = "MID_PRICE")

fut_data = rd.get_data(universe= ["YBAH5", "YBAM5", "YBAU5", "YBAZ5", "YBAH6", "YBAM6", "YBAU6", "YBAZ6"], fields = ["BID", "CONVX_BIAS", "EXPIR_DATE"])

irs_data = rd.get_data(universe=["AUDQM3AB1Y=", "AUDQM3AB2Y=", "AUDQM3AB3Y=", "AUDQM3AB4Y=", "AUDQM3AB5Y=", "AUDQM3AB7Y=", "AUDQM3AB10Y="], fields = "MID_PRICE")

rd.close_session()

bbsw_helpers = []

bbsw_helpers = [ ql.DepositRateHelper( ql.QuoteHandle(ql.SimpleQuote(depo_data.loc[depo_data['Instrument']=='AUD3MD=', 'MID_PRICE'].values[0] / 100)), ql.Period(3, ql.Months), 3, ql.Australia(), ql.Following, False, ql.Actual360(), ) ]

bbsw3m = ql.Bbsw3M()

bbsw_helpers += [ ql.FuturesRateHelper( ql.QuoteHandle( ql.SimpleQuote( fut_data.loc[fut_data['Instrument'] == inst, 'BID'].values[0] ) ), start_date, bbsw3m, ql.QuoteHandle(fut_data.loc[fut_data['Instrument'] == inst, 'CONVX_BIAS'].values[0]), ql.Futures.IMM ) for inst, start_date in [ ("YBAH5", ql.Date(19, ql.March, 2025)), ("YBAM5", ql.Date(18, ql.June, 2025)), ("YBAU5", ql.Date(17, ql.September, 2025)), ("YBAZ5", ql.Date(17, ql.December, 2025)), ("YBAH6", ql.Date(18, ql.March, 2026)), ("YBAM6", ql.Date(17, ql.June, 2026)), ("YBAU6", ql.Date(16, ql.September, 2026)), ("YBAZ6", ql.Date(16, ql.December,2026)) ] ]

discount_curve = ql.RelinkableYieldTermStructureHandle() discount_curve.linkTo(aonia_curve)

bbsw_helpers += [ ql.SwapRateHelper( ql.QuoteHandle(ql.SimpleQuote(3.516/100)), ql.Period(5, ql.Years), ql.Australia(), ql.Annual, ql.Following, ql.Actual365(), bbsw3m, ql.QuoteHandle() ql.Period(0, Days), discount_curve) ]

bbsw3m_curve = ql.PiecewiseConvexMonotoneForward( 2, ql.Australia(), bbsw_helpers, ql.Actual365Fixed() ) bbsw3m_curve.enableExtrapolation()

today = bbsw3m_curve.referenceDate() end = today + ql.Period(60, ql.Years) bbsw_dates = [ ql.Date(serial) for serial in range(today.serialNumber(), end.serialNumber() + 1)] bbsw_rates = [ bbsw3m_curve.forwardRate( d, bbsw3m.maturityDate(d), ql.Actual360(), ql.Simple ).rate() for d in bbsw_dates ]

ax = plt.figure(figsize=(9, 6)).add_subplot(1, 1, 1) ax.axhline(0.0, linewidth=1, color="black") ax.set_xlim(min(bbsw_dates).to_date(), max(bbsw_dates).to_date()) ax.yaxis.set_major_formatter(PercentFormatter(1.0)) ax.plot_date([d.to_date() for d in bbsw_dates], bbsw_rates, "-")

plt.xlabel('Date') plt.ylabel('Rate') plt.title("BBSW Curve") plt.grid(True) plt.show()

For reference, the data I have obtained for deposits, futures and swaps are as follows:

Deposits Instrument MID_PRICE 0 AUDOND= 4.3 1 AUDSND= 4.25 2 AUDTND= 4.3 3 AUDSWD= 4.35 4 AUD2WD= 4.58 5 AUD3WD= 4.42 6 AUD3MD= 4.49

Futures Instrument BID CONVX_BIAS EXPIR_DATE 0 YBAH5 96.19 0.262 2025-03-13 1 YBAM5 96.48 0.482 2025-06-12 2 YBAU5 96.63 0.758 2025-09-11 3 YBAZ5 96.73 1.086 2025-12-11 4 YBAH6 96.8 1.464 2026-03-12 5 YBAM6 96.83 1.889 2026-06-11 6 YBAU6 96.84 2.359 2026-09-10 7 YBAZ6 96.81 2.871 2026-12-10

SWAPS Instrument MID_PRICE 0 AUDQM3AB1Y= 3.987 1 AUDQM3AB2Y= 3.621 2 AUDQM3AB3Y= 3.492 3 AUDQM3AB4Y= 3.475 4 AUDQM3AB5Y= 3.516 5 AUDQM3AB7Y= 3.651 6 AUDQM3AB10Y= 3.833

is-source avatar Sep 11 '24 07:09 is-source