An R frontend to the QuantLib Calendar API
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
fig.path = "man/figures/README-",
out.width = "100%"
)
The goal of calendarrr
is to enhance the current ecosystem of date manipulation packages
out there, mainly lubridate
, by adding date calculation methods that respect
customizable business days and holidays.
calendarrr
provides an R frontend to the QuantLib
Calendar
library. This package shamelessly rips out sections of QuantLib
corresponding
to calendar calculations, and exposes them as the S3 class, calendar
.
The RQuantLib
package exposes some of this as well, but in a different form
and as a subset of a larger purpose of exposing the entire QuantLib
library.
There are a few benefits of calendarrr
vs RQuantLib
.
RQuantLib
does not have the ability to add custom holidays.RQuantLib
requires that you install QuantLib
yourself (at least on Mac),calendarrr
calendarrr
tries to focus on providing a consistent and user friendly interface to theYou can install the released version of calendarrr from CRAN with:
# no you cannot
install.packages("calendarrr")
And the development version from GitHub with:
# install.packages("devtools")
devtools::install_github("DavisVaughan/calendarrr")
Easily create a calendar with cal_create()
. Provide it the name of the QuantLib
calendar you want to create. There are ~30 calendars, each with their own
unique holiday schedule (not all implemented yet).
Use cal_add_holidays()
to add custom holidays on top of the holidays already
library(calendarrr)
library(magrittr)
# some random days to add as extra holidays
extra_holidays <- as.Date(c("2018-01-02", "2018-01-04"))
usa <- cal_create("UnitedStates") %>%
cal_add_holidays(extra_holidays)
usa
You can check if a certain date is a holiday, weekend, business day, or the end of the month.
# A Tuesday
today <- as.Date("2018-07-31")
custom_holiday <- as.Date("2018-01-02")
cal_is_business_day(dates = today, cal = usa)
cal_is_end_of_month(today, usa)
cal_is_holiday(today, usa)
cal_is_holiday(custom_holiday, usa)
cal_is_weekend(today, usa)
You can "adjust" a date relative to a calendar and a business day convention. Adjusting moves a date to the next/previous business day if it is not already a business day.
a_saturday <- as.Date("2018-07-28")
# Adjusts to next monday
cal_adjust(a_saturday, usa, convention = "following")
# Adjusts to previous friday
cal_adjust(a_saturday, usa, convention = "preceding")
You can "advance" a date relative to a calendar and business day convention.
Advancing moves a date by a length
+ unit
to the next business day. For example, 1 day
.
# Shift 5 business days forward
# (1 business week in this case because there were no holidays)
cal_advance(today, usa, n = 5, unit = "days")
# What if this was around a holiday? Say, July 4th?
# July 4th was a Wednesday
july_4 <- as.Date("2018-07-04")
july_2_monday <- july_4 - 2
# Moves forward 5 business days, ignoring July 4th
cal_advance(july_2_monday, usa, n = 5, unit = "days")
# You can go backwards too
cal_advance(july_2_monday, usa, n = -5, unit = "days")
# Also, note that the default calendar does not include July 4th as a holiday,
# but the UnitedStates one does. Here is the default:
cal_advance(july_2_monday, n = 5, unit = "days")
There is also a handy cal_end_of_month()
function.
cal_end_of_month(as.Date("2018-01-15"), usa)
All functions are vectorized, of course, and are blazing fast because they are written in C++.
lub_end_of_month <- function(x) {
d <- lubridate::days_in_month(x)
m <- lubridate::month(x)
y <- lubridate::year(x)
lubridate::make_date(y, m, d)
}
dates <- as.Date("2018-01-01") + 1:1000
microbenchmark::microbenchmark(
cal_end_of_month(dates, usa),
lub_end_of_month(dates)
)
Also note that the results of these are not equivalent, as cal_end_of_month()
again respects business days and will not allow the end of the month to fall
on a business day or holiday. For example, 2018-03-31
is a Saturday.
# Respects business day and says the "end of month" is the last business day
# in March
cal_end_of_month(dates, usa)[59]
# Just goes to the end of the month
lub_end_of_month(dates)[59]