Skip to content

factrix.metrics.corrado

Corrado nonparametric rank test on event abnormal returns.

Standalone metric in cell (*, SPARSE, *, PANEL) — not part of the default profile. Available via from factrix.metrics import corrado_rank_test.

factrix.metrics.corrado.corrado_rank_test

corrado_rank_test(df: DataFrame, *, factor_col: str = 'factor', return_col: str = 'forward_return') -> MetricOutput

Corrado nonparametric rank test for event abnormal returns.

A non-parametric alternative to the CAAR t-test. Robust to extreme returns, non-normal distributions, and cross-asset heteroscedasticity. Direction-adjusted for two-sided signals (extension of the original one-directional test).

Formula

For each asset \(i\), rank return across the full sample (event + non-event), transform to \(U_{i,t} = \mathrm{rank} / (T+1) - 0.5\), and on event rows form \(U_{\text{event,signed}} = U_{\text{event}} \cdot \mathrm{sign}(\text{factor})\). Test statistic \(z = \mathrm{mean}(U_{\text{event,signed}}) / (\mathrm{std}(U_{\text{all}}) / \sqrt{N_{\text{events}}})\).

Parameters:

Name Type Description Default
df DataFrame

Full panel with date, asset_id, factor, forward_return. Must include non-event rows for ranking.

required

Returns:

Type Description
MetricOutput

MetricOutput with value=mean rank deviation, stat=z.

Notes

factrix uses the pooled std of U_all across all (asset, date) cells in the denominator, instead of the time-series std of the cross-sectional mean used by Corrado (1989) eq. (5). The two coincide under iid ranks but diverge when event-date clustering is present; treat this as a robustness screen against parametric BMP / CAAR rather than a substitute for a reference event-study package when strict size control matters.

Short-circuits to MetricOutput with metadata["reason"]="insufficient_events" when N_events < MIN_EVENTS_HARD, and "degenerate_rank_variance" when std(U_all) < EPSILON.

References
  • Corrado (1989). "A Nonparametric Test for Abnormal Security-price Performance in Event Studies." Journal of Financial Economics 23(2), 385–395. The nonparametric rank test factrix implements with a pooled-std denominator simplification.
  • Corrado & Zivney (1992). "The Specification and Power of the Sign Test in Event Study Hypothesis Tests Using Daily Stock Returns." Journal of Financial and Quantitative Analysis 27(3), 465–478. Source of the direction-adjustment idea applied to two-sided signals.

Examples:

>>> import factrix as fx
>>> from factrix.preprocess import compute_forward_return
>>> from factrix.metrics.corrado import corrado_rank_test
>>> panel = compute_forward_return(
...     fx.datasets.make_event_panel(n_assets=50, n_dates=400, seed=0),
...     forward_periods=5,
... )
>>> result = corrado_rank_test(panel)
>>> result.name
'corrado_rank'

Event-study contracts

Corrado's primitive is \(\text{signed\_rank} = \text{uniform\_rank}(\text{forward\_return}) \times \text{sign}(\text{factor})\) — note that the direction adjustment is on the rank, not on the return itself. The Event-study contracts table contrasts this with caar (magnitude-weighted) and event_quality (sign-only on the raw return). The estimation_window section specifies the per-asset baseline this test ranks against.

Use cases

  • Robustness screen against parametric CAAR / BMP


    Rank-based two-sided \(z\) on event-window abnormal returns. Robust to extreme returns, non-normal distributions, and cross-asset heteroscedasticity — flips the conclusion when parametric CAAR is being driven by a handful of outliers.

  • Direction-adjusted nonparametric inference


    Ranks are sign-flipped via sign(factor) before pooling, so the test handles two-sided signals (long / short events) directly — the Corrado-Zivney (1992) extension to the original one-directional test.

Worked example — rank test alongside parametric CAAR

corrado_rank_test on a synthetic event panel

import factrix as fx
from factrix.metrics.corrado import corrado_rank_test
from factrix.metrics.caar import compute_caar, caar
from factrix.preprocess import compute_forward_return

raw   = fx.datasets.make_event_panel(
    n_assets=200, n_dates=500, event_rate=0.02,
    post_event_drift=0.004, seed=2024,
)
panel = compute_forward_return(raw, forward_periods=5)

rank_out = corrado_rank_test(panel)
print(rank_out.value, rank_out.stat, rank_out.metadata["p_value"])
# 0.041  5.18  2.2e-07   (approximate)

# Compare to parametric CAAR — divergence flags outlier-driven CAAR:
caar_out = caar(compute_caar(panel), forward_periods=5)
print(caar_out.stat, rank_out.stat)
# 6.42   5.18

See also

  • caar / bmp_test


    Parametric counterparts; read alongside Corrado for an outlier-robustness cross-check.

    api/metrics/caar →

  • clustering_diagnostic


    The pooled-std denominator factrix uses diverges from the Corrado (1989) eq. (5) form when event-date clustering is present — inspect Herfindahl-Hirschman index (HHI) before reading \(p\) at the size boundary.

    api/metrics/clustering →

  • Statistical methods


    Corrado nonparametric rank test specification and the deviation from eq. (5) factrix takes.

    reference/statistical-methods →

  • Metric applicability reference


    When this metric applies, sample-size guards, and the per-asset full-sample ranking contract.

    reference/metric-applicability →

  • Individual × Sparse landing


    Adjacent event-study metrics in the same cell.

    api/metrics/individual-sparse →