Calendar effects are part of the
model specification. In seasight, they are therefore
treated as explicit candidate choices rather than hidden package data.
This keeps the package focused on model search, diagnostics and
reporting while leaving production calendars under the control of the
user or institution.
The practical rule is:
seasonal built-ins for standard effects
where possible;build_user_xreg() for institution-supplied
moving-holiday dates;td_candidates;with_td, td_name and the report’s
“TD regressor” column.seasight intentionally does not ship broad holiday
datasets such as holiday or chcal. National
holidays, bridge days, school calendars, religious holidays and trading
calendars are source- and sector-specific. A generic bundled calendar
can easily be wrong for a production series.
For Easter, the simplest path is usually to let X-13 handle the
effect through the model specification. seasight exposes
this through include_easter.
library(seasight)
library(seasonal)
y <- AirPassengers
res_easter <- auto_seasonal_analysis(
y = y,
include_easter = "auto",
engine = "auto"
)
res_easter$table[1, c(
"model_label", "with_easter", "easter_window", "with_td", "td_name",
"score_100"
)]In "auto" mode, X-13 tests whether Easter improves the
model and selects among its supported Easter windows. The result columns
report the effect actually retained, not merely the requested mode. Use
include_easter = "always" only when the effect is part of
the production policy for that series; this fixes
easter[easter_len]. Use include_easter = "off"
when Easter is known to be irrelevant or is handled elsewhere; this
disables both inclusion and testing.
For working-day or trading-day effects, many institutions already maintain calendar regressors. Pass those directly as a named list. The names are carried through into the candidate table and HTML report.
dates <- seq(as.Date("1949-01-01"), by = "month", length.out = length(y))
days_in_month <- function(date) {
first <- as.Date(format(date, "%Y-%m-01"))
next_month <- seq(first, by = "month", length.out = 2)[2]
as.integer(next_month - first)
}
length_of_month <- vapply(dates, days_in_month, integer(1))
td_len <- ts(length_of_month - mean(length_of_month), start = start(y), frequency = frequency(y))
res_td <- auto_seasonal_analysis(
y = y,
td_candidates = list(length_of_month = td_len),
td_usertype = "td",
include_easter = "auto",
engine = "auto"
)
res_td$table[1, c("model_label", "with_td", "td_name", "td_p", "score_100")]The example above is deliberately simple. In production, the regressor should come from the relevant business, statistical or national-accounts calendar.
build_user_xreg()For holidays with known dates, such as Diwali, Lunar New Year,
Ramadan-related effects or local events, use
build_user_xreg(). Internally this uses
seasonal::genhol() and then aligns the resulting regressor
to the target series.
diwali_dates <- as.Date(c(
"2018-11-07", "2019-10-27", "2020-11-14", "2021-11-04",
"2022-10-24", "2023-11-12", "2024-11-01"
))
cny_dates <- as.Date(c(
"2018-02-16", "2019-02-05", "2020-01-25", "2021-02-12",
"2022-02-01", "2023-01-22", "2024-02-10"
))
holiday_xreg <- build_user_xreg(
y = y,
holidays = list(
diwali = list(dates = diwali_dates, start = -7, end = 0),
lunar_new_year = list(dates = cny_dates, start = -3, end = 3)
),
td_usertype = "holiday"
)
names(holiday_xreg)
res_holiday <- auto_seasonal_analysis(
y = y,
td_candidates = holiday_xreg,
include_easter = "auto",
engine = "auto"
)
res_holiday$table[1, c(
"model_label", "with_td", "td_name", "with_easter", "easter_window",
"td_p", "score_100"
)]For SEATS candidates with user regressors, X-13 needs future
regressor values over its forecast horizon. seasight pads
pulse-type holiday regressors with zeros for this purpose. For non-pulse
regressors, such as trading-day counts, provide future calendar values
yourself where possible.
The candidate table and the HTML report show which calendar option
was selected. The final “Top candidates” table includes a “TD regressor”
column with either the candidate name, such as diwali, or
none.
sa_report_html(
y = y,
td_candidates = holiday_xreg,
include_easter = "auto",
title = "AirPassengers calendar-regressor example",
outfile = tempfile(fileext = ".html")
)This makes the calendar decision auditable: a reviewer can see whether no calendar regressor was used, whether Easter was included, and which user-supplied holiday candidate won.