If you do not permit any form of inference (e.g. if a user gave some dates which did not define a regular swap schedule and needed to infer stubs, or if dates were supplied with tenors like '1y1y') then I would consider a schedule to be fully defined by the following parameters:
effective: datetime,
front_stub: Optional[datetime],
back_stub: Optional[datetime],
termination: datetime,
frequency: str,
roll: int | str,
modifier: str,
calendar: list
There must be a regular schedule defined between the following dates. A regular schedule is one which has correct and fully qualified periods in every period, aligning with the roll:
- effective and termination (if there are no stubs)
- effective and back_stub (if there is no front_stub)
- front_stub and termination (if there is no back_stub)
- front_stub and back_stub (if both are given)
For the regular schedule it should be constructed by progressing forwards fron the initial date by the set number of months according to schedule and setting the date in the month according to the roll which may be numeric or something systematically defined like end-of-month or IMM date.
Once these dates have been determined (effectively unadjusted dates), they must be adjusted using a modifier and a business day calendar. This produces all values associated with a Schedule.
This is how rateslib determines schedules:
# PYTHON
from rateslib.scheduling import Schedule
s = Schedule(
effective=dt(2015, 3, 18),
termination=dt(2016, 3, 16),
frequency="q",
roll="imm",
modifier="mf",
calendar="ldn",
payment_lag=0,
)
###
freq: Q, stub: SHORTFRONT, roll: imm, pay lag: 0, modifier: mf
Period Unadj Acc Start Unadj Acc End Acc Start Acc End Payment
0 Regular 2015-03-18 2015-06-17 2015-03-18 2015-06-17 2015-06-17
1 Regular 2015-06-17 2015-09-16 2015-06-17 2015-09-16 2015-09-16
2 Regular 2015-09-16 2015-12-16 2015-09-16 2015-12-16 2015-12-16
3 Regular 2015-12-16 2016-03-16 2015-12-16 2016-03-16 2016-03-16
This page has some more info: Schedule Docs
When you start to get into inference, when the user does not supply all the necessary fields and they should be inferred from the most common options it becomes quite complex combinatorially. I try to discuss some of the choices in the chapter on Scheduling in this book: Coding Interest Rates