# 股市回测平台 — 技术选型推荐(纯回测范围) > **一句话总体推荐**:**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_calendars(`XSHG`)+ tushare `trade_cal` 兜底 | 回测/回放对齐、版本化 | `XSHG` 覆盖截至 2025,2026+ 需兜底 | | **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,不支持 Polars**(Polars 属闭源付费 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 + TimescaleDB(hypertable + 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+区间载入;前端服务端聚合/降采样再渲染。 - **TimescaleDB**:chunk 对齐查询模式;CAGG 刷新滞后读防护(`materialized_only` + 时间戳护栏);并发读副本/连接池。 ### 6.3 可维护性 - **避免停维库**:backtrader 自 2023 停维、pandas-ta 停滞。指标自研隔离层,便于将来换 TA-Lib。 - **回测可复现性**:每次回测绑定策略版本+参数+数据快照三元组。 ### 6.4 合规(已大幅缩水) - 数据源 ToS 对商业/再分发有约束;公开免费接口(新浪/东财/腾讯)盘中高并发被封,仅作降级。**商用上线前须取得数据授权**(Wind/Choice/聚宽/Tushare 高级档)。 ### 6.5 版本陷阱 - lightweight-charts v5:`createSeriesMarkers(series, markers)` 取代 v4 `setMarkers()`。 - TimescaleDB 2.28+ 弃 PG15,锁 PG16/17。 - exchange_calendars `XSHG` 覆盖截至 2025,2026+ 需 extensions/tushare 兜底。 - ECharts v6 WebGL 在低端机需回归测试。