HK Weather Prediction Market Pipeline: WeatherNext + HKO + Polymarket
- Open-Meteo WeatherNext API client for HK forecasts - HKO public data client (current conditions, 9-day forecast, typhoon warnings) - HK-specific weather extraction and calibration - Polymarket market scanning, price discovery, and market creation proposals - Trading strategy engine: edge detection, Kelly criterion sizing, probability calibration - End-to-end pipeline with dry-run mode and scheduled runner - Interactive dashboard with live HK weather + forecasts + trading signals Dependencies: Python 3.10+, openmeteo-requests, pandas No API keys needed for dry-run mode. Polymarket trading requires private key in .env.
This commit is contained in:
+112
@@ -0,0 +1,112 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Quick test and display of HK weather forecasts with trading signals."""
|
||||
|
||||
import sys
|
||||
from datetime import datetime, timedelta
|
||||
from weather.hk_extractor import HKExtractor
|
||||
from weather.hko_client import HKOClient
|
||||
from weather.openmeteo_client import OpenMeteoClient
|
||||
from strategy.signals import SignalGenerator
|
||||
from strategy.calibrator import ProbabilityCalibrator
|
||||
from strategy.kelly import KellyCriterion
|
||||
|
||||
|
||||
def main():
|
||||
print("╔══════════════════════════════════════════════════════╗")
|
||||
print("║ HK Weather Prediction Market Dashboard ║")
|
||||
print(f"║ {datetime.now():%Y-%m-%d %H:%M:%S} HKT ║")
|
||||
print("╚══════════════════════════════════════════════════════╝")
|
||||
print()
|
||||
|
||||
# Fetch data
|
||||
weather = HKExtractor()
|
||||
hko = HKOClient()
|
||||
|
||||
print("─── Current Conditions ───────────────────────────────")
|
||||
current = hko.get_current_weather()
|
||||
if current:
|
||||
temps = current.get("temperature", [])
|
||||
for t in temps[:3]:
|
||||
print(f" {t['place']:20s} {t['value']}°C")
|
||||
print(f" Humidity: {current.get('humidity', [{}])[0].get('value', 'N/A')}%")
|
||||
warning = current.get("warning_message", "")
|
||||
if warning:
|
||||
print(f" ⚠ {warning}")
|
||||
|
||||
om = OpenMeteoClient()
|
||||
cur = om.get_current_conditions()
|
||||
if cur:
|
||||
print(f" Feels like: {cur.get('apparent_temp', 'N/A')}°C")
|
||||
print(f" Wind: {cur.get('wind_speed', 'N/A'):.1f} km/h")
|
||||
print(f" Pressure: {cur.get('surface_pressure', 'N/A'):.1f} hPa")
|
||||
|
||||
# Typhoon info
|
||||
typhoon = hko.get_typhoon_info()
|
||||
if typhoon:
|
||||
signal = hko.get_current_signal_level()
|
||||
print(f" Typhoon signal: {'T' + str(signal) if signal else 'None'}")
|
||||
|
||||
print()
|
||||
print("─── HKO 9-Day Forecast ───────────────────────────────")
|
||||
hko_fc = hko.get_forecast()
|
||||
if hko_fc:
|
||||
for day in hko_fc[:5]:
|
||||
print(f" {day['date']} ({day['week']}): "
|
||||
f"{day['forecast_temp_min']}-{day['forecast_temp_max']}°C, "
|
||||
f"Wind: {day.get('forecast_wind', 'N/A')}")
|
||||
|
||||
print()
|
||||
print("─── WeatherNext (Open-Meteo) Forecast ───────────────")
|
||||
fc = weather.get_hk_forecast(lead_days=5)
|
||||
wnext = fc.get("sources", {}).get("weathernext", [])
|
||||
for day in wnext[:5]:
|
||||
print(f" {day['date']}: "
|
||||
f"↑{day['temp_max_calibrated']:.1f}°C ↓{day['temp_min_calibrated']:.1f}°C, "
|
||||
f"Rain: {day['precipitation_probability_calibrated']:.1f}% ({day['precipitation_sum']:.1f}mm), "
|
||||
f"Wind: {day['wind_speed_max_calibrated']:.1f} km/h")
|
||||
|
||||
print()
|
||||
print("─── Trading Signals ──────────────────────────────────")
|
||||
sig_gen = SignalGenerator()
|
||||
sig_gen.generate_signals()
|
||||
print(sig_gen.get_signal_summary())
|
||||
|
||||
# Also show market creation proposals
|
||||
print()
|
||||
print("─── Proposed Markets (for Polymarket) ────────────────")
|
||||
tomorrow = datetime.now() + timedelta(days=1)
|
||||
if wnext:
|
||||
d1 = wnext[0] if len(wnext) > 0 else {}
|
||||
rain_p = d1.get("precipitation_probability_calibrated", 50)
|
||||
temp_p = d1.get("temp_max_calibrated", 30)
|
||||
wind_p = d1.get("wind_speed_max_calibrated", 15)
|
||||
|
||||
print(f" 1. 'Will it rain in HK on {tomorrow:%Y-%m-%d}?' [YES: ~{rain_p:.0f}%]")
|
||||
print(f" 2. 'Will HK temp exceed 33°C on {tomorrow:%Y-%m-%d}?' [YES: ~{min(95, max(5, 50 + (temp_p - 33) * 20)):.0f}%]")
|
||||
print(f" 3. 'Will HK temp exceed 35°C on {tomorrow:%Y-%m-%d}?' [YES: ~{min(95, max(5, 50 + (temp_p - 35) * 20)):.0f}%]")
|
||||
print(f" 4. 'Will rain exceed 10mm in HK on {tomorrow:%Y-%m-%d}?' [check hourly]")
|
||||
print(f" 5. 'Will a T8 signal be hoisted in HK in the next 7 days?'")
|
||||
|
||||
print()
|
||||
print("─── Kelly Sizing Sim ─────────────────────────────────")
|
||||
kelly = KellyCriterion(bankroll_usdc=1000.0)
|
||||
for name, our_p, mkt_p in [
|
||||
("Rain tomorrow", rain_p, 45),
|
||||
("Temp > 35°C", min(95, max(5, 50 + (temp_p - 35) * 20)), 30),
|
||||
]:
|
||||
r = kelly.size_bet(our_p, mkt_p, "buy_yes")
|
||||
if r.kelly_active:
|
||||
print(f" {name}: Bet ${r.size_usdc:.2f} YES (edge={r.edge:.3f})")
|
||||
else:
|
||||
r2 = kelly.size_bet(our_p, mkt_p, "buy_no")
|
||||
if r2.kelly_active:
|
||||
print(f" {name}: Bet ${r2.size_usdc:.2f} NO (edge={r2.edge:.3f})")
|
||||
else:
|
||||
print(f" {name}: No edge (model={our_p:.0f}% vs market={mkt_p:.0f}%)")
|
||||
|
||||
print()
|
||||
print("═" * 56)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user