Skip to content

AadiXD200/polymarket-weather-bot

Repository files navigation

Polymarket Weather Prediction Bot

An autonomous quantitative trading system that identifies and exploits pricing inefficiencies in Polymarket weather derivative markets. The bot ingests multi-model meteorological ensemble forecasts, computes a probability distribution over temperature outcomes, and bets when its model price diverges significantly from the CLOB market price.


Performance

Paper Trading (Simulated fills at real CLOB prices)

Metric Value
Total trades 63 resolved positions
Win rate 82.5% (52W / 11L)
Gross P&L +$806.49 USDC
Total capital deployed $2,264.15 USDC
ROI on deployed capital +35.6%
Avg model edge at entry 20.6 percentage points above market price
Edge range 2.5pp – 93pp
Period Mar 28 – Apr 3, 2026 (7 days)

Direction breakdown:

Side Trades Win Rate P&L ROI
NO 60 83% +$797.68 +36.1%
YES 3 67% +$8.81 +17.1%

Top 5 trades:

Market Entry Size P&L ROI
Houston NO, Mar 28 $0.06 $17 +$249.14 +1438%
Houston NO, Apr 2 $0.44 $157 +$203.39 +130%
Houston NO, Apr 1 $0.43 $128 +$169.26 +133%
Tel Aviv NO, Apr 1 $0.47 $138 +$159.23 +115%
San Francisco NO, Apr 2 $0.54 $143 +$124.10 +87%

City breakdown:

City Trades Win Rate P&L ROI
Houston 6 83% +$623.53 +186.7%
San Francisco 2 100% +$230.20 +90.9%
Tel Aviv 1 100% +$159.23 +115.1%
Dallas 12 92% +$79.26 +28.8%
Seattle 5 100% +$17.09 +42.4%
Miami 6 100% +$14.08 +23.1%
Buenos Aires 11 82% +$8.59 +3.1%
Paris 2 0% -$233.64 -100%

Note: Paper trading uses real-time CLOB mid prices for entry simulation. Actual live fills would incur bid-ask spread costs (~0.5–2pp per trade) not reflected here.

Live Trading (Real USDC on-chain)

The system has been deployed live on Polygon via the Polymarket CLOB API. As of Apr 5, 2026, 18 real positions are on-chain across 8 cities (Atlanta, Buenos Aires, Chicago, Miami, Sao Paulo, Seattle, Munich, San Francisco), entered between Apr 1–3, 2026. Live resolution tracking is active and awaiting market settlement.


Architecture

polymarket-weather-bot/
├── main.py                  # CLI entry point — scan, exit-scan, resolve, status
├── daemon.py                # Scheduler: runs scans on NWP model update cadence
├── config.py                # All tunable parameters (edges, Kelly, cities, filters)
├── db.py                    # SQLite layer (paper_trades.db / live_trades.db)
│
├── data/
│   ├── openmeteo.py         # Multi-model forecast fetcher (GFS, ECMWF, ICON, GEM, MF)
│   ├── noaa.py              # ASOS station historical observations
│   ├── polymarket.py        # CLOB price + order book queries
│   ├── climatology.py       # Historical temperature distribution
│   └── ...
│
├── signals/
│   ├── ensemble.py          # Combines 5 NWP models → mean, std, score
│   ├── edge_calculator.py   # Core alpha engine: model prob → Kelly bet
│   ├── nowcaster.py         # Blends live observations into forecast
│   ├── bias_corrector.py    # Per-city/model bias correction
│   └── ...
│
├── broker/
│   ├── paper_broker.py      # Simulated execution with all risk checks
│   ├── live_broker.py       # Real CLOB order submission via py-clob-client
│   └── position_manager.py  # Resolution engine + P&L settlement
│
├── metrics/
│   ├── calibration.py       # Shrinkage factor from resolved trade history
│   ├── sharpe.py            # Rolling risk-adjusted return tracking
│   └── reporting.py         # Dashboard data aggregation
│
└── web_dashboard.py         # Flask dashboard with live P&L + open positions

Signal Generation Pipeline

  1. Forecast ingestion — Fetches the 5 latest NWP runs for the target ICAO station from Open-Meteo: GFS, ECMWF, ICON, GEM, Météo-France.

  2. Ensemble statistics — Computes mean, standard deviation, and spread score. High std (models disagree) increases position uncertainty. Low std for NO bets is a skip signal — tight model agreement means temperature is likely heading for a specific bucket.

  3. Nowcasting — If the station has a real-time ASOS observation for the current day, it blends into the forecast using a time-weighted regime (observation weight rises from 0% at midnight to 80% by market close).

  4. Bucket probability — Integrates a Student-t distribution (ν=4, fat tails) over the temperature bucket [lo, hi] to compute P(actual_high ∈ bucket).

  5. Edge calculationedge = model_prob − market_mid_price. Only signals where |edge| > adaptive_min_edge are tradeable.

  6. Filters applied before entry:

    • Minimum edge threshold (dynamic, scales with lead time)
    • NO entry price gate: 0.20 – 0.75 (empirically optimal range)
    • Ensemble std gate: skip NO bets when std < 0.8°C (model consensus = bad for NO)
    • Order book depth check: skip if top-5 CLOB depth < $150 USDC
    • Timing filter: skip if market price has been converging toward model value
    • Global deployment cap: max 40% of portfolio in open positions
  7. Kelly sizing — Fractional Kelly (25%) with tier scaling and a hard cap of $15/trade.


Key Parameters (config.py)

Parameter Value Description
MIN_EDGE 0.08 Minimum model–market gap to enter
KELLY_FRACTION 0.25 Fractional Kelly multiplier
MAX_TRADE_USDC 15.0 Hard per-trade dollar cap
MAX_DEPLOYED_FRACTION 0.40 Max % of portfolio in open positions
NO_ENTRY_MIN_PRICE 0.20 Skip NO bets below 20¢
NO_ENTRY_MAX_PRICE 0.75 Skip NO bets above 75¢
NO_MIN_ENSEMBLE_STD 0.8°C Skip NO bets when models tightly agree
FORECAST_T_DF 4 Student-t degrees of freedom (fat tails)

Setup

Requirements

pip install -r requirements.txt
# Key deps: py-clob-client, flask, requests, python-dotenv, scipy

Credentials

cp .env.example .env
# Fill in POLYMARKET_PRIVATE_KEY, POLYMARKET_PROXY_ADDRESS, and API credentials
# Generate CLOB API creds: python scripts/gen_clob_creds.py

Running

# Paper trading scan (safe, no real money)
python main.py --scan --paper

# Live scan (real orders)
python main.py --scan --live

# Check for exits / stop-losses
python main.py --exit-scan --live

# Resolve settled markets and update P&L
python main.py --resolve --live

# Web dashboard (port 5001)
python web_dashboard.py

# Autonomous daemon (scheduled scans + exits)
python daemon.py

Deployment (GCP / systemd)

The polybot.service and polybot-dashboard.service files are ready-to-use systemd unit files for running the daemon and dashboard as persistent services on a GCP VM.

sudo cp polybot.service /etc/systemd/system/
sudo systemctl enable polybot
sudo systemctl start polybot

Data Sources

Source Used For
Open-Meteo NWP forecasts: GFS, ECMWF, ICON, GEM, Météo-France
NOAA ASOS Historical + real-time station observations
Polymarket Gamma API Market metadata, resolution outcomes
Polymarket CLOB API Live order book prices, order submission
Polymarket Data API Portfolio positions, mark-to-market values

Disclaimer

This is an experimental research project. Prediction market trading involves real financial risk. Past paper trading performance does not guarantee live results. The average edge per trade is small and individual positions can result in total loss.

About

Autonomous quantitative trading bot for Polymarket weather derivative markets — multi-model ensemble forecasting, Kelly criterion sizing, live CLOB execution

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors