Polymarket Bot
A Rust trading system for Polymarket’s BTC 5-minute Up/Down markets. It streams 1-minute OHLCV from Hyperliquid as the resolution proxy, gates entries on orderbook microstructure, and shares feature and model code between the lab harness and the live runner so research changes carry into execution unchanged. It currently runs in paper mode while fees, fills, tick semantics, and replay-price ambiguity are modeled more tightly.
- Role
- Solo Engineer · Research + Build
- Period
- 2026
- Status
- Production
How the system fits together.
The calls that shaped it.
- 01
Designed several online ML strategies on one shared feature pipeline, then persisted model state per coin so experiments restart without losing learning history.
- 02
9-crate Rust workspace: `poly-core` (types + math), `poly-data` (Kraken + Hyperliquid feeds, cross-asset alignment), `poly-strategies` (rules — momentum-meanreversion, market-making, scalper, copy-trading, cross-market arb, crypto arb — plus `MlSignalTrader`), `poly-lab` (~37 lab strategies including the five named ML variants), `poly-ml` (feature engineering crate), `poly-execution` (paper + live), `poly-backtest`, `poly-api` (Axum dashboard backend), `poly-cli`.
- 03
Wrote a deep ML analysis pass on 4,403 live predictions identifying the real failure modes — stale z-score normalization clipping fresh signal magnitudes, overfitting at 1.7-3.3 samples per feature with a placebo L2, sigmoid saturation at 0.52-0.56 — with concrete fixes (rolling-window stats, L2 bump, Platt rescaling, fractional-Kelly sizing) and an impact-vs-effort prioritization that I committed back into the codebase as fix-target #1.
- 04
Settlement math grounded in actual token mechanics: position_size / entry_price gives the share count, payouts are share × $1 on the winning side and 0 on the loser, so a $25 ticket at 0.30 returns +$58.33 on win versus −$25 on loss. Entry gates require model conf ≥ 0.53, ask ≤ 0.55, and microstructure agreement before a single dollar goes on the book.
- 05
I separated tested mechanics from unresolved assumptions: settlement, share count, and gate evaluation are reproducible, while fees, partial fills, tick effects, and replay pricing are documented as known gaps before moving beyond paper trading.
- 06
Broader `poly-ml` feature crate: separate from the BTC-window inputs the lab models use, `poly-ml::features` builds a supervised feature table from orderbook spread, depth imbalance, taker flow, RSI, whale pressure, holder concentration, and EMA crossover — labeled for 1h / 4h / 24h future-move classification — for a different class of model entirely from the 5-min Up/Down brain.
- 07
Next.js dashboard on top via the Axum API for live PnL, per-strategy WR, model weights, and trade JSONL replay.
The interesting work isn't the stack. It's the boundaries.
What it runs on.
- 01 Rust workspace, 9 crates, async on Tokio
- 02 Polymarket CLOB via polymarket-client-sdk + alloy for EIP-712 signing
- 03 Hyperliquid WS (BTC/ETH/SOL 1-min OHLCV) — resolution proxy
- 04 Online SGD logistic regression with epoch retrain every 10-15 windows
- 05 rust_decimal for money, rusqlite for persistence, tracing + JSONL trade log for observability
- 06 Axum + tower-http API; Next.js dashboard for live monitoring