Production-ready, high-frequency bot that captures YES/NO mispricings on Polymarket. Designed for sub-microsecond strategy ticks, fill-or-kill execution, and multi-market orchestration via a supervisor.
- Binary markets satisfy
YES + NO โ $1.00; dislocations create risk-free spread. - Bot buys the cheaper side first, then hedges the opposite side while keeping fee/edge-adjusted projected pair cost under the effective limit:
effective_pair_cost(avg_yes, avg_no, TAKER_FEE_BPS) <= (MAX_PAIR_COST - EDGE_BUFFER)after the simulated fill. - All orders are Fill-Or-Kill (FOK) to avoid resting quotes; DRY_RUN mode simulates fills.
- Hedging: if inventory imbalance exceeds
HEDGE_TOLERANCE, force-buy the lighter side.
Example
YES = 0.52, NO = 0.45 โ pair_cost = 0.97
Buy 100 NO @ 0.45 โ later YES = 0.48
Buy 100 YES @ 0.48 โ payout $100, cost $93 โ +$7 locked profit
Data Flow (single-market)
WebSocket prices (wss://ws-subscriptions-clob.polymarket.com/ws/market)
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ MarketFeed โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโ
โ prices dict
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ KabobagoolStrategy โ
โ (orchestration + risk limits) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ PositionTracker + decision.py (pure logic) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโ
โ validated order
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ExecutionClient (py-clob-client, FOK only) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Polymarket CLOB (fills/trades) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Startup reconciliation: recent BUY fills for PROXY_ADDRESS โ PositionTracker
Observability (sidecar): Feed/Strategy โ RuntimeSnapshot โ Health/Metrics (/health, /status, /metrics)
Data Flow (Hydra multi-market)
WebSocket prices (one shared connection)
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ MultiplexedMarketFeed โ
โ (fan-out; never awaits strategy) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโ
โ best-ask updates
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ConflatingPriceBuffer (per market; YES+NO) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ MarketEngine (per market task) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ KabobagoolStrategy โ
โ (per market) + PositionTracker + decision.py โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโ
โ order request
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ExecutionClient (global queue + min interval) โ
โ (wallet-level serialization + FOK only) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Polymarket CLOB (fills/trades) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Startup reconciliation (per engine): recent BUY fills for PROXY_ADDRESS โ PositionTracker
Observability (single server): Engines/Feed snapshots โ task_health.py (/health, /status, /metrics)
Key Modules (production path)
config.pyโ env validation, logging, reconciliation & health toggles.feed.pyโ WebSocket towss://ws-subscriptions-clob.polymarket.com/ws/market, auto-reconnect, cache reset to1.0on disconnect.strategy.pyโ orchestration; asyncio lock guards; caches config for hot path.decision.pyโ pure, deterministic selection/validation functions.position.pyโ inventory & locked-profit math (@dataclass(slots=True)+__slots__).client.pyโ async wrapper overpy-clob-client, executes all blocking calls inrun_in_executor, always usesOrderType.FOK.reconcile.pyโ replays historical BUY trades (default 72h) so restarts donโt double-buy.health.pyโ FastAPI health/metrics server (Prometheus-friendly gauges and counters).
Supervisor/Discovery (multi-market)
discovery.pyโ pulls Gamma markets + order books; filters by glob patterns, volume, and time-to-expiry; normalizes token IDs (decimal strings).market_supervisor.pyโ orchestrates per-market engines, shared feed, unified health/metrics, and Prometheusfile_sdtargets.supervisor_config.pyโ typed supervisor config loader with profile + local override support.multiplex_feed.py/market_engine.py/task_health.pyโ Hydra shared feed, per-market engines, unified health/metrics.
Project Layout
kabobagool/
โโโ src/
โ โโโ main.py # Single-market entrypoint
โ โโโ config.py # Env + defaults (fails fast on missing secrets)
โ โโโ client.py # ExecutionClient async wrapper
โ โโโ feed.py # MarketFeed websocket handler
โ โโโ strategy.py # KabobagoolStrategy orchestration
โ โโโ decision.py # Pure strategy logic
โ โโโ position.py # PositionTracker + Side enum
โ โโโ reconcile.py # State restore from historical trades
โ โโโ health.py # /health, /status, /metrics endpoints
โ โโโ discovery.py # Market discovery (Gamma + books)
โ โโโ transport.py # Swappable HTTP layer (aiohttp / curl_cffi TLS impersonation)
โ โโโ market_supervisor.py # Multi-market supervisor entrypoint
โ โโโ supervisor_config.py # Typed config loader for supervisor
โ โโโ multiplex_feed.py # Shared WebSocket + per-market ConflatingPriceBuffer (Hydra)
โ โโโ market_engine.py # Per-market asyncio task runner (Hydra)
โ โโโ task_health.py # Unified health/metrics server (Hydra)
โ โโโ bot_config.py # Immutable per-market config dataclass
โ โโโ benchmark.py # Performance harness
โ โโโ test_strategy.py # Strategy unit tests (29+)
โ โโโ test_reconcile.py # Reconciliation regression tests
โ โโโ test_transport.py # Transport layer tests
โ โโโ test_hydra.py # Hydra tests
โโโ scripts/
โ โโโ load-profile.sh # Merge base + profile into .env
โ โโโ run-local.sh # Run supervisor locally (Hydra)
โ โโโ switch-profile.sh # Switch active .env profile
โโโ docs/
โ โโโ DEPLOYMENT.md # Production deployment notes
โ โโโ PROFILES.md # Strategy profiles
โ โโโ hosting_plan.md # Deployment/infra notes
โ โโโ metrics_guidelines.md # Prometheus/Grafana tips
โ โโโ events.md # Sample markets
โโโ tests/ # pytest-based tests/utilities
โโโ docker-compose.yml # Supervisor service definition
โโโ Dockerfile # Supervisor image
โโโ README.md
Operational Guarantees
- Non-blocking concurrency: all signing/HTTP in thread executor; WS heartbeat never starves.
- Atomic execution: FOK orders only; no resting limits.
- Defensive behavior: reconnect on WS drop, clear stale prices, 0.5s cooldown after failed order, reconciliation before live trading.
Run python3 src/benchmark.py and confirm the hot path stays under ~1 ยตs/tick and sustains >1M ticks/s (machine-dependent).
Prerequisites
- Python 3.10+ (3.11+ recommended for local dev scripts)
- Docker (optional, for running the supervisor via docker-compose)
- Polymarket credentials:
PRIVATE_KEY,PROXY_ADDRESS - Optional:
curl_cffifor TLS impersonation (USE_BROWSER_IMPERSONATION=true)
Setup
python3 -m venv venv
source venv/bin/activate
pip install -r src/requirements.txt # single-market bot
pip install -r supervisor-requirements.txt # supervisor (Hydra)
# Prepare credential & profile files (do not hand-edit .env directly)
cp .env.profiles/base.env.template .env.profiles/base.env # add PRIVATE_KEY/PROXY_ADDRESS
# Choose a profile: 15min | crypto | sports | test | conservative | hydra-test
./scripts/load-profile.sh test # merges base + profile into .env (backs up previous)Legacy single-market fallback (not recommended): cp .env.example .env then set TOKEN_YES/TOKEN_NO and thresholds.
# Dry run (simulated fills), INFO logs
DRY_RUN=true LOG_LEVEL=INFO python src/main.py
# Live trading, minimal logging
DRY_RUN=false LOG_LEVEL=WARNING python src/main.py
# Debug everything (app + websockets)
LOG_LEVEL=DEBUG WEBSOCKETS_LOG_LEVEL=DEBUG python src/main.pyObservability
- Health server on
:8080by default:/health(liveness with staleness),/status,/metrics(Prometheus). Toggle viaENABLE_HEALTH_SERVER/ENABLE_METRICS. - Reconciliation:
ENABLE_RECONCILIATION=truereplays lastRECONCILIATION_LOOKBACK_HOURS(default 72) hours of BUY trades for the proxy wallet; setRECONCILIATION_REQUIRED=trueto fail startup on errors.
Purpose: auto-discover high-volume Polymarket markets and run each market as an asyncio task in a single supervisor process (shared WebSocket, global order queue, unified health/metrics).
Quick start
# Local testing (no Docker required)
./scripts/run-local.sh hydra-test
# Or via docker-compose (supervisor container)
docker compose up -d supervisorCore mechanics
- Shared WebSocket:
MultiplexedMarketFeedmaintains one connection, fans out best-ask updates to per-marketConflatingPriceBuffers. - Per-market runner:
MarketEngineconsumes price updates and calls strategy logic. - Wallet fairness:
ExecutionClientuses a global order queue withGLOBAL_ORDER_MIN_INTERVAL_Sspacing to avoid wallet-level rate limits. - Unified health: Single
/health,/status,/metricsendpoint withmarketlabel per engine.
Note on Docker reachability
- In
docker compose, the health server binds inside the supervisor container; publish the chosen port (defaultHEALTH_PORT_BASE) if you want to scrape it from outside Docker.
Supervisor-specific envs
MARKET_PATTERNS: comma-separated globs for market slugs (e.g.,US*Election*).MIN_VOLUME: minimum 24h volume filter (e.g.,5000).MIN_DURATION_HOURS/MAX_DURATION_HOURS: expiry window; defaults exclude <5m and >720h.MAX_MARKETS: cap on concurrent markets (default 20).ENABLE_BOOK_SCREEN=true: require order-book pair cost โคSPAWN_PAIR_COST(default 1.02) before spawning.HEALTH_PORT_BASE: port for the supervisor health server (default 8000).TARGETS_PATH: Prometheus target file (default/var/lib/kabobagool/targets.json).GLOBAL_ORDER_MIN_INTERVAL_S: seconds between orders across all markets (default: 0.5).
- Required:
PRIVATE_KEY,PROXY_ADDRESS - Market:
TOKEN_YES,TOKEN_NO(decimal strings) - Strategy:
MAX_PAIR_COST(default 0.98),EDGE_BUFFER(0.0),TAKER_FEE_BPS(1),BATCH_SIZE(50),HEDGE_TOLERANCE(100),FORCE_HEDGE_IMBALANCE(0) - Rate limiting:
COOLDOWN_BASE_S,COOLDOWN_MAX_S,COOLDOWN_BACKOFF,GLOBAL_ORDER_MIN_INTERVAL_S(supervisor) - Safety:
DRY_RUN(true/false) - Logging:
LOG_LEVEL(WARNING/INFO/DEBUG),WEBSOCKETS_LOG_LEVEL - Network:
CLOB_PROXY_URLfor geo-bypass (optional),HOST(default https://clob.polymarket.com),CHAIN_ID(137),USE_BROWSER_IMPERSONATION(false) for TLS fingerprint bypass via curl_cffi - Observability:
ENABLE_HEALTH_SERVER,ENABLE_METRICS,HEALTH_CHECK_PORT(8080),HEALTH_PRICE_STALENESS_THRESHOLD(60s) - State restore:
ENABLE_RECONCILIATION,RECONCILIATION_LOOKBACK_HOURS(72),RECONCILIATION_REQUIRED
# Unit tests
python3 src/test_strategy.py # Strategy + decision logic (29+ tests)
python3 src/test_reconcile.py # Reconciliation regression tests
python3 src/test_transport.py # Transport layer (aiohttp/curl_cffi)
python3 src/test_hydra.py # Hydra components
# Optional: pytest suite in ./tests (requires pytest installed)
python3 -m pytest -q
# Benchmarks
python3 src/benchmark.py
# Syntax check
python3 -m py_compile src/*.py- Missing env vars: ensure
.env.profiles/base.envhas credentials then rerun./scripts/load-profile.sh <profile>. - Frequent WS drops: network issues or rate limits; bot auto-reconnects and resets prices to 1.0 to avoid stale trades.
- No fills: lower
MAX_PAIR_COST, confirm token IDs are decimal strings, and verify proxy wallet is funded. - Supervisor spawns nothing: adjust
MARKET_PATTERNS,MIN_VOLUME, or raiseMAX_MARKETS; check book-screen thresholdSPAWN_PAIR_COST.
- Secrets live only in
.env.profiles/base.envand generated.env(git-ignored). Do not commit. - All orders are FOK to avoid resting exposure; DRY_RUN defaults to true for safety in development.
- Proxy/private keys should use a dedicated funded wallet; consider hardware wallet or secrets manager in production.