Skip to content

149: Restore single-token-mm strategy as layer ​

Identity ​

  • Status: restoration design (open; new-build, not recovery)
  • Spawned from: F6 of ADR-024 pivot, 2026-05-13
  • Original module: never existed (designed in ADR-021 PROPOSED → DEFERRED)
  • Recovery: N/A — green-field implementation per ADR-021 design
  • Target taxonomy: single-token-mm (4th base algorithm per ADR-021; cycling-inventory paradigm — only one in this class)
  • Original ADR: ADR-021 (DEFERRED)
  • Type: restoration (greenfield per deferred ADR)

Context ​

Single-token-mm market-makes on ONE side (YES or NO) of a binary market with cycling inventory — target position level, requote loop, sell-side enabled. Architecturally distinct from directional (accumulating: fill-and-hold): single-token-mm aims for inventory cycling at target spread, not directional position accumulation. Per F3 design + ADR-021: not a profile of directional, distinct algorithm — the only cycling-inventory class.

Data model needs (from polymarket-data-model.md) ​

  • Market.tokens[target_side].best_bid/best_ask — single-side orderbook
  • Market.tick_size (0.01 / 0.001 split critical for spread profile choice)
  • Market.accepting_orders, Market.active, Market.closed — gating
  • Cross-event meta-layer hook (per ADR-021 cross-event design) — DEFERRED in restoration v1

Restoration scope ​

  • New module: crates/pm-bot/src/domain/strategies/single_token_mm.rs
  • Profiles per ADR-021:
    • Classic: target_spread=2¢, requote_sensitivity=1¢
    • WideSpread: target_spread=5¢, requote_sensitivity=3¢ (volatile windows)
  • Implement ScannerHooks + Strategy trait per ADR-025
  • Requote engine: target spread maintenance, sell-side ladder on inventory accumulation
  • Strategy config: single_token_mm.* knobs (target_side, target_spread_cents, requote_sensitivity_cents, target_inventory_usdc, etc.)
  • Add StrategyType::SingleTokenMm variant + dispatcher branch
  • Config schema: new crates/pm-bot/src/config/strategy/single_token_mm.rs

Prerequisites ​

  • ADR-025 ReadCtx pattern (existing, F5.1 landed).
  • Sell-side orders уже available в OrderClient::place_limit_order per F3 finding (retraction of D §6.5 false claim). No new pm-sdk ops required for v1.
  • No new Decision variants required (uses existing PostOrder + CancelOrder).
  • Cross-event meta-layer hook (per ADR-021): DEFERRED out of v1 restoration scope — v1 = single-market only. Cross-event meta-layer is StrategyComposer hook addition per feedback_3_base_algorithms — separate future item.
  • Requote loop semantics: timer-driven re-evaluation tick already supported by scanner periodic dispatch (verify per F3 §scanner-dispatch).

Out of scope ​

  • Cross-event meta-layer / StrategyComposer hook — v1 deferred per ADR-021 design.
  • Не модифицировать core engine за пределами ScannerHooks impls.
  • Не вводить новые traits в core layer.

Acceptance criteria ​

  • ScannerHooks impl green per contract test pattern
  • Requote loop semantics test: target spread maintenance under sim-CLOB price walk
  • Sell-side ladder test: inventory accumulation → sell at target → cycle
  • Profile differentiation test: Classic vs WideSpread parameter routing
  • VERIFIED markers per feedback_silent_feature_broken
  • ADR-021 promoted from DEFERRED → ACCEPTED (or ADR amendment confirming v1 restoration scope)

Dependencies ​

  • Independent of #145-#148 (no shared infra blockers).
  • Future dependency: StrategyComposer hook (separate backlog item, deferred).

LOC estimate ​

  • New strategy + requote engine: ~2500-3500 LOC (greenfield per ADR-021 design)
  • New strategy config: ~200 LOC
  • Tests: ~600-900 LOC (requote semantics + profile differentiation critical)
  • Total: ~3000-4500 LOC

References ​

  • ADR-024, ADR-025, ADR-021
  • docs/strategies/single-token-mm-prd.md (DEFERRED PRD)
  • docs/strategies/single-token-mm.md (DEFERRED FSD)
  • CLAUDE.md taxonomy (4 base algorithms — single-token-mm = 4th)
  • feedback_3_base_algorithms memory (cycling-inventory class distinction)