Hypothesis
A symmetric MM posting width=0.002 quotes on the BTC-hit-$1M binary market captures positive spread PnL with Sharpe > 0.5 over 30 days, because the market is mean-reverting in a tight range (0.483–0.497) with a real CLOB spread of 0.003.
Data used
- Endpoint:
GET https://clob.polymarket.com/prices-history?market=<token_id>&interval=max&fidelity=1 - Market:
will-bitcoin-hit-1m-before-gta-vi-872, YES token105267568073659068217311993901927962476298440625043565106676088842803600775810 - 4,260 observations, 2026-04-20 → 2026-05-20 (30 days), median interval 600 s
- Live book (2026-05-20): best bid=0.490, best ask=0.493, spread=0.003, mid=0.4915
- Sample rows: | t | p | |---|---| | 1776718843 | 0.4915 | | 1776726011 | 0.4920 | | 1776736804 | 0.4910 | | 1776751232 | 0.4915 | | 1776758436 | 0.4905 |
Method
Symmetric MM quotes: $b = m_t - 0.001$, $a = m_t + 0.001$ (width $w=0.002$). Depth $d$ USD per side. Fill rule: crossing-price (see harness note). Maker fee = 0%. Inventory limit $5,000 USD.
Width × Depth PnL grid (BTC $1M, 30-day PnL in USD):
| width \ depth | $50 | $200 | $1000 |
|---|---|---|---|
| 0.001 | +0.49 | +1.97 | -15.74 |
| 0.002 | +4.98 | +19.91 | +58.35 |
| 0.005 | +0.39 | +1.57 | +7.85 |
| 0.010 | +0.20 | +0.78 | +3.91 |
| 0.020 | 0.00 | 0.00 | 0.00 |
Width × Depth Sharpe grid (BTC $1M, annualised):
| width \ depth | $50 | $200 | $1000 |
|---|---|---|---|
| 0.001 | 0.112 | 0.112 | -0.155 |
| 0.002 | 0.971 | 0.971 | 0.695 |
| 0.005 | 0.285 | 0.285 | 0.285 |
| 0.010 | 0.095 | 0.095 | 0.095 |
Best config (w=0.002, d=$200) detail: - Fills: 120 total (62 bid / 58 ask) — near-balanced, 2.8% of ticks - Gross spread capture (theoretical): $49.01 - Cash: −$750.99 | Inventory MTM: $770.90 - Max |inventory|: $1,751.60 USD - Return on max capital: 19.91 / 1751.60 = 1.14% / 30d → ~13.7% annualised - Sharpe (annualised, time-weighted): 0.971
Adverse selection comparison (PSG Champions League — FAIL): - Market trended 0.165 → 0.585 (directional move, 42pp in 30d) - ALL 21 configs negative; best: w=0.005 → −$47.68 gross, −$238.39 on $1000 depth - Adverse selection mechanism: rising price fills our asks → we go short → pay mark-up at close
Result
- BTC $1M: EV > 0 net of fees at w=0.002. Sharpe 0.971 (below 1.0). Return on max capital 13.7% annualised.
- PSG CL: All configs FAIL due to directional adverse selection. Spread capture ($108) swamped by inventory loss ($555+).
- Colorado NHL (w=0.001): +$366 apparent profit but dominated by directional inventory gain (price +20pp); NOT robust spread capture.
Key sensitivity: BTC profits only at widths ≤ 0.01 (market range = 0.014; wider quotes never fill). PSG losses scale linearly with depth.
Reproduction
source ~/.pmvenv/bin/activate
# Single config:
python3 /home/workspace/pm_mm_backtest.py --market btc_1m --width 0.002 --depth 200
# Full sweep:
python3 /home/workspace/pm_mm_backtest.py --sweep
# Results CSV: /tmp/pm_data/sweep_results.csv
Failure mode / next step
- Fill model overcount: crossing-price fills ≈ 3× more than real in a mean-reverting market; true Sharpe likely 0.3–0.5 range. Next: validate against Polymarket trade-auth API to get real taker flow.
- Inventory cap missing in live trading: the $5,000 max inventory cap is a soft control; without hedging (e.g., correlated NO token), the MM has uncapped binary resolution risk.
- Queue position: we assume top-of-book priority; in reality other MMs compete at the same tick. Effective fill rate could be 5–10× lower.
- Single 30-day window: n=120 fills for BTC is too small to confirm Sharpe robustly (95% CI spans ~±0.8); need multi-period test or out-of-sample validation.