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: 185 samples with 1 evaluation.
 Range (min … max):  26.196 ms …  33.489 ms  ┊ GC (min … max): 0.00% … 0.00%
 Time  (median):     26.670 ms               ┊ GC (median):    0.00%
 Time  (mean ± σ):   27.113 ms ± 990.672 μs  ┊ GC (mean ± σ):  1.72% ± 2.31%

    ▄█▆▃           ▂
  ▄▆████▅▄▂▃▁▁▁▁▂▅██▅█▄▃▁▃▁▁▁▁▁▁▁▁▁▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▂▁▁▁▂ ▂
  26.2 ms         Histogram: frequency by time         31.6 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: 42 samples with 1 evaluation.
 Range (min … max):  118.464 ms … 134.836 ms  ┊ GC (min … max): 1.46% … 1.29%
 Time  (median):     120.916 ms               ┊ GC (median):    2.85%
 Time  (mean ± σ):   120.861 ms ±   2.442 ms  ┊ GC (mean ± σ):  2.49% ± 0.63%

   ▃▁  ▁   ██▆
  ▇██▁▇█▇▇▇███▇▇▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▄ ▁
  118 ms           Histogram: frequency by time          135 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([]))