Автоматический бот для заработка на weather prediction markets на Polymarket
weather-bot | Порт: 3201/home/app/polymarket-weather-bot/home/app/.claude/skills/weather-bot/SKILL.md592e45e (28 Apr 2026)Бот, который 24/7 сканирует погодные рынки на Polymarket, сравнивает с профессиональными прогнозами (Open-Meteo/NOAA) и ставит limit orders когда находит расхождение >5%.
Целевые метрики:
UI: Web dashboard на szhub.space/weather-bot (FastAPI + Vanilla JS)
Правило: НИКОГДА не использовать токен Бендера. Свой TG бот или Web Push.
┌─────────────────────────────────────────────────┐
│ Weather Bot │
│ │
│ ┌──────────┐ ┌──────────┐ ┌───────────────┐ │
│ │ Scanner │→ │ Analyzer │→ │ Executor │ │
│ │(Gamma API)│ │(Open-Meteo)│ │(CLOB Orders) │ │
│ └──────────┘ └──────────┘ └───────────────┘ │
│ ↓ ↓ ↓ │
│ ┌──────────────────────────────────────────┐ │
│ │ SQLite DB │ │
│ │ markets | forecasts | trades | pnl │ │
│ └──────────────────────────────────────────┘ │
│ ↓ │
│ ┌──────────┐ ┌──────────┐ │
│ │ Telegram │ │ Logs │ │
│ │ Alerts │ │ (Winston)│ │
│ └──────────┘ └──────────┘ │
└─────────────────────────────────────────────────┘
| # | Модуль | Что делает |
|---|---|---|
| 1 | Scanner | Gamma API → находит активные weather markets (город, тип, порог, дата) |
| 2 | Forecaster | Open-Meteo API → получает прогноз, строит probability model |
| 3 | Analyzer | Сравнивает model P vs market P, считает edge |
| 4 | Executor | Если edge > порог → limit order через CLOB API |
| 5 | Tracker | Отслеживает открытые позиции, P&L, resolution |
| 6 | Notifier | Telegram алерты: новые ставки, resolution, daily P&L |
| 7 | Risk Manager | Max per market, daily loss limit, kill switch |
| Компонент | Технология | Почему |
|---|---|---|
| Язык | Python 3.10+ | py-clob-client — официальный SDK |
| Trading | py-clob-client | Polymarket CLOB API |
| Weather | Open-Meteo API | Бесплатно, без API key, hourly 16 дней |
| DB | SQLite | Лёгкая, уже используем в futures-screener |
| Process | PM2 | Уже есть на сервере |
| Alerts | Telegram Bot | У нас уже есть Bender |
| Scheduler | APScheduler | Python cron внутри процесса |
| Logs | loguru | Простой structured logging |
py-clob-client>=0.1.0
web3==6.14.0 # ВАЖНО: пиннить! Новые версии ломают py-clob-client
python-dotenv
requests
aiohttp
apscheduler
loguru
python-telegram-bot
Каждые 5 минут сканирует Gamma API на новые/обновлённые weather markets.
GET https://gamma-api.polymarket.com/markets
?tag=weather
&active=true
&closed=false
{
"condition_id": "0x...",
"question": "Will the high temperature in NYC on April 27 be 75°F or higher?",
"tokens": [
{"token_id": "12345...", "outcome": "Yes", "price": 0.72},
{"token_id": "67890...", "outcome": "No", "price": 0.28}
],
"volume": 15000,
"end_date": "2026-04-27T23:59:00Z",
"resolution_source": "NOAA Climate Data"
}
Из текста вопроса извлекаем:
marketsCREATE TABLE markets (
id TEXT PRIMARY KEY, -- condition_id
question TEXT,
city TEXT,
date TEXT, -- YYYY-MM-DD
metric TEXT, -- high_temp, low_temp, precip, wind
threshold REAL, -- в °C (нормализовано)
operator TEXT, -- gte, lte, between
yes_token_id TEXT,
no_token_id TEXT,
volume REAL,
end_date TEXT,
resolution_source TEXT,
created_at TEXT,
status TEXT DEFAULT 'active' -- active, traded, resolved
);
Для каждого найденного рынка получает профессиональный прогноз.
GET https://api.open-meteo.com/v1/forecast
?latitude=40.71
&longitude=-74.01
&hourly=temperature_2m,precipitation,wind_speed_10m
&temperature_unit=fahrenheit
&timezone=America/New_York
&forecast_days=7
CITIES = {
"NYC": {"lat": 40.71, "lon": -74.01, "tz": "America/New_York"},
"London": {"lat": 51.51, "lon": -0.13, "tz": "Europe/London"},
"Seoul": {"lat": 37.57, "lon": 126.98, "tz": "Asia/Seoul"},
"Tokyo": {"lat": 35.68, "lon": 139.69, "tz": "Asia/Tokyo"},
"LA": {"lat": 34.05, "lon": -118.24,"tz": "America/Los_Angeles"},
"Chicago": {"lat": 41.88, "lon": -87.63, "tz": "America/Chicago"},
"Miami": {"lat": 25.76, "lon": -80.19, "tz": "America/New_York"},
"Dallas": {"lat": 32.78, "lon": -96.80, "tz": "America/Chicago"},
"Denver": {"lat": 39.74, "lon": -104.99,"tz": "America/Denver"},
"Seattle": {"lat": 47.61, "lon": -122.33,"tz": "America/Los_Angeles"},
}
Для вопроса "Will high temp ≥ 75°F?":
N(forecast_max, sigma)P(temp ≥ threshold) = 1 - CDF(threshold)from scipy.stats import norm
def calculate_probability(forecast_max, threshold, days_ahead):
sigma = {1: 2, 2: 2, 3: 4, 4: 4, 5: 4}.get(days_ahead, 6)
prob = 1 - norm.cdf(threshold, loc=forecast_max, scale=sigma)
return round(prob, 4)
# Пример: прогноз 78°F, порог 75°F, завтра
# P = 1 - CDF(75, μ=78, σ=2) = 0.933 → 93.3% вероятность YES
forecastsCREATE TABLE forecasts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
market_id TEXT,
forecast_value REAL, -- predicted max/min/etc
model_probability REAL, -- наша оценка P(YES)
sigma REAL, -- uncertainty
fetched_at TEXT,
FOREIGN KEY (market_id) REFERENCES markets(id)
);
def analyze_opportunity(market, forecast):
model_prob = forecast.model_probability
market_prob = market.yes_price # текущая цена YES на Polymarket
edge = model_prob - market_prob
# Фильтры
if abs(edge) < 0.05: return None # edge < 5% → skip
if market.volume < 5000: return None # low liquidity → skip
if forecast.sigma > 5: return None # too uncertain → skip
# Направление
if edge > 0:
side = "YES" # модель говорит вероятнее чем рынок думает
price = model_prob - 0.02 # чуть ниже модели для заполнения
else:
side = "NO"
price = (1 - model_prob) - 0.02
return {
"market_id": market.id,
"side": side,
"price": price,
"edge": abs(edge),
"model_prob": model_prob,
"market_prob": market_prob
}
| Уровень | Edge | Действие | Размер ставки |
|---|---|---|---|
| Weak | 5-10% | Ставим min | $5 |
| Medium | 10-20% | Стандарт | $10-15 |
| Strong | 20%+ | Aggressive | $20-50 |
from py_clob_client.clob_types import OrderArgs, OrderType
from py_clob_client.order_builder.constants import BUY
def place_bet(client, token_id, price, size):
order = OrderArgs(
token_id=token_id,
price=round(price, 2), # кратно 0.01
size=size,
side=BUY
)
signed = client.create_order(order)
response = client.post_order(signed, OrderType.GTC)
return response
RISK_CONFIG = {
"max_per_market": 50, # макс $50 на 1 рынок
"max_daily_loss": 100, # -$100/день → стоп
"max_open_positions": 20, # не более 20 одновременно
"max_total_deployed": 300, # макс $300 в позициях
"min_volume": 5000, # skip рынки с volume < $5K
"min_edge": 0.05, # skip edge < 5%
"max_position_pct": 0.15, # не более 15% банка на 1 ставку
"cooldown_same_market": 3600, # 1 час между ставками на один рынок
}
🌤️ NEW BET
NYC High Temp ≥ 75°F (Apr 27)
Model: 93.3% | Market: 72% | Edge: 21.3%
→ BUY YES @ $0.71 × $15
Status: Order placed (GTC)
✅ RESOLVED — WIN
NYC High Temp ≥ 75°F (Apr 27)
Actual: 79°F → YES wins
Profit: +$4.35 (29% ROI)
📊 DAILY SUMMARY
Bets: 12 | Won: 9 | Lost: 3 | WR: 75%
P&L: +$38.50 | Total deployed: $180
Bank: $538.50 (+7.7% today)
/home/app/polymarket-weather-bot/
├── .env # PRIVATE_KEY, TELEGRAM_TOKEN, etc
├── ecosystem.config.js # PM2 config
├── requirements.txt
├── bot.py # Main entry point + scheduler
├── scanner.py # Gamma API market discovery
├── forecaster.py # Open-Meteo + probability model
├── analyzer.py # Edge detection
├── executor.py # CLOB order placement
├── risk.py # Risk management
├── tracker.py # Position tracking + P&L
├── notifier.py # Telegram alerts
├── db.py # SQLite schema + helpers
├── config.py # Constants, cities, thresholds
├── utils.py # Parsing, conversion helpers
├── data/
│ └── weather-bot.db # SQLite database
└── logs/
└── bot.log
| # | Шаг | Что делаем | Время |
|---|---|---|---|
| 1 | Scaffold + Auth | Проект, .env, py-clob-client подключение, тест API | 30 мин |
| 2 | Scanner + Forecaster | Gamma API парсинг weather markets + Open-Meteo прогнозы + probability model | 1-2 часа |
| 3 | Analyzer + Executor | Edge detection + limit order placement + SQLite tracking | 1-2 часа |
| 4 | Risk + Notifier | Risk limits, kill switch, Telegram алерты, daily summary | 1 час |
| 5 | Test + Deploy | Тест с $5-10 реальных, PM2, мониторинг первые 24ч | 1 час |
Итого: 1-2 дня до рабочего бота.
clobTokenIds[0] = YES| Что | Сколько |
|---|---|
| USDC на Polygon | $200-500 |
| MATIC на газ | $1-2 |
| Open-Meteo API | $0 (free) |
| Gamma API | $0 (free) |
| VPS | $0 (наш сервер) |
| Итого | $201-502 |