5.5 KiB
06 — Migration Plan
Phased so that every phase leaves the repo in a working, testable state, and the risky unknowns (wallet auth on V2, pUSD) are attacked first. v1 cannot trade anyway (CLOB V1 is gone — 03), so there is no parallel-run constraint: we are building v2 in place, deleting v1 as replacements land.
Phase 0 — Repo hygiene & toolchain (small)
src/polymaker/package skeleton (02 layout), typer CLI stub.- pyproject:
requires-python = ">=3.12",.python-version→ 3.12.x, freshuv lock; dev group: ruff, mypy, pytest, pytest-asyncio; ruff replaces black; GitHub Actions running lint+types+tests. - Delete immediately (nothing depends on them working):
poly_stats/,update_stats.py, the read-only Sheets CSV hack, dead commented code. The rest of the v1 code (trading.py/main.py/data_updater/…) was parked underlegacy/during the port and has now been deleted — it survives only in git history onmain. - Remove deps: gspread, gspread-dataframe, google-auth. Add: httpx, pydantic, structlog, typer, rich, watchfiles, uvloop, py-clob-client-v2.
Exit: uv run polymaker --help works; CI green; no Google imports left.
Phase 1 — Catalog, config, scanner (replaces Sheets as data source)
- pydantic config models + TOML loading + hot reload (05 §1).
- Gamma keyset client, tag resolution, SQLite catalog, market scoring
(rewards + rebates + vol),
polymaker scan/markets/markets add(05 §2). - CLOB public data client (books batch, midpoints, prices-history) for enrichment.
Exit: politics markets scanned, ranked, and selected into markets.toml
in seconds, with no Google anywhere. (v1 bot is now un-runnable — fine, see
above.)
Phase 2 — Execution core (the V2 unknowns live here — do the spikes first)
- Spike A (days, throwaway code): wallet auth on V2. Wrap USDC→pUSD, set allowances, place + cancel one post-only order with our exact wallet (signature_type 2), read it back on the user WS. Resolves 03 §9 items 3/7. Decision output: keep proxy wallet vs. move to EOA; py-clob-client-v2 vs. direct signing.
- Spike B: WS contract. Capture live
book/price_change/best_bid_ask/tick_size_changepayloads (custom features on), confirm ping/pong, write the parsers against reality. - Then build: MarketDataService (books + analytics + resync), UserStream, StateStore + order/trade state machine, ExecutionGateway (signer, httpx, rate budgeter, heartbeats, batch ops, reconciler), Merger (native Python, Safe-or-EOA per Spike A), journal.
- Integration test: on 1–2 quiet live markets with $10-size manual targets, prove place/cancel/fill/merge/reconcile round-trips, then heartbeat-driven auto-cancel on kill.
Exit: engine can hold a hand-specified quote set live, survive WS drops, crashes, and restarts safely. Journal capture running 24/7 from here on (the backtester's data supply).
Phase 3 — Strategy engine (04) + simulation
- Pure strategy module: FV, vol/toxicity, regime machine, quote construction, reward/rebate utility, inventory/exit logic — with unit tests per component.
- Replay backtester over the journals accumulated since Phase 2; parameter study for the political profiles.
- Paper mode (
run --paper) end-to-end. - Delete the parked v1 code — the port is done. (Done:
legacy/removed.)
Exit: paper trading ≥2 weeks, ≥10 political markets, meeting the acceptance gates from 04 §9 (positive PnL under conservative fills, markouts
−0.5 tick at +5m, zero risk breaches).
Phase 4 — Live rollout + ops hardening
- RiskManager fully wired (caps, kill switches, event-group limits), alert
webhook,
status/pnl/flatten/doctorpolished. - Go live: 2–3 markets at minimum size → widen coverage/size on weekly review of the KPI set. us-east VPS placement.
- Reward/rebate reconciliation against actual daily payouts.
Exit: stable unattended operation; income attribution (spread vs rewards vs rebates) reported per market.
Phase 5 — Deferred (separately scoped)
- External data feeds (07): polls, news, cross-venue.
- Neg-risk set-arb + NegRiskAdapter conversions (04 §7) if the structural edge shows up in captured data.
- Optional: RTDS
activityflow features, Prometheus/Grafana, Polymarket US venue.
Deletion ledger (what's gone by the end of Phase 3)
trading.py, main.py, update_markets.py, update_stats.py, poly_data/,
poly_utils/, poly_stats/, data_updater/, poly_merger/ (entire Node
runtime), positions/ runtime dir, credentials.json expectations,
SPREADSHEET_URL, Python 3.9 pin, gspread/gspread-dataframe/google-auth,
py-clob-client (v1), pandas-in-hot-path, all print() logging, all bare
excepts, all gc.collect() calls.
Risk register
| Risk | Mitigation |
|---|---|
| V2 SDK auth bugs with proxy/Safe wallets | Spike A first; EOA fallback decided in days, not after building |
| pUSD mechanics undocumented corners | Spike A covers wrap/allowance/merge collateral; treat collateral as per-market config |
| WS payload drift (young V2 docs) | Spike B parses from captured reality; parsers tolerate unknown fields |
| Maker-only exits too slow in a news jump | Position caps sized for survivable worst case (04 §6); EVENT regime pulls quotes early; accept this as the strategy's core tradeoff |
| Rewards program parameters shift | All reward math data-driven from per-market API fields; utility recalibrated from actual payouts |
| Strategy underperforms | Paper-gate before capital; journal-driven iteration loop is the product as much as the bot |