Modeling Overnight, Tomorrow-Next, and Spot-Next Rates in QuantLib
Summary
The document asks how to represent overnight, tomorrow-next, and spot-next foreign-exchange rate quotes when building an overnight-indexed curve in QuantLib. The proposed setup creates separate overnight indices with different settlement-day counts and assigns them to rate helpers for the three short-dated quotes. The response recommends using one overnight index for all three quotes, since the index supplies rate conventions while each OIS rate helper’s settlement days distinguish the quote dates.
An example constructs three one-day helpers with settlement lags of zero, one, and two days, then shows that the resulting curve has successive short-dated nodes. This illustrates how the quote conventions enter curve construction without requiring separate index definitions. The example is specific to the conventions and calendar shown; users must still check currency, business-day calendar, day count, valuation date, and the meaning of their market quotes before applying the pattern to another market.
Key ideas
- Use one overnight index to supply shared rate conventions for ON, TN, and SN quotes.
- Represent the different short-dated settlement conventions through each OIS helper’s settlement-day setting.
- The example shows helpers producing successive short-dated curve nodes.
- Calendar, currency, day-count, and quote conventions still need to match the market being modeled.
Tags
Full text
# How to handle ON, TN, and S/N in quantlib
# How to handle ON, TN, and S/N in quantlib
I'm wondering how to precisely handle the quote convention of ON, TN, and S/N of FX quote. How to handle these convention in quantlib.
Here is my code, is that correct?
```
settlementDays = 2 #OIS convention
discount_term_structure = ql.RelinkableYieldTermStructureHandle()
oindex_on = ql.OvernightIndex('',0,ql.USDCurrency(),calendar,ois_dayCount,discount_term_structure)
oindex_tn = ql.OvernightIndex('',1,ql.USDCurrency(),calendar,ois_dayCount,discount_term_structure)
oindex_sn = ql.OvernightIndex('',2,ql.USDCurrency(),calendar,ois_dayCount,discount_term_structure)
oindex = ql.OvernightIndex('',settlementDays,ql.USDCurrency(),calendar,ois_dayCount,discount_term_structure)
oisHelpers = []
oisHelpers.append(ql.OISRateHelper(0,ql.Period(ois_data.loc[0,'Tenor']), ql.QuoteHandle(ois_data.loc[0,'Rate_handler']),oindex_on))
oisHelpers.append(ql.OISRateHelper(1,ql.Period(ois_data.loc[1,'Tenor']), ql.QuoteHandle(ois_data.loc[1,'Rate_handler']),oindex_tn))
oisHelpers.append(ql.OISRateHelper(2,ql.Period(ois_data.loc[2,'Tenor']), ql.QuoteHandle(ois_data.loc[2,'Rate_handler']),oindex_sn))
oisHelpers = oisHelpers + [ql.OISRateHelper(settlementDays,ql.Period(ois_data.loc[i,'Tenor']), ql.QuoteHandle(ois_data.loc[i,'Rate_handler'])\
,oindex) for i in range(3,len(ois_data))]```
Tenor Rate Rate_handler
0 1D 0.0160 <QuantLib.QuantLib.SimpleQuote; proxy of <Swig...
1 1D 0.0159 <QuantLib.QuantLib.SimpleQuote; proxy of <Swig...
2 1D 0.0159 <QuantLib.QuantLib.SimpleQuote; proxy of <Swig...
3 1W 0.0159 <QuantLib.QuantLib.SimpleQuote; proxy of <Swig...
4 2W 0.0159 <QuantLib.QuantLib.SimpleQuote; proxy of <Swig...
5 3W 0.0159 <QuantLib.QuantLib.SimpleQuote; proxy of <Swig...
6 1M 0.0159 <QuantLib.QuantLib.SimpleQuote; proxy of <Swig...
7 2M 0.0158 <QuantLib.QuantLib.SimpleQuote; proxy of <Swig...
8 3M 0.0157 <QuantLib.QuantLib.SimpleQuote; proxy of <Swig...
9 6M 0.0151 <QuantLib.QuantLib.SimpleQuote; proxy of <Swig...
10 9M 0.0145 <QuantLib.QuantLib.SimpleQuote; proxy of <Swig...
11 1Y 0.0138 <QuantLib.QuantLib.SimpleQuote; proxy of <Swig...
12 2Y 0.0122 <QuantLib.QuantLib.SimpleQuote; proxy of <Swig...
13 3Y 0.0112 <QuantLib.QuantLib.SimpleQuote; proxy of <Swig...
14 4Y 0.0114 <QuantLib.QuantLib.SimpleQuote; proxy of <Swig...
15 5Y 0.0115 <QuantLib.QuantLib.SimpleQuote; proxy of <Swig...
16 6Y 0.0116 <QuantLib.QuantLib.SimpleQuote; proxy of <Swig...
17 7Y 0.0118 <QuantLib.QuantLib.SimpleQuote; proxy of <Swig...
18 8Y 0.0121 <QuantLib.QuantLib.SimpleQuote; proxy of <Swig...
19 9Y 0.0124 <QuantLib.QuantLib.SimpleQuote; proxy of <Swig...
20 10Y 0.0127 <QuantLib.QuantLib.SimpleQuote; proxy of <Swig...
21 12Y 0.0131 <QuantLib.QuantLib.SimpleQuote; proxy of <Swig...
22 15Y 0.0137 <QuantLib.QuantLib.SimpleQuote; proxy of <Swig...
23 20Y 0.0143 <QuantLib.QuantLib.SimpleQuote; proxy of <Swig...
24 25Y 0.0145 <QuantLib.QuantLib.SimpleQuote; proxy of <Swig...
25 30Y 0.0146 <QuantLib.QuantLib.SimpleQuote; proxy of <Swig...
```
## Answer by David Duarte (score 2)
https://quant.stackexchange.com/a/54851
I don't think that is the best way to implement it.
From a curve construction perspective the index for ON, SN and TN is the same and is just used to get the rate conventions.
```
index = ql.OvernightIndex('USD_ON', 0, ql.USDCurrency(), ql.UnitedStates(), ql.Actual360())
helpers = ql.RateHelperVector()
helpers.append( ql.OISRateHelper(0, ql.Period('1D'), ql.QuoteHandle(ql.SimpleQuote(0.0010)), index) )
helpers.append( ql.OISRateHelper(1, ql.Period('1D'), ql.QuoteHandle(ql.SimpleQuote(0.0015)), index) )
helpers.append( ql.OISRateHelper(2, ql.Period('1D'), ql.QuoteHandle(ql.SimpleQuote(0.0020)), index) )
import pandas as pd
pd.DataFrame([{
"earliestDate": h.earliestDate().ISO(),
"pillarDate": h.pillarDate().ISO(),
"maturityDate": h.maturityDate().ISO(),
"quote": h.quote().value()
} for h in helpers])
```
```
crv = ql.PiecewiseLogLinearDiscount(ql.Date().todaysDate(), helpers, ql.ActualActual())
crv.nodes()
```
((Date(12,6,2020), 1.0), (Date(15,6,2020), 0.9999916667361105), (Date(16,6,2020), 0.9999875001215266), (Date(17,6,2020), 0.9999819446662784))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.