Files
tick-stock-panel/docs/factor-platform-plan.md
T
shy3130 b3e492d890 feat(factor-editor): 算子/字段面板与模板库 UX 迭代
- 算子区去重: 移除裸 chips 行, 速查表升级为唯一算子面板(默认展开, 挂载时置 open 避免与折叠态打架)
- 速查表重设计: 时序(13)/截面(3)/工具(9)三张分组卡片, 每行=完整签名+中文说明+参数约束, 点击整行插入公式光标处; 与 chips 共用 OPERATOR_GROUPS 单一数据源
- 折叠标题突出: 白色前景色+medium 字重+accent 箭头(展开旋转), 悬停变色
- 可用字段: 展开高度 160→256px; 分组名提亮加粗; 字段英文 id 蓝色(与算子签名同色), 中文保持灰色
- 模板库 5→12: 新增 低波动/量比回落/RSI超卖/低振幅/隔夜反转/距高点回落/换手稳定, 全部经 /api/factors/validate 预校验
- 校验/试算按钮居右(ml-auto)
- factor-platform-plan.md §5.2 模板计数同步
2026-09-05 18:19:34 +08:00

404 lines
32 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.
# 因子平台总体方案(研究线产品与架构设计 v1)
> 状态标记约定与 `factor-system-design.md` 一致:
> 【现状】= 当前仓库已存在、已核对代码;【设计】= 本方案提出、尚未实现。
> 所有阶段代号 P0–P4 见 §10 路线图。
## 执行状态(2026-09-04
P0–P3 已全部实现并通过验证(后端 98 项因子相关测试 + 全量套件 + 前端 build + 真实数据 E2E):
- **P0 已实现**`/factors` 一级页(检验/因子库/编辑器/组合 四 tab)、检验页 UX 六项、回测页 tab 移除与跳转、候选方案注入策略页。
- **跟进整合(2026-09-04)**:侧边栏「挖掘」菜单移除,AI 挖掘并入 `/factors?tab=mining`(第 5 个 tab);`/mining``/backtest?tab=mining` 旧链接保留参数重定向。
- **自动挖掘(2026-09-05,P3 后续)**:检验页新增「自动挖掘」入口(`POST /api/backtest/mining/auto`)——L1 全量统计筛选(`app/services/auto_mining.py`,门槛按探索/均衡/严格三档)自动生成达标因子池,随请求持久化筛选摘要(达标清单 + 未达标原因分布),L2 相关性剪枝 / L3 束搜索组合 / L4 嵌套样本外验证与达标门槛全部复用现有挖掘引擎;worker 子进程启动时加载因子注册表(自定义/复合因子可入池)。组合搜索本身不依赖 LLM;AI 的位置留给后续"从失败模式生成新 DSL 因子假设"。
- **因子 ↔ 策略结合(2026-09-05,四条桥全部已实现)**:① 策略触发器编辑内 Zap 快捷建因子条件信号(`SignalTriggerActions` + `AddFactorSignalDialog`,阈值给建议值,`csg_f_*` 自动挂接当前策略入场/卖出触发器);② 因子库「生成策略」一键产出单因子排名策略(`GenerateFactorStrategyDialog` 渲染 `FactorRankResearchMatrixStrategy` 模板,matrix_native,保存为 `custom_factor_*`);③ 自定义信号 AI 提示词注入全部因子分组(`custom_signals_ai.py::_format_fields`,行前缀「因子·」,白名单 `allowed_fields()` 收口);④ 策略回测因子归因(`strategy.py` 入场候选因子快照 → 胜/败单入场信号日因子均值,结果区第 4 个 tab,`meta.scoring` 非空即产出;矩阵单因子排名类策略因 META.scoring 设计为空,暂不产出归因,为已知边界)。
- **编辑器交互重构(2026-09-05)**:算子区合并为单一可点面板(全部 25 个 DSL 算子按「时序/截面/工具」分组,点击插入光标处,悬停显示签名与参数约束,替代"16 高频 chips + 静态速查表"双列表);可用字段 chip 双语(英文 id 等宽 + 中文标签浅色);「从模板开始」下拉新增「我的因子」分组(导入已保存自定义因子公式),非初始公式替换前弹确认防误覆盖。
- **因子库扩充(2026-09-05**:目录 61 → 77(新增 16 个虚拟因子,追加于目录尾部,挖掘调度前 48 项顺序不变):规模(流通市值对数,由换手率反推流通股本)、收益分解(隔夜/日内 20 日累计)、120 日动量与动量加速度、RSI 边际变化、下行波动、波动率状态(5/60)、振幅趋势、量能潮 OBV、20 日均成交额、均换手/换手波动(低换手溢价)、一年价格位置与距一年高点、KDJ K-D 差。双内核同步实现(`strategy/scoring.py` 评分路径 + `backtest/matrix.py` 矩阵内核,ddof 口径对齐存量约定);批量检验上限 64 → 96。
- **P1 已实现**`backend/app/factors/registry.py` 注册表(61 内置因子单一事实源)、快照/契约测试、`GET /api/factors`
- **P2 已实现**`backend/app/factors/dsl.py` 公式编译器(词法→EBNF 语法→语义校验 E001–E016→Polars 表达式,两阶段求值解决跨截面套时序窗口)、`POST /api/factors/validate|trial`、编辑器 tab。
- **P3 已实现**`stats_v2.py`Newey-West t / BH-FDR q / DSR,纯 numpy)、批量检验接线与前端服务端判读;`store.py` 自定义/复合因子持久化 + 评分桥(与策略共用同一条物化路径)+ CRUD API + 启动多轮加载;组合 tab;生命周期状态(草稿/激活/观察/退役)与状态流转 API。
- **P4 部分实现**:生命周期状态已落地;**巡检 tab 与后台衰减定时任务延后**(见 §10),复合因子权重 ICIR 自动配置模式延后。
- 验证环境备注:因子批量检验对 custom/composite 的底层依赖先经内置补算路径物化(`factor.py::_compute_missing_factors`),已按 fail-closed 语义处理缺失列。
## 0. 文档定位与阅读顺序
| 文档 | 角色 | 生效裁定 |
| --- | --- | --- |
| 本文(factor-platform-plan.md | **产品与架构总体方案**:两线架构、导航与页面、交互设计、功能全集、路线图 | 本文 §2–§8 生效后,`factor-system-design.md` §11 的"不新增顶层页面"结论**由本文取代** |
| `factor-system-design.md` | **后端技术 spec**FactorSpec schema、DSL 文法与算子表、统计口径(NW/BH-FDR/DSR)、API 契约、缓存键、测试矩阵 | 除 §11 外全部继续有效;本文引用不复制 |
两文冲突时:产品/前端/导航以本文为准;后端 schema、统计公式、API 字段以旧文为准。
## 1. 架构总览:两线模型
### 1.1 模型
```text
研究线(发现问题) 交易线(执行战法)
┌─────────────────────────┐ ┌─────────────────────────┐
│ 因子库(注册表) │ │ 策略引擎(战法) │
│ ↑ 检验(IC/IR/多空) │ │ 时机/买卖规则/仓位/风控 │
│ ↑ 公式DSL(自定义因子) │ │ ↑ 评分选股 │
│ ↑ 组合因子(加权合成) │ │ ↑ 验证(鲁棒性/步进) │
│ 挖掘(自动搜索因子组合) │ │ 回测(策略绩效) │
└───────────┬─────────────┘ └───────────↑─────────────┘
│ 唯一桥梁:策略 scoring 配置 │
└────────── 因子(组合)权重 ──────────────────┘
```
- **因子层**回答"此刻全市场谁排前面"(截面排序);**战法层**回答"何时进、买几只、多重仓、何时出、怎么止损"。
- 两线只通过**评分配置**结合:`{"scoring": {"cf_hotmom": 0.6, ...}}`。因子不会"变成"策略,因子给策略供货。
- 【现状】桥已存在:`backend/app/strategy/scoring.py:13` `VIRTUAL_SCORING_DEPENDENCIES`35 个虚拟因子依赖声明)、`scoring_value_expr`(按名取值表达式)、`mining.py:342` 挖掘候选产物本身就是 `scoring = dict(zip(factor_names, weights))`
- 【现状】研究线已分裂在两处:因子检验是 `/backtest?tab=factor`,挖掘是独立页 `/mining``frontend/src/router.tsx:126-127`)。本方案将研究线收拢。
### 1.2 各能力现状对照
| 能力 | 现状 | 本方案落点 |
| --- | --- | --- |
| 因子检验(批量/单因子) | 【现状】`backtest/factor.py` 61 因子、Rank IC/分年/衰减/分环境;前端 FactorDiscovery | §3(搬迁 + UX 重设计) |
| 因子注册 | 【现状】硬编码 `FACTOR_COLUMNS``factor.py:36`),加因子=改代码 | §4 + 旧文 §2 L-REG 注册表 |
| 公式配置 | 【现状】无(公式即代码) | §5 + 旧文 §3 DSL |
| 自动挖掘 | 【现状】`mining.py` beam search + 嵌套验证 + 晋升门槛,`/mining` 页 | §7(协同设计,不搬家) |
| 因子→策略 | 【现状】scoring 机制可用;复合因子需改代码 | §6 + 旧文 §8 FactorCompositeSpec |
| 生命周期管理 | 【现状】无 | §8(P4) |
## 2. 信息架构与导航【设计】
### 2.1 导航变化
```text
现状: 回测(/backtest: 因子|策略|验证) 挖掘(/mining) …
目标: 回测(/backtest: 策略|验证) 因子(/factors) 挖掘(/mining) …
↑ 导航顺序:回测 → 因子 → 挖掘 相邻
```
- 新增一级路由 `/factors`,导航标签「因子」,插入在回测与挖掘之间(`router.tsx` + `Layout.tsx`,两者为二开文档 §5.2 高冲突热点,diff 必须最小)。
- `/backtest` 瘦身为「策略」「验证」两个 tab。
- **旧链接兼容**`/backtest?tab=factor``<Navigate to="/factors" replace>`,沿用现有先例——`Backtest.tsx:38-43` 已用同一模式把 `tab=mining` 重定向到 `/mining` 并保留 query 参数。`tab=factor` 的重定向须保留 `run/candidate` 类参数的传递习惯(对齐 mining 先例)。
### 2.2 候选方案抽屉的归属
【现状】候选方案抽屉内联在 `Backtest.tsx:114`,头部门按钮打开;因子候选(FactorDiscovery「保存候选」)与策略候选共用该存储,且已有"载入复测"流转(`Backtest.tsx:35`)。
【设计】P0 将抽屉提取为共享组件 `CandidateDrawer`,**回测页与因子页都放入口**。裁定理由:候选是研究线的产物、交易线的原料,两边都要能开;提取是搬移不是复制(CONTRIBUTING §7 共享组件原则)。
### 2.3 因子页骨架
```text
/factors
├─ tab=inspect(检验) P0:现有 FactorDiscovery 整体迁入 + UX 六项改造(§3)
├─ tab=library(因子库) P1:注册表浏览器(§4)
├─ tab=editor(编辑器) P2:自定义公式因子(§5)
├─ tab=composite(组合) P3:组合因子构建器(§6)
└─ tab=lifecycle(巡检) P4:衰减监控看板(§8)
```
- tab 状态走 URL query`?tab=`),与回测页习惯一致,保证可收藏、可跳转。
- P0 只落地 `inspect`,其余 tab 以"规划中"占位不渲染入口(YAGNI:不提前放空壳 tab)。
## 3. 检验 tab 详细设计(P0,纯前端)
### 3.1 页面线框
```text
┌──────────────────────────────────────────────────────────────────────┐
│ 因子检验 [候选方案] [AI 挖掘→] │
│ ┌ 三句话说清楚(可折叠,默认展开,关后记忆到 localStorage)─────────┐ │
│ │ ① 因子 = 用来给股票打分排序的特征(如 20日涨幅、换手率变化)。 │ │
│ │ ② 这里检验:过去一段日子里,哪些特征真的能预测次日涨跌。 │ │
│ │ ③ IC = 预测准确度(绝对值越大越准),IR = 稳定度(越大越稳)。 │ │
│ └──────────────────────────────────────────────────────────────────┘ │
│ ┌ 筛选配置 ────────────────────────────────────────────────────────┐ │
│ │ 想好要测什么了吗?没有的话从预设开始: │ │
│ │ [全面体检 61] [快速体检 10] [趋势动量 14] [超跌反转 9] │ │
│ │ [量价资金 11] [财务价值 7] 当前: 全面体检 ✓(点预设=替换选择) │ │
│ │ 已选 61/61 全选 清空 [🔍 搜索因子 (名称/公式)] │ │
│ │ ┌─ 限高 45vh 内部滚动列表(现状保留)────────────────────────┐ │ │
│ │ │ ▾ 动量 (6) 本组测:过去 N 日涨了多少 … │ │ │
│ │ │ ☑ 5日动量 5个交易日累计收益率 │ │ │
│ │ └────────────────────────────────────────────────────────────┘ │ │
│ │ 资产与范围 / 日期 / 调仓 / 分组 / 佣金(现状保留) │ │
│ │ [ 筛选 61 个因子 ] │ │
│ └──────────────────────────────────────────────────────────────────┘ │
│ ┌ 筛选结果 ─────────────────────────────────────────────────────────┐ │
│ │ 结论句:61 个因子中 7 个有效*。最强:5日反转(IC −0.041)。 │ │
│ │ 表格: 排名 | 因子(含方向箭头) | 预测力IC | 稳定度IR | IC胜率 | │ │
│ │ 多空收益 | 最大回撤 | [结论徽章] | 操作 │ │
│ └──────────────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────────────┘
```
### 3.2 预设场景入口
**设计动机**:现状默认全选 61 个,用户第一个动作是"做选择题";预设把第一个动作变成"按一下"。
预设清单(数量已按 `factor.py` FACTOR_COLUMNS 实际分组核对:动量 6、趋势 8、均线偏离 10、量价 9、价格位置 6、超买超卖 3、收益形态 3、波动率 5、流动性 2、涨停基因 2、财务 7,共 61):
| 预设 | 数量 | 构成规则 | 适合谁 |
| --- | --- | --- | --- |
| 全面体检(默认) | 61 | 全部因子 | 不知道从哪开始的人;标注"耗时最长" |
| 快速体检 | 10 | 除财务组外每组取窗口中位代表因子(如动量组取 20日动量) | 想快速看一圈的人 |
| 趋势动量 | 14 | 动量组 + 趋势组 | 关心趋势行情下什么有效 |
| 超跌反转 | 9 | 超买超卖组 + 价格位置组 | 关心抄底反转逻辑 |
| 量价资金 | 11 | 量价组 + 流动性组 | 关心资金与量能信号 |
| 财务价值 | 7 | 财务组 | 关心基本面(需财务数据源能力) |
交互规则:
1. 点预设 = **替换**当前选择集(不是叠加),按钮立即显示"当前预设 ✓"。
2. 用户手动改勾选后,状态变为「自定义」,所有预设按钮取消高亮。
3. 预设是**纯前端选择集**,不新增后端概念;构成规则在代码里以"组名 + 组内规则/显式 id 列表"声明,实现时从 `columns.data` 按组过滤生成(不硬编码 61 个 id 的第二份清单)。
4. 「快速体检」的代表因子实现时从 FACTOR_COLUMNS 按"窗口中位"解析;解析失败的组整组纳入(fail-open 但数量标注会变)。
### 3.3 三句话引导条
- 位置:页面标题下方,结果区上方;`<details>` 式可折叠,默认展开,关闭状态记 `localStorage`key 纳入现有 preferences 机制则更好,实现时择一,不新增后端字段)。
- 文案即 §3.1 线框中三句,不许加第四句——解释超过三句就没人读。
- 每句中的术语(IC/IR)与表头 tooltip(§3.4)文案保持一致。
### 3.4 表头判读 tooltip(文案定稿)
悬停表头即出,内容一句话 + 判读标准。列名同步通俗化(括号内保留原术语供专业用户):
| 列 | 通俗列名 | tooltip 文案 |
| --- | --- | --- |
| IC 均值 | 预测力 IC | 每天用因子给股票打分、与次日真实涨跌算相关性(Rank IC)的均值。\|IC\|≥0.02 且稳定,即有预测力;负值同样有效(反向使用)。 |
| IR | 稳定度 IR | IC 均值 ÷ IC 波动。≥0.3 值得关注,≥0.5 相当稳定。 |
| IC 胜率 | 预测日占比 | IC 与预测方向一致的天数占比。50% 是抛硬币,55%+ 不错。 |
| 多空收益 | 多空收益 | 每期买因子最高组、(模拟)卖最低组的累计收益差。注意 A 股做空受限,此列为理论口径。 |
| 最大回撤 | 最大回撤 | 上述多空组合最痛的一段亏损幅度,衡量拿得住不住。 |
| 排名 | 排名 | 按当前排序键排序的名次,默认按 \|IC\|。 |
### 3.5 结果判读(徽章 + 结论句)
- 【现状】结果行字段:`ic_mean / ir / ic_win_rate / long_short_return / long_short_max_drawdown / error``FactorDiscovery.tsx:372-376`);**当前 API 无 t 值**。
- 【设计·P0】客户端经验阈值判读(须在 UI 上明示"经验规则"):
- `有效``|ic_mean| ≥ 0.02 且 |ir| ≥ 0.3`
- `边缘``|ic_mean| ≥ 0.02 或 |ir| ≥ 0.3`(其一成立)
- `无效`:其余
- `计算失败``error` 非空(现状已有 error 显示)
- 【设计·P3 起】后端 metrics_v2(旧文 §6`t_newey_west`)落地后,判读切换为**服务端显著性与阈值双条件**,前端仅渲染服务端 verdict;P0 的客户端阈值作为降级路径保留。
- 结论句模板:`{N} 个因子中 {M} 个有效。最强:{label}IC {值})。`N=参与计算的因子数(排除 error),M=有效徽章数。结论句挂在表头右侧,字号小、颜色 muted。
### 3.6 因子方向标识
- 位置:**结果表**因子名旁,非复选框列表(检验前方向未知,不预测)。
- 推导:`ic_mean > 0``↑ 值大看多``ic_mean < 0``↓ 值小看多`null/error → 不显示。
- 这是从数据推导的事实(样本内 IC 符号),非先验声明,因此**不进因子库元数据**(P1 因子库的方向列同样取最近一次检验的 IC 符号,并标注样本区间)。
### 3.7 路径闭环
1. **保存候选**后 toast`已保存到候选方案(右上角查看)`;因子页头部有「候选方案」按钮(§2.2 共享抽屉)。
2. **单因子检验**页(FactorDiscovery 内部 mode=single)顶部加返回链:`← 返回批量结果`,保留现有列表参数不丢。
3. **因子库 → 检验**联动(P1):`/factors?tab=inspect&focus={factor_id}` 打开检验页并只勾选该因子。
4. **AI 挖掘 →**:因子页头部的 `/mining` 链接(研究线互链,§7)。
### 3.8 状态设计(CONTRIBUTING §7 强制项)
| 状态 | 触发 | 展示 |
| --- | --- | --- |
| 加载(因子清单) | columns.isLoading | 列表区骨架/「因子加载中…」(现状已有) |
| 加载(运行中) | run.isPending | 按钮禁用 + 进度文案(现状已有),期间**保留上次结果**不闪空(现状行为核对) |
| 空结果 | results=[] | EmptyState + 引导语「试试更长时间范围或减少因子」 |
| 错误 | run.isError | 错误条 + 重试按钮,保留左侧配置 |
| 无权限/无数据 | 财务预设但无财务数据源能力 | 预设按钮禁用 + title 说明「需要财务数据能力」(对齐能力矩阵门控习惯) |
### 3.9 迁移清单(P0 范围内的代码动作,供实施 PR 参考)
| # | 动作 | 文件 | 性质 |
| --- | --- | --- | --- |
| 1 | 新建 `/factors` 路由 + `Factors.tsx` 页壳(tab=inspect | `router.tsx``pages/Factors.tsx` | 新增 |
| 2 | FactorDiscovery 连同其 queryKeys 原样迁入 | `pages/backtest/FactorDiscovery.tsx` → 组件复用 | 搬移 |
| 3 | `tab=factor` 重定向 `/factors`(保参,对齐 mining 先例) | `pages/Backtest.tsx` | 修改 |
| 4 | Backtest 移除因子 tabMODES 剩 策略/验证 | `pages/Backtest.tsx` | 修改 |
| 5 | 候选抽屉提取共享组件,两页挂入口 | `Backtest.tsx``components/CandidateDrawer.tsx` | 提取 |
| 6 | UX 六项(§3.2–§3.7 | `FactorDiscovery.tsx`(或其子组件拆分) | 新增 |
| 7 | 导航项「因子」 | `Layout.tsx` | 修改 |
不做的:不改 queryKeys.ts 键结构、不改任何 API、不动 factor.py。
## 4. 因子库 tabP1,依赖 L-REG 注册表)
### 4.1 列表
- 数据源:`GET /api/factors`(旧文 §10 已定义),P1 前无此接口时**本 tab 不上线**(不放假数据)。
- 列:`id / 中文名 / 分组 / 类型(basevirtualcompositecustom/ 公式(desc 或 DSL)/ 最近 IC(含样本区间)/ 状态徽章 / 资产类型 / warmup 天数`
- 筛选:搜索框(id/名称/公式,复用检验 tab 同款逻辑)+ 类型、分组、状态下拉。
- 行点击 → 详情抽屉。
### 4.2 详情抽屉
- FactorSpec 全字段(旧文 §2.2 的 17 字段)按人话展示:公式、方向(最近检验 IC 符号 + 样本区间)、warmup"需要 X 日历史预热")、依赖列、适用资产。
- 操作:「去检验」(§3.7 联动)、「克隆到编辑器」(P2 后可用)、custom/composite 显示「编辑」「停用」。
- 底部:最近一次检验报告摘要(IC/IR/多空/回撤)+「查看完整报告」跳检验 tab。
### 4.3 状态徽章
与 §8 状态机一致:`active / watch / retired / draft`。P1 只有 `active`(全部内置因子)与 `draft`(编辑器产物),watch/retired 在 P4 激活。
## 5. 因子编辑器 tab(P2,依赖 DSL 编译器)
### 5.1 布局
```text
┌────────────────────────┬──────────────────────────┐
│ 公式编辑区 │ 校验与预览区 │
│ textarea (等宽字体) │ ✓/✗ 语法校验(错误码+定位) │
│ 算子面板 (25 个, 三组) │ 依赖列集合 │
│ 时序/截面/工具, 点击插入│ warmup = max(窗口) 提示 │
│ 可用字段 ▾ (双语 chip) │ [试算最近 40 日 IC] │
│ 从模板开始/我的因子 ▾ │ 试算结果: IC 走势 sparkline │
│ [校验] [试算 40 日] │ 注册/更新表单 │
└────────────────────────┴──────────────────────────┘
```
### 5.2 交互流
1. 输入公式 → 调 `POST /api/factors/validate`(旧文 §10;错误码 E001–E016 见旧文 §3.5,含负 shift 即未来函数的 E005)。
2. 校验通过 → 展示编译产物:依赖列集合、warmup_bars(旧文 §3 规则 4)。
3. 试算:选近 40 交易日 + 当前资产,跑一次 Rank IC 快照(复用检验引擎计算路径,**不另写计算逻辑**);展示 IC 序列 sparkline 与均值。
4. 注册:状态 `draft`,写入注册表;后续在检验 tab 跑完整检验后转 `active`(§8 状态机)。编辑已有因子时公式变化保存为新版本并回草稿态。
5. 模板起点:「从模板开始 / 我的因子」下拉——经典模板(12 个范式, 覆盖反转/动量/波动/量价/换手/超卖/位置)+ 我的因子(已保存自定义因子公式导入);替换非初始公式前弹确认。
6. 点选插入:全部 25 个 DSL 算子按「时序(13)/截面(3)/工具(9)」分组,点击插入光标处(与后端 `dsl.OPERATORS` 同步维护),悬停显示签名与参数约束;79 个可用字段 chip 双语显示(英文 id 等宽 + 中文标签),点击插入。
### 5.3 约束(红线)
- 编辑器产物只经 DSL 编译到 Polars 表达式这一条计算路径(旧文 §3),**禁止**出现第二套求值器(CONTRIBUTING 禁止平行实现)。
- 注册因子 id 冲突拒绝,不自增后缀静默改名。
- 每一步的服务端校验 fail-closed:校验不过,注册按钮禁用且展示原因。
## 6. 组合 tabP3,依赖 FactorCompositeSpec
### 6.1 组合构建器
- 成分:从因子库多选(上限 8 个,对齐挖掘 max_factors 习惯),每行显示该因子最近 IC/IR。
- 权重三模式:
1. **手动**:逐项权重滑杆,实时归一显示;
2. **ICIR 自动**`w_i ∝ max(ICIR_i, 0)`,窗口 504 交易日,**只用 (twindow, t−1] 数据**(旧文 §8 点时规则,严禁 t 日数据参与 t 日权重);
3. **均等**1/N。
- 预览:选定回看区间内,组合 IC/IR 曲线 vs 各成分——证明"组合优于单因子"或及时劝退。
### 6.2 注册与桥接
- 「注册为复合因子」→ FactorCompositeSpec 入注册表,类型 `composite`
- 桥接机制**零引擎改动**(旧文 §8 已论证):注册时自动写入 `VIRTUAL_SCORING_DEPENDENCIES` 对应条目 → 立即出现在策略评分可选列表。
- 「一键创建策略」:打开策略新建表单并预填 `scoring = {组合id: 1.0}`,用户补战法参数——完成研究线→交易线的最后一步。
## 7. 与挖掘页协同【设计】
裁定:**挖掘保持独立页**(已有用户习惯 + 任务型界面本就该独立),做研究线互链而非合并。
1. 因子页头部「AI 挖掘 →」链到 `/mining`
2. 挖掘候选详情加「查看因子检验」:跳 `/factors?tab=inspect&focus=...` 预选该候选的成分因子。
3. P4 可选:挖掘晋升的候选自动以 `watch` 状态写入因子库(人工确认后转 active)——默认不自动转正,晋升门槛(`mining.py` GATE_*)只证明样本外可行,不过不代表可持续。
## 8. 因子生命周期(P4
### 8.1 状态机
```text
draft ──(完整检验通过)──▶ active ──(衰减告警/人工)──▶ watch ──(持续衰减/人工)──▶ retired
▲ │
└──────────────(重新编辑公式, 重新走检验)──────────────────┘
```
| 迁移 | 触发条件 | 动作 |
| --- | --- | --- |
| draft→active | 检验报告满足:\|IC\|≥0.02 且 \|IR\|≥0.3(或 metrics_v2 后 t 显著) | 进策略可选列表 |
| active→watch | 滚动 63 日 IR < 0,或滚动 63 日 \|IC\| 较全样本减半 | 因子库标黄,不影响策略运行 |
| watch→retired | 连续两个观察窗(126 日)仍衰减,或人工 | 从策略可选列表隐藏(已引用它的策略配置**不破坏**,仅新建不可选) |
| retired→draft | 人工重新编辑 | 重走检验 |
### 8.2 衰减监控
- 计算:后台低频任务(日线收盘后),对 active/watch 因子重算滚动 63 日 Rank IC/IR——复用检验引擎同一条 IC 计算路径。
- 展示:因子库 tab 状态列 + P4 的 `lifecycle` 看板(衰减榜:谁最近不行了)。
- 通知:首版只做页面内徽章;接通知服务(`NotificationFormatter` 继承点)为可选后续,防打扰。
## 9. 后端支撑映射
| 本方案功能 | 后端依赖 | 旧文章节 | 代码落点 |
| --- | --- | --- | --- |
| 检验 tab(§3) | 无新依赖(P0 纯前端) | — | — |
| 因子库(§4) | L-REG 注册表 + `GET /api/factors` | §2、§10 | 【设计】`app/factors/registry.py`(三处合一:factor.py:36 + scoring.py 虚拟因子 + pipeline ENRICHED_COLUMNS |
| 编辑器(§5) | DSL 编译器 + `POST /api/factors/validate` | §3、§10 | 【设计】`app/factors/dsl.py` |
| 判读升级(§3.5 | metrics_v2t_newey_west 等) | §6 | factor.py `_calc_ic` 扩展(现状 `factor.py:738-750` |
| 组合(§6 | FactorCompositeSpec + scoring 桥 | §8 | scoring.py `VIRTUAL_SCORING_DEPENDENCIES`(现状 `scoring.py:13`,写路径自动化) |
| 生命周期(§8) | 衰减重算任务 + 状态字段 | §6(IC 口径复用) | 【设计】注册表状态字段 + 低频任务 |
## 10. 路线图(PR 切分)
> 与旧文 §14 的十个 PR 合并视图:数据线四个 PRst_history / delisted_kline / industry_pit / index_ext)独立并行,不受本路线图阻塞。
### P0 — 因子页拆分 + 检验 UX(1 个 PR,纯前端)
- 范围:§2 导航/路由/重定向 + §3.9 迁移清单 7 项 + §3.2–§3.7 UX 六项。
- 依赖:无。
- 验收:`/factors` 可用;旧链接 301 语义跳转;候选抽屉两页可用;六项 UX 逐项截图;窄屏检查;`pnpm build` 过;queryKeys 无变更。
- 回滚:revert 单 PR 即回到现状,无数据迁移。
### P1 — 注册表 + 因子库(2 个 PR:后端 / 前端)
- 后端:L-REG 注册表(旧文 §2FACTOR_COLUMNS 由注册表生成、对外常量保留兼容别名;scoring.py 改读注册表、函数签名不变)+ `GET /api/factors`
- 前端:因子库 tab 上线(§4)。
- 验收:注册表生成结果与现 61 因子逐项一致(快照测试);旧候选方案引用的历史 id 全部可读。
### P2 — DSL + 编辑器(2 个 PR
- 后端:DSL 编译器 + validate/试算端点(旧文 §3,含 E001–E016)。
- 前端:编辑器 tab(§5)。
- 验收:错误因子公式全路径测试;试算与检验引擎同源计算对拍一致。
### P3 — metrics_v2 + 组合 + 判读升级(2 个 PR)
- 后端 ametrics_v2NW t 值等,旧文 §6;测试=黄金参考向量 + 可选 dev 组 statsmodels 对拍)。
- 后端 b+前端:FactorCompositeSpec + scoring 桥自动化 + 组合 tab(§6)+ 结果判读切服务端(§3.5)。
- 验收:组合因子在策略评分中可选且数值路径唯一;DSR/BH-FDR 数值测试过。
### P4 — 生命周期(1 个 PR,可延后)
- §8 状态机 + 衰减任务 + 巡检看板。
- 验收:衰减告警可复现(构造样本);retired 因子不破坏存量策略配置(兼容测试)。
## 11. 验证矩阵(对齐 CONTRIBUTING §9
| 改动 | 最低验证 |
| --- | --- |
| P0 前端 | `pnpm build`;手工检查:加载/空/错/禁用/无权限五态、预设切换与自定义态、搜索不丢选择(回归本轮已验证的行为)、旧链接重定向、候选抽屉双页、窄屏 |
| P1 注册表 | 后端 pytest:注册表快照=现 61 因子、历史 id 兼容、scoring 行为不变(对拍测试);API 契约测试 |
| P2 DSL | 编译器单测(合法/非法公式全错误码)、防未来函数(E005 用例)、试算与检验同源对拍 |
| P3 统计 | NW/BH-FDR/DSR 数值断言(黄金向量);组合因子端到端:注册→策略评分可选→回测出数 |
| P4 生命周期 | 衰减触发用例、retired 兼容用例、低频任务不阻塞启动 |
| 全阶段 | `git diff --check`;每 PR 附界面证据(截图覆盖改动前后) |
## 12. 兼容性与风险
| 项 | 影响 | 对策 |
| --- | --- | --- |
| 旧链接 `/backtest?tab=factor` | 收藏/外链失效 | Navigate 重定向保参(mining 先例) |
| 候选方案存储 | 无 schema 变化 | 仅抽屉组件提取,存储与"载入复测"链路不动 |
| 因子 id | 不变 | P0 不碰 factor.py;P1 注册表生成需逐项快照对齐 |
| `router.tsx`/`Layout.tsx` 高冲突热点 | 上游合并冲突面 | diff 最小化:只加一条路由/一个导航项,不动既有结构 |
| P0 判读阈值是经验值 | 可能误判"有效" | UI 明示"经验规则";P3 换服务端显著性后降级为兜底 |
| 方向箭头取自样本内 IC 符号 | 过拟合误读 | tooltip 注明"样本内方向,历史不代表未来" |
| 编辑器产生大量低质因子 | 注册表膨胀 | draft 不进策略可选列表;必须过完整检验才 active |
## 13. 不做什么(YAGNI,续旧文 §16)
1. 因子市场/分享/导入第三方因子包——无真实需求前不做。
2. 因子自动再训练/自动调参流水线——自动权重窗口已是点时滚动,更细即过拟合。
3. 实时因子流(盘中逐 tick 因子值)——研究线是日频截面,实时因子属于监控线的事。
4. 跨市场(港美股)因子——数据源与交易规则均不支持。
5. 因子血缘图谱可视化——注册表依赖列字段已可追溯,图形化为炫技。
6. 把挖掘页合并进因子页——任务型界面独立存在(§7 裁定)。
## 14. 完成标准
本方案"完成"= 路线图 P0P3 全部合入且:
1. `/factors` 四 tab(检验/库/编辑器/组合)可用,旧链接可达;
2. 一个不懂量化的用户按 §3.1 引导能独立跑出一次检验并读懂结论句(可用性自测标准);
3. 一个自定义公式因子走完 编辑→校验→试算→注册→检验→进策略评分 全链路无断点;
4. 全程未产生第二套计算逻辑(注册/编辑器/组合均编译到同一条 Polars/检验路径);
5. P0–P3 各 PR 验收标准逐项通过,界面证据与测试结果真实可查。