Тема
Three-Algorithm Migration Runbook (operator-grade, manual one-time)
Status: STUB v2 (Phase C revised post user clarification, 2026-05-07). Concrete knob translations land alongside ADR-018 sprints — values in this stub are placeholders until Sprint 2/3/4 ship.
This runbook is the operator-facing migration guide for the 3-algorithm consolidation per adr-018-three-algorithms-consolidation.md.
Migration model
One-time, manual, per strategy row. Bot binary carries NO env-alias parsing for legacy MERGE_ARB_* / BUCKET_ARB_* / MAKER_* strategy knobs. After cutover, strategy configuration is in SQLite config.db only (per ADR-015).
The operator:
- Reads the legacy strategy row's knobs (env file or
pm-cli strategy describe <legacy_label>if already migrated to SQLite under the legacy schema). - Maps each knob to the new algorithm's
definitionJSON keys via the translation table below. - Removes the legacy row (
pm-cli strategy remove --label <legacy_label>). - Adds the new row (
pm-cli strategy add --algorithm <directional|binary-arb|multi-arb> --profile <profile-name> --field key=value ...) OR uses the WebUI Add-Strategy form. - Restarts pm-bot.
There is no auto-migration tool, no env-alias compatibility layer, no deprecation timeline. Migration is one-shot per row.
Pre-flight checklist
- [ ] pm-bot binary at version that includes the new algorithm + profile schema (Sprint 2 / 3 / 4 release).
- [ ]
pm-cli strategy describe <legacy_label>outputs current knob values (or operator has the original env file at hand). - [ ] Production
config.dbbackup taken (cp config.db config.db.bak-pre-migration-<date>). - [ ] No active bot session running on the target strategy (
docker compose stop pm-botor pause via dashboard). - [ ] Operator has the relevant runbook section open (per algorithm).
Per-strategy migrations
merge-arb → binary-arb (after Sprint 2 lands)
Concrete translation table to be filled with cents-conversion mappings during Sprint 2 author work. Skeleton:
Legacy MERGE_ARB_* env knob | New binary_arb.* SQLite key | Conversion |
|---|---|---|
MERGE_ARB_BUY_LIMIT_PRICE | (removed in v3 jitter-capture) | dropped — v3 uses entry order type instead |
MERGE_ARB_BAND_EXIT_PRICE | (removed) | dropped — replaced by Decision A/B/C/D logic |
MERGE_ARB_MID_FILTER_LOWER / _UPPER | (removed) | dropped — admission predicate is (ask_y + ask_n) ≤ min_pair_cost_cents/100 |
MERGE_ARB_LOT_SHARES | binary_arb.lot_shares | direct |
MERGE_ARB_BUDGET_PER_CID | binary_arb.budget_per_market | direct |
MERGE_ARB_MIN_MERGE_SHARES | (removed; merge always operates on full balanced inventory) | dropped |
MERGE_ARB_NEG_RISK_ENABLED | binary_arb.neg_risk_enabled | direct |
MERGE_ARB_STALE_INVENTORY_SECS | binary_arb.max_position_age_secs | direct |
| (new) | binary_arb.entry_order_type | default Fok |
| (new) | binary_arb.min_pair_cost_cents | default 98 |
| (new) | binary_arb.min_book_spread_cents | default 2 |
| (new) | binary_arb.min_book_liquidity_shares | default 5 |
| (new) | binary_arb.resolution_path | default MergeImmediate |
| (new) | binary_arb.stop_loss_drawdown_pct | default 30 |
| (new) | binary_arb.imbalance_tolerance_pct | default 3 |
| (new) | binary_arb.min_merge_gas_buffer_usdc | default 0.02 (revised post critique) |
| (new) | binary_arb.resolution_proximity_secs | default 1800 |
| (new) | binary_arb.profile | default JitterCapture |
Example operator session:
sh
# Inspect legacy
pm-cli strategy describe merge-arb-prod
# Remove legacy row
pm-cli strategy remove --label merge-arb-prod
# Add new binary-arb row
pm-cli strategy add \
--label binary-arb-prod \
--algorithm binary-arb \
--profile JitterCapture \
--wallet-label live \
--budget-limit-usd 100 \
--field binary_arb.lot_shares=5 \
--field binary_arb.budget_per_market=5 \
--field binary_arb.neg_risk_enabled=true \
--field binary_arb.entry_order_type=Fok \
--field binary_arb.min_pair_cost_cents=98 \
--field binary_arb.resolution_path=MergeImmediate
# Verify
pm-cli strategy describe binary-arb-prod
# Restart bot
docker compose -f ~/pm-backtest/instances/<instance>/docker-compose.yml restart pm-botmaker → directional MakerPostOnly (after Sprint 3 lands)
Concrete translation table to be filled during Sprint 3. Skeleton in directional-prd.md §11. NoMaker / Sniper sub-types map to MakerPostOnly profile. SpreadMaker (paired post-only) routes to binary-arb with binary_arb.profile=PairedRebate instead — see binary-arb migration above.
maker-rebate (cheaper-leg path) → directional MakerRebateSingleSide (after Sprint 3 lands)
Concrete translation table to be filled during Sprint 3. Rebate-eligibility filter routes through new MarketFilter primitive. Paired-rebate path (TD-7-shipped) migrates separately via Sprint 5 → binary-arb PairedRebate profile.
bucket-arb → multi-arb (after Sprint 4 lands)
Behavioural rename only — every BUCKET_ARB_* knob preserves its semantics under multi_arb.*. Operator runs pm-cli strategy remove --label <legacy> then pm-cli strategy add --algorithm multi-arb --profile Basket --field multi_arb.<knob>=<value> ... with the same numeric values.
single-token-mm (Sprint 7, ADR-021 — no migration; new algorithm)
single-token-mm is a new 4th algorithm with no legacy module to migrate from. Operators wishing to run two-sided market-making create a fresh strategy row at any time after Sprint 7 ships:
sh
pm-cli strategy add \
--label mm-classic-prod \
--algorithm single-token-mm \
--profile Classic \
--wallet-label live \
--budget-limit-usd 10 \
--field single_token_mm.target_spread_cents=2 \
--field single_token_mm.lot_shares=25 \
--field single_token_mm.side_selection=Both \
--field single_token_mm.min_book_spread_cents=4 \
--field single_token_mm.min_book_liquidity_shares=50 \
--field single_token_mm.requote_sensitivity_cents=1 \
--field single_token_mm.max_drift_cents=5 \
--field single_token_mm.stop_loss_drawdown_pct=0.10 \
--field single_token_mm.budget_per_market=10Pre-flight checks specific to single-token-mm (in addition to standard pre-flight):
- [ ] Target market is in the Polymarket Maker Rebate Program (
MarketFilterwould fail-fast at strategy-add time per INV-9 if not). - [ ] Both bid AND ask legs qualify for rebate on the chosen token (system-analyst verified self-trade prevention before Sprint 7 cutover).
- [ ] Rate-limit budget:
markets_count × cycles_per_hour × 4_calls_per_cycle / 3600 ≤ 350 calls/sec. Strategy-add validation rejects configurations exceeding this.
Operators choose WideSpread over Classic for volatile windows (news events, debates, primary nights) where target_spread_cents=5 reduces adverse-fill risk at cost of throughput.
Verification
After each migration:
pm-cli strategy listshows the new entry; legacy entry absent.pm-cli strategy describe <new_label>confirms knob values.- Dry-run smoke: start pm-bot with
BOT_STRATEGY_LABEL=<new_label> BOT_DRY_RUN=truefor ≥ 1 minute; confirm orders emit (or no admission, if expected) and no panics. - Capture-replay parity check (per CI tier per ADR-018):
- Tier-1 hash equality for renames (
maker/maker-rebate single-side/bucket-arb). - Tier-2 invariant + PnL bound for
binary-arbv3 (decision tape will differ by design).
- Tier-1 hash equality for renames (
- Audit row:
sqlite3 config.db 'SELECT * FROM strategy_audit ORDER BY ts DESC LIMIT 5'confirmsremoveandaddactions recorded.
Rollback
If migration produces undesired behaviour:
- Stop bot.
- Restore
config.dbfrom snapshot:cp config.db.bak-pre-migration-<date> config.db. - Restart with the legacy strategy row reinstated.
The bot binary released with Sprint 2 / 3 / 4 still runs the legacy strategy modules until each absorption sprint deletes them — rollback is a config-DB swap, not a binary downgrade. After the legacy module is deleted (final cutover sprint), rollback requires a binary downgrade to the pre-deletion release.
Cross-references
adr-018-three-algorithms-consolidation.md— taxonomy + sprint plan.adr-019-binary-arb-jitter-capture.md— binary-arb v3 design._3-algorithms-taxonomy.md— algorithm + profile mapping + 6-profile operator surface.adr-015-multi-wallet-and-strategy-config.md— SQLite config schema (where strategy rows live).multi-wallet-migration-runbook-2026-05-03.md— structural template.