A production-ready Python bot exploiting the ~2.7-second lag between Binance price moves and Polymarket odds updates on short-duration BTC/ETH markets.
- Run in paper trading mode for at least 1 week before going live
- This edge is time-limited — the lag may narrow or disappear as the market matures
- Monitor win rate closely — if it drops below ~60%, stop and investigate
- Never risk capital you cannot afford to lose
- Ensure your use of Polymarket complies with their Terms of Service and your local regulations
👉 Contact: Miacle709 📞
The POLYARB web dashboard (default port in .env, e.g. http://localhost:8080) shows run status, KPIs (balance, drawdown, win rate, latency, PnL, max bet), pause / resume / kill, and a recent-trades table.
- Dashboard: http://localhost:8080
- Pause trading:
curl -X POST http://localhost:8080/api/pause - Resume:
curl -X POST http://localhost:8080/api/resume - Kill:
curl -X POST -H "X-Confirm-Kill: CONFIRM" http://localhost:8080/api/kill - Stats JSON:
curl http://localhost:8080/api/stats - Health JSON:
curl -i http://localhost:8080/api/health(returns503if degraded) - Recent trades:
curl http://localhost:8080/api/trades?n=20 - Periodic status logs:
logs/status_YYYY-MM-DD.jsonl(stats + health snapshots) - Daily summaries:
logs/daily_summary_YYYY-MM-DD.json
BinanceFeed (WebSocket) ──signals──► PolymarketTrader ──orders──► Polymarket CLOB
│
RiskManager (Kelly + Kill Switch)
│
DashboardServer (HTTP :8080)
│
TradeLogger (JSONL files)
git clone <repo>
cd polymarket-arbitrage-bot
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements.txtcp .env.example .env
# Edit .env — at minimum set PAPER_TRADING=true to startpython simulator.py --days 7 --asset BTCUSDT --threshold 0.15
# Outputs simulation_results.json with win rate, PnL, drawdown statspython main.py
# Dashboard: http://localhost:8080Optional preflight check (recommended before service start):
python main.py --check-config# In .env:
PAPER_TRADING=false
POLYMARKET_PRIVATE_KEY=0x...
POLYMARKET_API_KEY=...
POLYMARKET_API_SECRET=...
POLYMARKET_API_PASSPHRASE=...sudo cp polymarket-arb.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable polymarket-arb
sudo systemctl start polymarket-arb
sudo journalctl -u polymarket-arb -f # follow logs- Location: AWS us-east-1 or eu-west-1 (close to Binance/Polymarket CDN)
- RAM: 2 GB minimum
- CPU: 2 vCPUs
- Network: Low-latency provider (Hetzner, Vultr, AWS Lightsail)
- Use a VPS in the same region as Binance's WebSocket servers
- Enable TCP_NODELAY (already set in websockets library)
- Prefer IPv4 over IPv6 for WebSocket connections
- Monitor
avg_latency_mson the dashboard; aim for <50ms
main.py # Entry point, asyncio orchestrator
config.py # All parameters, loaded from .env
state.py # Shared mutable state (thread-safe)
binance_feed.py # Binance WebSocket feed + signal detection
polymarket_trader.py # Signal processing + CLOB order placement
risk_manager.py # Kelly sizing, kill switch, daily limits
logger.py # Structured logging + JSONL trade journal
dashboard_server.py # aiohttp HTTP dashboard
simulator.py # Standalone paper trading simulator
logs/
├── bot.log # Human-readable rolling log
└── trades_YYYY-MM-DD.jsonl # Machine-readable trade journal
| Control | Default | Description |
|---|---|---|
| Kill switch | -40% drawdown | Stops all trading permanently |
| Daily pause | -10% daily | Pauses until next UTC day |
| Max open positions | 3 | Concurrent bet limit |
| Min edge | 3% | Minimum edge required to enter |
| Fractional Kelly | 0.25× | Reduces variance vs full Kelly |
| Max bet | $50 | Hard cap per trade |
| Signal staleness | 200ms | Discard signals older than this |
The JSONL trade log is easy to analyse with pandas:
import pandas as pd
df = pd.read_json("logs/trades_2025-12-01.jsonl", lines=True)
entries = df[df.event == "ENTRY"]
print(entries.groupby("asset")[["edge", "size_usd"]].mean())- Create a Polygon wallet (MetaMask or hardware wallet)
- Fund with USDC on Polygon network
- Visit https://polymarket.com and connect wallet
- Generate API credentials: https://docs.polymarket.com/#authentication
- For order signing, review EIP-712 signing in
polymarket_trader.py(or use the officialpy-clob-clientlibrary)
After 1 week of paper trading, calibrate _estimate_fair_prob() in
polymarket_trader.py to match your actual observed win rate per move size:
# Example calibration from paper trading results:
# move_pct=0.15 → actual win rate 63% → set base to 0.63
# move_pct=0.30 → actual win rate 71% → check curve shape
# move_pct=0.50 → actual win rate 79%This is the most important tuning step for live profitability.
