Dependence-robust inference toolkit for heavy-tailed cross-asset event studies
Project description
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.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file robust_eventstudy-0.1.0.tar.gz.
File metadata
- Download URL: robust_eventstudy-0.1.0.tar.gz
- Upload date:
- Size: 718.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
28fff75b7f68ae7a9820b709cd32a7499b18028c54e291c31b775e7dea437c27
|
|
| MD5 |
7519937218c31cc40aeeb017879dad6d
|
|
| BLAKE2b-256 |
2764a87be92a6eafd7e2a8f96a85bb35a887006e4ce1cb49a5b16206763eae2a
|
Provenance
The following attestation bundles were made for robust_eventstudy-0.1.0.tar.gz:
Publisher:
publish.yml on studiofarzulla/robust-eventstudy
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
robust_eventstudy-0.1.0.tar.gz -
Subject digest:
28fff75b7f68ae7a9820b709cd32a7499b18028c54e291c31b775e7dea437c27 - Sigstore transparency entry: 2147954425
- Sigstore integration time:
-
Permalink:
studiofarzulla/robust-eventstudy@cdc63f658a5887a0ae63d74469df6750bf285c8c -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/studiofarzulla
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@cdc63f658a5887a0ae63d74469df6750bf285c8c -
Trigger Event:
release
-
Statement type:
File details
Details for the file robust_eventstudy-0.1.0-py3-none-any.whl.
File metadata
- Download URL: robust_eventstudy-0.1.0-py3-none-any.whl
- Upload date:
- Size: 32.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
738b64ed07904cfc3b2801c8667848d3c164d70088e2876ce0f278ced01ee242
|
|
| MD5 |
f97ba2b9f6938ae49fc3da3d88454f0f
|
|
| BLAKE2b-256 |
0eca86a9bec2a581b8b09a2cafdb9b90ac827bf96e3ba60f08d061e5a6a093b2
|
Provenance
The following attestation bundles were made for robust_eventstudy-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on studiofarzulla/robust-eventstudy
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
robust_eventstudy-0.1.0-py3-none-any.whl -
Subject digest:
738b64ed07904cfc3b2801c8667848d3c164d70088e2876ce0f278ced01ee242 - Sigstore transparency entry: 2147954466
- Sigstore integration time:
-
Permalink:
studiofarzulla/robust-eventstudy@cdc63f658a5887a0ae63d74469df6750bf285c8c -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/studiofarzulla
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@cdc63f658a5887a0ae63d74469df6750bf285c8c -
Trigger Event:
release
-
Statement type: