Creating Custom Test Statistics
Simon Mueller
2026-09-06
Source:vignettes/custom-test-statistics.Rmd
custom-test-statistics.RmdIntroduction
The EventStudy package supports two types of test statistics:
- Single-event statistics – Computed for each event individually (e.g., AR t-test, CAR t-test)
- Multi-event statistics – Computed across all events in a group (e.g., Cross-Sectional t-test, Patell Z, Sign test)
Both types inherit from TestStatisticBase and implement
a compute() method. This vignette walks through creating
custom test statistics of each type.
The TestStatisticBase Interface
Every test statistic must:
- Inherit from
TestStatisticBase - Set a
namefield (short code used as column name in results) - Implement
compute(data_tbl, model)returning a tibble
For single-event tests, data_tbl contains one event’s
data and model is the fitted model for that event. For
multi-event tests, data_tbl contains all events in a group
and model is a nested tibble of all models.
Example: Wilcoxon Signed-Rank Test (Single Event)
A non-parametric test for whether abnormal returns in the event window are symmetrically distributed around zero:
library(EventStudy)
WilcoxonARTest <- R6::R6Class("WilcoxonARTest",
inherit = TestStatisticBase,
public = list(
name = "WilcoxonAR",
compute = function(data_tbl, model) {
event_data <- data_tbl %>%
dplyr::filter(event_window == 1)
ar <- event_data$abnormal_returns
# Wilcoxon signed-rank test against 0
test_result <- wilcox.test(ar, mu = 0, conf.int = TRUE)
tibble::tibble(
n_obs = length(ar),
V_statistic = test_result$statistic,
p_value = test_result$p.value,
median_ar = median(ar, na.rm = TRUE),
conf_low = test_result$conf.int[1],
conf_high = test_result$conf.int[2]
)
}
)
)Example: Kolmogorov-Smirnov Test (Multi-Event)
A non-parametric test comparing the distribution of AARs against a normal distribution:
KSTest <- R6::R6Class("KSTest",
inherit = TestStatisticBase,
public = list(
name = "KS",
compute = function(data_tbl, model) {
aar_stats <- data_tbl %>%
dplyr::filter(event_window == 1) %>%
dplyr::group_by(relative_index) %>%
dplyr::summarise(
aar = mean(abnormal_returns, na.rm = TRUE),
n_events = dplyr::n(),
n_pos = sum(abnormal_returns > 0, na.rm = TRUE),
n_neg = sum(abnormal_returns <= 0, na.rm = TRUE),
.groups = "drop"
) %>%
dplyr::mutate(caar = cumsum(aar))
# KS test of AARs against normal
ks <- ks.test(aar_stats$aar, "pnorm",
mean = 0, sd = sd(aar_stats$aar))
aar_stats %>%
dplyr::mutate(
ks_D = ks$statistic,
ks_pvalue = ks$p.value
)
}
)
)Registering Custom Statistics
Add your test statistic to a statistics set:
# Single-event: add to SingleEventStatisticsSet
single_stats <- SingleEventStatisticsSet$new()
single_stats$add_test(WilcoxonARTest$new())
# Multi-event: add to MultiEventStatisticsSet
multi_stats <- MultiEventStatisticsSet$new()
multi_stats$add_test(KSTest$new())
# Or create a custom set from scratch
custom_single <- StatisticsSetBase$new(
tests = list(ARTTest$new(), CARTTest$new(), WilcoxonARTest$new())
)Using Custom Statistics in the Pipeline
params <- ParameterSet$new(
single_event_statistics = single_stats,
multi_event_statistics = multi_stats
)
task <- EventStudyTask$new(firm_data, index_data, request_data)
task <- run_event_study(task, params)
# Results appear as columns in the task data
task$data_tbl$WilcoxonAR # single-event results
task$aar_caar_tbl$KS # multi-event resultsBuilt-in Test Statistics
The package includes the following built-in test statistics:
Single-event: - ARTTest – Abnormal
Return t-test - CARTTest – Cumulative Abnormal Return
t-test - BHARTTest – Buy-and-Hold Abnormal Return
t-test
Multi-event: - CSectTTest –
Cross-Sectional t-test (AAR/CAAR) - PatellZTest – Patell
standardized residual test - SignTest – Simple sign test -
GeneralizedSignTest – Cowan (1992) generalized sign test -
RankTest – Corrado (1989) rank test - BMPTest
– Boehmer, Musumeci & Poulsen (1991) test -
CalendarTimePortfolioTest – Calendar-time portfolio
approach
Key Points
- Inherit from
TestStatisticBase - Set a unique
namefield (becomes the column name in results) - Return a tibble from
compute() - For multi-event stats, include
relative_index,aar,caar, andcar_windowcolumns for compatibility with plotting functions - Use
add_test()to add to existing statistics sets