Skip to content
All library documents

SONIA OIS Valuation Requires Historical Overnight Fixings

Article Quant Q&A · Author: kismsu

Summary

This QuantLib discussion explains why repricing a SONIA overnight indexed swap at a later valuation date can fail when the swap has already accrued. QuantLib reports a missing index fixing for an overnight date within the elapsed period, even though the example rebuilds a flat curve for the new date. The accepted answer says to supply a fixing for each day from the swap start through the new valuation date; QuantLib then combines those observations when calculating the swap value.

The example illustrates the distinction between updating a discount or forwarding curve and providing realized overnight rates for dates that have passed. Its scope is narrow: it gives a practical data requirement for this QuantLib OIS setup, but does not explain how to obtain or validate fixings, or discuss conventions and alternative index behaviors.

Key ideas

  • A later valuation of an accrued SONIA OIS requires historical overnight index fixings for elapsed dates.
  • Rebuilding a flat curve does not replace the realized fixings needed for the accrual period.
  • The accepted answer says to provide each daily fixing since the swap start and let QuantLib compose them.

Tags

Full text
# Pricing IRS over a range of days using QuantLib


# Pricing IRS over a range of days using QuantLib












I'm trying to figure out the way to value SONIA swap over the range of days based on the example in the QuantLib Python book (which has bonds in it).

```
import QuantLib as ql

rate = 0.02
calculation_date = ql.Date(10, 12, 2021)
ql.Settings.instance().evaluationDate = calculation_date
day_count = ql.Actual365Fixed()
ois_curve = ql.FlatForward(calculation_date, rate, day_count)

curve_handle = ql.RelinkableYieldTermStructureHandle(ois_curve)

swap = ql.MakeOIS(
    swapTenor=ql.Period("1Y"),
    overnightIndex=ql.Sonia(curve_handle),
    fixedRate=ql.nullDouble(),
    fwdStart=ql.Period("0Y"),
    swapType=ql.Swap.Receiver,
    discountingTermStructure=curve_handle,
    fixedLegDayCount=day_count
)
```

As expected `print(swap.NPV()) 0`.

Now to calculate a NPV on this swap after a month (assuming the same flat curve for simplicity)

```
new_date = calculation_date + ql.Period("1M")
ql.Settings.instance().evaluationDate = new_date
new_ois_curve = ql.FlatForward(new_date, risk_free_rate, day_count)
curve_handle = ql.RelinkableYieldTermStructureHandle(new_ois_curve)
```

After calling `NPV` I get the following error

```
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
/tmp/ipykernel_10169/552115063.py in <module>
----> 1 swap.NPV()

~/miniconda3/envs/notebooks/lib/python3.9/site-packages/QuantLib/QuantLib.py in NPV(self)
   9657 
   9658     def NPV(self):
-> 9659         return _QuantLib.Instrument_NPV(self)
   9660 
   9661     def errorEstimate(self):

RuntimeError: 2nd leg: Missing SoniaON Actual/365 (Fixed) fixing for December 14th, 2021
```

I can see for instance here that the way to fix it to provide fixing for an index. The question I have here is how may data points would I need to price this OIS swap? Do I need to provide index fixing for every day between swap start date and new valuation date?

## Answer by Luigi Ballabio (score 3, accepted)

https://quant.stackexchange.com/a/70735

Yes, you need to provide index fixing for every day between the start date and the valuation date. The code will compose them.

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.