-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Description
Hi,
When building a mark-to-market (MtM) cross-currency basis curve between EUR (Ester) and USD (SOFR), the MtMCrossCurrencyBasisSwapRateHelper gives unrealistic zero rates and discount factors for the long end of the curve.
The short end, calibrated using FX forwards, behaves as expected. The issue appears when extending the curve using MtMCrossCurrencyBasisSwapRateHelper.
I’m trying to build a EUR–USD MTM xccy basis curve where both indices are overnight (OIS).
For maturities up to 1Y, I use FX forwards, which produce correct and stable results.
Beyond 1Y, using MtMCrossCurrencyBasisSwapRateHelper, the resulting zero rates explode (see data below).
helper = ql.MtMCrossCurrencyBasisSwapRateHelper(
basis=ql.QuoteHandle(basisQuote),
tenor=ql.Period("2Y"),
fixingDays=2,
calendar=ql.JointCalendar(ql.TARGET(), ql.UnitedStates()),
convention=ql.ModifiedFollowing,
endOfMonth=False,
baseCurrencyIndex=ql.Estr(),
quoteCurrencyIndex=ql.Sofr(),
collateralCurve=ql.YieldTermStructureHandle(collateralCurve),
isFxBaseCurrencyCollateralCurrency=False,
isBasisOnFxBaseCurrencyLeg=True,
isFxBaseCurrencyLegResettable=True,
paymentFrequency=4,
)
| Date | TimeFromRef | ZeroRate | Discount |
|---|---|---|---|
| 27/11/2026 | 1.025 | 1969.78 | 1.7e-09 |
| 26/11/2027 | 2.036 | 1025.54 | 8.5e-10 |
| 27/11/2028 | 3.056 | 705.92 | 4.3e-10 |
| 26/11/2030 | 5.081 | 451.33 | 1.1e-10 |
| 26/11/2035 | 10.153 | 254.89 | 5.8e-12 |
I noticed the constructor for MtMCrossCurrencyBasisSwapRateHelper expects IborIndex objects for the floating legs — not OISIndex (like Ester or Sofr).
Could this mismatch be the cause of the issue when both indices are OIS? or is it an issue with my inputs?