c93af97059
- 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.
113 lines
5.0 KiB
Python
113 lines
5.0 KiB
Python
#!/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()
|