Hypothesis
For any active binary Polymarket market, $b_Y + b_N > 1$ (sell-both arb) or $a_Y + a_N < 1$ (buy-both arb) should occur when the CLOB is stale or fragmented.
Data used
- 300 active markets, top by total volume, fetched 2026-05-20
- CLOB top-of-book for both YES and NO tokens per market
- Market IDs include high-volume events: BTC price, US elections, macro events
Sample from scanned set:
Market: "New Rihanna Album before GTA VI?"
YES: bid=0.51 ask=0.52 | NO: bid=0.48 ask=0.49
bid_Y+bid_N = 0.99 (<1 ✓) | ask_Y+ask_N = 1.01 (>1 ✓)
Method
$$\text{sell_arb} = b_Y + b_N - 1 \quad (\text{arb if} > 0)$$ $$\text{buy_arb} = 1 - a_Y - a_N \quad (\text{arb if} > 0)$$
Execution: sell YES at $b_Y$ + sell NO at $b_N$, collect $b_Y + b_N$; pay $1 at resolution (one always wins).
Size constrained to $\min(\text{depth}{b_Y}, \text{depth}{b_N})$.
Fee: 0 % taker on CLOB; net = gross.
Result
| Metric | Value |
|---|---|
| Markets scanned | 300 |
| Mean mid-sum $(m_Y + m_N)$ | 1.00000 |
| Sell-both violations | 0 |
| Buy-both violations | 0 |
| Typical half-spread | 0.001–0.005 (0.1–0.5 ¢) |
Binary markets maintain perfect $\$1$ parity. The bid-ask spread is symmetric and tight (median 0.1 ¢), leaving no room for basket arb after spread costs are embedded.
Reproduction
# type_a_results.json produced by main scanner
source ~/.pmvenv/bin/activate
python3 /mnt/projects/tnt_85c10df4451042ca/prj_c7cb91b70b2f42ac/pm_struct_arb_scanner.py
# results: /tmp/pm_data/type_a_results.json
Failure mode / next step
The scan covers only top-300 by volume. Very illiquid markets (< $100 volume/day) may show stale books where $b_Y + b_N > 1$ momentarily — but at such small depth ($<$10 units) that max profit would be cents. A future check on markets with volume < $1 k/day may find transient violations, but execution risk (partial fills, latency) would dominate.