Focused async Python bot for Polymarket that buys No on standalone non-sports yes/no markets.
FOR ENTERTAINMENT ONLY. PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED. USE AT YOUR OWN RISK. THE AUTHORS ARE NOT LIABLE FOR ANY CLAIMS, LOSSES, OR DAMAGES.
bot/: runtime, exchange clients, dashboard, recovery, and thenothing_happensstrategyscripts/: operational helpers for deployed instances and local inspectiontests/: focused unit and regression coverage
The bot scans standalone markets, looks for NO entries below a configured price cap, tracks open positions, exposes a dashboard, and persists live recovery state when order transmission is enabled.
The runtime is nothing_happens.
Real order transmission requires all three environment variables:
BOT_MODE=liveLIVE_TRADING_ENABLED=trueDRY_RUN=false
If any of those are missing, the bot uses PaperExchangeClient.
Additional live-mode requirements:
PRIVATE_KEYFUNDER_ADDRESSfor signature types1and2DATABASE_URLPOLYGON_RPC_URLfor proxy-wallet approvals and redemption
pip install -r requirements.txt
cp config.example.json config.json
cp .env.example .envconfig.json is intentionally local and ignored by git.
The runtime reads:
config.jsonfor non-secret runtime settings.envfor secrets and runtime flags
The runtime config lives under strategies.nothing_happens. See config.example.json and .env.example.
You can point the runtime at a different config file with CONFIG_PATH=/path/to/config.json.
The dashboard binds $PORT or DASHBOARD_PORT when one is set.
The shell helpers use either an explicit app name argument or HEROKU_APP_NAME.
export HEROKU_APP_NAME=<your-app>
./alive.sh
./logs.sh
./live_enabled.sh
./live_disabled.sh
./kill.shGeneric deployment flow:
heroku config:set BOT_MODE=live DRY_RUN=false LIVE_TRADING_ENABLED=true -a "$HEROKU_APP_NAME"
heroku config:set PRIVATE_KEY=<key> FUNDER_ADDRESS=<addr> POLYGON_RPC_URL=<url> DATABASE_URL=<url> -a "$HEROKU_APP_NAME"
git push heroku <branch>:main
heroku ps:scale web=1 worker=0 -a "$HEROKU_APP_NAME"Only run the web dyno. The worker entry exists only to fail fast if it is started accidentally.
| Script | Purpose |
|---|---|
scripts/db_stats.py |
Inspect live database table counts and recent activity |
scripts/export_db.py |
Export live tables from DATABASE_URL or a Heroku app |
scripts/wallet_history.py |
Pull positions, trades, and balances for the configured wallet |
scripts/parse_logs.py |
Convert Heroku JSON logs into readable terminal or HTML output |
Local config, ledgers, exports, reports, and deployment artifacts are ignored by default.
