Automated paper-trading bot for Polymarket “highest temperature” markets. It compares professional weather forecasts to market prices, sizes trades with Kelly-style logic, and manages exits with stops and take-profit rules. No Polymarket SDK — plain Python and public HTTP APIs.
| Repository | github.com/Poly-Tutor/Polymarket-Weather-bot |
| Telegram | @AlterEgo_Eth |
- Is: A research and simulation tool that tracks a virtual balance, records forecasts and prices, and simulates buys/sells against Polymarket Gamma prices (bid/ask). It does not submit signed orders to the Polymarket CLOB — treat it as paper trading until you wire in execution yourself.
- Is not: Financial advice. Prediction markets can lose money quickly. Test thoroughly before risking real capital.
how.to.run.weather.bot.mp4
- Python 3.10+ installed (python.org)
- Internet access (forecasts + Polymarket APIs)
git clone https://github.com/Poly-Tutor/Polymarket-Weather-bot.git
cd Polymarket-Weather-bot(If your local folder name differs, cd into the project root that contains bot_v2.py and config.json.)
pip install requestsCreate or edit config.json in the project root. Minimal example:
{
"balance": 10000.0,
"max_bet": 20.0,
"min_ev": 0.1,
"max_price": 0.45,
"min_volume": 500,
"min_hours": 2.0,
"max_hours": 72.0,
"kelly_fraction": 0.25,
"max_slippage": 0.03,
"scan_interval": 3600,
"calibration_min": 30,
"vc_key": "YOUR_VISUAL_CROSSING_KEY"
}| Field | Meaning |
|---|---|
balance |
Starting virtual bankroll |
max_bet |
Cap per trade (dollars) |
min_ev |
Minimum expected value after fees logic (see strategy below) |
max_price |
Do not buy YES above this price (limits chasing expensive contracts) |
min_volume |
Minimum Polymarket volume on that outcome |
min_hours / max_hours |
Only consider markets resolving in this window |
kelly_fraction |
Fraction of full Kelly to use (e.g. 0.25 = quarter Kelly) |
max_slippage |
Max allowed spread (ask − bid) at entry |
scan_interval |
Seconds between full scans (3600 = hourly) |
calibration_min |
Minimum resolved samples before per-city sigma calibration updates |
vc_key |
Visual Crossing API key (optional; used for historical max temps / validation) |
Never commit real API keys to git. Use environment-specific secrets or local-only config.json.
Main bot (full strategy, 20 cities):
python bot_v2.py # main loop: hourly scan + position monitoring
python bot_v2.py status # balance and open positions
python bot_v2.py report # resolved markets breakdownStop with Ctrl+C — state is written under data/.
In a second terminal, from the same project folder:
python dashboard_server.pyOpen http://127.0.0.1:8765/ in your browser. The page polls /api/summary, which reads data/state.json and data/markets/*.json — run it alongside bot_v2.py to watch equity, open positions, recent exits, and entry EV/Kelly lines.
python dashboard_server.py --port 9000 # custom portThe server binds to 127.0.0.1 only (local machine).
data/state.json— virtual balance and aggregate statsdata/markets/— one JSON file per city/date with forecasts, snapshots, and positionsdata/calibration.json— learned forecast uncertainty per city/source (after enough resolutions)
- 6 US cities, NWS hourly forecasts + simple rules
- Good for understanding the idea (airport-aligned coords, bucket matching) without Kelly, multi-model blending, or full exit logic
- Uses
simulation.jsonfor a small virtual balance in--livemode
- 20 cities (US, Europe, Asia, Americas, Oceania)
- Forecasts: ECMWF (Open-Meteo), US short-range blend (GFS seamless / “HRRR” path in code), METAR for same-day reality check
- EV + fractional Kelly sizing, slippage filter, self-calibration of uncertainty
- Stops, trailing stop, take-profit by time-to-resolution, and forecast-shift exits
- Docstring still says
weatherbet.py— runpython bot_v2.py(or rename the file locally if you prefer the old name)
Polymarket lists questions like: “Will the highest temperature in Chicago on April 4 be between 46–47°F?” Each outcome is a bucket (range of temperatures). The market price is the crowd’s implied probability. If a high-quality forecast says “my best guess falls squarely in this bucket” but the YES ask is still cheap, there may be positive expected value (EV) — same spirit as sports betting edges, but driven by weather models instead of team stats.
The bot automates: pull forecasts → map to the same buckets Polymarket uses → estimate probability → compare to price → size the bet → manage risk until resolution or exit.
Official resolution uses specific airport METAR stations (e.g. NYC → LaGuardia KLGA, Dallas → Love Field KDAL). Using city-center lat/lon can skew the predicted max by several degrees; on 1–2° buckets, that error dominates. This repo pins airport coordinates per city to align forecasts with the market’s ground truth.
- ECMWF (via Open-Meteo, bias correction on) — global backbone, daily max for several days ahead.
- US short-range model — for US cities, the code prefers the short-range daily max when available (implemented as GFS seamless in Open-Meteo; comment in code refers to HRRR-style use).
- METAR — current observation at the station; useful for today (D+0) when the day is in progress.
The bot picks a “best” temperature per snapshot (US: prefer short-range; else ECMWF) and uses that to decide which single bucket matches (in_bucket).
- For interior buckets, probability is effectively 1 if the point forecast falls inside the range, else 0 (sharp step).
- For open-ended buckets (“or below” / “or higher”), a normal CDF tail model is used with a sigma (uncertainty): wider sigma → smoother probabilities at the edges.
Sigma starts from defaults (roughly 2°F / 1.2°C) and is recalibrated from past errors per city and source once you have enough resolved history (calibration_min).
- EV compares estimated win probability
pto the ask price (cost per $1 payoff). If EV is belowmin_ev, the trade is skipped. - Kelly suggests a theoretical optimal fraction of bankroll; the bot uses
kelly_fraction(e.g. 0.25) to be more conservative than full Kelly. - Bet size is
min(Kelly × balance, max_bet)so no single trade blows the account.
Trades only if all of these pass (among others):
- Market volume ≥
min_volume - Time to resolution within
[min_hours, max_hours] - Spread ≤
max_slippage(and a fresh API check on bestAsk/bestBid) - Ask <
max_price - EV ≥
min_ev
Positions are monitored between full scans (about every 10 minutes) and also updated during scans:
- Stop-loss: initial stop near 80% of entry (20% adverse move on the position’s mark).
- Trailing: if price moves ~20% in your favor vs entry, stop can move to breakeven.
- Take-profit (monitor path): if more than 24h to resolution, scale out at staged thresholds (e.g. 75¢ if 48h+ left; 85¢ if 24–48h); inside 24h it tends to hold toward resolution.
- Forecast change: if the best forecast moves materially out of your bucket (with a buffer so noise doesn’t exit every hour), the position can close early (
forecast_changed). - Resolution: when Polymarket marks the market closed, the bot reads outcome prices from the Gamma API and settles P&L as win/loss.
All of the above runs against public prices and a local balance. Connecting to real trading requires Polymarket wallet signing and CLOB integration — not included here. Treat outputs as backtest / paper until you add that layer.
| API | Auth | Role |
|---|---|---|
| Open-Meteo | None | ECMWF + short-range daily max |
| Aviation Weather METAR | None | Live station temps |
| Polymarket Gamma | None | Events, markets, prices |
| Visual Crossing | Free tier key | Historical max temps (optional) |
config.jsonnot found: Run commands from the directory that containsconfig.json.- No trades: Tighten
min_ev, raisemax_price, or lowermin_volumeslightly — or wait for markets inside the hour window. - Connection errors: The main loop waits and retries; check firewall/VPN.
Questions or collaboration: Telegram @AlterEgo_Eth.
This software is for education and research. It is not investment advice. Weather markets involve model error, liquidity, and operational risk. Past simulated performance does not guarantee future results.