Files
qlib/docs/DEV_PLAN_v3.md
T
Simon 82240e383d docs: 同步操作说明/架构/路线图(归档操作、图表基座、数据库目标硬约束)
- USAGE 新增 §6.3.1「归档的日常操作」:查看 / 筛选(回写 URL)/ 导出完整 JSON /
  以此参数再跑 / 删除(写明「删除即失去结果,结果只存归档一份」)/
  历史归档用 restore_experiment_from_job 按原 id 重建;并说明归档完整度如何标注
- USAGE/README 更正技术栈与图表基座:TradingView Lightweight Charts 4.2.3 为唯一
  图表基座(ECharts 已从 package.json、pnpm-lock.yaml、node_modules、文档与
  架构图标注中全部清除),并记录实测证据(个股页图表根节点为
  div.tv-lightweight-charts,页面 canvas 无一来自其它图表库)
- ARCHITECTURE 更正「当前数据库」(原写 SQLite/未来 MySQL):现为本机 MariaDB 10.11,
  §6 补目标库硬约束;USAGE 补服务器身份与实测连接证据
- AGENT.md 新增 §0.1:数据库目标只允许本机 MariaDB,禁止 192.168.1.10,
  由 config.py::assert_db_target_allowed 硬拦截(命中直接抛错,不静默降级)
- DEV_PLAN_DIVIDEND_BACKTEST 记录三轮实施与验证、归档恢复边界(§12.5)、已知限制
- DEV_PLAN v2/v3 标注为历史记录(避免把当时的远端库地址当现状照抄);
  ROADMAP 更正 M3 图表选型
2026-09-20 07:31:20 +08:00

187 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 下阶段开发计划(架构 v3 · Chart Service / Signal↔Fill / 个股研究页 主线)
> 依据:[ARCHITECTURE_v3.md](./ARCHITECTURE_v3.md)(新架构 v3)、[AGENT.md](../AGENT.md)(约束)、
> [DEV_PLAN_v2.md](./DEV_PLAN_v2.md)(M6–M8 已执行完毕)、代码现状(2026-09,MySQL 已为默认库)。
> 本文件回答:**v3 相对已落地能力的增量是什么、下一阶段做什么、按什么顺序。**
---
## 0. 现状 vs v3(已完成清单)
**数据库**:MySQL(qlib@192.168.1.10)默认,15 张业务表,Alembic head `e1f2a3b4c5d6`;
> ⚠️ **历史记录,勿照抄**:当前 DB 目标为本机 MariaDB 10.11(`127.0.0.1:3306/qlib`),
> 远端 `192.168.1.10` **已被禁止作为 DB 目标**(代码层 `assert_db_target_allowed` 硬拦截,
> 见 `AGENT.md` §0.1)。以下涉及该地址的描述均为当时状态。
SQLite→MySQL 迁移数据 16,057,265 行校验一致(M-DB)。
**研究/选股主线(M6–M8 已完成)**:
| 能力 | 落地位置 | v3 对应 |
|---|---|---|
| Universe 过滤(ST/上市天数/退市/白名单/as_of) | `quant/universe.py` | §14/§20 范围 |
| Selection:A 条件 + B 因子评分,当前/历史 as_of,可解释 | `quant/selection.py`、`selection_service` | §14/§22.1 |
| 选股结果落库 + `/api/selections` | `selection_snapshot/selection_result` | §8 |
| 回测与选股共用评分引擎(一致性测试锁定) | `quant/composite.build_score_panel` | §26 |
| 因子目录入库 + 组合落库 CRUD | `factor_definition`、`factor_composite` | §11/§13/§8 |
| 行情口径显式化(price_adjustment,研究默认不复权) | Repository `adjust` 过滤 | §20.5 前半 |
| Signal 规则引擎 + 落库 + `/api/signals` + Web 页 | `signal_snapshot/signal_event` | §15/§8 |
| Portfolio v1(等权;约束字段预留+如实标注) | `quant/portfolio.py` | §16 子集 |
| Strategy 命名资产 + `/api/strategies`(expand) | `strategy` 表 | §17 |
| Experiment/Job/SSE、Web 六页+选股/信号页 | — | §19/§23/§27 |
| Agent 10 工具 | `agent/tools_impl.py` | §25 子集 |
**v3 主要增量(下一阶段目标)**:
1. **Chart Service / 统一可视化**(§20/§21):后端 Chart DTO + Chart API;前端 K 线等图表
(推荐 TradingView Lightweight Charts);**前端只展示、不重算**选股/信号/成交。
2. **Signal 与 Actual Fill 严格区分并同图呈现**(§20.3/§22.3):`signal_event`(策略信号)
与 `backtest_trade`(实际成交)分别标记;回测结果补 `selection_history / signal_history / fills`。
3. **Stock Research Page**(§20.4):单只股票的 K 线 + 事件标记 + 技术指标 + 选股/信号/成交明细
+ 因子/理由的一站式页面。
4. **A 股复权与回测价格口径**(§20.5):图表显示价(不复权/前复权/后复权)与回测执行价
分开记录(`adjust_mode / price_basis / execution_price_basis`),必要时坐标转换。
5. **Bar Replay**(§20.6,第二阶段)。
6. **数据/规则底座补全**(§4/§8):行业、指数与**历史成分**、停牌、ST 名单等同步
(支撑 survivorship-bias-free Universe 与回测真实性)。
7. **研究与模型增强**:因子相关性/暴露分析、Model Service(选股模式 C)、组合约束执行。
---
## 1. 执行状态(2026-09:主线与可自证支撑已交付)
> M9(Chart/回测历史/个股页/双图库/复权口径/Bar Replay)、B1(指数历史成分)、
> C1(因子相关性)、C2(单股上限执行)、D1(Job stage+列表/取消)、D2(选股 Job 化)、
> D4(Agent 14 工具)均已完成并提交(ROADMAP V3 行含 commit;每阶段全量 pytest + ruff,
> 前端 tsc 通过;B1/D2 迁移已应用 MySQL)。
> 延后项与原因:B2/B3(停牌/ST/三大报表:依赖 Tushare 对应接口权限,离线无法端到端验证,
> 留 `sync` 扩展点)、B4(结果实体化:现行 JSON 快照已可复现,实体化按需)、
> C3(Qlib 模型选股:计划标注「按需」)、D3(Redis:未出现排队/广播触发场景,
> config 预留 `redis.url` 即可启用)。
## 2. 主线:M9 可视化与成交口径(对齐 v3 新重点)
> 目标:把已能产生的 Selection / Signal / Backtest 结果变成**同一时间轴上、可解释、
> Signal↔Fill 分明**的个股与组合视图。前端一律消费 Chart API 的 ChartResult(v3 §20.1),
> 禁止前端自行重算。
### 1.1 Chart DTO 与 Chart Service(后端先行)
- Domain `chart.py`:`ChartResult{symbol, name, adjust_mode, bars[], volume[], indicators{},
selections[], signals[], fills[], holding_periods[], strategy_scores{}, factor_values{},
benchmark{}, metadata{adjust_mode, price_basis, execution_price_basis}}`(v3 §20.2 结构)。
- `application/services/chart_service.py`:只做**聚合与坐标整理**,不重算 Selection/Signal/Backtest
—— 输入来自各 engine/Repository 的既有结果。
- API(v3 §20.2):
- `GET /api/stocks/{symbol}/chart?range=&adjust=none|qfq`(K 线 + 量)
- `GET /api/stocks/{symbol}/signals` / `/selections`(该股参与过的信号/选股历史)
- `GET /api/backtests/{experiment_id}/stocks/{symbol}/chart`(回测视图:fills/holding)
- `GET /api/backtests/{experiment_id}/trades`、`/positions`(回测成交/持仓展开)
- 验收:Chart API 返回结构与 v3 §20.2 一致;K 线与 fills 价格位于同一坐标系。
### 1.2 回测结果补 selection_history / signal_history / fills(Signal↔Fill 区分)
- `BacktestResult` 扩展(v3 §22.3):`selection_history`(各调仓日选出的候选与排名)、
`signal_history`(每期信号)、`fills`(实际成交记录:symbol/date/side/price/qty/cost/费/
reason:signal→fill 或 被拒 reason)。
- 引擎层:`TopKBacktestRunner` 调仓过程把「目标候选(Selection 视图)」「信号意图」与
「实际成交(扣除涨停/停牌/现金后的 Fill)」三份记录输出;既有一致性测试保持通过
(重构不改默认策略语义)。
- 前端标记语义:`BUY SIGNAL / SELL SIGNAL`(虚线)vs `EXECUTED BUY / EXECUTED SELL`(实心),
点击可见 signal→fill 或未成交原因。
- 验收:回测里被涨停拦下而未成交的 Buy 意图在 UI 上可见且说明原因;默认回测数值回归一致。
### 1.3 K 线 Chart 组件(前端)
- 引入图表方案:按 v3 推荐优先 **TradingView Lightweight Charts**
(npm 走 AGENT.md §0 代理);若安装受限则回退 ECharts candlestick(依赖已有),组件层隔离
便于替换。
- `components/StockChart/`:K 线 + 成交量 + 事件标记(signals/fills/selections)+ 技术指标开关
(MA/MACD/RSI 至少 MA)。
- 验收:同一 K 线上信号与成交用不同 marker;tooltip 显示价格/原因;tsc 通过。
### 1.4 Stock Research Page(个股研究页)
- 新路由 `/stocks/[symbol]`(v3 §20.4 版式):头部(代码/名称/当前信号/分数)→ K 线主图 →
量 → 指标 → 明细表(selection/signal/trade,可点开原因)→ 因子值与理由 → 风险标注。
- 数据全部来自 1.1/1.2 Chart API;股票池页每行可跳入本页。
- 验收:任一有数据的股票可完整浏览「为什么信号/选股/成交」;无数据/停牌显示占位。
### 1.5 复权口径落地(图表显示价 vs 回测执行价)
- Chart `adjust=none|qfq|hfq`:qfq/hfq 基于 `adjust_factor` 现算(不落地新行情);
回测执行保持研究主口径(`price_adjustment`,默认不复权)并写入
`metadata.execution_price_basis`。
- 图表与成交若口径不同由 Chart Service 做坐标换算(K 线同样复权到执行价基准,保证 marker 对齐)。
- 验收:对发生过除权(有 adjust_factor)的股票,切换显示口径后 fills 仍贴合 K 线。
### 1.6 Bar Replay(第二阶段,置于 M9 尾部可选)
- 按 as_of 逐日回放,仅用当时可得数据(复用 `resolve_observation_date`/repository `adjust` 过滤),
检查未来函数与 Selection/Signal 一致性。阶段验收:选定区间重放与静态回测结果一致。
---
## 2. 支撑线 B:数据与规则底座补全(为真实性与 Survivorship-free Universe)
> 与 M9 并行、按需插入(不阻塞主线首个可用版本)。
| 任务 | 内容 | 验收 |
|---|---|---|
| B1 行业/指数/成分同步 | 新增 Tushare Provider + Repository 表 `industry / stock_industry / index / index_daily / index_constituent_history`(历史成分,v3 §9/§30 红线) | 指数成分可查历史某日名单;universe 支持「按指数成分」过滤并回测可用历史名单 |
| B2 停牌与 ST 名单 | `suspend_data / stock_st_data` 表 + 同步 + Repository;研究侧 `exclude_suspended`/ST 口径落地(不再仅当前名称快照) | Selection/回测的 ST/停牌处理基于 as_of 当日名单;一致性测试更新 |
| B3 财务扩展 | `income_statement / balance_sheet / cashflow_statement`(按 announce_date 版本化) | 条件选股可用更多 fundamental 字段(严格 announce 可见) |
| B4 研究结果结构化 | `factor_test` 结果落库;`selection_rule / signal_rule / universe` 由 JSON 快照升级为实体表(沿用现有 selection/signal 快照思路) | 历史查询/复用不再依赖解析 JSON;迁移测试通过 |
---
## 3. 支撑线 C:研究与模型增强
| 任务 | 内容 | 验收 |
|---|---|---|
| C1 因子相关性/暴露 | Factor Research 增加因子相关性矩阵、行业/市值暴露、不同市场阶段统计(v3 §12) | 因子研究页展示 ≥2 因子相关性与暴露;单测 |
| C2 Portfolio 约束执行 | Portfolio v1.1:单股上限、行业上限、现金管理的实际权重分配(约束默认关保持向后兼容) | 开启约束的回测满足约束且结果 unimplemented 移除对应项 |
| C3 Model Service / 选股模式 C | qlib_adapter feature(Alpha158 子集)+model(LightGBM walk-forward,seed 固定)→预测分;Selection `method=model`(v3 §14.1C) | 模式 C 可选通(样本外 walk-forward 报告);不阻塞主线 |
---
## 4. 支撑线 D:基础设施与 Agent
| 任务 | 内容 | 验收 |
|---|---|---|
| D1 Job stage 上报 + SSE 长连 | executor 写入 stage(data_loading/factor_calculation/selection/signal/backtesting…,v3 §23);SSE 由 0.4s 轮询改事件推送;Job 列表/取消 API | 前端进度显示阶段名;取消可生效 |
| D2 全市场研究 Job 化 | 全市场选股/信号/因子研究统一走异步 Job(当前同步 60s+) | Web 选股页异步提交并轮询/SSE |
| D3 Redis(可选触发) | 本机 127.0.0.1:6379:Job 队列 / SSE pub-sub / 因子缓存(DEV_PLAN_v2 §7 触发点) | 按触发点启用并说明收益 |
| D4 Agent 工具补齐 | 按 v3 §25:`inspect_factor / create_composite_factor / get_backtest_result / create_experiment`(现 10 → 14) | Agent 编排用例通过;白名单不变式 |
---
## 5. 建议执行顺序(前 8 个 commit 序列)
每步遵循:Domain → Repository Protocol → Infra(Model→Migration→Repo) → Service → API → 前端 →
测试(相关模块)→ 更新文档;改结果结构先跑一致性回归,禁止悄悄改策略语义(v3 §26)。
1. **1.1 Chart DTO + Chart Service 骨架**(含复权坐标元数据):定义 ChartResult、股票
chart/信号/选股只读 API(数据来自现有 repo/engine)。验收:ChartResult 结构对齐 v3 §20.2。
2. **1.2 回测补 selection_history/signal_history/fills**:引擎输出三份记录;默认回测数值
逐项一致回归(v3 §28 Selection/Signal Consistency)。验收:涨停未成交意图可见。
3. **1.3 前端 K 线组件**(lightweight-charts 或 ECharts candlestick 兜底)+ marker。
验收:同图 signal↔fill 标记可辨、可点开原因。
4. **1.4 Stock Research Page `/stocks/[symbol]`**:接入 1.1/1.2 API。验收:闭环页面可用。
5. **1.5 复权口径落地**:Chart adjust 切换 + 坐标换算。验收:除权股 marker 对齐。
6. **B1 行业/指数/历史成分同步 + Universe 成分过滤**(survivorship 红线)。
7. **B2 停牌/ST 名单落地**(研究口径从名称快照升级为名单)。
8. **C2/C1 组合约束执行 与 因子相关性**(二选一先做,另一项随后)。
之后:B3/B4 → 1.6 Bar Replay → C3 模型选股 → D1–D4 基础设施/Agent。
---
## 6. 风险与注意
- **重构保一致**:BacktestResult/引擎扩展时以默认配置数值一致回归为门禁(v3 §26/§28)。
- **口径混用**:研究执行默认不复权;图表 qfq/hfq 仅在显示层换算 —— 严禁把 qfq 显示价写回研究数据。
- **未来函数**:历史成分/停牌/ST 均须 as_of 当日名单(v3 §9/§30);Chart/Replay 只消费 <=as_of。
- **前端不重算**:所有 selection/signal/fill 标记来自后端 DTO;图表库选择尽量可替换。
- **范围控制**:M9 不引入实盘、分布式、复杂表达式引擎;Bar Replay/模型选股按需推进。
- **MySQL 收尾**(沿用 DEV_PLAN_v2 §2 遗留表):大结果 MEDIUMTEXT、Repository 批量压测、MySQL 集成冒烟开关。