polyweather — Weather tail-event bot
Buys $0.01-$0.10 outcomes on Polymarket weather markets when an Open-Meteo ensemble forecast implies ≥2× the market's probability. 20 cities, 4-hour scan cycle, 20-position cap.
| Strategy type | Tail events |
|---|---|
| Asset | Multi-city |
| Timeframe | Event-driven |
| Market type | Weather |
| Minimum capital | $30 |
| Dependencies | @polymarket/clob-client, ethers |
What it does
polyweather hunts for extreme-temperature outcomes on Polymarket weather markets priced between $0.01 and $0.10 where an ensemble weather forecast says the real probability is at least 2× the market-implied probability. It buys the underpriced tails as FOK takers and holds to resolution.
The edge
Weather markets are populated mostly by casual bettors. The Polymarket book on a "Will NYC hit 95°F tomorrow?" market underprices unlikely outcomes because nobody wants to bet against a sunny forecast for $0.06 even when the historical probability is 12%.
The bot's edge is a real weather forecast (Open-Meteo's ensemble model, free + no auth). When the ensemble says 8% probability and the Polymarket book quotes 3¢ (implied 3%), the gap is your edge. Bet sizes are intentionally tiny ($3 default) because tail outcomes have huge variance — most positions resolve to zero, but the winners pay 10-30x.
How it works
Scan cycle (default every 4 hours):
- Discover active weather markets across the 20 covered cities (NYC, London, Paris, Toronto, Tokyo, Shanghai, Singapore, Seoul, Munich, Tel Aviv, etc., full list in source
CITIES) - Fetch the Open-Meteo ensemble forecast for that city's coordinates for the market's resolution day
- Compute the implied probability of the market's threshold outcome from the ensemble's percentile distribution
- Compare: if
ensemble_prob ≥ edge × market_prob(default edge = 2.0×), the outcome is underpriced - Filter: market price between $0.01 and $0.10, ensemble probability ≥ 2% (
MIN_ENSEMBLE_PROB) - Bet: FOK taker at the market ask price,
--bet $3per position - Cap: up to
--max-pending 20simultaneous positions
Uses viem for signing (instead of ethers, because that's what @polymarket/clob-client-v2 v3.x took as its preferred path).
Sample output
[24/05/2026, 09:00:01] Scanning 47 weather markets... [24/05/2026, 09:00:14] NYC | "Will NYC hit 95°F on May 27?" | market=$0.06 ensemble=14% edge=2.3× — entering [24/05/2026, 09:00:14] BUY (FOK) 50sh @ $0.060 ($3.012 incl fee) [24/05/2026, 09:00:14] Filled: 0x1ab2c3d4... [24/05/2026, 13:00:01] Scanning 47 weather markets... [24/05/2026, 13:00:14] Singapore | "Will Singapore hit 34°C on May 27?" | market=$0.04 ensemble=9% edge=2.25× — entering [27/05/2026, 23:30:00] Resolved WIN "NYC 95°F" | 50sh × $1.00 - $3.00 = +$47.00 | Bal: $77.00
Design targets
Expected value: at 2× edge, a $3 bet at $0.05 entry returns $60 if it wins ($1 × 60 shares) minus $3 cost = $57 net, with ensemble-implied 10% chance. Expected per bet: 10% × $57 - 90% × $3 = $5.70 - $2.70 = +$3.00. Real outcomes have high variance: long stretches of losses punctuated by occasional 10-30x payoffs.
Capital efficiency: 20 max positions × $3 = $60 in active bets. $30 starting bank lets you size up over time as winning resolutions pay out.
FAQ
Why a 2× edge minimum?
Below 2×, the variance of tail outcomes overwhelms the edge. At 2× the long-run expectation is strongly positive even after factoring in ensemble forecast error. You can drop the minimum to 1.5× in source if you want more trades.
What weather data source?
Open-Meteo's free ensemble API. No authentication, generous rate limits, refreshes hourly. The bot uses each ensemble member as a sample to build a probability distribution for the threshold outcome.
Does it work in every city?
Coverage is the 20 cities in the CITIES object: NYC, London, Paris, Toronto, São Paulo, Buenos Aires, Seoul, Seattle, Dallas, Atlanta, Miami, Chicago, Ankara, Wellington, Lucknow, Munich, Tel Aviv, Tokyo, Shanghai, Singapore. Adding more cities is a 1-line edit per city (lat/lon + unit).
What's included
polyweather/weather.jspolyweather/run.sh(auto-restart wrapper)polymarket-limits.js- README with adding cities, edge tuning, and an explanation of the ensemble probability calculation
Configuration
| Flag | Default | Description |
|---|---|---|
| --live | — | Place real orders. Default is dry-run. |
| --sim-balance 30 | 30 | Starting balance in dry-run mode (USD). |
| --max-balance 0 | 0 | Cap balance used for sizing. 0 = use full balance. |
| --bet 3 | 3 | Fixed bet amount per position in USD. |
| --edge 2.0 | 2.0 | Minimum forecast/market edge multiplier before entering. |
| --max-pending 20 | 20 | Maximum simultaneous open positions. |
| --scan-interval 14400 | 14400 | Seconds between market scans. Default is 4 hours. |