天气战士 · 老实看天气很枯燥吧?
用看股票的方式看天气 蜡烛图 · 分时走势 · 日/周/月 K 线 · 五档盘口 · 成交明细 · 自选城市 · 行情刷新频率 网页版 · Android APK lolikonnn.github.io/weather-fighter GitHub · B 站 · QQ 空间关于作者
Ciallo~(∠・ω< )⌒☆ | 在哪 | 地址 | | --- | --- | | GitHub | @lolikonnn | | B 站 |2744759271 |
| QQ 空间 |
站里左上角那个 By lolikonnn 点开就是这里。
改名说明:仓库原叫weather-exchange,已改名为weather-fighter。
旧网址 https://lolikonnn.github.io/weather-exchange/ 现在是 404 —— GitHub Pages
不会跟着仓库改名做路径跳转,请换用上面的新地址。
这份 README 只讲「这是什么、怎么用」。
公式是怎么调出来的、踩过哪些坑、哪些字段是真数据哪些是建模的,
都在 docs/NOTES.md —— 不关心实现细节的话不用点进去。
每次更新改了什么 → CHANGELOG.md。
每个数字是从哪个接口拿的 → docs/APIS.md。--- !界面预览
上图:分时走势(当日逐小时气温 + 均价线 + 昨收基准线),左侧城市收藏,右侧「未来 5 天高低温」与「每小时气温流水」。
界面预览
| 分时走势 | 日 K + 温差 | | --- | --- | | !分时走势 | !日K | | 降水副图(日 K · 按天聚合) | 风副图(周 K · 按周聚合) | | --- | --- | | !降水副图 | !风副图 | | 空气副图(日 K · AQI + PM2.5 + 紫外线) | 雷达回波(八个大区) | | --- | --- | | !空气副图 | !雷达回波 | | 卫星云图 | 降水预报 | | --- | --- | | !卫星云图 | !降水预报 | | | | | --- | --- | | !7日明暗带 | !副图叠加到主图 |上左:7日图按自然日铺明-暗交替的底色(四明三暗,一眼看出一天一天的界限),紫色 PM2.5 线叠在主图上。
上右:日 K 上叠加降水量线(青色,走最右侧第 3 根 Y 轴);副图口径随时可用「📈 叠到主图」按钮拉到主图。| 台风路径 | 预警信号 | | --- | --- | | !台风路径 | !预警信号 | | 地震(中国地震台网 + USGS 两路合并) | | --- | | !地震 |
地震面板用的是两路合并的真实目录:中国地震台网(CENC)经 Wolfx 转发(api.wolfx.jp
带 Access-Control-Allow-Origin: *)+ 美国 USGS(免 key、CORS 全开,补 130 天窗口与全球覆盖)。
按离当前城市的真实大圆距离排序,近的排前面;副标题写着
「最近 130 天 · 700 公里内 N 次(中国地震台网 x · USGS y) · 最近一次 X 公里」,
每一行还标着自己是哪一路来的。
至于 CENC 自己的站点 www.ceic.ac.cn:响应是 200,但不带跨域头,浏览器里直连读不到 —— 所以才借 Wolfx。
| 观星条件(天文七页的第一页) | 潮汐 |
| --- | --- |
| !观星条件 | !潮汐 |
左:观星条件页按小时给云量、透明度、光污染,再折算成今晚能不能看;等级用 1–9 级(天文通那套档位),
银河的门槛是 5 级。页面下半截是「全年气候」—— 拿 Open-Meteo 归档接口近 10 个完整年的逐日全天平均云量,
聚合成 12 个月的少云率。
右:潮汐页的调和常数来自 Neaps tide-database(TICON-4,CC BY 4.0),16 个站点各 50 个分潮,
本地推算,对香港天文台 744 个整点的平均绝对差 0.036 m。| 当前所在地(按坐标取的天气) | 指数条 = 左栏镜像 | | --- | --- | | !当前所在地 | !指数条 |
左:定位到越秀区,天气是按经纬度直接取的,所以标「无官方站号」;体感/风向/气压走 Open-Meteo 补齐。
右:顶栏指数条跟左栏「当前位置 + 自选城市」完全同步,点一下就能切城市。| 行情头:统计格 + 月相/昼长 + 预警滚动条 | | --- | | !行情头 |
就是主图正上方那一块。左边是天气 + 价格,右边一格一个数,按同类分了五行:
今天有多热(最高 / 最低 / 体感 / 全天波动)、风(风速 / 风向 / 平均风速 / 气压)、
天上有什么(云量 / 紫外线 / 湿度 / 降水)、日月(日出 / 日落 / 昼长 / 月相)、
读数基准(今日 0 点 / 昨日 23 点 / 同期 / 观测点)。
月相没有任何数据源直接给,是按朔望月自己算的;昼长优先用数据源的日照秒数,没给就拿日出日落相减;
云量和紫外线取的是当前这个小时的值(抬头看一眼天,和这个数对得上才有用)。
算法和取舍都写在 docs/NOTES.md 里。
最下面那条预警滚动条是行情软件里"滚动播报"那个位置。它只滚当前正在看的那座城市的预警
——自选里切到哪座城市,条子就跟着换(不是“定位在哪就永远滚哪”);标签上会写清是哪座城市。
筛法不是按距离画圈(画圈会把隔壁市的一起卷进来),也不只是"把城市名拿去标题里找" ——
那样子串会撞上同名:青海省的「海南」和海南省、「吉林市」和「吉林省」、北京的朝阳区和长春的
朝阳区…… 2026-10-10 修过一次:现在先认省(气象局的标题是「<省>[<市>[<区>]]发布…」),
省对不上就直接否掉;同一个省里再看有没有点名本城/本区;标题只点了省的那种(省级预警)省内所有城市与区县都算 ——
所以「海南省发布暴雨蓝色预警」全省可见,而它不会再跑到青海去。在看区县时会把上级市一起算进来
(区一级常常没有自己的预警)。这个区市一条都没生效的时候整条收起来,不留"暂无预警"占位。
内容比可视区短就静态显示,长了才自己慢慢往左走(26 像素/秒)。
手指可以随时横向拖、桌面滚轮也能滚 —— 一碰它就停下来让位,松手几秒后接着走。
系统里开了「减少动态效果」时不自动走,但仍然拖得动。
整条可以点,点开就是完整的预警信号面板(横向拖过就不算点,免得想拖一下却跳进面板)。| 7日横轴带日期 | 预报 K(10 天历史 + 16 天预报) | | --- | --- | | !7日横轴 | !预报K | | 术语对照表 | 手机竖屏 · 自选 | | --- | --- | | !术语对照表 | !手机自选 |
左:顶栏 ?术语 打开。里面有一节专门讲 主图上那几条线 —— 红色实线(气温)、金色线(均价)、
灰色水平虚线(基准线,值=昨天 23 点)、深浅交替的日界带、以及自己叠上去的
蓝/绿/灰蓝/紫细线(降水 / 风速 / 云量 / PM2.5)和 K 线图上的 MA5/10/20/30/60。| 手机竖屏 · 台风 | 手机竖屏 · 雷达(按省自动选中华南) | | --- | --- | | !手机台风 | !手机雷达 | | 手机竖屏 · 主图不再被压扁 | 手机竖屏 · 主图全屏(⤢) | | --- | --- | | !手机主图 | !手机全屏 |
左:窄高屏上主图原来会被 flex:1 压成 0 高(页签下面直接就是副图,看起来像"主图不见了"),
现在窄屏给.chart-box{flex:1 1 auto;min-height:170px},整页高度改为.pane-center内部滚动。
行情头在竖屏默认只留「气温」「天空」两组统计格、后面三组折起来(点「全部数据 ▾」全放),
省下来的高度都给主图;行情头底部那条红色小条是预警滚动条(跟着当前城市走)。
右:全屏按钮用 CSS(position:fixed;inset:0 + 隐藏其它块)而不是 Fullscreen API ——
iOS Safari 至今不支持 Element.requestFullscreen,CSS 方案在哪都能用,Esc 也能退出。
| 日 K 日期轴不再被缩放条压住 |
| --- |
| !日K日期轴 |
日期标签原本落在H-26 .. H-14,而dataZoom滑块的顶边在H-20,两者正好重叠。
把主 K 线图的| 涨空心、跌实心(A 股习惯) | | --- | | !空心K线 |grid(52,56,16,34)改成grid(52,56,16,46),把标签抬到滑块上方。
气温 K 线比真股票密集得多,全实心会糊成一片色块。涨的实体只留描边,跌的实心填充,
影线走 borderColor 所以仍是涨色 —— 涨跌方向在一堆重叠的 K 线里也能一眼扫出来。
| 首次访问的免责弹窗 | 网页底端常驻的免责声明 |
| --- | --- |
| !免责弹窗 | !免责声明 |
左:第一次打开弹一次(localStorage.welcomed记住,之后不再弹;?welcome=1可强制弹)。
右:弹窗关掉之后,底端那条一直在,点它可以把完整声明再弹回来 ——
私自开展天气预报业务是违法的,这条不能只藏在弹窗里。| 免责声明在手机竖屏(落在底部页签上方) | | --- | | !手机免责声明 |
407×760 的手机视口。body 是 grid,加这一行必须同步改三处
grid-template-rows(桌面 / 竖屏 / 横屏),否则最后一行会被挤出视口。
实测无横向或纵向溢出,.disclaimer 落在底部页签上方。
桌面截图 1600×1000。手机截图是 407×760 的真实手机视口,不是把桌面版缩小出来的。
(注意:Windows 上无头 Chrome 会把 --window-size=407,760 悄悄夹到约 500px 宽,
然后只截左边 407px —— 那样得到的"手机截图"右侧是被裁掉的,不能用。要量真手机布局,
必须把页面装进一个 407px 宽的 iframe 里,getBoundingClientRect() 拿到的才是真值。)
| 操盘手 · 开局说明 | 操盘手 · 操盘中 |
| --- | --- |
| !操盘手封面 | !操盘手中 |
左:点顶栏的 🎮 点击做空天气 进来的开场说明(面板标题叫 Climate Create Bet,
入口按钮仍然叫「点击做空天气」),把爆仓线一次讲清,最后一条是中途退出不会作废。
右:一局进行中的样子 —— 顶栏写着 第 18 天 03:30 · 已交易 975 / 2880 根 · 20 倍杠杆;图上除了
15 分钟 K 线与 MA5/MA20,还有一条紫色虚线的大盘(同省城市平均)和一条持仓均价虚线;
K 线下面是活跃度量柱,最下面是账户权益曲线。右侧面板是保证金 / 强平价 / 爆仓距离与挂单区。
截图这一局标的是厦门 WXI,持仓多 195 手。| 操盘手 · 爆仓 | 操盘手 · 结算 | | --- | --- | | !爆仓 | !结算 |
左:100 倍杠杆满仓,反向走掉 9 个点(约 0.9%)就没了,整屏红闪 + 震动;结算卡最后一句是
「最后请欣赏绚丽多彩的空中飞人表演!」—— 这一句从做出来那天到现在一字未改。
右:30 天交易走完自动结算,按收益倍数评级(S/A/B/C/D/E/SSS,爆仓固定 F),记本机最佳(收益率)。
八个等级各有一句收场白,语气是欠揍雌小鬼那味、等级越低越嚣张:
爆仓那句(红)最欠揍 → E 亏本接着嘲 → D「这也值得高兴吗」→ C 棒读式夸奖(中性色)→
B/A「诶?居然…不过运气用完就没啦」→ S/SSS 嘴上不认输、心里已经服了(金)。
这些句子里提到杠杆的地方都是按这一局真实用的倍率现算的:100× 就会说「100 倍杠杆…
反向约 0.9%」(和卡片上「杠杆」那一行、以及新手入门的规则表逐字对得上);
1× / 5× 爆仓用的是那句不提数字的 —— 不为了让句子好看去编一个数。
它是嘴替,不是天气预报。| 操盘手 · K 线周期 | | --- | | !K 线周期 |
右下角那块:1 分 / 5 分 / 15 分 / 30 分 / 1 时 / 4 时 / 1 日七档,局中随时切。卡片里会直接标明这一档
是「数据源原样」还是「拿 N 根并成 1 根」还是「插值画出来的」—— 见
七档 K 线周期。
这块连下面的「行情速度」一起,六项设置都会记住上次调好的那一套 ——
本金 / K 线周期 / 行情速度 / 杠杆 / 仓位 / 音效。结束一局、关掉页面、明天再进来还是那个样子。
设置跟「进行中的那一局」分开存:点「结束本局」清掉的是那一局,设置不受影响。| 操盘手 · 手机竖屏 | | --- | | !手机操盘 |
窄屏:主图钉在顶部不动,只有控件区滚动,做多 / 做空常驻屏幕最底部 ——
可以一边看着图一边下单,不用滚来滚去(滚一下图就被推走那种设计已经改掉了)。
卡片弹出来的时候(开场说明 / 新手入门 / 结算 / 退出确认)那条常驻键会自动收起来,
不会压住卡片自己的按钮。| 操盘手 · 新手入门 | | --- | | !新手入门 |
面板右上角的 ?:不看股票的人也能照着玩 —— 这是什么、怎么看图、怎么下单、什么时候结束,
四节都在一张卡里,手机上整页可滚。
截图是 500×1000 的窄视口(Windows 上无头 Chrome 能开的最小宽度),行情是真实数据(广州)。
这是什么
一个把气温当成股价来展示的天气软件。整个交互、配色、术语都照搬 A 股行情终端: | 股票里的东西 | 这里对应什么 | | --- | --- | | 股票代码 | 城市代码(中国天气网的101010100 这类 9 位码) |
| 最新价 / 涨跌幅 | 当前气温 / 相对昨日同一时次的变化(分母用绝对温标,见下) |
| 分时图 | 今天 00:00–23:00 的逐小时气温,含均价线、昨收虚线 |
| 日 K / 周 K / 月 K | 每天的开盘价 = 当日 00:00 气温,收盘价 = 当日 23:00 气温,最高/最低 = 当日极值 |
| 成交量(现在叫「温差」) | 日内最高温 − 最低温;底部副图页签可切到 降水 / 风 / 云量 / 空气 |
| MA5 / MA10 / MA20 / MA60 | 最近 5 / 10 / 20 / 60 天的平均气温,看大方向 |
| MACD / KDJ / RSI / BOLL / WR | 已经删掉了 —— 这几个股票指标对看天气没用,换成了下面「天气功能」里的真东西 |
| 五档盘口(卖五~卖一 / 买一~买五) | 未来 5 天的预报最高温(卖盘,由高到低)与预报最低温(买盘,由低到高) |
| 成交明细 / 逐笔 | 最近 60 个逐小时观测,涨跌按对上一时次着色 |
| 自选股 | 「城市收藏」(跟电商里的「商品收藏」同一个构词)。第一次打开会预置 北京/上海/广州/深圳/长沙/武汉(只在这一项从没存过时塞;把收藏删光就照实为空,不会再冒出来)。增删就点那颗星:空心 ☆ = 没收藏,实心 ★(金色)= 收藏了,全站统一这一个符号。星的位置分两档、两种档位的横坐标都钉死成一条线(名字格固定 90px,所以星不随名字长短飘):桌面端紧跟城市名,手机端在城市名与涨跌之间那片空档、跨两行垂直居中。名字比格子长时(区县全名最长 15 字)——桌面端只给「选中那一行」开横向滚动把名字看全(动内层、外层格子不动,所以星不晃);手机端名字格占满剩余宽度、根本不超出,不滚。可按涨幅或名称排序、长按某一行还能上下拖动自定义顺序(松手即保存);行情头城市名旁边那颗星点一下就能加/取。加城市走搜索框或「全部城市」抽屉(352 城)——原来的「热门城市」那块已删除(项目初期的试验内容) |
| 行情刷新频率 | 1s / 3s / 5s / 10s / 30s / 1m / 5m / 手动 |
| 涨跌配色 | 红涨绿跌(A 股)/ 绿涨红跌(美股)一键切换 |
| K 线实体 | 涨空心、跌实心(A 股习惯)。气温 K 线比真股票密集得多,全实心会糊成一片色块;空心后涨跌一眼可辨。实现上就是把 itemStyle.color 设成 transparent 只留描边,影线走 borderColor 所以仍是涨色 |
| 平盘日 | 画中性绿(--flat: #00b578;2026-10-07 从灰改成绿,"持平的灰色改为绿色吧")。开盘价取当日第一个有效整点、收盘价取最后一个,两者相等就是"一天下来没升没降"—— 实测 576 个交易日里有 19 天(3.3%)。这种日子既不红也不绿,量柱也同色,跟 tooltip 里的 U.trendColor() 一致 |
| 涨跌幅的尺度 | 气温是间隔尺度量,摄氏 0 度是人为约定的,所以比值的分母必须加上 273.15 换成绝对温标。否则 0℃ 以下符号会整个翻转(实测哈尔滨 90 个交易日里 88 天收盘价在 0℃ 以下、其中 47 天"升温却显示成负数",最离谱的一天大降温 11.3℃ 却显示 +235.4%)。换算之后涨跌幅落在 ±0.2%~2.5%,恰好是真实股票一天的波动区间 |
| 数据来源与兜底 | 每个城市先试中国气象局的官方站号(实况最准),取不到就退回 Open-Meteo。注意气象局的"没有观测"不是一个空值,而是一整套 9999 哨兵(数值字段 9999、字符串字段 "9999"、lastUpdate 停在最后一次正常上报)—— 澳门/台北这类长期停报的站会一直返回它。所以实况一律先过 cleanNow() 清洗,洗完没有可用温度就当没取到走 Open-Meteo,而不是把 9999 显示成 9999.0℃ / +3358% |
天气功能
炒股软件的长相下面,装的是气象台真正会给的东西。顶栏那一排按钮就是入口: | 按钮 | 打开什么 | 数据源 | | --- | --- | --- | | 🛰 雷达回波 | 雷达拼图,三层可选:全国 → 八大区(东北/华北/华东/华中/华南/西北/西南)→ 单站(精确到城市)。三层都是可横向滚动的一排按钮(滚轮也能滚,见 docs/NOTES.md)。打开时默认取当前正在查看的城市的雷达站,另有「📡 当前位置」快捷入口可一键跳到所在地的雷达站。城市多到一个省二十几个按钮,所以「📡 当前位置」旁边还有个城市搜索框:城市名/拼音/城市代码都能搜,本省找不到就自动去全国目录找(跨省结果显示成成都 · 四川),回车直接进第一条。每 6 分钟一帧,可拖滑块也可自动播放,能回看约 30 小时 | image.nmc.cn 中央气象台雷达拼图 |
| ☁ 卫星云图 | 气象卫星云图,两种产品可切:真彩云图(风云四号 B 星,默认档,白天最好看)/ 红外云图(风云二号,每 30 分钟一张)。能回看一天 | image.nmc.cn 国家卫星气象中心 WXBL / WXCL |
| 🌧 降水预报 | 中央气象台全国降水量预报图,两种产品可切:最近 1 小时实况(默认档,每小时一张)/ 未来 24 小时预报(每 12 小时一张) | image.nmc.cn STFC_SFER_ER1 / STFC_SFER_ER24 |
| 🌀 台风路径 | 西北太平洋活动台风的实时路径 + 中央气象台 120 小时预报路径。底图是「亚洲–太平洋」,中国和台风同框,看得出台风往哪走 | typhoon.nmc.cn |
| ⚠ 预警信号 | 全国生效中的气象预警,按颜色分级,含发布单位与完整正文。按离当前城市的距离排序,最近的排最前,每条标出距离;列表可上下滚动。顶栏下面那条预警滚动条点开的也是它 | typhoon.nmc.cn 预警接口 |
| 🌡 海陆温 | 两张全国图:陆地气温实况(中央气象台,每小时一张)/ 海表温度(NASA GIBS 的卫星融合产品,有几天延迟)。两张图分开署名 —— 数据挂错来源跟"自行更改预报内容"是同一类问题 | image.nmc.cn + NASA GIBS |
| 🌋 地震 | 真目录,不是图片:中国地震台网(CENC,经 Wolfx 转发)+ 美国 USGS 两路合并,取最近 130 天、700 公里内,按到当前城市的大圆距离排序;震级分色(≥6 红 / ≥5 橙 / ≥4 黄 / 其余蓝)。副标题写明「N 次(中国地震台网 x · USGS y) · 最近一次 X 公里」,每行标注来源 | api.wolfx.jp(CENC)+ earthquake.usgs.gov |
| 🔭 天文 | 天文爱好者那几样,七个子页:🌌 观星条件(低云/中高云分层打分 + 降水/湿度/风/月光/气溶胶,直接给出今晚最合适的那一段;云太多会封顶;另给本站光污染 1~9 级与近 10 年的全年少云夜气候)· 🔭 此刻星空(不联网:此刻地平线以上的亮星、五颗肉眼行星、银河中心高度、月球距离与视大小)· 🌇 朝霞晚霞(自拟启发式:中高云当画布、低云别挡死地平线、气溶胶够不够浓)· 🌌 极光 · 空间天气(当前所在位置上空的极光概率 %(NOAA OVATION 1° 网格)+ 太阳风速度/Bz + 太阳耀斑等级 + Kp 未来三天柱状 + G1~G5 等级)· 🌗 日月(日出日落、月出月落、黄金/蓝调时刻、天文夜、月球距离、月相、下次满月/新月)· ☄️ 流星雨(接下来五场的极大、ZHR、辐射点、母体彗星,以及极大夜的月光干扰)· 🌊 潮汐(16 个港口的 50 个分潮现算:此刻水位与涨落速率、未来 24 小时曲线、高平潮/低平潮时刻表、未来 7 天潮差、形状因子 F 判半日潮还是全日潮、月中天与高潮间隙) | NOAA SWPC(极光 / Kp / 太阳风 / 耀斑 / 太阳黑子)+ Open-Meteo(分层云量 / 能见度 / 气溶胶)+ Neaps tide-database(TICON-4 / NOAA,CC BY 4.0)+ 本地推算(亮星 / 行星 / 日月出没 / 月相 / 潮汐调和常数求和) |
只有雷达能做到城市级:气象局除了全国拼图和八大区拼图,还发布每个雷达站自己的产品
(image.nmc.cn/.../RDCP/..._ECREF_AZ####_...,图上自带压字「雷达站名 / 数据范围 / 观测时间」)。
352 个城市里有 156 个能匹配到独立站(清单见 web/data/radar-cities.json),剩下的
(佛山、珠海、惠州、东莞、中山、江门、上海、拉萨、香港、澳门、台北……)用离它最近的那个有站城市的单站产品:
气象局没有「按坐标取雷达」的接口,所以无论手选城市还是纯坐标定位(当前所在地),都只能落到最近的单站产品上。
大区拼图一覆盖就是几百公里,本地那块雨根本看不出来,这正是要的效果。打开时头部会写明用的是哪一站、离当前城市多远。
> 这套「就近站」的口径在雷达和天文两个地方都用到了:雷达是“离当前城市最近的有站城市”,
> 天文是“用当前所在城市的经纬度算日月出没”,都是本地算完再取数,不依赖任何“按坐标查询”的服务。
单站页没有入口页面,靠 slug 拼出来({省拼音}/{市拼音}.htm,如guang-dong/guang-zhou.htm)。
云图和降水预报官方只有全国版,没有区域版,所以这两页是「全国图 + 按城市对齐时次」,
不能像雷达那样放大到城市。这也是把它们默认档改成「真彩云图 / 最近 1 小时实况」的原因 ——
既然放不大,就默认给最新最清晰的那张。
台风是路径图不是图片,点列表里任意台风就能看它的轨迹。
打开就先有东西看:每次冷启动要拉六份数据(历史 560 天、近 92 天 + 16 日预报、实况、预报、
官方快照、官方月度日历),手机上一次好几秒;可这里面绝大部分根本不会变 ——
昨天的日K、上个月的历史,跟刚才打开时一模一样。所以:① 这六件事并发发出去
(原来是一条await接一条的瀑布,要串行等六轮网络往返);② 上次那份行情存在localStorage里
(最多 2 座城市、一份 336 KB,派生数据不存、逐小时只留最近 116 天),
下次打开先把它原样渲染出来,状态栏写明正在更新 …(当前显示 12 分钟前的数据),
同时照常去拉最新的,回来再替换 —— 就是手机天气软件那个体感。
功能页头部那行「这一屏在看什么」的说明,手机竖屏上也显示:标题和 ✕ 占第一行,它换到第二行。
数据源是会挂的,挂的时候要有个交代,而且整站还得能用:Open-Meteo 的免费额度是按天/按小时
算的,用尽就全线 429(2026-10-07 真发生过,主站报 Daily API request limit exceeded. Please try again tomorrow.)。
关键前提:气象局那三路(实况 / 官方预报 / 官方日历)跟 Open-Meteo 是互相独立的,
那种情况下它们照常返回。所以:
① 三份"贵且不太会变"的响应各占一个localStorage槽位(arch历史逐小时 /fcst近期+预报 /
min 15 分钟行情),每个两档有效期 —— 新鲜期内零请求,而数据源挂了时连过期的也认
(arch30 天、fcst/min14 天)。过期的 K 线照样是那条 K 线,比一张空图强得多。
② 历史逐小时的 archive 主机挂了还会换 historical-forecast-api 那台(配额是分开的)。
③ 降级合并:新拿回来的那份如果只有气象局几路(曲线是空的),就**把实时的行情栏字段贴到
历史曲线上**,而不是拿空曲线把好曲线顶掉。
④ 盘口不依赖 Open-Meteo:obList()优先吃fcst.daily(官方 5 日预报);以前它先检查
d.daily 非空才往下走 —— 额度一用尽就显示"暂无预报数据",那条守卫已经拆了。
⑤ 空曲线时主图上会写明原因,不是干巴巴一句"暂无K线数据"。
⑥ 「点击做空天气」只硬依赖 15 分钟行情,给它持久缓存就能照常开局。
> 实测(tmp/degrade.js,真实现场):报价头 22.9℃ +6.4 +2.21%、
> 盘口 12 个子元素 / 官方 5 日预报齐全、有历史快照时曲线一根不少且 now 是刚拉的、
> 游戏也能开局(连接状态 = 行情推送中)。
> 只有逐时流水是空的 —— 它读的就是 Open-Meteo 那一份,而气象局的 now 只有一个观测点,
> 凑不出 60 行流水;宁可空着,也不拿一个点重复 60 遍。
地震这一页跟上面几个不一样:它是真目录不是图片 —— 从 USGS 拉最近 130 天、
700 公里内的地震,按到当前城市的大圆距离排序,近的排前面,副标题写着
「最近 130 天 · 700 公里内 N 次 · 最近一次 X 公里」。震级用颜色分档(≥6 红 / ≥5 橙 /
≥4 黄 / 其余蓝)。目录是两路合并的:中国地震台网(CENC)自己的站点 www.ceic.ac.cn
响应 200 却不带跨域头、浏览器直连读不到,所以走 Wolfx(api.wolfx.jp) 转发的那一份
(它带 Access-Control-Allow-Origin: *);USGS 那一路负责补 130 天窗口与全球覆盖。
两边按 ±10 分钟且球面距离 ≤100 公里 判重,重复时保留 CENC 那条(中文地名更有用)。
Wolfx 的《使用许可》要求注明来源,所以列表底部与每一行都写了来源。底部副图页签从股票的 MACD / KDJ / RSI / BOLL / WR 换成了五个天气口径, 而且每个都跟着上面选的主图周期走: | 页签 | 画什么 | | --- | --- | | 温差 | 日内温差(最高 − 最低) | | 降水 | 降水量柱(左轴 mm)+ 降水概率线(右轴 %) | | 风 | 风速柱(按蒲福风级着色)+ 阵风虚线 + 顶部风向箭头 | | 云量 | 低云 / 中云 / 高云堆叠面积 + 总云量线 | | 空气 | PM2.5 柱 + AQI 线(含「良 100」参考线) | 副图右侧还有一个 「📈 叠到主图」 按钮:把当前副图的口径拉一条线画到上面的主图上 (降水 → 青色降水量线、风 → 绿色风速线、云量 → 灰蓝云量线、空气 → 紫色 PM2.5 线)。 这条线走主图最右侧的第 3 根 Y 轴(
offset:44),不跟百分比轴抢刻度;按钮状态会记在
localStorage 里,副图切回「温差」时自动置灰。口径与主图对齐统一按时间键查表,不是按下标 ——
按下标会在「分时/7日」上整体错位(主图是「今天 24 小时 / 昨天→未来五天」,而聚合序列是
「从现在往前 2 小时起 24 小时」)。
日界明暗带:7日 / 多日折线图按自然日铺明-暗交替的底色(7 天 = 四明三暗),
并在每条日界画竖虚线,一眼能看出一天一天的界限。单日分时(只有一天)不铺带。
带子挂在一条不画线的独立系列上(z:1),保证永远在气温线和均价线之下。
选分时就是今天的逐小时,选7日就是逐小时 168 个点(昨天 + 今天 + 未来五天),
选日 K 就按天聚合最近 60 天,
选周 K / 月 K 就按周 / 按月,选预报 K 就是最近 10 天 + 未来 16 天(一共约 26 根)。
聚合口径按物理量定:
降水量求和、降水概率取最大、风速阵风取最大、云量和 PM2.5/AQI 取平均;
风向不能平均,取「风最大的那一刻」的风向。
预报 K 的窗口以前是往回留 45 天,图上四分之三都是历史 —— 过去的占比过多,
现在历史只留 10 天当参照,重心全部让给预报。周期页签的「7日」口径是 昨天 + 今天 + 未来五天(共 168 个逐时点)—— 天气预报最要紧的就是后面这几天,所以窗口是往前压的,不是往回看。 窗口的尾端故意停在"未来第五天":右侧栏那块「未来 5 天高低温」列的就是这五天, 两块图上下对着看,正好一一对应。
7日图的横轴会写日期:10-05 12:00 10-06 12:00 …,每个自然日一格日期,
正好压在明暗带的交界上,和上面说的日界带是一套东西。
这里踩过一个坑:轴标签的S.seven标志从来没被传进去过(seriesFor()的返回对象里没有这个字段),
所以 formatter 分支永远走不到,横轴只有 00:00 / 12:00 而没有日期。
这一档的「温差」副图也跟着主图走,而且逐小时那两档换了口径。
温差(当日最高 − 当日最低)是每天的量:一天一个数,摊到 24 个小时上就是一条平线
(分时档下整幅图只剩一根柱子)。所以分时 / 7日 改成「较当日均温」:
这一小时的气温比当天平均冷暖多少,围绕 0 上下,每天一个完整的波。
日K / 周K / 月K 仍然是"当天的日内温差" —— 那里一天本来就是一根柱子。
横轴类别直接用主图的时间键,上下两块图一格对一格。
以前它不管主图什么周期,一律画 553 根日K:主图 24 小时、副图 553 天,说的不是同一段时间。
雷达 / 云图 / 降水预报这三张是图片,文件名里的时次戳是 UTC(不是北京时间),
前端按floor(分钟/6)*6(雷达)、:15 / :45(云图)、整点(降水实况)对齐到官方出图的
整点网格,再换算成本地时区显示。界面上的时次和图上自带的压字时间戳是对得上的 ——
这是这套时间换算正确的硬证据。
点击做空天气
顶栏右上角有个 🎮 点击做空天气,点进去是拿这个城市的真实天气当行情的小游戏。入口按钮和面板标题不是一个名字,这是故意的。
按钮(顶栏那个)一直叫 🎮 点击做空天气;点进去之后,面板左上角和开场说明上的标题是
🎮 Climate Create Bet。改名时只动了面板里那两处,按钮一个字没碰。
不看股票也能玩。 面板右上角有个 ?,点开是「新手入门」:这是什么、怎么看图、
怎么下单、什么时候结束,四节讲完,不假设读者懂 K 线。开场封面讲的是“参数”(天数、杠杆、成本),
这一张讲的是"读图"(蜡烛四个价、红绿代表什么、黄线和紫线是什么、右边那串数字只看哪两个),
两处不重复。
为什么标的是「天气指数」而不是气温
第一版直接拿气温当价格,收到了很准的差评:不太行,因为必然大趋势是冬天降温夏天升温。太稳定了没有什么感觉,只要稳住总会升/降的。问题在于气温是个太温和的信号。它有昼夜循环、有季节趋势,一个小时才挪一两度, 做成 15 分钟 K 线就是一条几乎水平的线 —— 抱着不动就能赢,盘感无从谈起。 真正有波动的是对流:CAPE(对流有效位能)能从 0 冲到 5000、阵风能从 2 m/s 冲到 60、 降水绝大多数时刻是 0、打雷时才爆。所以标的是 WXI 复合天气指数 —— 而且它有语义: 指数高 = 当地天气好,指数低 = 天气差。 ``
① 舒适度 comfort ∈ [0,100](有绝对含义,不是"偏离常态多少")
体感温度 0.34 + 湿度(露点) 0.15 + 降水 0.21 + 天气码 0.20 + 阵风 0.05 + 空气 0.05
晴/基本晴 ≈ 81.5 多云/阴 ≈ 79.9 毛毛雨 ≈ 74 阵雨 ≈ 65
雷暴 ≈ 57 雷暴+冰雹 ≈ 50 (广州 92 天实测)
② 基本面 anchor = 1000 + (慢速comfort − 中位) × 8
"慢速"是半衰期 12 小时的 EMA —— 即时 comfort 会被单根雷暴砸出大坑
③ 价格 —— 事件驱动,不是"连续噪声 + 慢回归"
每根按到达率生成若干笔"成交事件",每笔带一次价格冲击:
impactState = impactState × (1 − INERTIA) + Σ事件冲击
价格 = anchor + impactState
`
指数涨 = 天气转好,指数跌 = 天气变差。 本质是在赌对流。
为什么用「事件驱动」而不是「连续噪声」
真实 15 分钟行情有个很硬的特征:lag-1 自相关 ≈ 0(实测欧易 10 个交易对是
−0.05 ~ +0.02)—— 也就是几乎无记忆,上一根涨跌对下一根没有预测力。
而"连续噪声 + 慢速均值回归"这种写法做不到这件事:
`
px = pxPrev + (anchor − pxPrev) × REVERT + noise
↑ 前景价格出现在等式右边 → 必然产生 AR(1) 记忆
`
只要回归慢(为了钉住基本面),滞后一阶相关就 ≈ 1−REVERT。实测锁死在 0.38,
扫 27 组参数下限就是 0.35 —— 数学上的必然,不是没调对。
真市场是事件驱动的:一笔成交到达 → 一次价格冲击 → 按韧性快速衰减 → 下一笔再来。
所以新版把价格定义成两个互不依赖的状态之和,前景价格不再出现在等式右边:
`
impactState = impactState × (1 − INERTIA) + Σ单笔冲击 // INERTIA = 0.92
价格 = anchor + impactState
`
关键在衰减与到达的相对速度:衰减慢于到达 → 冲击首尾相接 → 又是 AR(1);
衰减快于到达 → 每笔基本独立 → 自相关降下来。顺带白拿两个真市场特征:
- 波动聚集:到达率自激 —— 来的事件多,下一根的到达率就更高
- 肥尾:单笔冲击用幂律尾巴,多数很小、偶尔一次清算瀑布
三项一次对上:
| 指标 | 真实 BTC / WIF | 旧架构 | 事件驱动 |
| --- | --- | --- | --- |
| p90/中位 | 3.50 / 3.25 | 4.2 | 3.95 |
| p99/中位 | 8.76 / 7.69 | 15.6 | 8.6 |
| 单根最大 | 4.2% / 38% | 8.5% | 26% |
| 峰度 | 16 / 472 | 5~13 | 42 |
| lag-1 自相关 | −0.01 ~ +0.02 | 0.38 | 0.17 ~ 0.28 |
复合:大盘、露点、盘子扰动
复合指数最早是这样设想的:
把某个地区里所有城市的温度做平均加权,得到的值就当作该地区的大盘指数,这样才有可炒的东西
从温度变成一个由大盘指数、当地温度、空气质量以及未来的预报等所共同决定的一个新指标。
……不然太没有挑战性了。……然后非常小的那种地方,比如小县城之类的,可以把这个随机扰动加大,
模拟一下庄家操盘。
所以现在图上多了一条紫色虚线的大盘(REG_C = '#c792ea')。它的构成和哪几项是真的:
| 项 | 真假 | 怎么来的 |
| --- | --- | --- |
| 本地 WXI | 真数据 | minutely_15 的气温 / 露点 / 降水 / 天气码 / 阵风 + pm2_5 |
| 区域大盘 | 真数据 | 同省最多 8 城的 15 分钟逐变量平均,再套同一套 comfort() |
| 空气质量 | 真数据 | air-quality-api 的逐小时 pm2_5(92 天),对齐到 15 分钟根 |
| 地震 | 真数据 | USGS 目录里震中/震级/时间,按到本城的大圆距离算冲击 |
| 台风 | 真数据 | 中央气象台 typhoon.nmc.cn 的路径点,逐根插值出中心距离与风速 |
| 预报偏离 | 真数据 | previous-runs-api 的 _previous_day1(提前 24 小时的预报)与实测之差 |
| 盘子扰动 | 建模 | 带衰减的随机游走,振幅按行政层级放大 |
| 成交事件 | 建模 | 到达率 + 幂律幅度(见上);驱动量(天气、盘子)是真的 |
| K 线上下影线 | 建模 | 15 分钟粒度拿不到根内极值:基础影线按 |涨跌|×0.30,另叠插针 |
三件想说明白的事:
- 大盘是真的,不是编出来的一条参考线。Open-Meteo 支持一次请求多个坐标
(latitude=a,b,c&longitude=x,y,z 直接返回数组),所以同省 8 城只要一个请求,
不额外吃额度。取的是和单城完全相同的变量集,所以能直接喂给同一套 comfort() ——
如果只平均气温,那等于把"趋势"又算了一遍,因为气温太慢太平。
- 没有按人口加权。
cities.json 里只有 id/name/prov/py/lat/lon/cma/path,没有人口字段, 所以就是等权。等权就等权,不假装。要加权得先找一个人口数据源,那是另一件事。
- "盘子扰动"是唯一一个纯建模项(加上影线),而且它故意在小地方更大:
cities.json 里没有人口,就按行政层级分档 —— 直辖市 3.0 / 省会 2.2 /
有国家站的地级市 1.6 / 有 path 的 1.2 / 区县 0.6,取 1.6 ÷ 该值 当振幅倍率
(夹在 [0.35, 2.6])。所以广州(有国家站,1.0×)和惠州(无站无 path,2.60×)
开出来的行情手感是不一样的 —— 小地方的"庄家操盘"是在这儿体现的,不是靠调大随机数。
它触发时会在屏幕中间闪一条 🏦 大单扫货 / 📉 有人出货。
顺带:G.regLine 是本局窗口那一截(长度 = 当前档位的一局根数 roundBars()),不是整段 92 天。
早期实现画线时多加了一个 G.regFrom 偏移,结果那条线在图上长度是 0、根本不显示 ——
探针把 大盘 series data 长度 = 0 打出来才发现的。
大盘线不参与 Y 轴范围计算,否则它会把蜡烛压扁;它只是个参考指标,不是可交易的合约。
四个"压力源",外加一整套"天文家族"
群里还说了:「如果有什么台风消息地震消息还可以再做一个新的压力源」「反正当地的什么情况,
乱七八糟的参数加进去就好了」。照做了,四项全部接真数据:
| 压力源 | 数据源 | 落进指数的形式 | 实测覆盖(广州一段 3552 根) |
| --- | --- | --- | --- |
| PM2.5 | air-quality-api.open-meteo.com 的 hourly=pm2_5 | 稳健标准化后乘 AIR_K = 6 —— 慢变量,管的是整段的偏置 | 99.3%,极值 ±47.5 点 |
| 地震 | earthquake.usgs.gov 的 fdsnws/event/1/query | 事件冲击:QUAKE_K × (震级 − 3.0) × (1 − 距离/700km),之后按 0.90 衰减 160 根 | 0.5%(本来就 rare) |
| 台风 | typhoon.nmc.cn 的 list_<年> + view_ | 逐根插值出台风中心,40 × (风速/30) × (1 − 距离/900km)² | 53.1%,极值 +9.4 点 |
| 预报偏离 | previous-runs-api.open-meteo.com 的 temperature_2m_previous_day1 | 实测 − 提前一天的预报,稳健标准化后乘 FCST_K = 2 | 95.8%,极值 ±15.5 点 |
几个实现上的关键点:
- 空气质量只能逐小时。
air-quality-api 的 minutely_15 返回的 time 数组长度是 0 (参数照收、HTTP 200,只看状态码发现不了)。所以 PM2.5 走 hourly + past_days=92,
再按小时键对齐到 15 分钟根。它照样是 92 天的真数据,不是拿 current 糊的。
- 地震为什么要经 Wolfx 转发:中国地震台网自己的站点
www.ceic.ac.cn 响应 200 但不带 CORS 头, 浏览器里直连读不到;Wolfx(api.wolfx.jp)把 CENC 的数据带 Access-Control-Allow-Origin: * 转了出来,
所以借它转发;另一路 USGS 免 key + CORS 全开,负责 130 天窗口与全球覆盖。
两边按「±10 分钟且球面距离 ≤100 公里」判重,重复时保留 CENC 那条(中文地名更有用)。
顺带主站天气页也因此有了 🌋 地震面板(见上面截图)。
- 台风的列表是倒序的。
list_2026 按新→旧排,只取最新 12 个会把 92 天窗口里 真正逼近华南的台风全切掉(沙德尔 211km / 紫檀 350km / 美莎克 477km 都在 7~8 月,
而最新的 12 个是 9 月底之后的)。所以取 30 个,并发限流 4,TTL 6 小时。
- 预报偏离的写法是个坑:正确写法是变量名加后缀,不是参数。
temperature_2m_previous_day1 表示"比有效时刻早 24 小时做出的那次预报"。
所有 models=xxx_previous_dayN 的写法都会 HTTP 400;
而 previous-runs-api 不加后缀时返回的数据与 historical-forecast-api
一模一样(864 个时刻一字不差),一度让人以为它只是个别名。
- 只在上升沿播报。这四项都是有惯性的状态量,不加判定的话一局 3552 根里会弹 540 次
"台风影响"。现在用 rise(f, 阈值) / fall(f, 阈值) 只在第一次越过时播,
于是一局里台风只剩 4~5 条、地震 0~1 条,其余是天气与盘子消息。
- 窗口偏置:92 天里台风/地震真的拢共就那么些,纯随机切窗口大多数时候覆盖不到。
所以 50% 的局挑"事件分最高"的那十天、50% 纯随机 —— 不是"每局必有事件",
那就成安排好的剧情了,也就没有“不知道这段是哪年月”这个前提。
- 取不到就退化成 0,绝不编数据。六个源各自独立
catch,任何一项挂了 只影响它那一项。
调参是量出来的,不是拍的(QUAKE_K / FCST_K / TYPHOON_K 各改过一轮):
- 第一版
FCST_K = 7 跑出预报项 min=-59.5 max=+54.8 —— ±6% 的抖动全来自预报误差,太猛,砍到 2。
QUAKE_K = 6 时 M4.6 / 653km 只值 0.64 点,等于没有,提到 12。
TYPHOON_K = 60 时 211km / 52m/s 会直接顶到 60 点,降到 40。
最终整局振幅中位数 25.1%(加这四项之前是 26.8%,但窗口口径换过,可比性有限); 单根中位涨跌仍是 0.266%。
天文家族:九条天文通道拧进同一根指数
同一个人后来又说:「模拟游戏要的不是真实而是戏剧性,要刺激」,以及「天文那些也接进去吧」。
接的是本地算得出来的那九样,全部落进 skyHeat 这一个标量,再由它去拧事件到达率、
混沌跳跃的概率与幅度、以及插针概率:
| 通道 | 系数 | 语义 |
| --- | --- | --- |
| 月光(照亮百分比) | MOON_K = 8 | 满月把暗目标全糊掉 |
| 流星雨(极大前后) | METEOR_K = 80 · 流量 METEOR_FLOW = 2.5 · 衰减 METEOR_DECAY = 0.985 | 爆发夜 |
| 超级月亮 | SUPER_K = 70 | 近地点满月 |
| 银心高度 | GALAXY_K = 22 | 银河中心越高越"看得见" |
| 头顶亮星与行星 | STAR_K = 8 | 此刻能数出几颗 |
| 天文夜长度 | NIGHT_K = 20 | 天真正黑透的那一段 |
| 潮汐(大潮/小潮) | SPRING_K = 26 | 朔望那几天 |
| 城市光污染等级 | LP_K = 12 | 1~9 级 |
| 地磁暴 Kp | Kp_K = 45 | 极光那一路 |
skyHeat = Σ|各项| ÷ 100(夹在 0~2),再用 HEAT_FLOW = 3.0 / HEAT_CHAOS_P = 9.0 /
HEAT_CHAOS_K = 1.5 / HEAT_SPIKE = 6.0 去拧到达率、混沌与插针 ——
输入全是真数据,手感是为戏剧性调的。同一批种子做 A/B(28,416 根):
p90 ×1.750、p99 ×1.763、单根最大 ×1.963,涨跌 >1% 的根数 1444 → 4244,
单局振幅中位数 21.8% → 34.3%,NaN 0 根。
规则
| | |
| --- | --- |
| 行情 | Open-Meteo minutely_15(15 分钟一根,92 天历史),随机截连续 37 天(前 7 天当预热) |
| K 线周期 | 1 分 / 5 分 / 15 分 / 30 分 / 1 时 / 4 时 / 1 日七档,局中随时切换 |
| 价格 | WXI 复合天气指数,基准 1000。指数高 = 当地天气好(comfort 基本面 + 事件驱动冲击) |
| 大盘 | 同省最多 8 城的 15 分钟逐变量等权平均,图上紫色虚线;拿不到就退化成纯本地行情 |
| 合约 | 1 手,指数每动 1 点盈亏 ¥10 |
| 本金 | 可自定义,1 千 ~ 1 亿,预设 10 万 / 30 万 / 100 万 / 300 万 / 1000 万。默认 30 万,开局时选,局中不给改 |
| 手续费 | 万分之五,开平都收,单笔最低 ¥5 |
| 滑点 | 单子越大越吃亏:SLIP_K × 名义金额 ÷ 盘子容量`,上限 10 点;小城市盘子更小 |
| 杠杆 | 1× / 5× / 10× / 20× / 50× / 100×(界面文案:稳健 / 激进 / 疯狂 / 天台 / 天台没护栏 / 久留美) |
| 单次仓位 | 10% / 30% / 50% / 满仓 |
| 一局 | 预热 7 天(一周)+ 交易 30 天(一个月)。进面板时前 7 天的 K 线已经铺满(只能看,不能下单),从第 8 天开始交易。每秒变 4 次(与速度档无关)。速度 15 / 30 / 60 / 120 / 240 分钟天气每秒(实时 / 慢 / 悠闲 / 正常 / 狂暴),30 天交易约 48 / 24 / 12 / 6 / 3 分钟,随时可暂停。默认「悠闲」= 每次更新正好推进一格 15 分钟天气 |
| 爆仓 | 权益 ≤ 占用保证金 × 10% 即强平 |
| 未收盘那根 | 最后那根 K 线是实时在动的:收盘价沿着真实的 15 分钟观测往前走,上下影线被逐个真样本刷新。成交也按这个盘中价(所见即所得),不是按还没走完的那根的收盘价 |
| 城市差异 | 大城市稳、小城市野。这个梯度是拿真实交易所数据标定的,不是拍的:欧易 9 个对 × 365 天 × 15 分钟,最稳的 BTC 单根中位 0.0994%、最野的 WIF 0.2541%,梯度 3.09×。现在游戏里直辖市 0.120%(≈BTC)、省会 0.142%(≈ETH)、地级市 0.175%(≈SOL)、区县更野 |
| 挂单 | 限价单(挂多 / 挂空)+ 止损、止盈各一张,挂单会冻结保证金 |
| 天气日历 | 只提示什么时候变天,不提示往哪边 |
| 中途退出 | 不作废。行情按**真实流
... (README truncated for length)