knitr::opts_chunk$set( collapse = TRUE, comment = "#>", eval = FALSE )
The standard market model assumes a constant beta over the estimation window. In practice, betas can vary over time due to changing firm risk, leverage, or market conditions. The EventStudy package provides two time-varying beta models:
rmgarch)The RollingWindowModel estimates alpha and beta using a rolling OLS window over the estimation period. The parameters from the last window are used for event-window prediction.
library(EventStudy) task <- EventStudyTask$new(firm_data, index_data, request) ps <- ParameterSet$new( return_model = RollingWindowModel$new(window_size = 60) ) task <- run_event_study(task, ps)
The window_size parameter controls the width of each rolling window. A smaller window captures faster parameter changes but is noisier:
# Shorter window: more responsive but noisier rw_short <- RollingWindowModel$new(window_size = 30, min_obs = 20) # Longer window: smoother but slower to adapt rw_long <- RollingWindowModel$new(window_size = 120, min_obs = 60)
After fitting, you can inspect the time series of rolling parameters:
ps <- ParameterSet$new( return_model = RollingWindowModel$new(window_size = 60) ) task <- run_event_study(task, ps) # Access rolling parameters from the fitted model model_data <- task$data_tbl$data[[1]] model_obj <- task$data_tbl$model[[1]] stats <- model_obj$statistics # Rolling betas over the estimation window plot(stats$rolling_betas, type = "l", main = "Rolling Beta over Estimation Window", xlab = "Window Index", ylab = "Beta") abline(h = stats$beta, lty = 2, col = "red") # final beta
For each position in the estimation window, a rolling OLS regression is fit:
$$R_{firm,t} = \alpha_w + \beta_w R_{market,t} + \varepsilon_t$$
where $w$ indexes windows of size window_size.
This produces time series of $\alpha_t$, $\beta_t$, and $\sigma_t$.
The parameters from the last rolling window are used to predict expected returns in the event window.
Abnormal returns are computed as: $$AR_t = R_{firm,t} - (\hat{\alpha}{last} + \hat{\beta}{last} R_{market,t})$$
The DCCGARCHModel uses bivariate DCC-GARCH to estimate time-varying conditional correlations and covariances, yielding time-varying betas.
The DCC-GARCH model requires the rmgarch and rugarch packages:
install.packages("rmgarch")
ps <- ParameterSet$new( return_model = DCCGARCHModel$new() ) task <- run_event_study(task, ps)
# GARCH(2,1) with DCC(1,2) dcc <- DCCGARCHModel$new( garch_order = c(2, 1), dcc_order = c(1, 2) ) ps <- ParameterSet$new(return_model = dcc)
The DCC(a,b) layer models the time-varying correlation
The time-varying beta is computed from the conditional covariance matrix $H_t$: $$\beta_t = \frac{H_{12,t}}{H_{22,t}} = \frac{Cov(R_{firm}, R_{market})t}{Var(R{market})_t}$$
The last $\beta_t$ is used for event-window prediction.
DCC-GARCH models can be sensitive to:
- Very short estimation windows (use at least 200 observations)
- Extreme returns or near-constant series
- The package uses purrr::safely() internally so convergence failures produce a warning rather than an error
| Feature | RollingWindowModel | DCCGARCHModel | |---------|-------------------|---------------| | Dependencies | None (base R OLS) | rmgarch, rugarch | | Speed | Fast | Slower | | Volatility Clustering | No | Yes | | Estimation Window | 60+ obs | 200+ obs recommended | | Robustness | Very robust | May fail to converge |
For most applications, the RollingWindowModel provides a good balance of flexibility and robustness. The DCCGARCHModel is preferred when time-varying volatility clustering is important.
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.