Skip to content
All library documents

Separate Fixing and Accrual Calendars in QuantLib OIS Helpers

Article Quant Q&A · Author: konst1989

Summary

The note describes a QuantLib modeling issue for SOFR overnight indexed swaps: SOFR fixings follow the US Government Bond market calendar, while the swap’s accrual and payment dates use the Federal Reserve calendar. It asks whether an OIS rate helper can accept separate calendars for fixing and accrual, since supplying an index with the desired calendar also changes the helper’s calculated start and maturity dates.

A code example creates overnight indices using each calendar and compares the resulting helper dates. The question also highlights a rate impact when a fixing is unavailable: the intended behavior is to compound using the last available fixing over the relevant period. No answer or workaround is included, so the document identifies the calendar and compounding requirements without establishing which implementation best reproduces them. The example is specific to SOFR but notes the issue may apply to other indices.

Key ideas

  • SOFR fixing dates and OIS accrual dates may follow different business calendars.
  • Changing an index calendar can affect the rate helper’s calculated effective and maturity dates.
  • Missing fixings are expected to use the last available fixing over the relevant compounding period.
  • The document poses the implementation problem but does not provide a verified workaround.

Tags

Full text
# QuantLib OISRateHelper Accrual and Fixing different calendars


# QuantLib OISRateHelper Accrual and Fixing different calendars












My question is specific to SOFR OIS swaps, but can be extended to other cases, where relevant: SOFR fixings (SOFRRATE Index) operate on GT (US govt bond mkt) calendar, while SOFR OIS swaps operate on FD (US Fed Reserve calendar). When using `OISRateHelper`, to get the object to have the correct start and end dates, I have to feed a custom-made index that is based on the FD calendar, rather than the correct GT calendar. This also has a downstream effect of the rate being slightly off as the expected logic when a fixing doesn't exist, is to compound over the relevant period using the last available fixing. Is there a way to specify to OISRateHelper a fixing calendar that is different from the accrual calendar? Is there a workaround available that reflects the expected behavior correctly?

```
import QuantLib as ql

calculation_date = ql.Date(17, 4, 2025)
ql.Settings.instance().evaluationDate = calculation_date

cal_FD = ql.UnitedStates(ql.UnitedStates.FederalReserve)
cal_GT = ql.UnitedStates(ql.UnitedStates.GovernmentBond)

yts_FD = ql.RelinkableYieldTermStructureHandle()
yts_GT = ql.RelinkableYieldTermStructureHandle()

idx_FD = ql.OvernightIndex("USD ON Test", 0, ql.USDCurrency(), cal_FD, ql.Actual360(), yts_FD)
idx_GT = ql.OvernightIndex("USD ON Test", 0, ql.USDCurrency(), cal_GT, ql.Actual360(), yts_GT)

swaps = {ql.Period("1W"): 1/100,}
tenors = list(swaps.keys())
quotes = [ql.SimpleQuote(swaps[k]) for k in tenors]
handles = [ql.QuoteHandle(quote) for quote in quotes]

def create_rate_helpers(idx):
    rate_helpers = []
    for quote, tenor in zip(handles, tenors):
        helper = ql.OISRateHelper(2, tenor, quote, idx, endOfMonth=False, 
                                fixedCalendar=cal_FD, paymentCalendar=cal_FD)
        rate_helpers.append(helper)
    
    return rate_helpers

rate_helpers_FD = create_rate_helpers(idx_FD)
rate_helpers_GT = create_rate_helpers(idx_GT)

print(rate_helpers_FD[0].earliestDate())
print(rate_helpers_GT[0].earliestDate())

print(rate_helpers_FD[0].maturityDate())
print(rate_helpers_GT[0].maturityDate())
```

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.