- 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 图表选型
187 lines
13 KiB
Markdown
187 lines
13 KiB
Markdown
# 下阶段开发计划(架构 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 集成冒烟开关。
|