Dependence-robust inference for heavy-tailed cross-asset event studies.
This package is the inference toolkit extracted from the analysis pipeline of:
Farzulla, M. "Do Cryptocurrency Markets Differentiate Infrastructure from Regulatory Shocks? A Multi-Moment Event Study with Dependence-Robust Inference." Under review at Digital Finance. Preprint DOI: 10.21203/rs.3.rs-8323026 Pipeline repository: studiofarzulla/crypto-event-study
Event studies on asset panels almost always violate the independence assumptions their tests import. A handful of assets (N ≈ 5–10) see the same events, their returns are heavily cross-correlated (crypto: ρ̄ ≈ 0.7), and their innovations are heavy-tailed (fitted Student-t ν ≈ 3–4). Under those conditions:
- pooling asset-event observations and bootstrapping them treats correlated observations as independent — p-values collapse toward zero;
- t-tests across per-asset coefficients are pseudoreplication — in the source paper the naive p = 0.0008 became p ≈ 0.32 under correct inference;
- parametric bootstraps with Gaussian innovations understate tail mass and bias bootstrap p-values downward;
- wild (sign-flip) bootstraps are near-degenerate for variance-equation coefficients, because ε² is sign-invariant — their tiny p-values are an artifact, not power.
robust-eventstudy packages the estimators and tests that survive these
critiques, for both moments of an event study — and keeps the known-bad
alternatives available, clearly labelled, so their optimism can be
demonstrated on your data rather than asserted.
| Module | Contents |
|---|---|
design |
EventStudyDesign: returns panel + events table → per-asset design matrices. Aggregate per-type event dummies, asymmetric pre/post windows per type (anticipation-confound control), extra regressors (e.g. sentiment), and the combined-dummy null design for restriction-imposed bootstraps. |
garch_bootstrap |
GarchXBootstrap: CCC model-based bootstrap of a GJR-GARCH-X variance-equation contrast across assets. Null-imposed p-values (the inference of record), bias-corrected basic CIs, per-asset contrast draws for design-effect calibration, and the wild bootstrap (with its warning label). Multiprocessing works under spawn and fork. |
innovations |
Innovation strategies for the parametric draws: StudentTCopulaInnovations (per-asset t marginals at the fitted ν, true t-copula with joint tail dependence — the correct default) and GaussianInnovations (the naive choice, kept to demonstrate its downward p-bias). |
returns |
Returns-leg machinery: ConstantMeanModel / MarketModel / EWMarketModel, event-level CAR aggregation, event-level block bootstrap, Ibragimov–Müller few-cluster test, Kolari–Pynnönen adjusted t, BCa intervals, DiD, minimum detectable effect. |
inference |
Closed-form corrections: Kish design effect with honest effective degrees of freedom df_eff = (N−1)/DEFF, correlation-weighted SE combination. |
io |
The paper's exact data preparation as documented functions (CoinGecko CSV loading, log/simple returns, winsorization, weekly→daily sentiment z-scores). |
The GARCH engine is gjr-garch-x
(≥ 0.3.0), whose seeded multistart estimation reproduces the research
pipeline's fits to ~4 decimal places (verified in this package's golden tests).
pip install robust-eventstudy
pip install robust-eventstudy[speed] # + numba: ~10x faster GARCH refitsFrom source (development versions):
pip install "gjr-garch-x @ git+https://github.com/studiofarzulla/gjr-garch-x@master"
pip install "robust-eventstudy @ git+https://github.com/studiofarzulla/robust-eventstudy@main"Python 3.11–3.13. (3.14 is untested upstream: parts of the scientific stack still misbehave there.)
The paper's returns-leg headline — infrastructure vs regulatory events show no distinguishable CAR difference (Δ = +7.19pp, block-bootstrap p = 0.283) — from the committed data, in ~10 lines:
import pandas as pd
from robust_eventstudy import block_bootstrap_diff, event_level_cars, im_test
from robust_eventstudy.io import load_coingecko_prices, simple_returns
# price CSVs + events.csv from github.com/studiofarzulla/crypto-event-study (data/)
returns = {s: simple_returns(load_coingecko_prices(f"data/{s.lower()}.csv"))
for s in ["BTC", "ETH", "XRP", "BNB", "LTC", "ADA"]}
events = pd.read_csv("data/events.csv")
infra = event_level_cars(returns, events[events.type == "Infrastructure"].to_dict("records"))
reg = event_level_cars(returns, events[events.type == "Regulatory"].to_dict("records"))
res = block_bootstrap_diff([e["mean_car"] for e in infra], [e["mean_car"] for e in reg])
print(f"diff = {res['diff']*100:+.2f}pp, p = {res['p_two']:.4f}") # +7.19pp, p = 0.2828The variance-leg inference of record (t-copula null-imposed bootstrap,
p = 0.322 at B=2000) runs through GarchXBootstrap:
from robust_eventstudy import EventStudyDesign, GarchXBootstrap
design = EventStudyDesign(returns_pct, events, extra_regressors=sentiment,
contrast=("Infrastructure", "Regulatory"),
start_date="2019-01-01")
boot = GarchXBootstrap(design.build()) # Student-t copula by default
obs = boot.fit_observed(seed=12345) # multistart per-asset fits
null = boot.run_null(b=2000, n_jobs=8, seed=12345 + 10_000)
print(obs.multiplier, null.p_one_sided)See tests/test_golden.py for the full reproduction of the committed
pipeline results, including exact seeds and data preparation.
The design goal is inference that doesn't overclaim. Expect:
- Null-imposed bootstrap p-values that include the estimator's finite-sample bias instead of assuming it away.
- Effective degrees of freedom reported alongside design-effect
corrections — with N=6 assets and ρ̄=0.69,
df_eff ≈ 1.1, and a t(1.1) tail is a very different animal from a normal one. - Warning labels on the seductive shortcuts: the Gaussian-innovation bootstrap and the wild bootstrap for variance coefficients are implemented, documented as biased, and kept for comparison.
- Minimum detectable effects, because a null result is only informative relative to what the design could have detected.
SizeStudy: simulate the whole inference ladder under a true null on your own panel (the paper's Table 8 / c10 machinery, generalized) — empirical size for each test rather than nominal claims.- Pre-event CAR anticipation diagnostics on the returns leg.
- Regime/break-control dummies in
EventStudyDesign(the paper's c8 battery).
If you use this package, please cite both the software (see CITATION.cff)
and the paper (DOI 10.21203/rs.3.rs-8323026).
MIT. Test fixtures under tests/data/ are copied from the
crypto-event-study
repository (MIT) at commit 1baf97c; price histories derive from CoinGecko
and sentiment aggregates from GDELT.