Files
stock/TECH_STACK.md
2026-08-07 16:08:34 +08:00

15 KiB
Raw Permalink Blame History

股市回测平台 — 技术选型推荐(纯回测范围)

一句话总体推荐Python 单语言后端FastAPI + 自研回测引擎)为"大脑与事实源"Vue 单页前端为"渲染器与控制台"PostgreSQL/TimescaleDB + Redis 承载数据,三者用 OpenAPI 契约解耦。

范围明确:本平台只做历史回测 + 回放式模拟交易,不做实盘。因此砍掉了所有实盘专属基建券商网关、Windows broker、程序化交易报备、限速、Kill Switch、talipp 流式指标等)——这些正是最难维护、风险最高的部分。

核心判断:A 股的量化生态(数据源、回测库)几乎只以 Python 存在——"后端选 Python"是生态约束下的唯一合理解。


范围变更记录2026-08

原方案含实盘量化。经确认只做回测 + 回放式模拟,不做实盘后,移除:

移除项 原因
vnpy / xtquant / xttrader 实盘网关 实盘下单专用,无实盘即不需要
Windows broker 节点(永久运维分叉) QMT 必须常驻 Windows无实盘 → 纯 Linux部署统一
程序化交易报备 / 硬限速≤299笔/秒) 只对实盘程序化交易生效,纯回测不受管
Kill Switch / 风控闸门 / 幂等下单 / 断线重连 全是"防回测 bug 造成真实亏损"的护栏
talipp 流式增量指标 实盘每根新K线增量算用回测批量算用 TA-Lib/自研即可
CTP期货、券商资质、投资者适当性 实盘门槛

保留并强化的核心单一回测引擎fast/strict、防过拟合体检、基准归因、复权因子管道、A股交易成本建模、指标单一事实源。

澄清:最早的"对接交易所显示买卖点"——不需要真连交易所。回测信号标在历史 K 线上即是买卖点显示。


一、技术栈总表

选型 作用 说明
前端基座 Vue 3.5 + Vite + TypeScript + Pinia SPA、状态管理 用户已有 Vue 生态
UI 组件 PrimeVue 5 表单/参数面板/大表/筛选 DataTable 成熟度对数据密集控制台是决定性的
K 线主图 lightweight-charts 5.x 纯渲染器:主图 + 指标副图 + createSeriesMarkers 标买卖点 TradingView 出品;不用任何内置指标算法(单一事实源)
分析面板 ECharts 6.1 + vue-echarts 净值/回撤/收益分布/热力图 WebGL 大数据
前端指标预览 防抖调后端算 单一指标实现 前端不保留任何指标库
后端服务 FastAPI + Uvicorn + Pydantic v2 REST + 自动 OpenAPI 契约 契约先于业务锁定
回测引擎(单一) 自研Polars/Numpy 向量化内核 + 事件化规则注入 唯一事实源fast/strict 两档 不做"快层+真层"双引擎
指标计算 纯 pandas/numpy 实现MVP→ TA-Lib生产 回测/图表共享同一份结果 Windows 上 TA-Lib C 库难装MVP 用纯 Python接口留好可替换
任务编排 MVP 同步;长回测引入 Dramatiq + 进程池 绕 GIL多进程并行参数扫描 进度落库 checkpoint
元数据库 PostgreSQL 16/17 + async SQLAlchemy 2.0 + Alembic 用户/策略/回测元数据/回测运行注册表
时序主库 TimescaleDB 2.28+(同一 PG 实例的扩展) K 线 Hypertable + Continuous Aggregates 多周期 + 列式压缩 用户已有 Postgres → 直接装扩展即可MVP 暂用 SQLite 零配置起步
缓存 Redis规模化后 热点 K 线缓存、任务队列 broker MVP 不引入
交易日历 exchange_calendarsXSHG+ tushare trade_cal 兜底 回测/回放对齐、版本化 XSHG 覆盖截至 20252026+ 需兜底
A股数据源 Tushare Pro+ AKShare校验+ BaoStock末位 历史 K 线/复权/财务/分红 多源冗余2025-08 Tushare 曾停摆
MVP 数据 合成数据种子(随机游走 OHLCV 零依赖即时可跑 DataProvider 接口下可一行切到 Tushare
港美股数据 Polygon更名 Massive付费档 历史+实时(远期) 仅开发期 mock 用免费源
鉴权 JWT + RBAC多用户时 用户/策略级权限 MVP 单用户可暂缓

二、系统架构

┌──────────────────────────────────────────────────────────────────┐
│  前端 (Vue 3.5 + Vite + TS + Pinia + PrimeVue)                      │
│  ┌────────────┐  ┌──────────────────┐  ┌────────────────────────┐  │
│  │ PrimeVue 5 │  │ lightweight-     │  │ ECharts 6.1            │  │
│  │ 参数表单    │  │ charts 5.x       │  │ 净值/回撤/归因/过拟合   │  │
│  │ 策略选择    │  │ K线+指标副图+    │  │                        │  │
│  │            │  │ 买卖点markers    │  │                        │  │
│  └────────────┘  └──────────────────┘  └────────────────────────┘  │
│   shallowRef+markRaw; series 不入响应式; onMounted/onBeforeUnmount │
└──────────────┬───────────────────────────────────────────────────┘
               │ REST类型化客户端由 OpenAPI 生成)
               ▼
┌──────────────────────────────────────────────────────────────────┐
│  后端 (FastAPI + Uvicorn + Pydantic v2)            [纯 Linux]       │
│  ┌────────────┐  ┌──────────────────────┐  ┌────────────────────┐  │
│  │ REST       │  │ DataProvider 适配器   │  │ 领域模型契约        │  │
│  │ OpenAPI 契约│  │ Tushare/AKShare/     │  │ Instrument/Bar/     │  │
│  │            │  │ Synthetic/复权管道    │  │ Signal/Order/Fill/  │  │
│  │            │  │                      │  │ Position/Portfolio/ │  │
│  │            │  │                      │  │ Strategy/Universe/  │  │
│  │            │  │                      │  │ Calendar            │  │
│  └────────────┘  └──────────────────────┘  └────────────────────┘  │
│        │  ┌─────────────────────────────────────────────────┐      │
│        │  │ 单一回测引擎 (Numpy/Polars + 规则注入)           │      │
│        │  │  ├ fast 档: 关 T+1/费用, 交互试探                 │      │
│        │  │  └ strict档: T+1/涨跌停/封板/成交量约束/全费用   │      │
│        │  │  + 防过拟合体检(walk-fwd/OOS/FDR/敏感性)         │      │
│        │  │  + 基准归因(超额/信息比率/beta/alpha)            │      │
│        │  │  + 回测运行注册表(run_id→策略版本+参数+数据快照) │      │
│        │  └─────────────────────────────────────────────────┘      │
└────────┼─────────────────────────────────────────────────────────┘
         ▼
   ┌───────────────────┐   ┌──────────────────────┐
   │ PostgreSQL 16/17  │   │ DataProvider 数据源   │
   │ + TimescaleDB     │   │ Tushare(主)/AKShare  │
   │ K线 Hypertable    │   │ BaoStock(末位)       │
   │ CAGG 多周期        │   │ Synthetic(MVP)       │
   │ + 关系/元数据      │   │ Polygon(港美股,远期) │
   └───────────────────┘   └──────────────────────┘

三个必须分离的关注点

关注点 落在哪 为什么
信号生成(指标+策略) Python 后端,单一实现 回测与图表必须用同一份结果,否则"看着赚回测亏"
订单执行(撮合) PaperBroker虚拟成交 隔离策略逻辑与成交逻辑;无实盘则永远是虚拟
数据获取 DataProvider 适配器 + 复权管道 上游随时失效,必须可热切换

先于业务落地的"领域模型契约"MVP 第一周定稿)

Instrument / Bar(OHLCV+复权标识+周期) / Signal / Order / Fill(含费用明细) / Position / Portfolio / Strategy(+版本) / Universe(股票池+成分历史) / TradingCalendar


三、关键取舍裁决

  1. 纯 Python 单语言栈。 A 股数据源与回测生态只以 Python 存在;性能瓶颈在向量化计算与多进程,不在 HTTP 层。
  2. 数据库TimescaleDB 单库起步。 它是 Postgres 扩展(用户已有 Postgres 可直接装),同一库内"信号 JOIN 行情 JOIN 订单"+ ACID。分钟级全市场≈十亿行确定要做时再把分钟K/Tick 下沉 ClickHouse 分层关系层与日K 留 PG。
  3. K 线主图用 lightweight-charts 5.x纯渲染器 不用任何内置指标算法;指标值全部后端算好喂给它。不用 klinecharts内置指标会与回测两套算法漂移
  4. 决策级指标全在后端 Python。 前端预览一律调后端,前端不保留指标库实现。
  5. 单一回测引擎 + 质量档位fast/strict,不做双引擎。同一撮合逻辑、同一代码路径,仅开关不同:
    • fast:关 T+1/费用/成交量约束,纯向量化,交互试探、参数网格。
    • strict:全开 A 股规则,出可审计报告。

    vectorbt 开源版基于 pandas/NumPy不支持 PolarsPolars 属闭源付费 PRO。向量化内核自研Polars/Numba


四、A股交易成本表已修正可配置 + 按生效日期版本化,基准日 2026-08

费用项 费率 方向 生效依据
印花税 0.05%(千分之零点五) 单边卖出 2023-08-28 减半(原 0.1%
过户费 0.001%(万分之零点一) 沪深双边均收 2022 年统一下调(原沪市万 0.2 单边)
佣金 万 1 含规费(最低 5 元) 双边 2026 主流;最低 5 元须建模
滑点 1-2 tick 双边 可配置

费用必须是参数表 + 生效日期版本化 + 显式基准日,非硬编码常量。


五、分阶段落地路线

阶段 0回测 MVP + 可视化(进行中)

跑通"输入 MACD/RSI/KDJ 参数 → 后端回测 → 画 K线+指标+收益+最大回撤+夏普+买卖点"。SQLite 默认库 + 合成数据零依赖可跑。不引入Redis、Dramatiq、任何行情/交易网关、K8s。

阶段 1完整回测 + 回放式模拟

  • strict 档完整性T+1、涨跌停主板±10%/科创创业±20%/北交所±30%)、成交量约束(单笔 ≤ bar 成交量 10-25%)、封板建模(一字板不可买/不可卖、停牌事件流、100 股整数手、全费用、滑点。
  • 股票池 + 成分历史(生存者偏差):用"当时成分股"而非"今天成分股"。
  • 防过拟合体检回测报告一等公民walk-forward、OOS 切分、参数敏感性、多重比较修正Bonferroni/FDR/White's Reality Check/SPA、样本自由度告警。
  • 基准归因超额收益、信息比率、跟踪误差、beta/alpha、up/down capture。
  • 回测运行注册表run_id → 策略版本 + 参数快照 + 数据快照 + 环境指纹 + 结果指纹
  • 结果缓存 + 多回测对比:相同三元组命中缓存;参数微调前后 diff 视图。
  • 切真实数据源Tushare 主 / AKShare 校验),全量本地落地缓存;复权因子管道(增量 + 回溯回填)。
  • 切到用户 Postgres + TimescaleDBhypertable + CAGG
  • 回放式模拟盘:选历史区间逐 bar 虚拟交易PaperBroker

阶段 2分钟级 + 规模化 + 工程化

  • 分钟级全市场回测(≈十亿行):按需引入 ClickHouse 分层分钟K/Tick关系层与日K 留 PG。
  • Dramatiq + 进程池跑长回测/参数扫描,进度落库 checkpoint。
  • 可观测:结构化日志 + 核心 metric回测耗时 P95、数据延迟→ OpenTelemetry + Grafana。
  • K8s + ArgoCD 部署。

六、关键风险与对策

6.1 数据正确性

  • A股复权是最大隐患:复权因子是每日增量、且会回溯修正的流。维护复权因子管道,查询显式选择前/后复权,否则回测收益与图表价格不一致。
  • 生存者偏差用当时成分股回测Tushare 为主、AKShare 校验,差异超阈值告警。
  • 单点数据源风险已验证2025-08-26 TusharePro 停运,仅依赖 Tushare 的系统当天停摆 → 强制多源 + 本地落地缓存。
  • 数据治理新鲜度监控、质量校验OHLC 不合理/成交量为负/缺口)、数据血缘。

6.2 性能瓶颈

  • 最致命陷阱:把大数据塞进 Pinia reactive。必须 shallowRef + markRaw + 仅加载可见区间按 pan/zoom 增量拉取;series 数据不入响应式;图表实例 onMounted/onBeforeUnmount 严格绑定。
  • GIL 误用CPU 密集回测走独立进程池FastAPI 路由只 dispatch。
  • 十亿级撑爆内存:谓词下推按 symbol+区间载入;前端服务端聚合/降采样再渲染。
  • TimescaleDBchunk 对齐查询模式CAGG 刷新滞后读防护(materialized_only + 时间戳护栏);并发读副本/连接池。

6.3 可维护性

  • 避免停维库backtrader 自 2023 停维、pandas-ta 停滞。指标自研隔离层,便于将来换 TA-Lib。
  • 回测可复现性:每次回测绑定策略版本+参数+数据快照三元组。

6.4 合规(已大幅缩水)

  • 数据源 ToS 对商业/再分发有约束;公开免费接口(新浪/东财/腾讯)盘中高并发被封,仅作降级。商用上线前须取得数据授权Wind/Choice/聚宽/Tushare 高级档)。

6.5 版本陷阱

  • lightweight-charts v5createSeriesMarkers(series, markers) 取代 v4 setMarkers()
  • TimescaleDB 2.28+ 弃 PG15锁 PG16/17。
  • exchange_calendars XSHG 覆盖截至 20252026+ 需 extensions/tushare 兜底。
  • ECharts v6 WebGL 在低端机需回归测试。