📡 天气数据采集与管道架构
文档生成: 2026-04-30 08:36 CST
覆盖: 全部数据源、采集脚本、存储与同步
一、总览
┌──────────────────────────────────────────────────────────────────┐
│ 数据源 (5路) │
├──────────────┬────────────┬────────────┬────────────┬────────────┤
│ HKO API │ Open-Meteo │ METAR │ WU PWS │Polyweather │
│ (官方) │ (NWP) │ (机场) │ (个人站) │ (市场) │
└──────┬───────┴──────┬─────┴──────┬─────┴──────┬─────┴──────┬─────┘
│ │ │ │ │
▼ ▼ ▼ ▼ ▼
┌──────────────────────────────────────────────────────────────────┐
│ JSONL 平面文件 │
│ data/hko/ data/history/metar/ data/history/wu_pws/ data/mm/ │
└────────────────────────────┬─────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────────┐
│ DuckDB (weather_market.duckdb) │
│ hko_obs | hko_daily | hko_forecast | metar_obs | wu_pws_obs │
│ wu_pws_daily | market_snapshots │
└────────────────────────────┬─────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────────┐
│ 预测模型 │
│ hko_predict.py → hko_prediction.json │
└──────────────────────────────────────────────────────────────────┘
二、数据源详细
2.1 HKO 官方 API(hko_data_fetcher.py)
脚本: polymarket/scripts/hko_data_fetcher.py
运行: cron 每分钟(--loop 模式,实际 fetch 间隔 10 分钟)
输出: data/hko/hko_latest.json + data/hko/hko_history_YYYYMMDD.jsonl
数据端点
| 端点 | 格式 | 频率 | 内容 |
|---|---|---|---|
rhrread (Current Weather) | JSON | 每小时 | 27 站实时温湿度 |
1-min temperature CSV | CSV | 每10分钟 | 40+ 站高精度温度 |
Max/Min since midnight CSV | CSV | 每10分钟 | 日最高/最低温(结算关键) |
1-min humidity CSV | CSV | 每10分钟 | 30+ 站湿度 |
10-min wind CSV | CSV | 每10分钟 | 风向/风速/阵风 |
1-min solar radiation CSV | CSV | 每10分钟 | 太阳辐射 (W/m²) |
1-min pressure CSV | CSV | 每10分钟 | 海平面气压 |
fnd (9-day forecast) | JSON | 每天2次 | 预报最高/最低/天气 |
flw (Local forecast) | JSON | 每小时 | 天气预报文本 |
RYES (Daily Report) | JSON | 每日 01:30 | 昨日官方最高/最低 |
Daily Extract XML | XML | 每月 | 官方结算值 |
AWS past 24h CSVs | CSV | 按需 | 全站 24h 历史 |
关键函数
fetch_hko_data() # 主入口:拉取全部端点
fetch_aws_past24h() # AWS GIS 24h 历史
save_latest(data) # 保存 hko_latest.json
append_history(data) # 追加 JSONL 日志
hko_latest.json 结构
{
"current": {"temp": 20.7, "humidity": 66, "icon": [51]},
"max_min": {"hko_max_since_midnight": 22.4, "hko_min_since_midnight": 20.2},
"all_stations": [...],
"forecast": {"today_forecast": {"max_temp": 26, "min_temp": 20, "weather": "...", "psr": "Low"}},
"local_forecast": {"description": "...", "general": "...", "outlook": "..."},
"warnings": {"codes": "", "messages": []},
"aws_24h": {...},
"fetch_time": "2026-04-30T08:00:00+08:00"
}
特殊处理
hko_temp=None 时跳过预测写入 开头时判为失败2.2 Open-Meteo NWP(weather_data_enricher.py)
脚本: polymarket/scripts/weather_data_enricher.py
API: api.open-meteo.com/v1/forecast
用途: 数值天气预报 (Numerical Weather Prediction),增强预报信号
拉取数据
| 参数 | 说明 |
|---|---|
temperature_2m_max | 日最高温(多模型集合) |
cloud_cover / cloud_cover_low / cloud_cover_mid | 云量层 |
shortwave_radiation | 短波辐射 (W/m²) |
precipitation | 小时降雨量 |
cape | 对流有效位能 (J/kg) |
relative_humidity_2m | 近地面湿度 |
多城市拉取
香港 + 全球 28 个城市(通过经纬度查询),每个城市获取 HKO 预报 + NWP 区域平均。
特殊功能
2.3 METAR 机场观测(metar_collector.py)
脚本: polymarket/scripts/metar_collector.py
API: aviationweather.gov/api/data/metar
用途: 机场气象观测(部分 Polymarket 天气合约的结算数据源)
采集范围
全球 29 个合约城市的 ICAO 机场站,例如:
| 城市 | ICAO |
|---|---|
| 香港 | VHHH |
| 深圳 | ZGSZ |
| 新加坡 | WSSS |
| 东京 | RJTT |
| 纽约 | KJFK |
| ... | ... |
数据字段
{
"icao": "VHHH",
"raw": "METAR VHHH 300730Z 04012KT ...",
"temp_c": 21.0,
"dewpoint_c": 17.0,
"wind_dir_deg": 40,
"wind_speed_kt": 12,
"visibility_m": 10000,
"cloud_base_ft": 2500,
"max_temp_24h": 26.0,
"min_temp_24h": 20.0
}
监听模式
python3 metar_collector.py --loop 300 # 每5分钟
python3 metar_collector.py --station VHHH # 单站
python3 metar_collector.py --hours 24 # 24h历史
输出
data/metar/latest_metar.json — 最新快照data/metar/metar_YYYYMMDD.jsonl — 按日 JSONL 日志metar_obs 表2.4 WU PWS 个人气象站(wu_pws_scraper.py)
脚本: polymarket/scripts/wu_pws_scraper.py
数据源: Weather Underground PWS Dashboard(SSR HTML 解析)
用途: 全球 PWS 5 分钟级地面观测(29 城市各 1 个精选站)
工作原理
WU Angular app 在服务端渲染时将 PWS 数据嵌入 HTML 标签,脚本直接解析 JSON 而非走 API。
HTML SSR → extract JSON → parse observations → save
数据字段
| 字段 | 单位 | 说明 |
|---|---|---|
tempHigh / tempLow / tempAvg | °F→°C | 日高/低/均 |
humidityHigh / humidityLow | % | 湿度范围 |
windspeedHigh / windgustHigh | mph→m/s | 风速/阵风 |
winddirAvg | deg | 平均风向 |
precipTotal | in→mm | 降水量 |
pressureMax / pressureMin | inHg→hPa | 气压范围 |
solarRadiationHigh | W/m² | 太阳辐射 |
uvHigh | index | UV 指数 |
监听模式
python3 wu_pws_scraper.py --loop 300 # 每5分钟
python3 wu_pws_scraper.py --station ISINGA249 # 单站
速率限制
批次间 sleep 3-5 秒,防止被 WU 封禁。
输出
data/wu_pws/pws_YYYYMMDD.jsonl — 按日 JSONL 日志wu_pws_daily + wu_pws_obs 表2.5 Polymarket 市场数据(polyweather_scraper.py)
脚本: polymarket/scripts/polyweather_scraper.py
API: polyweather.club/api/polymarket/data
用途: 抓取 Polymarket 天气合约盘口 + 市场价 + 历史交易
数据字段
| 端点 | 内容 |
|---|---|
/api/polymarket/data?date= | 市场盘口、价格历史、WU 预报、MM 仓位 |
/api/data | WU 实时温度 |
关键提取内容
{
"markets": [...], # 活跃市场列表
"outcome_prices": {...}, # 各 bin 的市场价
"orderbook": {...}, # 盘口深度
"price_history": [...], # 历史交易
"wunderground": {...}, # WU 预报
"positions": {...} # MM 持仓
}
输出
data/market_snapshots/ — 分钟级市场快照market_snapshots 表三、DuckDB 存储(sync_to_duckdb.py)
脚本: polymarket/scripts/sync_to_duckdb.py
运行: cron 每 15 分钟
数据库: data/weather_market.duckdb(约 ~50MB,列式存储)
表结构
| 表名 | 来源 | 字段 | 更新方式 |
|---|---|---|---|
hko_obs | HKO 1-min CSV | station, ts, temp, max_since_midnight, humidity, solar, wind... | 追加 |
hko_daily | HKO RYES | date, max_temp, min_temp, forecast_max | 追加 |
hko_forecast | HKO fnd | target_date, max_temp, weather, psr, fetch_ts | 追加 |
metar_obs | METAR API | icao, valid, temp_c, wind_speed, visibility... | 追加 |
wu_pws_daily | WU PWS | station, date, temp_high_c, temp_low_c, precip_mm... | 追加 |
wu_pws_obs | WU PWS | station, ts, temp_c, humidity, wind_speed... | 追加 |
market_snapshots | Polyweather | ts, market_data (JSON) | 追加 |
增量同步逻辑
# 每张表独立增量
last_ts = db.execute("SELECT MAX(ts) FROM hko_obs").fetchone()
new_rows = [row for row in jsonl_data if row['ts'] > last_ts]
db.executemany("INSERT INTO hko_obs VALUES (...)", new_rows)
DB 锁处理
hko_predict.py 遇到锁时重试 3 次(5s 间隔),read_only 模式连接。
四、数据管道调度
Cron 任务
| 任务 | 频率 | 脚本 |
|---|---|---|
| HKO 数据采集 | 每分钟 | hko_data_fetcher.py --loop |
| HKO 预测 | 每 10 分钟 | hko_predict.py |
| DuckDB 增量同步 | 每 15 分钟 | sync_to_duckdb.py |
| METAR 采集 | 每 5 分钟 | metar_collector.py --loop 300 |
| WU PWS 采集 | 每 5 分钟 | wu_pws_scraper.py --loop 300 |
| Open-Meteo NWP | 每小时 | weather_data_enricher.py |
| 市场快照 | 每 5 分钟 | polyweather_scraper.py |
时间线(每天)
00:00 新日周期开始
01:30 RYES 日报发布(昨日官方值)
06:00 fnd 预报更新
08:00 日内预测激活(轨迹/内陆/激进信号启用)
10:00-14:00 峰值预测窗口
16:00 风控时间窗口结束
17:00+ 锁定模式(只降不升)
18:00 fnd 第二次更新
23:59 日内观测停止
五、数据文件布局
polymarket/data/
├── weather_market.duckdb # 主数据库
│
├── hko/
│ ├── hko_latest.json # 最新快照
│ ├── hko_prediction.json # 预测输出
│ ├── hko_prediction_log.jsonl # 预测历史
│ ├── hko_history_20260430.jsonl # 按日观测日志
│ ├── nwp_bias.json # NWP 偏差 EMA
│ └── hko_llm_cache.json # LLM 推理缓存
│
├── history/
│ ├── metar/
│ │ └── metar_20260430.jsonl
│ └── wu_pws/
│ └── pws_20260430.jsonl
│
├── metar/
│ └── latest_metar.json
│
├── wu_pws/ # PWS 持久数据
│
├── mm/ # MM 策略数据
│ ├── weather_quotes.jsonl # 报价日志
│ ├── weather_fills.jsonl # 成交日志
│ ├── weather_positions.json # 持仓状态
│ ├── weather_state.json # 运行时状态
│ └── auto_trading.json # 自动交易开关
│
└── market_snapshots/ # 市场快照
└── snapshot_20260430T080000.json
六、API 暴露(Web 端)
数据通过 polymkt.sopher.cool 的 Flask 路由暴露:
| 路由 | 数据源 | 用途 |
|---|---|---|
/api/weather/hk/live | hko_latest.json | 当前温度/最高/最低/湿度 |
/api/weather/hk/bracket | hko_prediction.json + Polymarket API | Bracket 策略 + 概率分布 |
/api/weather/hk/tomorrow | hko_latest.json + Open-Meteo | HKO 预报 + NWP 7 日 |
/api/weather/hk/all | DuckDB backtest | 回测历史 |
/api/weather/hk/day-over-day | DuckDB | 连续日对比 |
/api/weather/hk/llm-predict | LLM API | LLM 实时推理 |
/api/weather/hk/llm-analyze | LLM API | LLM 综合分析 |
/api/weather/hk/llm-betting | hko_prediction.json + LLM | 投注建议 |
/api/weather/hk/history-curves | DuckDB | 历史温度曲线 |
/api/weather/data | DuckDB | 多城市行情总览 |
/api/weather/data/distribution | DuckDB | 多城市概率分布 |
/api/weather/paper | data/mm/ | Paper trading 数据 |
/mm/weather | Dashboard | MM 策略监控面板 |
/weather/hk | Dashboard | HK 天气主页面 |
/weather/decision | Dashboard | 决策中心 |
七、回填与维护
历史回填
python3 scripts/hko_backfill.py # 回填 HKO 观测
python3 scripts/history_backfill.py # 回填 WU PWS 历史
python3 scripts/migrate_to_duckdb.py # 一次性 SQLite → DuckDB 迁移
NWP 偏差更新
结算后调用(手动/脚本):
python3 scripts/hko_predict.py --update-nwp-bias <actual_max> [date]
更新 data/hko/nwp_bias.json 中的 EMA 偏差值。
DB 统计
python3 scripts/sync_to_duckdb.py --stats
八、数据流完整性检查
关键数据门控
| 检查 | 脚本 | 处理 |
|---|---|---|
hko_temp=None 时跳过预测 | hko_predict.py | 不写文件,等待下次 |
| DB 写锁重试 ×3 | hko_predict.py | 5s 间隔,报错退出 |
| HTML 错误 CSV 响应 | hko_data_fetcher.py | 返回 None |
| WU PWS 空数据 | wu_pws_scraper.py | 跳过该站 |
| METAR 超时 | metar_collector.py | 跳过批次 |
| 市场 API 空响应 | polyweather_scraper.py | 重试 2 次 |
数据新鲜度
九、脚本速查
| 脚本 | 功能 | 运行方式 |
|---|---|---|
hko_data_fetcher.py | HKO 官方数据采集 | cron 每分钟 |
hko_predict.py | 最高温预测 | cron 每10分钟 |
weather_data_enricher.py | Open-Meteo + 偏差 | cron 每小时 |
metar_collector.py | METAR 机场观测 | cron 每5分钟 |
wu_pws_scraper.py | WU PWS 抓取 | cron 每5分钟 |
polyweather_scraper.py | 市场数据抓取 | cron 每5分钟 |
sync_to_duckdb.py | 平面文件→DuckDB | cron 每15分钟 |
hko_backfill.py | HKO 历史回填 | 按需 |
hko_llm_reasoning.py | LLM 推理模块 | hko_predict 调用 |
hko_llm_betting.py | LLM 投注建议 | API 触发 |
hko_live_predict.py | 仅监测不写文件 | 监控用途 |
history_backfill.py | WU 历史回填 | 按需 |
migrate_to_duckdb.py | 数据库迁移 | 一次性 |