Skip to content

What (One-liner)

Engle-Granger two-step cointegration test: do two series share a long-run equilibrium; returns t-stat / p-value / hedge ratio / spread z-score. The mandatory pre-screen for pairs trading.

How to use

Drag cointegration_v1 onto the Canvas, fill series_a and series_b (required) + optional significance (default 0.05). Output is the boolean verdict plus the full statistics.

Typical usage:

series_a = SPY prices
series_b = IVV prices        # both track the S&P 500 — should cointegrate strongly
→ is_cointegrated: True, hedge_ratio ≈ 1.0, z_score ≈ 0

Core formulas

Step 1 — OLS:   a_t = α + β · b_t + ε_t
Step 2 — ADF:   H0: ε_t has unit root (not cointegrated)
                H1: ε_t is I(0) stationary
                → p-value < significance → reject H0 → cointegrated

spread_t = a_t - α - β · b_t
z_t = (spread_t - mean(spread)) / std(spread, ddof=0)

Rounding contract (pinned by the golden):

  • t_stat / p_value / critical_values / z_score → round(4)
  • hedge_ratio / spread_mean / spread_std → round(6)

Assumptions & applicability

Assumptions: both series I(1) + linear cointegration + constant-only (no trend) + synchronised timestamps.

Fits: ETF pairs trading, cross-market arbitrage, macro long-run relations; n≥30 (n≥100 sturdier in practice).

Does not fit: HFT / tick, > 2 series (use Johansen), non-linear / regime-switching.

Input / Output contract

{series_a, series_b, significance?}{is_cointegrated, t_statistic, p_value, critical_values: {1%, 5%, 10%}, hedge_ratio, spread_mean, spread_std, current_z_score, n_observations, _method}. Details in the frontmatter.

Known limitations

  1. Pairwise only (> 2 needs Johansen)
  2. Low power at n=30; n≥100 more reliable
  3. Constant-only (no deterministic trend)
  4. No SE / CI for β
  5. No structural-break test (Gregory-Hansen unimplemented)
  6. Spread std uses ddof=0 (Bloomberg sometimes uses ddof=1)

References

Engle-Granger (1987) Nobel-winning original + Hamilton (1994) Ch.19 textbook + MacKinnon (2010) critical-value tables (used internally by statsmodels). Full citations in the frontmatter.

Golden Test

tests/golden/fixtures/tier2/cointegration/, 1e-12 tolerance (post-rounding byte-equality), 4 tests:

  • matches_reference — field-by-field byte equality vs the wrapper-mirrored reference
  • determinism — 5 reruns byte-identical
  • rejects_short_series — n<30 → error payload
  • significance_threshold_matters — significance flips is_cointegrated but leaves t_stat / p_value / hedge_ratio and other intrinsic quantities unchanged

The reference walks the same statsmodels.coint + np.linalg.lstsq OLS derivation, pinning Pangura's wrapper behaviour (input casts / rounding / design matrix / std ddof).

Changelog

  • 1.0.0 (2026-04-20) — First Active

Verifiable intelligence for the decisions that demand scrutiny.