An automated market making bot for the Polymarket Prediction Market that provides liquidity by maintaining orders on both sides of the order book with customizable parameters
Python
1,512
37 commits
updated Jul 9, 2026
A maker-only market-making bot for Polymarket CLOB V2, focused on political markets. Single async process, local-file config, typed and tested.
[!WARNING] Market making on Polymarket is competitive and can lose money. This is a reference implementation and a research harness, not a guaranteed-profitable product. Test in
--papermode first; go live with small size.
.env, and a funded wallet is a complete deployment.Uses uv and Python 3.12+.
uv sync --extra dev # install deps + dev tools
uv run polymaker --help
cp .env.example .env # then edit two values:
PK — the private key of your signer walletBROWSER_ADDRESS — your Polymarket address (shown on the profile / developer page)Everything else is TOML under config/:
config.toml — wallet/engine/risk/execution settingsstrategy.toml — named parameter profiles (political-longdated, political-hot)markets.toml — the trade list (populated via the CLI below)# 1. discover + rank political markets (writes to state.db)
uv run polymaker scan
uv run polymaker markets
# 2. add markets to the trade list
uv run polymaker markets-add <slug> --profile political-longdated
# 3. dry run: full pipeline against the live feed, no orders posted
uv run polymaker run --paper
# 4. preflight the wallet before going live
uv run polymaker doctor
# 5. self-tests: a deep post-only order (free), then a real fill round-trip (~cents)
uv run polymaker livetest # place a deep post-only order + cancel (no fill)
uv run polymaker moneydoctor # limit rest + market buy + market sell, auto-flattens
# 6. go live
uv run polymaker run
# ops
uv run polymaker status # positions / open orders
uv run polymaker cancel-all # panic button
market WS ─▶ OrderBook ─▶ (wake) ─▶ Quoter ─▶ strategy (pure) ─▶ reconcile ─▶ ExecutionGateway
user WS ─▶ StateStore RiskManager ┘ (post-only, heartbeat)
Gamma ─▶ Catalog/scanner ─▶ SQLite periodic REST reconcile ┘
One async event loop. The strategy layer is a pure function (book, inventory, params, clock) → TargetQuotes — deterministic and unit-tested. The engine owns
all I/O and state around it; the ExecutionGateway wraps py-clob-client-v2
(which handles the V2 EIP-712 signing) and offloads its blocking calls to a
thread pool so the hot path never stalls. State (positions, orders, PnL, catalog)
lives in one SQLite file; raw WS/order events are journaled to journal/ for
replay.
Maker-only, quoting both sides of each market as USDC-collateralized bids:
r = FV − skew(inventory);
half-spread δ = base + c_vol·σ + c_tox·toxicity. Post BUY-YES at r − δ
and BUY-NO at (1 − r) − δ. Because both legs are bids that sum below 1,
a filled pair merges back to USDC at locked edge 1 − p − q — a maker-only
exit that never crosses the spread.QUIET (farm rewards in-band), TRENDING
(lean + widen + half size), EVENT (sweep/jump detected → pull quotes, cool
off), REDUCE_ONLY (inventory cap / near end date → exits only), HALTED
(stale data / resolved / kill switch → cancel all).Tune it all via profiles in config/strategy.toml.
uv run pytest # unit suite (offline)
POLYMAKER_LIVE=1 uv run pytest tests/test_live_marketdata.py # live WS integration
uv run ruff check src tests # lint
uv run mypy src # types (strict)
Implemented and live-verified end to end (auth → book → strategy → sign → post → cancel): config, catalog/scanner, order book + analytics, strategy (FV, vol/toxicity, regime, quoting), state store + lifecycle, execution gateway + reconciler + heartbeat, market/user websockets, risk manager, merger (EOA path), engine, CLI, paper mode, journal capture. 83 tests; ruff + mypy strict clean.
Not yet built: a replay backtester over the captured journals, and external data feeds (polls / news / cross-venue). Merging through a Safe/proxy wallet routes a tx via the relayer and isn't wired yet — until then inventory exits via limit sells rather than merging.
MIT
0 followers · starred Apr 2026
113 followers · starred Aug 2025
260 followers · starred Jan 2026
57 followers · starred Jan 2026
An automated market making bot for the Polymarket Prediction Market that provides liquidity by maintaining orders on both sides of the order book with customizable parameters
Python
1,512
37 commits
updated Jul 9, 2026
A maker-only market-making bot for Polymarket CLOB V2, focused on political markets. Single async process, local-file config, typed and tested.
[!WARNING] Market making on Polymarket is competitive and can lose money. This is a reference implementation and a research harness, not a guaranteed-profitable product. Test in
--papermode first; go live with small size.
.env, and a funded wallet is a complete deployment.Uses uv and Python 3.12+.
uv sync --extra dev # install deps + dev tools
uv run polymaker --help
cp .env.example .env # then edit two values:
PK — the private key of your signer walletBROWSER_ADDRESS — your Polymarket address (shown on the profile / developer page)Everything else is TOML under config/:
config.toml — wallet/engine/risk/execution settingsstrategy.toml — named parameter profiles (political-longdated, political-hot)markets.toml — the trade list (populated via the CLI below)# 1. discover + rank political markets (writes to state.db)
uv run polymaker scan
uv run polymaker markets
# 2. add markets to the trade list
uv run polymaker markets-add <slug> --profile political-longdated
# 3. dry run: full pipeline against the live feed, no orders posted
uv run polymaker run --paper
# 4. preflight the wallet before going live
uv run polymaker doctor
# 5. self-tests: a deep post-only order (free), then a real fill round-trip (~cents)
uv run polymaker livetest # place a deep post-only order + cancel (no fill)
uv run polymaker moneydoctor # limit rest + market buy + market sell, auto-flattens
# 6. go live
uv run polymaker run
# ops
uv run polymaker status # positions / open orders
uv run polymaker cancel-all # panic button
market WS ─▶ OrderBook ─▶ (wake) ─▶ Quoter ─▶ strategy (pure) ─▶ reconcile ─▶ ExecutionGateway
user WS ─▶ StateStore RiskManager ┘ (post-only, heartbeat)
Gamma ─▶ Catalog/scanner ─▶ SQLite periodic REST reconcile ┘
One async event loop. The strategy layer is a pure function (book, inventory, params, clock) → TargetQuotes — deterministic and unit-tested. The engine owns
all I/O and state around it; the ExecutionGateway wraps py-clob-client-v2
(which handles the V2 EIP-712 signing) and offloads its blocking calls to a
thread pool so the hot path never stalls. State (positions, orders, PnL, catalog)
lives in one SQLite file; raw WS/order events are journaled to journal/ for
replay.
Maker-only, quoting both sides of each market as USDC-collateralized bids:
r = FV − skew(inventory);
half-spread δ = base + c_vol·σ + c_tox·toxicity. Post BUY-YES at r − δ
and BUY-NO at (1 − r) − δ. Because both legs are bids that sum below 1,
a filled pair merges back to USDC at locked edge 1 − p − q — a maker-only
exit that never crosses the spread.QUIET (farm rewards in-band), TRENDING
(lean + widen + half size), EVENT (sweep/jump detected → pull quotes, cool
off), REDUCE_ONLY (inventory cap / near end date → exits only), HALTED
(stale data / resolved / kill switch → cancel all).Tune it all via profiles in config/strategy.toml.
uv run pytest # unit suite (offline)
POLYMAKER_LIVE=1 uv run pytest tests/test_live_marketdata.py # live WS integration
uv run ruff check src tests # lint
uv run mypy src # types (strict)
Implemented and live-verified end to end (auth → book → strategy → sign → post → cancel): config, catalog/scanner, order book + analytics, strategy (FV, vol/toxicity, regime, quoting), state store + lifecycle, execution gateway + reconciler + heartbeat, market/user websockets, risk manager, merger (EOA path), engine, CLI, paper mode, journal capture. 83 tests; ruff + mypy strict clean.
Not yet built: a replay backtester over the captured journals, and external data feeds (polls / news / cross-venue). Merging through a Safe/proxy wallet routes a tx via the relayer and isn't wired yet — until then inventory exits via limit sells rather than merging.
MIT
0 followers · starred Apr 2026
113 followers · starred Aug 2025
260 followers · starred Jan 2026
57 followers · starred Jan 2026