Pricing IBOR Interpolated Stub Periods#

Stubs on derivatives can often cause problems in derivatives pricing. The rateslib framework developed is designed to make the UI and pricing process simple. That is, an IRS, for example, has two Legs and each Leg might have two Curves for pricing; a forecasting Curve to project fixings (which is not necessary for the fixed leg), and a discounting Curve to discount the projected cashflows.

This all works well except for IBOR stub periods, which might need two forecasting curves on a Leg to project two different IBOR rates and interpolate them to derive the resultant fixing for the FloatPeriod.

If we setup a pricing model we can explore the possibilities. This model creates Euribor 1M and 3M Curves and a separate ESTR discounting Curve.

In [1]: solver = Solver(
   ...:     curves=[
   ...:        Curve({dt(2022, 1, 1): 1.0, dt(2023, 1, 1): 1.0}, id="estr"),
   ...:        Curve({dt(2022, 1, 1): 1.0, dt(2023, 1, 1): 1.0}, id="eur1m"),
   ...:        Curve({dt(2022, 1, 1): 1.0, dt(2023, 1, 1): 1.0}, id="eur3m"),
   ...:     ],
   ...:     instruments=[
   ...:         IRS(dt(2022, 1, 1), "1Y", spec="eur_irs", curves="estr"),
   ...:         IRS(dt(2022, 1, 1), "1Y", spec="eur_irs1", curves=["eur1m", "estr"]),
   ...:         IRS(dt(2022, 1, 1), "1Y", spec="eur_irs3", curves=["eur3m", "estr"]),
   ...:     ],
   ...:     s=[1.5, 1.6, 1.7],
   ...:     instrument_labels=["1Ye", "1Y1s", "1Y3s"],
   ...:     id="eur rates"
   ...: )
   ...: 
SUCCESS: `func_tol` reached after 3 iterations (levenberg_marquardt), `f_val`: 3.987399602230732e-14, `time`: 0.0120s

We now create an IRS which has 2 month stub periods at the front and back of the Instrument.

In [2]: irs = IRS(
   ...:     effective=dt(2022, 1, 15),
   ...:     termination=dt(2022, 11, 15),
   ...:     front_stub=dt(2022, 3, 15),
   ...:     back_stub=dt(2022, 9, 15),
   ...:     frequency="Q",
   ...:     fixed_rate=1.5,
   ...:     currency="eur",
   ...:     leg2_fixing_method="ibor"
   ...: )
   ...: 

If we price and risk this swap naively using the 3M IBOR curve the stub periods will be calculated from that 3M curve directly, and there is no dependence at all to the 1M curve.

In [3]: irs.rate(curves=["eur3m", "estr"], solver=solver)
Out[3]: <Dual: 1.666874, (eur3m0, eur3m1, estr0, ...), [100.4, -102.0, -0.0, ...]>

In [4]: irs.delta(curves=["eur3m", "estr"], solver=solver)
Out[4]: 
local_ccy                     eur
display_ccy                   eur
type        solver    label      
instruments eur rates 1Ye   -0.59
                      1Y1s  -0.00
                      1Y3s  80.95

In [5]: irs.cashflows(curves=["eur3m", "estr"], solver=solver)
Out[5]: 
               Type   Period  Ccy  Acc Start    Acc End    Payment Convention  DCF    Notional   DF Collateral  Rate  Spread  Cashflow      NPV  FX Rate  NPV Ccy
leg1 0  FixedPeriod     Stub  EUR 2022-01-15 2022-03-15 2022-03-17    ACT365F 0.16  1000000.00 1.00       None  1.50     NaN  -2424.66 -2417.25     1.00 -2417.25
     1  FixedPeriod  Regular  EUR 2022-03-15 2022-06-15 2022-06-17    ACT365F 0.25  1000000.00 0.99       None  1.50     NaN  -3780.82 -3755.15     1.00 -3755.15
     2  FixedPeriod  Regular  EUR 2022-06-15 2022-09-15 2022-09-17    ACT365F 0.25  1000000.00 0.99       None  1.50     NaN  -3780.82 -3741.09     1.00 -3741.09
     3  FixedPeriod     Stub  EUR 2022-09-15 2022-11-15 2022-11-17    ACT365F 0.17  1000000.00 0.99       None  1.50     NaN  -2506.85 -2474.34     1.00 -2474.34
leg2 0  FloatPeriod     Stub  EUR 2022-01-15 2022-03-15 2022-03-17    ACT365F 0.16 -1000000.00 1.00       None  1.67    0.00   2693.15  2684.92     1.00  2684.92
     1  FloatPeriod  Regular  EUR 2022-03-15 2022-06-15 2022-06-17    ACT365F 0.25 -1000000.00 0.99       None  1.67    0.00   4202.64  4174.11     1.00  4174.11
     2  FloatPeriod  Regular  EUR 2022-06-15 2022-09-15 2022-09-17    ACT365F 0.25 -1000000.00 0.99       None  1.67    0.00   4202.64  4158.48     1.00  4158.48
     3  FloatPeriod     Stub  EUR 2022-09-15 2022-11-15 2022-11-17    ACT365F 0.17 -1000000.00 0.99       None  1.67    0.00   2784.57  2748.46     1.00  2748.46

However, it is also possible, only in the case of an “ibor” fixing_method, to supply a dict of forecasting curves, from which it will interpolate the fixing using the maturity date of the tenor fixings and the end date of the period. In this format the keys of the dict are the IBOR tenors available, e.g. “3m” and the values of the dict represent the Curve objects or the Curve str ids from which will identify the Curves to be extracted from the Solver.

In [6]: irs.rate(curves=[{"3m": "eur3m", "1m": "eur1m"}, "estr"], solver=solver)
Out[6]: <Dual: 1.647258, (eur3m0, eur3m1, eur1m0, ...), [80.3, -81.6, 20.1, ...]>

In [7]: irs.delta(curves=[{"3m": "eur3m", "1m": "eur1m"}, "estr"], solver=solver)
Out[7]: 
local_ccy                     eur
display_ccy                   eur
type        solver    label      
instruments eur rates 1Ye   -0.59
                      1Y1s  16.24
                      1Y3s  64.74

In [8]: irs.cashflows(curves=[{"3m": "eur3m", "1m": "eur1m"}, "estr"], solver=solver)
Out[8]: 
               Type   Period  Ccy  Acc Start    Acc End    Payment Convention  DCF    Notional   DF Collateral  Rate  Spread  Cashflow      NPV  FX Rate  NPV Ccy
leg1 0  FixedPeriod     Stub  EUR 2022-01-15 2022-03-15 2022-03-17    ACT365F 0.16  1000000.00 1.00       None  1.50     NaN  -2424.66 -2417.25     1.00 -2417.25
     1  FixedPeriod  Regular  EUR 2022-03-15 2022-06-15 2022-06-17    ACT365F 0.25  1000000.00 0.99       None  1.50     NaN  -3780.82 -3755.15     1.00 -3755.15
     2  FixedPeriod  Regular  EUR 2022-06-15 2022-09-15 2022-09-17    ACT365F 0.25  1000000.00 0.99       None  1.50     NaN  -3780.82 -3741.09     1.00 -3741.09
     3  FixedPeriod     Stub  EUR 2022-09-15 2022-11-15 2022-11-17    ACT365F 0.17  1000000.00 0.99       None  1.50     NaN  -2506.85 -2474.34     1.00 -2474.34
leg2 0  FloatPeriod     Stub  EUR 2022-01-15 2022-03-15 2022-03-17    ACT365F 0.16 -1000000.00 1.00       None  1.61    0.00   2610.16  2602.19     1.00  2602.19
     1  FloatPeriod  Regular  EUR 2022-03-15 2022-06-15 2022-06-17    ACT365F 0.25 -1000000.00 0.99       None  1.67    0.00   4202.64  4174.11     1.00  4174.11
     2  FloatPeriod  Regular  EUR 2022-06-15 2022-09-15 2022-09-17    ACT365F 0.25 -1000000.00 0.99       None  1.67    0.00   4202.64  4158.48     1.00  4158.48
     3  FloatPeriod     Stub  EUR 2022-09-15 2022-11-15 2022-11-17    ACT365F 0.17 -1000000.00 0.99       None  1.62    0.00   2704.26  2669.19     1.00  2669.19

Notice that in this case the relevant risk sensitivity exposure has been measured against the 1M curve to which the IRS has some direct dependence.