Expiry Calendar
An expiry calendar is used to calculate the last trading date, delivery dates and the conversion of absolute and relative futures contracts
Introduction
The expiry calendar is used with forward curves to calculate the last trading day and the delivery period of a financially traded contract. It uses expiry rules for date calculation which can be different for specific period code types.
Expiry Rules
An expiry rule is a set of instructions in English that are used to determine a date from a period code. There are a number of pre-defined words that can be used to describe the actions to take and these are described in detail below.
Each rule starts with the word go and the starting point for each calculation is the start of delivery for the period code the calculation is for.
Expiry rule syntax
The basic syntax for an expiry rule is as follows:
expiry: move (move|align)* (exception THEN (move|align)*)? ("for" periodcode)? (timelimit)?
move: (moverel|moveabs)
Relative movement
The syntax for a relative movement is as follows:
("then") "go" ("back"|"forward") t TIME ("using calendar")
TIME: ('day'|'days'|'week'|'weeks'|'month'|'months'|'quarter'|'quarters'|'season'|'seasons'|'year'|'years')
An example instruction to move back 1 day from the start of delivery using the trading calendar:
go back 1 day using calendar
Absolute movement
The syntax for an absolute movement is as follows:
("then") "go to the" ("beginning"|"end"|number suffix|lastday|"penultimate") "of the" ("previous"|"current"|"next")? TIME
lastday rule
last ([Mm]'onday'|[Tt]'uesday'|[Ww]'ednesday'|[Tt]'hursday'|[Ff]'riday'|[Ss]'aturday'|[Ss]'unday'|trading day)
'trading day' can only be used for delivery rules, e.g.
delivery starts on last trading day of the current month then go forward 2 days then align forwards
An example instruction to go to the end of the previous month:
go to the end of the previous month
Alignment
After each movement, you can optionally align the current calculated date using the following syntax:
("then")? ("align"|"align forwards")
An example instruction to go to the end of the previous month and then align to the trading calendar:
go to the end of the previous month then align
Rules for specific period codes
You can specify a period code type in the rule that will specify to use this rule specifically for those types of period codes, e.g
go to the end of the previous month then align for quarters
Time limited rules
You can specify that a rule is applicable after or before a certain point in time
go to the end of the previous month then align for quarters after 2021-01-01
Exceptions and complex rules
Sometimes, the trading rules for a calendar include some complex rules that determine when trading of a certain product ceases. These can be mostly handled using an except if or an unless clause in the expiry rule. The except clause syntax is as follows
except if (exception information) then
The unless clause syntax is as follows
unless (exception information) then
The difference between an except if and an unless clause is the starting date that the exception clause uses:
Except if
The date tested in the exception clause is the calculated date after any preceeding clauses have been executed.
Unless
The date tested in the exception clause is the original start-of-delivery date, therefore ignoring any preceeding clauses. If the unless exception is true, then the date is reset to the original start-of-delivery date.
Example of except if versus unless
Consider the following 2 rules:
Unless Rule
go back 1 days using calendar unless there is a non-business day within 1 day before then go to the end of the current day using calendar
Except if Rule
go back 1 days using calendar except if there is a non-business day within 1 day before then go to the end of the current day using calendar
Using a contract with a start date of Monday 23rd October 2023
- The unless clause will create an expiry date of the 23rd October 2023.
- The except if clause will create an expiry date of the 20th October 2023.
Using a contract with a start date of Tuesday 24th October 2023
- The unless clause will create an expiry date of the 23rd October 2023.
- The except if clause will create an expiry date of the 23rd October 2023.
Proximity to a holiday date
The exception information can involve proximity to a holiday day:
there is a holiday (within)? t time (before|after)
This checks to see if there is a holiday day either within or specifically on a number of days/weeks before or after.
e.g.
... except if there is a holiday within 7 days after then ...
Proximity to a non-business date
The exception information can involve proximity to a non-business day:
there is a non-business day (within)? t time (before|after)
This checks to see if there is a non-business day either within or specifically on a number of days/weeks before or after.
e.g.
... except if there is a non-business day within 7 days after then ...
The week/month/quarter/season/year ends on a specific day
You can make an exception for when the period ends on a specific day:
the last day of the (week|month|quarter|season|year) is a DOW
e.g.
... except if the last day of the month is a Monday then ...
The week/month/quarter/season/year starts on a specific day
You can make an exception for when the period starts on a specific day:
the first day of the (week|month|quarter|season|year) is a DOW
e.g.
... except if the first day of the month is a Monday then ...
Delivery Rules
You can override the logic for calculating the start and end of delivery for specific period codes using the delivery rule syntax:
delivery (starts|ends) (on)? (at)? (the)? moveperiod (move|align)* (for periodcode)? (timelimit)?;
moveperiod: ("beginning"|"end"|date suffix) "of the" ("previous"|"current"|"next")? TIME
An example for ICE Low Sulphur Gasoil Futures where the start of delivery is always the 16th of the delivery month:
delivery starts on the 16th of the current month
Delivery rules use the delivery calendar if provided, otherwise they use the trading calendar.
Creating an expiry calendar
To create an expiry calendar and add your specific expiry rules to it, use the ExpiryCalendar function with a daily, business or holiday calendar as the trading calendar.
The trading calendar is used to calculate the expiry and delivery dates for any period code.
eombus = ExpiryCalendar(BusinessCalendar())
eombus.addRule("go to the end of the previous month then align")
The example above creates an expiry calendar using a business calendar where the expiries for all period codes is the last business day of the month prior to delivery.
You can also specify a separate delivery calendar which will be used to calculate the delivery start and end dates.
eombus = ExpiryCalendar(BusinessCalendar(), "#HENG")
Saving and re-using your calendar
Once you have created your expiry calendar, you can save it to the expiry calendar service using the save command on the expiry service as follows:
save ${expiry:my_calendar}
Now, whenever you need to use your calendar in a script, you can simply use the active variable which will read your calendar from the expiry calendar service as follows:
cal = ${expiry:"my_calendar"}