Files
poly-maker/docs/scoping/06-migration-plan.md
T
Daniel Sapkota c7b686116e Getting there
2026-07-05 17:50:04 -04:00

110 lines
5.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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, fresh
`uv 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
under `legacy/` during the port and has now been deleted — it survives only in
git history on `main`.
- 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_change` payloads (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 12 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`/`doctor` polished.
- Go live: 23 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 `activity` flow 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 |