Skip to main content

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)
note

'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"}