用 React 19 + Vite 8 写了个本地优先的 ETF 研究台:三源 fallback / 信号原因链 / 商品归因

5 阅读4分钟

给一只 ETF 写了个本地优先的研究台:React 19 + Vite 8 + 三源 fallback

etf-1-decision.png

etf-1-top.png

etf-2-trend.png

etf-3-commodity.png

etf-4-tracking.png 最近在 GitHub 上线了一个个人项目,分享一下技术决策和取舍。

项目背景

我自己持有 512400(南方有色金属 ETF),盘中想要一个工具同时回答这 4 个问题:

  1. 今天到底是追高、观望,还是回调低吸?
  2. 现在价格离估算净值多远?折价还是溢价?
  3. 是黄金 / 铜 / 铝 / 锂 / 稀土哪个商品在推这只 ETF?
  4. 相对 000819 基准跟踪和流动性怎么样?

雪球、同花顺、东财之间能凑齐,但一屏看完的工具我没找到。商业级量化平台又太重,单标的研究只用 5% 的能力。Notebook 写出来又麻烦每次手跑。

所以自己写了一个:github.com/Leonard-Don…(开源 MIT)。

下面讲讲核心的技术取舍。

为什么 React 19 + Vite 8 纯前端 SPA

后端我考虑过 FastAPI + TimescaleDB,但单标的场景下:

  • 数据量小:一只 ETF 的盘中 + 历史最多几千个 K 线 + 数百次报价
  • 用户场景是「一个人盘中看自己电脑」,不是多人并发
  • 后端反而增加部署 / 维护成本,给一个工具加包袱

最终选纯前端 SPA + 本地 JSON 快照。React 19 + Vite 8 的理由:

  • Vite 的 HMR 比 webpack 快一个量级,盘中频繁改代码的开发体验好
  • React 19 的并发渲染(useTransition / startTransition)对盘中频繁更新友好
  • 不需要 SSR,组件树并不复杂

三源数据 Fallback 怎么设计

每个数据源都有自己的失败模式:

优势失败模式
东方财富quote / K 线 / 估值完整接口结构偶尔变
腾讯财经实时报价稳定历史数据少
天天基金净值 / 阶段收益权威盘中估值有延迟

实现层:所有读取都走 runtime fetcher 抽象,按 priority 顺序调用。任一源返回非预期结构时记录错误状态并立刻切到下一源。

关键点:UI 上同时展示当前数据来源 + 新鲜度(例如「东方财富,2 秒前」)—— 用户永远不会被偷偷换源。降级可见,是合规和信任的底线。

代码层关键入口:

src/analysis/realtimeQuote.js   // 实时报价兜底逻辑
/api/realtime/*                 // 本地代理路由(仅 dev 环境,规避浏览器跨域)

本地 JSON 快照而不是 DB

每次刷新会追加 src/data/history/512400-snapshots.json

  • ✅ 优点:无 schema、无 migration、git diff 可读、刷新 = pure append
  • ⚠️ 缺点:单文件最终会变大(目前几 MB 量级,未到性能瓶颈)

对于「研究我自己投的 ETF」这个场景,JSON 快照 100% 够用。如果以后要做多标的,再换 PostgreSQL / TimescaleDB。

信号合成:简单加权而不是 ML

研究台核心是把多个信号合成「今天的建议动作」:

  • 趋势跟随:均线穿越 + 动量斜率
  • 回撤低吸:从近 30 日高点的回撤幅度
  • 因子共振:商品驱动(铜 / 铝 / 锂 / 稀土)与 ETF 持仓权重的耦合
  • 自动优化:在最近样本上 grid search 最优参数,做样本外验证评分

合成层用简单加权而不是 ML,理由:

  • 单标的样本少,ML 容易过拟合
  • 简单规则可解释,复盘时容易回溯哪一步信号错了
  • 维护成本低,全部逻辑在 src/analysis/ 下可读

最有用的部分:原因链。系统给出每个判断的 3 条具体证据,可读可改可辩论。

跟踪质量层(vs 000819 基准)

ETF 不是越接近基准越好,但跟踪偏差太大也是 risk。专门做了一个 panel:

  • 跟踪差:与 000819 日 return 的差
  • 折溢价温度:IOPV 估算 vs 实际价格(用标准差 σ 量化偏离)
  • 成交额分位:流动性是否够

局限性诚实呈现

  • 单标的不可扩展——这就是设计哲学,要做多标的请重写
  • 本地优先依赖你电脑——关机就没了,需要主动备份历史
  • 不接交易——所有信号仅供研究 / 复盘,没有实盘执行入口
  • 数据源依赖公开网页接口——东方财富改版我也要跟着改

谁用得上

  • 自己投了 512400 或类似单标的 ETF,想盘中看真实状态
  • ETF 套利学习者,想理解折溢价 / 跟踪误差怎么算
  • 量化研究 builder,想看一个「单标的 + 本地优先」的工程实践参考

仓库

github.com/Leonard-Don…

MIT 协议,欢迎 Issue / PR / fork。如果你也在做单标的研究台、ETF 本地工具或多源数据 fallback 架构,欢迎评论里聊。