242 lines
13 KiB
HTML
242 lines
13 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="zh-CN">
|
|
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>PolyWeather - 天气衍生品智能地图</title>
|
|
<meta name="description" content="PolyWeather 天气衍生品智能地图,聚合 METAR、MGM、DEB、多模型预报与历史对账分析。">
|
|
|
|
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
|
|
|
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap"
|
|
rel="stylesheet">
|
|
|
|
<link rel="stylesheet" href="/static/style.css?v=legacy-v19">
|
|
</head>
|
|
|
|
<body>
|
|
<div id="map"></div>
|
|
|
|
<header id="header">
|
|
<div class="brand">
|
|
<h1>PolyWeather</h1>
|
|
<span class="subtitle">天气衍生品智能分析</span>
|
|
</div>
|
|
<button class="info-btn" id="btnShowGuide" title="查看系统技术说明">技术说明</button>
|
|
<div class="live-badge" id="liveBadge">
|
|
<span class="pulse-dot"></span>
|
|
<span>实时</span>
|
|
</div>
|
|
<button class="refresh-btn" id="refreshAllBtn" title="刷新所有数据" aria-label="刷新所有数据">↻</button>
|
|
</header>
|
|
|
|
<nav id="cityList" class="city-list">
|
|
<div class="city-list-header">
|
|
<span>监控城市</span>
|
|
<span class="city-count" id="cityCount">0</span>
|
|
</div>
|
|
<div id="cityListItems" class="city-list-items">
|
|
<!-- Dynamically populated -->
|
|
</div>
|
|
</nav>
|
|
|
|
<aside id="panel" class="detail-panel hidden">
|
|
<div class="panel-header">
|
|
<button class="panel-close" id="panelClose">✕</button>
|
|
<div class="panel-title-area">
|
|
<h2 id="panelCityName">—</h2>
|
|
<div class="panel-meta">
|
|
<span id="panelRiskBadge" class="risk-badge">—</span>
|
|
<span id="panelLocalTime" class="local-time">—</span>
|
|
<button class="history-btn" id="btnShowHistory" title="查看历史记录与准确率">历史对账</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="panelContent" class="panel-body">
|
|
<section class="hero-section">
|
|
<div class="hero-weather" id="heroWeather"></div>
|
|
<div class="hero-temp">
|
|
<span class="hero-value" id="heroTemp">—</span>
|
|
<span class="hero-unit" id="heroUnit">°C</span>
|
|
</div>
|
|
<div class="hero-max-time" id="heroMaxTime"></div>
|
|
<div class="hero-details">
|
|
<div class="hero-item">
|
|
<span class="label">当前实测</span>
|
|
<span class="value" id="heroCurrent">—</span>
|
|
</div>
|
|
<div class="hero-item">
|
|
<span class="label">WU 结算参考</span>
|
|
<span class="value highlight" id="heroWU">—</span>
|
|
</div>
|
|
<div class="hero-item">
|
|
<span class="label">DEB 预测</span>
|
|
<span class="value" id="heroDEB">—</span>
|
|
</div>
|
|
</div>
|
|
<div class="hero-sub" id="heroSub"></div>
|
|
</section>
|
|
|
|
<section class="chart-section">
|
|
<h3>今日温度走势</h3>
|
|
<div class="chart-wrapper">
|
|
<canvas id="tempChart"></canvas>
|
|
</div>
|
|
<div class="chart-legend" id="chartLegend"></div>
|
|
</section>
|
|
|
|
<section class="prob-section">
|
|
<h3>结算概率分布</h3>
|
|
<div id="probBars" class="prob-bars"></div>
|
|
</section>
|
|
|
|
<section class="models-section">
|
|
<h3>多模型预报</h3>
|
|
<div id="modelBars" class="model-bars"></div>
|
|
</section>
|
|
|
|
<section class="forecast-section">
|
|
<h3>多日预报</h3>
|
|
<div id="forecastTable" class="forecast-table"></div>
|
|
<div class="sun-info" id="sunInfo"></div>
|
|
</section>
|
|
|
|
<section class="ai-section">
|
|
<h3>AI 深度分析</h3>
|
|
<div id="aiAnalysis" class="ai-box">
|
|
<span class="ai-placeholder">点击城市后加载...</span>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="risk-section">
|
|
<h3>数据偏差风险</h3>
|
|
<div id="riskInfo" class="risk-info"></div>
|
|
</section>
|
|
</div>
|
|
</aside>
|
|
|
|
<div id="loading" class="loading-overlay hidden">
|
|
<div class="loading-spinner"></div>
|
|
<span>正在获取气象数据,请稍候...</span>
|
|
</div>
|
|
|
|
<!-- 鈹€鈹€ Technical Guide Modal 鈹€鈹€ -->
|
|
<div id="guideModal" class="modal-overlay hidden">
|
|
<div class="modal-content large">
|
|
<div class="modal-header">
|
|
<h2>📚 PolyWeather 系统技术说明</h2>
|
|
<button class="modal-close" id="guideModalClose">✕</button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div class="guide-grid">
|
|
<div class="guide-card">
|
|
<h3>🧮 DEB 动态融合预测</h3>
|
|
<p><b>Dynamic Ensemble Blending</b> 是系统的核心预测层。它不是对 ECMWF、GFS、ICON、GEM、JMA 等模型的简单平均,而是结合最近样本表现、当前实况与城市偏置后得到的动态加权结果。</p>
|
|
</div>
|
|
<div class="guide-card">
|
|
<h3>🎯 结算概率引擎</h3>
|
|
<p>右侧的结算概率分布基于 DEB 预测值与多模型离散度动态计算。μ代表当前分布中心,会随着模型、实况和时间变化而变动,不是固定预报值。</p>
|
|
</div>
|
|
<div class="guide-card">
|
|
<h3>✈️ 结算点与主观测源</h3>
|
|
<p>Polymarket 结算逻辑以机场 METAR 为主。系统现在优先使用 Aviation Weather API 的机场报文与原始 METAR,并区分观测时间与接收时间,避免把发布延迟误认成温度变化。</p>
|
|
</div>
|
|
<div class="guide-card">
|
|
<h3>📍 Ankara 专属增强</h3>
|
|
<p>Ankara 不走通用城市逻辑。结算主站以 LTAC / Esenboğa 为准,周边领先信号优先参考 Turkish MGM 站网,其中 <b>Ankara (Bölge/Center)</b> 是重点监控站,不由 Etimesgut 代替。</p>
|
|
</div>
|
|
<div class="guide-card">
|
|
<h3>📆 未来日期分析</h3>
|
|
<p>点击多日预报后打开的模态框,主要用于分析下一个交易日。 6-48 小时趋势以 weather.gov 和 Open-Meteo 为主,部分城市可会补充 Meteoblue; 0-2 小时临近判断则优先看 METAR 与周边站。</p>
|
|
</div>
|
|
<div class="guide-card">
|
|
<h3>📊 历史对账规则</h3>
|
|
<p>历史准确率对账只统计已结算的样本。网页端采用近15天滚动视图,机器人 /deb 报告采用近7天窗口,不把当天未结算的样本算入胜率和 MAE。</p>
|
|
</div>
|
|
</div>
|
|
<div class="guide-footer">
|
|
<p>※ 数据源以 Aviation Weather / METAR、Turkish MGM、Open-Meteo、weather.gov 为主,部分城市补充 Meteoblue。</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 鈹€鈹€ History Chart Modal 鈹€鈹€ -->
|
|
<div id="historyModal" class="modal-overlay hidden">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h2>📊 <span id="historyModalTitle">历史准确率对账</span></h2>
|
|
<button class="modal-close" id="historyModalClose">✕</button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div class="history-stats" id="historyStats"></div>
|
|
<div class="history-chart-wrapper">
|
|
<canvas id="historyChart"></canvas>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="futureForecastModal" class="modal-overlay hidden">
|
|
<div class="modal-content large future-modal">
|
|
<div class="modal-header">
|
|
<h2>📆 <span id="futureForecastTitle">未来日期分析</span></h2>
|
|
<button class="modal-close" id="futureForecastClose" aria-label="关闭未来日期分析">✕</button>
|
|
</div>
|
|
<div class="modal-body future-modal-body">
|
|
<div class="history-stats" id="futureForecastStats"></div>
|
|
|
|
<section class="future-modal-section">
|
|
<h3>📈 温度走势</h3>
|
|
<div class="history-chart-wrapper future-chart-wrapper">
|
|
<canvas id="futureForecastChart"></canvas>
|
|
</div>
|
|
</section>
|
|
|
|
<div class="future-modal-grid">
|
|
<section class="future-modal-section">
|
|
<h3>🎯 结算概率分布</h3>
|
|
<div id="futureProbBars" class="prob-bars future-prob-bars"></div>
|
|
</section>
|
|
|
|
<section class="future-modal-section">
|
|
<h3>🧮 多模型预报</h3>
|
|
<div id="futureModelBars" class="model-bars"></div>
|
|
</section>
|
|
</div>
|
|
|
|
<div class="future-modal-grid">
|
|
<section class="future-modal-section">
|
|
<h3><span class="section-inline-icon" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19V5"/><path d="M10 19V10"/><path d="M16 19V7"/><path d="M22 19V13"/></svg></span>未来 6-48 小时趋势</h3>
|
|
<div id="futureTrendGrid" class="future-trend-grid"></div>
|
|
</section>
|
|
|
|
<section class="future-modal-section">
|
|
<h3 id="futureNowcastTitle">⏱ 目标日午后峰值窗口</h3>
|
|
<div id="futureNowcast" class="future-text-block"></div>
|
|
</section>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Leaflet JS -->
|
|
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
|
|
<!-- Leaflet Heatmap Plugin -->
|
|
<script src="https://leaflet.github.io/Leaflet.heat/dist/leaflet-heat.js"></script>
|
|
<!-- Chart.js -->
|
|
<script src="https://cdn.jsdelivr.net/npm/chart.js@4/dist/chart.umd.min.js"></script>
|
|
<script src="/static/app.js?v=legacy-v19"></script>
|
|
</body>
|
|
|
|
</html>
|
|
|
|
|
|
|
|
|