Getting there

This commit is contained in:
Daniel Sapkota
2026-07-05 17:50:04 -04:00
parent bfacef317b
commit c7b686116e
92 changed files with 8062 additions and 7964 deletions
+109
View File
@@ -0,0 +1,109 @@
# 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 |