Zephyr is a weather-driven prediction market trading system focused on exploiting probability mispricing in event-based contracts.
Instead of “guessing” outcomes, Zephyr treats prediction market prices as implied probabilities and compares them to forecast probabilities derived from professional meteorological models.
Prediction markets price contracts like:
- YES = $0.60 → market implies a 60% chance
- NO = $0.40 → market implies a 40% chance
Meanwhile, modern ensemble weather models (NOAA GEFS, ECMWF, HRRR) provide probabilistic forecasts.
Zephyr finds situations where:
Forecast probability significantly differs from market probability
Example:
- Forecast says 80% chance of >5" snow
- Market is priced at 60%
- Edge = +20% expected value
Zephyr trades only when this gap is large and stable.
Zephyr converts ensemble outputs into probabilities:
[ P(event) = \frac{#runs\ exceeding\ threshold}{N} ]
Example:
- 42 of 50 runs predict >5 inches snow
→ Forecast probability = 84%
Market price is treated directly as probability:
[ P_{market} = price ]
Zephyr enters positions only if:
- Probability gap exceeds 10–20%
- Multiple models agree
- Forecast confidence is increasing
Zephyr performs best on clean threshold contracts:
- Temperature cutoffs
“Will NYC exceed 85°F tomorrow?” - Snowfall totals
“Will Boston get >3 inches this week?” - Hurricane landfall events
These markets are more structured and forecastable than vague outcomes.
Weather has variance, even with strong models.
Zephyr enforces strict bankroll controls:
- Max 2–3% exposure per contract
- Portfolio of many small edges
- No single-event oversized bets
Long-term profitability comes from repetition, not jackpots.
Planned integrations include:
- NOAA GEFS ensemble forecasts
- ECMWF ensemble probabilities
- HRRR radar nowcasts
- Emergency bulletins and alerts
- Market pricing feeds (Polymarket)
- NOAA ingestion + ensemble probability computation (prototype for one test event)
- Market price scraper + implied probability engine (Polymarket public quote pull)
- Edge detection + trade signal generator
- Backtesting framework (CSV-driven)
- Automated execution + bankroll rules (paper-order logging + fractional Kelly + hard cap)
This repository now includes a first working step for GEFS ingestion and event-probability computation:
scripts/gefs_event_probability.py
It pulls the latest GEFS ensemble run from NOAA NOMADS and computes:
[ P(event) = \frac{runs\ exceeding\ threshold}{total\ runs} ]
Default test event:
- NYC max 2m temperature tomorrow (America/New_York) >= 85F
Precipitation events are also supported in the pipeline (e.g., total precip >= 0.1 in),
and can be logged via scripts/log_snapshots.py when Polymarket markets match the filters.
Run:
python3 scripts/gefs_event_probability.pyExample with custom threshold:
python3 scripts/gefs_event_probability.py --threshold-f 30Build a forecast probability from GEFS and compare it to a market implied probability.
Option A (manual market probability):
python3 scripts/generate_signal.py --market-probability 0.42Option B (live Polymarket quote by market slug):
python3 scripts/generate_signal.py --polymarket-slug your-market-slugPrecipitation example:
python3 scripts/generate_signal.py \
--event-type precip_total \
--threshold-in 0.1 \
--polymarket-slug your-market-slugPaper-log orders when a trade is triggered:
python3 scripts/generate_signal.py \
--market-probability 0.42 \
--paper-ledger data/paper_orders.csvRun the built-in sample backtest:
python3 scripts/run_backtest.pyShow per-trade detail:
python3 scripts/run_backtest.py --show-tradesUse your own CSV:
python3 scripts/run_backtest.py --csv path/to/your_backtest.csvCSV columns:
event_idcontract_tickerforecast_probabilitymarket_probabilityoutcome(1for YES outcome,0for NO outcome)- optional:
timestamp
Discover Polymarket weather/temperature markets (filtered by volume, city, and date window), compute GEFS probabilities, and store snapshots in SQLite:
python3 scripts/log_snapshots.py --db data/zephyr.sqliteUse data/market_universe.json to tune cities, volume, and date window.
Record a resolved outcome:
python3 scripts/record_outcome.py --market-slug your-market-slug --outcome 1Export joined snapshots + outcomes for backtesting:
python3 scripts/build_backtest_from_db.py --db data/zephyr.sqliteThen run the backtest:
python3 scripts/run_backtest.py --csv data/backtest_from_db.csvZephyr is built on one principle:
Trade weather markets like quant probability arbitrage, not gambling.
Forecasts are data. Prices are probabilities. Profit is the gap.