Headless Python bot that quotes Polymarket CLOBs on BTC-linked binary markets, using a model-based fair probability versus the order book, with PostgreSQL persistence and a local web dashboard for PnL, execution health, and logs. Designed for long-running Linux operation via systemd user services.
- Price reference: Binance websocket for low-latency spot updates, with a median of Binance, Coinbase, and Kraken to re-anchor periodically.
- Fair value: Maps spot vs strike, time to expiry, and chosen volatility to a probability (log-normal style; supports terminal, barrier, and a comparative 50/50 model where implemented).
- Quoting: Compares fair price to the CLOB midpoint; if edge and liquidity filters pass, places bid and ask around fair with configurable spread, plus inventory and distance guards.
- Operation: Paper mode (simulated fills,
POLY_ENABLE_LIVE_TRADING=0) or live CLOB posting (POLY_ENABLE_LIVE_TRADING=1+ wallet / API credentials). See Polymarket CLOB authentication.
👉 Contact: Miacle709 📞
pip install -r requirements.txt
pip install py-clob-clientSet a connection string the app can use (local or hosted):
Schema is applied automatically on startup from db_schema.py.
cp env.example .env
# or: cp envs/live-template.env .envEdit at minimum:
DATABASE_URLPOLY_ENABLE_LIVE_TRADING=0for paper first;1for live CLOB- For live:
POLY_PRIVATE_KEYand, unless using auto-derived API credentials,POLY_API_KEY,POLY_API_SECRET,POLY_PASSPHRASE(aliasesPOLYMARKET_*are supported; seeenv.example)
# Terminal 1
python market_maker.py
# Terminal 2
python server.py
# Dashboard: http://localhost:5050On each quote cycle (default 30s, configurable):
- Resolve a BTC reference (rest median + continuous websocket feed as implemented).
- Pull active BTC-tagged markets from the Gamma API and filter to supported question types (terminal, barrier, comparative; unsupported structures are skipped).
- For each eligible market: compute fair vs CLOB mid; if edge ≥
POLY_MIN_EDGE(and risk limits allow), place or refresh post-only style two-sided limits around fair at roughly ± half ofPOLY_SPREAD_PCT(full behavior is inConfigand order helpers inmarket_maker.py).
Tuning and kill-switch settings are exposed as POLY_* environment variables; optional POLY_STRATEGY_PROFILE (conservative, balanced, target_clone, aggressive) supplies preset defaults where individual keys are not set.
.
├── market_maker.py # Main trading loop, fair value, CLOB + paper path
├── server.py # Flask API + static dashboard
├── index.html # Dashboard UI
├── db_schema.py # PostgreSQL tables and migrations
├── env.example # Full env template
├── envs/
│ └── live-template.env # Minimal production-oriented template
├── deploy/systemd/ # Service unit templates (used by install script)
├── scripts/
│ ├── install-systemd-user.sh
│ ├── start-systemd-user.sh | stop-systemd-user.sh | status-systemd-user.sh
│ ├── append_daily_metrics.py
│ └── reset_db.py
├── data/ # e.g. daily_metrics.csv (from metrics script)
├── logs/ # bot_YYYYMMDD.log
├── LIVE_PROFIT_VALIDATION_CHECKLIST.md
└── requirements.txt
market_maker.py defines a Config dataclass; runtime overrides use env vars. Common knobs:
| Area | Example env | Role |
|---|---|---|
| Modes | POLY_ENABLE_LIVE_TRADING |
0 paper, 1 live CLOB |
| Profile | POLY_STRATEGY_PROFILE |
Preset bundle for risk/cadence |
| Quotes | POLY_SPREAD_PCT, POLY_MIN_EDGE |
Spread width and minimum edge to quote |
| Sizing | POLY_ORDER_SIZE, POLY_MAX_POSITION |
Notional and per-market cap |
| Cadence | POLY_QUOTE_REFRESH_SEC |
Loop interval |
| Safety | POLY_MAX_DAILY_LOSS, POLY_MAX_OPEN_ORDERS |
Loss kill-switch and open-order cap |
| Universe | POLY_MARKETS_WATCHED, POLY_MARKETS_FETCH_LIMIT, POLY_MIN_MARKET_LIQUIDITY |
How many and which markets to consider |
| Inventory | POLY_INVENTORY_* |
Soft/hard limits and skew to reduce one-sided risk |
| Execution / UI | POLY_EXEC_*, POLY_PASSIVE_BUFFER_*, POLY_MIN_MID_DISTANCE_PCT, POLY_MAX_MID_DISTANCE_PCT |
Telemetry bands and post-only style distance to mid |
See env.example for the full list, including execution score weights, minimum shares, and comparative-event hazard overrides.
From the repository root, after .env exists:
bash scripts/install-systemd-user.shThis installs user units polybot-bot and polybot-dashboard (from deploy/systemd/*.template) with restart on failure. Useful commands:
systemctl --user status polybot-bot.service
systemctl --user status polybot-dashboard.service
journalctl --user -u polybot-bot.service -fConvenience scripts: scripts/status-systemd-user.sh, scripts/stop-systemd-user.sh, scripts/start-systemd-user.sh.
For sessions that survive logouts across reboots when using user services:
sudo loginctl enable-linger $USERAlternative: run python market_maker.py and python server.py in tmux (see previous README behavior; same idea).
Before increasing size, review:
- Uptime and absence of tight restart loops
- Kill switch not firing repeatedly
- Acceptable quote/ack/fill rates and latency in the dashboard
- Inventory not stuck one-sided for long stretches
Daily metrics (optional): append a row to data/daily_metrics.csv with:
python scripts/append_daily_metrics.pyUse a steady cadence (e.g. daily) to review trends in PnL, win rate, and operational metrics.
Structured go-live review: follow LIVE_PROFIT_VALIDATION_CHECKLIST.md for a first-week profitability and health pass/fail template.
With server.py running, open http://localhost:5050 for:
- Cumulative PnL, hourly breakdown, and win rate
- Recent trades and per-market PnL
- BTC context and log tail
- Quote monitor, model type visibility (
terminal,barrier,comparative_5050where used) - Header telemetry (status, websocket health, orders/latency, trend markers)
/api/execution_telemetryand/api/statusfor machine-readable health
- Start with small
POLY_ORDER_SIZEand increase only after validation. - Binary markets resolve 0/1 — model error and adverse selection can dominate short-term PnL.
- Inventory — lopsided fills and spot moves can lose money before you flatten.
- Resolution / expiry — the bot applies expiry rules (e.g. skips near expiry); do not ignore manual book risk.
- Regulatory / ToS — ensure Polymarket and prediction-market use are permitted where you run this.
This software is for educational and operational use at your own risk; there is no warranty of profit or fitness for a particular purpose.