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();
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 datefrequency
, the frequency used to create the schedulerollConvention
, 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.