The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

Creating Custom Test Statistics

Simon Mueller

2026-10-09

Introduction

The EventStudy package supports two types of test statistics:

  1. Single-event statistics – Computed for each event individually (e.g., AR t-test, CAR t-test)
  2. 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:

  1. Inherit from TestStatisticBase
  2. Set a name field (short code used as column name in results)
  3. 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 results

Built-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

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.