Schedule#

The rateslib.scheduling module generates swap schedules. Scheduling swaps is a surprisingly complex issue, especially when one wants to infer some necessary parameters from the given information. We will give examples of the basic Schedule s and further explain some of the more complicated inference patterns.

Summary#

Classes#

rateslib.scheduling.Schedule(effective, ...)

Generate a schedule of dates according to a regular pattern and calendar inference.

Methods#

rateslib.scheduling._check_regular_swap(...)

Tests whether the given the parameters define a regular leg schedule without stubs.

rateslib.scheduling._infer_stub_date(...)

Attempts to infer either a front or back stub in an unspecified schedule.

Scheduling Examples#

Regular Schedule#

A regular schedule under a generic business day calendar. Note how this swap actually starts and end on the 1st of the month but the holiday adjusted effective and termination dates are actually the 3rd and 2nd.

In [1]: schedule = Schedule(
   ...:     effective=dt(2022,1,1),
   ...:     termination=dt(2023,1,1),
   ...:     frequency="S",
   ...:     calendar="bus",
   ...:     payment_lag=1
   ...: )
   ...: 

In [2]: schedule
Out[2]: 
freq: S,  stub: SHORTFRONT,  roll: 1,  pay lag: 1,  modifier: MF
    Period Unadj Acc Start Unadj Acc End  Acc Start    Acc End    Payment
0  Regular      2022-01-01    2022-07-01 2022-01-03 2022-07-01 2022-07-04
1  Regular      2022-07-01    2023-01-01 2022-07-01 2023-01-02 2023-01-03

If the same schedule is created with the adjusted dates input as the effective and termination dates then a roll day is inferred, in this case as 2, creating a different schedule to the above.

In [3]: schedule = Schedule(
   ...:     effective=dt(2022,1,3),
   ...:     termination=dt(2023,1,2),
   ...:     frequency="S",
   ...:     calendar="bus",
   ...:     payment_lag=1
   ...: )
   ...: 

In [4]: schedule
Out[4]: 
freq: S,  stub: SHORTFRONT,  roll: 2,  pay lag: 1,  modifier: MF
    Period Unadj Acc Start Unadj Acc End  Acc Start    Acc End    Payment
0  Regular      2022-01-02    2022-07-02 2022-01-03 2022-07-04 2022-07-05
1  Regular      2022-07-02    2023-01-02 2022-07-04 2023-01-02 2023-01-03

The original schedule can be obtained by directly specifying the roll day and not relying on roll day inference.

In [5]: schedule = Schedule(
   ...:     effective=dt(2022,1,3),
   ...:     termination=dt(2023,1,2),
   ...:     frequency="S",
   ...:     roll=1,
   ...:     calendar="bus",
   ...:     payment_lag=1
   ...: )
   ...: 

In [6]: schedule
Out[6]: 
freq: S,  stub: SHORTFRONT,  roll: 1,  pay lag: 1,  modifier: MF
    Period Unadj Acc Start Unadj Acc End  Acc Start    Acc End    Payment
0  Regular      2022-01-01    2022-07-01 2022-01-03 2022-07-01 2022-07-04
1  Regular      2022-07-01    2023-01-01 2022-07-01 2023-01-02 2023-01-03

Defined Stubs#

A schedule with specifically defined stubs.

In [7]: schedule = Schedule(
   ...:     effective=dt(2021,1,1),
   ...:     termination=dt(2021,10,1),
   ...:     frequency="Q",
   ...:     front_stub=dt(2021, 2, 26),
   ...:     back_stub=dt(2021, 8, 29),
   ...:     calendar="bus",
   ...:     payment_lag=1
   ...: )
   ...: 

In [8]: schedule
Out[8]: 
freq: Q,  stub: FRONTBACK,  roll: 29,  pay lag: 1,  modifier: MF
    Period Unadj Acc Start Unadj Acc End  Acc Start    Acc End    Payment
0     Stub      2021-01-01    2021-02-28 2021-01-01 2021-02-26 2021-03-01
1  Regular      2021-02-28    2021-05-29 2021-02-26 2021-05-31 2021-06-01
2  Regular      2021-05-29    2021-08-29 2021-05-31 2021-08-30 2021-08-31
3     Stub      2021-08-29    2021-10-01 2021-08-30 2021-10-01 2021-10-04

Note that the above schedule must have a regular swap defined between stub dates. In this case the roll, inferred as 29, allows this, and the unadjusted dates are then adjusted under the business day holiday calendar to the provided stubs. Schedules that cannot be inferred validly will raise.

Stub and roll generation can also be implied if the front_stub and/or back_stub are blank. Only one side can be inferred however so with a dual sided stub at least one date must be given. In the following case “FRONT” suffices as the stub input since the specific date is given, but “LONGBACK” provides the necessary detail for inference. Without specifying roll here it would be inferred as 26, but an alternative, valid value can be forced. Invalid combinations (those that do not permit regular swaps between stub dates) raise errors.

In [9]: schedule = Schedule(
   ...:     effective=dt(2021, 1, 1),
   ...:     termination=dt(2021, 10, 1),
   ...:     frequency="Q",
   ...:     front_stub=dt(2021, 2, 26),
   ...:     stub="FRONTLONGBACK",
   ...:     roll=30,
   ...:     calendar="bus",
   ...:     payment_lag=1
   ...: )
   ...: 

In [10]: schedule
Out[10]: 
freq: Q,  stub: FRONTLONGBACK,  roll: 30,  pay lag: 1,  modifier: MF
    Period Unadj Acc Start Unadj Acc End  Acc Start    Acc End    Payment
0     Stub      2021-01-01    2021-02-28 2021-01-01 2021-02-26 2021-03-01
1  Regular      2021-02-28    2021-05-30 2021-02-26 2021-05-31 2021-06-01
2     Stub      2021-05-30    2021-10-01 2021-05-31 2021-10-01 2021-10-04
In [11]: try:
   ....:     Schedule(
   ....:         effective=dt(2021, 1, 1),
   ....:         termination=dt(2021, 10, 1),
   ....:         frequency="Q",
   ....:         front_stub=dt(2021, 2, 26),
   ....:         stub="FRONTLONGBACK",
   ....:         roll=25,
   ....:         calendar="bus",
   ....:         payment_lag=1
   ....:     )
   ....: except ValueError as e:
   ....:     print(e)
   ....: 
date, stub and roll inputs are invalid

Simple Inference#

One-sided stub inference can also be made if no stub dates are defined.

In [12]: schedule = Schedule(
   ....:     effective=dt(2021, 1, 1),
   ....:     termination=dt(2021, 7, 15),
   ....:     frequency="Q",
   ....:     stub="SHORTFRONT",
   ....:     calendar="bus",
   ....:     payment_lag=1
   ....: )
   ....: 

In [13]: schedule
Out[13]: 
freq: Q,  stub: SHORTFRONT,  roll: 15,  pay lag: 1,  modifier: MF
    Period Unadj Acc Start Unadj Acc End  Acc Start    Acc End    Payment
0     Stub      2021-01-01    2021-01-15 2021-01-01 2021-01-15 2021-01-18
1  Regular      2021-01-15    2021-04-15 2021-01-15 2021-04-15 2021-04-16
2  Regular      2021-04-15    2021-07-15 2021-04-15 2021-07-15 2021-07-16
In [14]: schedule = Schedule(
   ....:     effective=dt(2021, 1, 1),
   ....:     termination=dt(2021, 7, 15),
   ....:     frequency="Q",
   ....:     stub="LONGBACK",
   ....:     calendar="bus",
   ....:     payment_lag=1
   ....: )
   ....: 

In [15]: schedule
Out[15]: 
freq: Q,  stub: LONGBACK,  roll: 1,  pay lag: 1,  modifier: MF
    Period Unadj Acc Start Unadj Acc End  Acc Start    Acc End    Payment
0  Regular      2021-01-01    2021-04-01 2021-01-01 2021-04-01 2021-04-02
1     Stub      2021-04-01    2021-07-15 2021-04-01 2021-07-15 2021-07-16