Holiday Calendars

A holiday calendar suite to integrate with the RDates library

This provides a set of the financial holiday calendars that can be integrated with RDates, the relative date library. It is built to be easy to understand but heavily optimised for integration with financial models.

Installation

HolidayCalendars can be installed using the Julia package manager. From the Julia REPL, type ] to enter the Pkg REPL mode and run

pkg> add HolidayCalendars

Basic Usage

At this point you can now start using HolidayCalendars in your current Julia session using the following command

julia> using HolidayCalendars

To work with the RDates library you then just need to use the CALENDARS calendar manager

julia> using RDates, Dates
julia> apply(rd"1b@LONDON", Date(2021,7,16), CALENDARS)
2021-07-19

Calendar Definitions

This package provides the following set of holiday calendars.

General Calendars

  • WEEKEND will mark Saturday and Sunday as holidays.

United Kingdom Calendars

  • UK/SETTLEMENT or LONDON is the bank holiday (and swap settlement) calendar for England and Wales.
  • UK/STOCK EXCHANGE or UK/LSE is the holiday calendar for the London Stock Exchange.
  • UK/METAL EXCHANGE or UK/LME is the holiday calendar for the London Metal Exchange.

European Calendars

  • TARGET is the TARGET holiday calendar.

United States Calendars

  • US/SETTLEMENT or NEW YORK is the bank holiday (and swap settlement) calendar for United States.

Benchmarks

When working with financial models, it's important to optimise the performance for high frequency of calls.

We use the cached calendar model by default so that we can perform a million calculations of holiday functions in under a second.

First we can check out the performance of calculating the number of business days within an 85 year period.

using HolidayCalendars, RDates, Dates, BenchmarkTools

d0 = Dates.Date(2015,1,1)
d1 = Dates.Date(2100,12,31)

cal = calendar(CALENDARS, "LONDON")
bizdaycount(cal, d0, d1)
res = @benchmark for _ in 1:1000000 bizdaycount(cal, d0, d1) end
println(IOContext(stdout, :compact => false), res)
BenchmarkTools.Trial: 186 samples with 1 evaluation.
 Range (min … max):  25.970 ms … 33.273 ms  ┊ GC (min … max): 0.00% … 5.87%
 Time  (median):     26.408 ms              ┊ GC (median):    0.00%
 Time  (mean ± σ):   26.908 ms ±  1.045 ms  ┊ GC (mean ± σ):  1.73% ± 2.32%

    ▇█▄          ▁▁
  ▃▅███▇▄▃▁▁▁▁▁▄▅██▆▄▁▁▁▂▁▁▂▁▁▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▂▁▁▂▁▁▁▁▁▂ ▂
  26 ms           Histogram: frequency by time        31.8 ms <

 Memory estimate: 15.26 MiB, allocs estimate: 1000000.

Next lets check out the performance of calculating the next business day.

using HolidayCalendars, RDates, Dates, BenchmarkTools

d0 = Dates.Date(2015,1,1)
d1 = rd"1b@LONDON"
res = @benchmark for _ in 1:1000000 apply(d1, d0, CALENDARS) end
println(IOContext(stdout, :compact => false), res)
BenchmarkTools.Trial: 38 samples with 1 evaluation.
 Range (min … max):  130.107 ms … 146.573 ms  ┊ GC (min … max): 1.23% … 1.13%
 Time  (median):     132.069 ms               ┊ GC (median):    2.42%
 Time  (mean ± σ):   132.300 ms ±   2.508 ms  ┊ GC (mean ± σ):  2.13% ± 0.54%

        ▂█
  ▅█▁▁▃▆███▆▃▆▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▃ ▁
  130 ms           Histogram: frequency by time          147 ms <

 Memory estimate: 76.29 MiB, allocs estimate: 5000000.

Registering a Calendar

To register a new calendar, then you can use calendar rules for defining it

HolidayCalendars.PeriodicCalendarRuleType
PeriodicCalendarRule(period::RDate, increment::RDate; include::Bool=true, cal_mgr::CalendarManager=NullCalendarManager())

A calendar rule which is generated by iterating on a period and then applying an increment. To mark the calendar rule is an exclusion then can set the include parameter to false.

julia> PeriodicCalendarRule(rd"1y", rd"1MAY+Last MON");
source
HolidayCalendars.ExplicitDateRuleType
ExplicitDateRule(;inclusions::Vector{Date}=[], exclusions::Vector{Date}=[])

A calendar rule to mark an explicit set of dates as holiday or not holidays.

source
HolidayCalendars.WindowCalendarRuleType
WindowCalendarRule(rule; from::Union{Nothing,Date}=nothing, to::Union{Nothing,Date}=nothing)

Restrict another calendar rule to within a window of [from, to].

source

You can then register these together into RuleBasedCalendar.

When registering your calendar, use setcachedcalendar! to make sure we're getting the necessary performance characteristics within financial models.

setcachedcalendar!(CALENDARS, "CAL NAME", WeekendCalendar() + RuleBasedCalendar([]))