← All work

// Trading · 2026

Polymarket Bots

Automated trading bots for Polymarket's short-duration crypto markets, built around a composite momentum signal.

active Python · Polymarket API · Binance API · Playwright

The problem

Polymarket’s BTC 5-minute markets resolve fast and need a bot that can time entries, size stakes sensibly, and not get stuck holding an unfilled order when the window closes.

What I built

A live/dry-run trading loop (bot.py) driven by a 7-indicator composite signal (strategy.py), plus the tooling around it:

  • backtest.py pulls Binance history for offline analysis; compare_runs.py sweeps config grids and exports the results to Excel for comparison.
  • setup_creds.py derives and persists Polymarket API credentials, and can drive the SDK’s trading-approval setup.
  • auto_claim.py is a Playwright worker that logs in once and then clicks through claim/redeem buttons on the portfolio page automatically.
  • reconcile_history.py recomputes bankroll state from the logged trade history, so the local bankroll tracker doesn’t drift from what actually filled.

An earlier, smaller version of the same idea lives in a companion repo, poly_bot — a minimal bot.py + polymarket_client.py pair. This project superseded it; this page links the current one.

Bot loop

Each stage below is a real file in the repo:

MARKET SCAN Gamma markets — slug-based discovery Binance spot/kline — window open px COMPOSITE MOMENTUM SIGNAL strategy.py analyze() — 7 indicators additive score, own threshold each confidence = |score| / 16.5, capped 1 ORDER-BOOK GATING / RISK CONFIG botlib.py — confidence gate by mode optional ask-gate: ENTRY_MIN/MAX_ASK MOMENTUM_LIVE.PY 5 pairs, BTC excl. hold to resolution no TP / no SL SOL_EDGE_LIVE.PY self-contained TP 0.95 SL @ 30% of entry LOGGING + BANKROLL RECONCILE *_live_log.jsonl — one line per fill reconcile_history.py rebuilds it BACKTEST + EDGE VALIDATION backtest.py — Binance history pull backtest_edge.py — entry×move rate ask-vs-outcome mispricing → real edge

Stack & approach

Targets Polymarket’s current Python SDK (polymarket-client) rather than the older community py-clob-client path, using Gamma market endpoints for slug-based market discovery. The live path posts a market order first and falls back to a limit order near the current ask if that doesn’t fill immediately; a fallback order still open when the window closes gets cancelled, leaving bankroll unchanged for that window. Stake sizing, drawdown guards, and order-book gating are config-driven rather than hardcoded.

strategy.py’s composite signal isn’t a vote — it’s an additive score across seven indicators, each contributing on its own threshold-tiered scale (a break past 0.10% of the window open is worth up to 7 points, tick-trend or RSI extremes up to 2 more), summed and normalized into a 0–1 confidence against a fixed maximum. bot.py gates entries on that confidence per trading mode (safe/aggressive/degen) and, optionally, a live order-book ask band. The two production scripts depart from that general path on purpose: momentum_live.py runs five pairs — BTC excluded after backtesting showed negative edge there — and holds every fill to resolution with no TP/SL, while sol_edge_live.py is SOL-only and self-contained (no bot.py/botlib.py dependency), actively exiting at a 0.95 bid or a stop set at 30% of the entry price instead of waiting out the window.

Status / results

Live trading code paths exist in the repo (momentum_live.py, sol_edge_live.py) alongside backtest and edge-validation scripts. No win-rate or PnL figures are published on this page yet — they’ll be added once there’s a validated result worth standing behind.