8-k-scanner
Scan SEC 8-K disclosures across a single ticker or a watchlist using Massive's pre-parsed disclosure taxonomy. Groups the underlying rows by filing (one 8-K…
Screen every pair in a basket for cointegration on daily closes and rank the tradeable ones by spread z-score. Runs the Engle-Granger two-step on log prices, tests the residual with a Dickey-Fuller t-stat against MacKinnon 2010 critical values, estimates the Ornstein-Uhlenbeck
$ npx -y skills add rgourley/quant-garage --skill pairs-scanner --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/pairs-scannerContext preview
The summary Claude sees to decide when to auto-load this skill.
Screen every pair in a basket for cointegration on daily closes and rank the tradeable ones by spread z-score. Runs the Engle-Granger two-step on log prices, tests the residual with a Dickey-Fuller t-stat against MacKinnon 2010 critical values, estimates the Ornstein-Uhlenbeck
name: pairs-scanner description: Screen every pair in a basket for cointegration on daily closes and rank the tradeable ones by spread z-score. Runs the Engle-Granger two-step on log prices, tests the residual with a Dickey-Fuller t-stat against MacKinnon 2010 critical values, estimates the Ornstein-Uhlenbeck half-life of mean reversion, and flags out-of-sample regime shifts via a 70/30 residual std ratio. Emits per-pair hedge ratio, ADF t-stat and p-value bucket, half-life, current z-score, and a stability label. Use when a PM or stat-arb desk has a sector basket and asks "which two names are statistically tethered right now, and how wide is the spread." Requires Stocks Starter.
You hand over a basket of tickers. The skill tests every pair for cointegration, estimates the historical tempo of mean reversion, and flags pairs where the spread is currently wide enough to trade.
This is a screen, not a strategy. It tells you which pairs are worth looking at, with the statistics that back the claim: hedge ratio, Engle-Granger t-stat, OU half-life, current z-score, and an out-of-sample stability read. The trader decides sizing, execution, and stop rules from there.
are cointegrated and currently wide"
mean-reversion tempo before committing
"test pair X-Y for mean reversion", "which of these are tethered"
sector and you want the within-sector pairs read
Not for: universe-wide screens (this is O(n²); a 100-name basket is 4,950 pairs, too many to eyeball). Not for high-frequency pairs (this uses daily closes; intraday cointegration needs tick data).
Optional:
below which a pair is skipped without a cointegration test
flag
half-life bounds in trading days
Two output layers from one run.
**Layer 1: canonical JSON** matching [`output-schema.json`](./output-schema.json). Per-pair `hedge_ratio_beta`, `adf_tstat`, `cointegration_bucket`, `pvalue_upper_bound`, `half_life_days`, `z_current`, `os_std_ratio`, `stability_label`, and a `tradeable` boolean with rejection reasons when false. Top-level `tradeable[]` is sorted by |z_current| descending; `considered_but_rejected[]` is sorted by ADF t-stat.
**Layer 2: rendered table**. Two sections: TRADEABLE (widest spreads first), then CONSIDERED BUT REJECTED with per-pair rejection reasons. See [`references/rendering.md`](./references/rendering.md).
1. **Pull daily closes** for every ticker over `lookback_days * 1.6 + 21` calendar days via `/v2/aggs/ticker/{T}/range/1/day/{from}/{to}?adjusted=true`. Intersect dates so every ticker has a close on every sample date. 2. **Prefilter on log-return correlation**. |Pearson rho| below `min_correlation` means the pair doesn't co-move enough to bother testing. Skipped pairs land in `skipped_correlation[]`. 3. **Engle-Granger two-step in both directions**. OLS log(A) on log(B) and log(B) on log(A). Pick the direction whose residual has the more negative ADF t-stat (the more stationary residual). The chosen dependent goes first in the pair label. 4. **Dickey-Fuller t-stat** on the residual, no constant, lag=1. Compared against MacKinnon 2010 critical values for N=2 cointegration with constant: -3.90 (1%), -3.34 (5%), -3.04 (10%). 5. **OU half-life** from OLS of Δresidual on lagged residual. half_life = ln(2) / θ, where θ = -slope. Returned as `None` when θ ≤ 0 (no mean reversion) or the estimate falls outside [0.5, 365] days. 6. **Current z-score** = (residual_last - mean) / std. 7. **Out-of-sample stability**. Split the sample 70/30. Fit beta on the in-sample chunk, apply it to the out-of-sample chunk, compare residual std ratio. `stable` when OS std < 1.5x IS std, else `regime_shift`. 8. **Tradeable flag** requires: p-value bucket ≤ `min_pvalue`, half-life in `[min_halflife, max_halflife]`, |z_current| ≥ `z_entry`, and stability_label ≠ `regime_shift`. Any failing filter goes into `tradeable_rejections[]`.
Methodology detail lives in [`references/methodology.md`](./references/methodology.md).
retry, and the `/v2/aggs` daily endpoint conventions.
Two-section table. TRADEABLE (widest spreads first) is the headline; CONSIDERED BUT REJECTED gives the transparency that says "here's what the scan looked at and why it didn't recommend those."
One call per ticker per run.
quads). Engle-Granger is a two-variable test. A basket-wide cointegration lens would need Johansen; queued.
proper). AIC-selected augmenting lags are standard for daily equities and would sharpen edge cases; queued.
60-day residual std series would show *when* the regime shifted, not just that it did; queued.
Bootstrap CI wou
Trade like a pro. Without the terminal. View the full landing page → Quant and equity research tools that run inside Claude, or behind your own UI.
Scan SEC 8-K disclosures across a single ticker or a watchlist using Massive's pre-parsed disclosure taxonomy. Groups the underlying rows by filing (one 8-K…
Track sell-side analyst positioning on a name via Benzinga Analyst Ratings. Pulls every rating event over the lookback window, classifies each as upgrade /…
Build a clean, point-in-time, ready-to-backtest OHLCV dataset for a US equity universe across an arbitrary date window. Emits parquet plus a manifest plus an…
Bayesian Online Change-Point Detection (BOCPD) on a ticker's daily log returns. Detects points in time where the return-generating distribution changed (regime…
Single-commodity macro read. Answers "is this commodity in a winning or losing macro setup right now" and names the macro driver that dominates it. Pulls one…
Reconcile a position file against splits, dividends, and spinoffs to catch breaks before they hit P&L or T+1 settlement. Use when an operator hands over a CSV…