robust-eventstudy
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
The problem
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.
What's in it
| 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).
Install
pip install robust-eventstudy # once published
pip install robust-eventstudy[speed] # + numba: ~10x faster GARCH refits
From source (both packages, until 0.3.0/0.1.0 are on PyPI):
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.)
Quickstart: reproduce a paper number
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.2828
The 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.
What this package will tell you that others won't
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.
Roadmap (v0.2)
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).
Citation
If you use this package, please cite both the software (see CITATION.cff)
and the paper (DOI 10.21203/rs.3.rs-8323026).
License
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.
Metadata
Release files for robust-eventstudy 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| robust_eventstudy-0.1.0.tar.gz | 718.9 kB | With provenance | Details for robust_eventstudy-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| robust_eventstudy-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for robust_eventstudy-0.1.0-py3-none-any.whl |
Total release size: 751.1 kB
Release files / robust_eventstudy-0.1.0.tar.gz
| Download URL | robust_eventstudy-0.1.0.tar.gz |
|---|---|
| Size | 718.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
28fff75b7f68ae7a9820b709cd32a7499b18028c54e291c31b775e7dea437c27
|
|
BLAKE2b-256 checksum How to use checksums |
2764a87be92a6eafd7e2a8f96a85bb35a887006e4ce1cb49a5b16206763eae2a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 12, 2026.
Transparency logRelease files / robust_eventstudy-0.1.0-py3-none-any.whl
| Download URL | robust_eventstudy-0.1.0-py3-none-any.whl |
|---|---|
| Size | 32.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
738b64ed07904cfc3b2801c8667848d3c164d70088e2876ce0f278ced01ee242
|
|
BLAKE2b-256 checksum How to use checksums |
0eca86a9bec2a581b8b09a2cafdb9b90ac827bf96e3ba60f08d061e5a6a093b2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 12, 2026.
Transparency logSecurity for robust-eventstudy 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for robust_eventstudy-0.1.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 12, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.