Schedules

A common problem in finance is the derivation of a schedule of dates. The schedule is generally used to determine accrued interest and payments.

A classic case is the interest rate swap, which typically accrues and pays interest on a regular basis. For example, a swap might accrue and pay interest every 3 months.

Building a schedule is conceptually simple, however the devil is in the detail. How should the end-of-month be handled? What about following a specific pattern like “the 3rd Wednesday of the month”? Should dates be adjusted to valid business days? What happens when trying to divide 22 months into 3 month units?

To manage this complexity, a schedule builder is used.

Schedule Builder

The strata-basics project includes a schedule builder that provides a powerful mechanism to create schedules. The key class is PeriodicSchedule which is used to create a Schedule.

The difference between the two is that PeriodicSchedule describes the schedule in terms of rules, whereas Schedule contains the actual expanded schedule periods.

The PeriodicSchedule class contains the following mandatory items:

  • startDate, the start of the first schedule period.
  • endDate, the end of the last schedule period.
  • frequency, regular periodic frequency to use.
  • businessDayAdjustment, the business day adjustment to apply.

The following optional items are also available to customize the schedule:

  • startDateBusinessDayAdjustment, overrides the business day adjustment to be used for the start date.
  • endDateBusinessDayAdjustment, overrides the business day adjustment to be used for the end date.
  • stubConvention, convention defining how to handle stubs.
  • rollConvention, convention defining how to roll dates.
  • firstRegularStartDate, start date of the first regular schedule period, which is the end date of the initial stub.
  • lastRegularEndDate, end date of the last regular schedule period, which is the start date of the final stub.

Using a PeriodicSchedule involves setting the mandatory items and as many optional ones as desired. For example:

    // example swap using builder
    PeriodicSchedule definition = PeriodicSchedule.builder()
        .startDate(LocalDate.of(2014, 2, 12))
        .endDate(LocalDate.of(2015, 3, 31))
        .businessDayAdjustment(BusinessDayAdjustment.of(
                BusinessDayConventions.MODIFIED_FOLLOWING, GlobalHolidayCalendars.EUTA))
        .frequency(Frequency.P3M)
        .stubConvention(StubConvention.LONG_INITIAL)
        .rollConvention(RollConventions.EOM)
        .build();
    Schedule schedule = definition.createSchedule();
Note: If the `PeriodicSchedule` contains an invalid definition, then an exception will be thrown when creating the schedule.

Frequency

The schedule is based on a periodic frequency. This determines how many periods there are in a year.

For example, there might be four periods per year, which results in a periodic frequency of “3 months”. (Note that this can also be referred to as “quarterly”).

The periodic frequency is represented by the Frequency class. Constants are provided for all the common periodic frequencies.

As a special case, there is a periodic frequency of ‘Term’. This value means that the schedule is not to be divided. Instead, the result will be a Schedule containing a single period matching the “term” of the input.

Stubs

When creating the schedule, each date between the start date and end date is allocated into a period. Most dates are allocated into a regular period, based on the periodic frequency. Any dates left over are allocated to a stub, either at the start or end.

For example, a 15 month swap can be neatly divided into 5 regular periods of 3 months each.

      |          15 months between start and end dates            |
start |-----------|-----------|-----------|-----------|-----------| end
 date | 3 months  | 3 months  | 3 months  | 3 months  | 3 months  | date
      | (regular) | (regular) | (regular) | (regular) | (regular) |

However, a 14 month swap cannot be split evenly into 3 month periods. Instead, there will be a number of regular periods and a stub.

One option is to have an initial stub of 2 months, known as short initial:

      |          14 months between start and end dates            |
start |-----------|-----------|-----------|-----------|-----------| end
 date | 2 months  | 3 months  | 3 months  | 3 months  | 3 months  | date
      | (stub)    | (regular) | (regular) | (regular) | (regular) |

Another option is to have an initial stub of 5 months, known as long initial:

      |          14 months between start and end dates            |
start |-----------|-----------|-----------|-----------|-----------| end
 date |       5 months        | 3 months  | 3 months  | 3 months  | date
      |       (stub)          | (regular) | (regular) | (regular) |

Another option is to have an final stub of 2 months, known as short final:

      |          14 months between start and end dates            |
start |-----------|-----------|-----------|-----------|-----------| end
 date | 3 months  | 3 months  | 3 months  | 3 months  | 2 months  | date
      | (regular) | (regular) | (regular) | (regular) | (stub)    |

Another option is to have an final stub of 5 months, known as long final:

      |          14 months between start and end dates            |
start |-----------|-----------|-----------|-----------|-----------| end
 date | 3 months  | 3 months  | 3 months  |       5 months        | date
      | (regular) | (regular) | (regular) |       (stub)          |

Note that it is possible, although rare, to have a stub at the start and end.

The PeriodicSchedule class allows the stub to be controlled in two main ways.

The most convenient approach is to use a StubConvention. This has eight possible values:

  • ‘ShortInitial’
  • ‘LongInitial’
  • ‘SmartInitial’
  • ‘ShortFinal’
  • ‘LongFinal’
  • ‘SmartFinal’
  • ‘None’
  • ‘Both’

The initial and final values correspond to the descriptions and diagrams above and fully define the stub required. The ‘SmartInitial’ convention will use ‘LongInitial’ rules when the stub is less than 7 calendar days and ‘ShortInitial’ rule when the stub is 7 days or longer. The ‘SmartFinal’ convention will use ‘LongFinal’ rules when the stub is less than 7 calendar days and ‘ShortFinal’ rule when the stub is 7 days or longer. The ‘None’ value specifies that there must be no stub, with an exception thrown if a stub is needed. The ‘Both’ value specifies that there are two stubs, for which dates must be specified.

The second approach to defining stubs is to specify one or two additional dates. The firstRegularStartDate is the start date of the first regular schedule period. This is also the end date of the initial stub. The lastRegularEndDate is the end date of the last regular schedule period. This is also the start date of the final stub.

If neither the stub convention nor stub dates are set, then the stub convention is implicitly set to be ‘None’, and no stubs are allowed.

Roll Convention

When building the schedule, there is a standard approach to creating the regular periods. In most cases, the schedule is based on a whole number of months - 1, 2, 3, 4, 6 or 12. In this case, the standard approach is to move to the same day-of-month. For example, if the first date is the 15th January, then adding 3 months will result in the 15th April.

Where the periodic frequency is week-based, the standard approach is to move to the same day-of-week. For example, if the first date is a Tuesday, then adding 2 weeks will result in a date on Tuesday 2 weeks later.

A RollConvention can be specified to override the standard approach.

The most common override is to specify ‘EOM’ which means “end-of-month”. The full definition of ‘EOM’ is to prefer end-of-month if there is a choice, otherwise use the numered day-of-month. The choice occurs when the first date is something like the 30th June - should it roll on the 30th of each month, or the last day of each month? Using the ‘EOM’ convention selects rolling on the last day of the month. For example, if the first date is the 30th June, then adding 1 month will result in the 31st July. But note that if the first date is the 12th June, then rolling will occur on the 12th of each month (as it only prefers end of month if there is a choice, and in this case there is no choice).

The second most common override is to specify ‘IMM’, which causes the dates to be on the 3rd Wednesday of each month. Other similar roll conventions exist for related rolling rules.

Date Adjustments

The schedule is always built initially using unadjusted dates. This means that date addition is performed ignoring holidays and weekends.

When the schedule of unadjusted dates is fully determined, date adjustments are applied to convert each schedule date to valid business day.

The businessDayAdjustment, startDateBusinessDayAdjustment and endDateBusinessDayAdjustment properties of the PeriodicSchedule builder are used to control the adjustment.

Schedule

The resulting Schedule class contains three items:

  • periods, the list of schedule periods, each with a start and end date
  • frequency, the frequency used to create the schedule
  • rollConvention, the roll convention used to create the schedule

The Schedule can also be used as the ScheduleInfo needed by a day count.

Methods are provided to merge and split the periods of the schedule. For example, if a schedule is created with a 3 month regular periodic frequency, it is possible to later split a period into a 1 month periodic frequency, or combine periods to make a 6 month periodic frequency.