first commit

This commit is contained in:
2026-08-07 16:08:34 +08:00
commit e0b5228008
51 changed files with 5175 additions and 0 deletions

187
TECH_STACK.md Normal file
View File

@@ -0,0 +1,187 @@
# 股市回测平台 — 技术选型推荐(纯回测范围)
> **一句话总体推荐****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` 覆盖截至 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不支持 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 + 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+区间载入;前端服务端聚合/降采样再渲染。
- **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` 覆盖截至 20252026+ 需 extensions/tushare 兜底。
- ECharts v6 WebGL 在低端机需回归测试。