Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Errors / FuturesRateHelper Convexity Adjustment Yield Curve bootstrapping issue #2068

Open
is-source opened this issue Sep 11, 2024 · 2 comments

Comments

@is-source
Copy link

is-source commented Sep 11, 2024

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

Copy link

boring-cyborg bot commented Sep 11, 2024

Thanks for posting! It might take a while before we look at your issue, so don't worry if there seems to be no feedback. We'll get to it.

@is-source is-source changed the title Errors / SwapRateHelper & FuturesRateHelper Yield Curve bootstrapping issue Errors / FuturesRateHelper Convexity Adjustment Yield Curve bootstrapping issue Sep 11, 2024
@lballabio
Copy link
Owner

Looking at the code, I'd say that the convexity adjustment is a rate and should be divided by 100 to be in the correct units (like you already do with deposit rates, for instance).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants