Strategy · Medium risk · Intermediate
Statistical arbitrage
Trade pairs of correlated markets when their spread diverges from its historical mean. Directional-free in expectation, but not in reality.
Published Apr 10, 2026
The idea
Two markets are statistically linked if their prices move together over time. “Will Candidate A win Iowa?” and “Will Candidate A win the nomination?” are obvious examples — the latter strictly contains the former. When the spread between correlated markets drifts from its historical mean, a stat-arb trader bets on mean reversion.
Unlike pure arbitrage, this is not risk-free. You’re trading an empirical regularity, which can and does break.
How polybot implements it
polybot’s stat_arb strategy maintains a rolling window of price correlations in DuckDB (market_correlations table). Every scan cycle:
- For each pair
(A, B)with correlation above a threshold (default0.7over 30 days), compute the current spreadprice(A) - β·price(B)where β is the rolling hedge ratio. - Compare to the mean and std of historical spreads. Entry when
|z-score| > 2, exit when|z-score| < 0.5. - Go long the underpriced leg, short the overpriced leg (or buy NO as a short proxy on markets that don’t support shorts).
z = (current_spread - hist_mean) / hist_std
if z > 2.0: # A too rich relative to B
self.emit(Signal(a.market_id, side="NO", size=size))
self.emit(Signal(b.market_id, side="YES", size=size * beta))
Where the edge comes from
- Liquidity asymmetry. Big news hits one market first; the correlated market catches up minutes later. Stat-arb front-runs the catch-up.
- Category-level mispricing. Political markets with 5 candidates sum to > $1 or < $1 frequently; the stat-arb engine redistributes toward the correct simplex.
- Cross-venue same-event. Polymarket and Kalshi quote the “same” event with different collateral and different audiences; their prices diverge systematically.
Where it fails
- Regime change. An explicit event reveal (“Candidate A dropped out”) re-prices both sides, and your spread jumps instead of mean-reverting.
- One-sided liquidity. You get filled on the short leg but can’t find the long — a common failure mode in thin weekend sessions.
- Correlation decay. A 30-day window may hide that the correlation broke 3 days ago. polybot defends with a secondary short-window correlation check (default 3 days); if short-window correlation falls below 0.4, the pair is skipped.
Configuration
polybot strategy enable stat_arb
polybot strategy config stat_arb \
--corr-threshold 0.7 \
--window-days 30 \
--short-window-days 3 \
--entry-z 2.0 --exit-z 0.5 \
--max-pairs 25 \
--max-size-usd 300
Pairs are auto-discovered from the correlation table; you don’t enumerate them. If you want to constrain, use --category politics to scope.
FAQ
How many pairs does polybot consider? All combinations of enabled markets with short-term correlation above the threshold. The scanner prunes aggressively — at any time, typically 10–50 pairs are “hot”.
How do you short on Polymarket? There’s no real short — buying NO is functionally a short YES. polybot handles the YES/NO mapping automatically so strategies can think in “long X, short Y”.
Does this belong in live mode on day one? No. Shadow for at least 30 days. You need enough trades to validate the z-score distribution on your capital.
Is stat-arb just a worse AI-model strategy? They’re complementary. Stat-arb needs nothing but price history; AI model needs a probability prior but can trade non-correlated setups.
Source: src/polybot/strategies/stat_arb.py.
Want this strategy tuned for your book?
Cryptuon can adapt polybot strategies to your capital, risk budget, and markets. Shadow-deployed before you go live.