-
Notifications
You must be signed in to change notification settings - Fork 0
/
README.Rmd
170 lines (124 loc) · 4.63 KB
/
README.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
---
output: github_document
---
<!-- README.md is generated from README.Rmd. Please edit that file -->
```{r setup, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
fig.path = "man/figures/README-",
out.width = "100%"
)
```
# calendarrr
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`.
## Related work
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),
which can be a major pain and raise the barrier to entry significantly. `calendarrr`
is self-contained.
- `calendarrr` tries to focus on providing a consistent and user friendly interface to the
calendar library.
## Installation
You can install the released version of calendarrr from [CRAN](https://CRAN.R-project.org) with:
``` r
# no you cannot
install.packages("calendarrr")
```
And the development version from [GitHub](https://github.com/) with:
``` r
# install.packages("devtools")
devtools::install_github("DavisVaughan/calendarrr")
```
## Example
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
<!-- implemented in your selected calendar. -->
```{r example}
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.
```{r}
# 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.
```{r}
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`.
```{r}
# 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.
```{r}
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++.
```{r}
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.
```{r}
# 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]
```