# 阶段 9 验收记录

## 交付范围

- 阶段选股：收盘行情定稿后按实际情绪阶段自动匹配策略、确定性计算并按交易日归档；不保留手动执行或编辑入口。
- 策略选股：29 套策略每日独立计算，不受情绪阶段门控；每套策略显示流派、适用环境、失效风险、适用阶段和条件。
- 自定义选股：109 个因子按分组选择，用户设置权重、方向、过滤条件、股票范围和输出数量后手动执行；策略和结果按账号隔离。
- 策略持续跟踪：只有用户明确加入的候选才进入跟踪，展示 T+1 开盘/收盘、T+3 收盘、T+5 收盘、最大涨幅和最大回撤。
- 会员边界：管理员和会员可读取与执行；普通用户保留同一页面结构，但业务内容灰化不可操作，服务端仍强制拒绝越权请求。

## 计算与数据口径

- 共登记 7 套阶段策略和 29 套独立策略，策略公式版本化；同一策略、交易日、因子快照和策略版本只保留一个运行结果。
- 选股由受控公式和真实数据确定性计算，LLM 不生成候选；自然语言编译公式留给阶段 10 的唯一 LLM 网关。
- 财务字段严格使用公告日不晚于选股日的数据，缺失值保持空值，不转换为零；公开网页来源不参与正式计算。
- 因子在筛选股票范围后计算覆盖率，截面百分位最优值为 1，并以股票标识稳定打破同分排序。
- `data_incomplete` 与 `no_signal` 分开表达；数据不完整不会伪装成当日无候选。
- 多因子策略明确命名为“动态多因子（基础版）”，未冒充尚未实现的 12 个月 IC 季度动态加权。

## 自动与账号边界

- 15:10 后且当日收盘快照为 `final` 时才启动盘后任务；重复调度复用同一运行记录，不重复生成候选。
- 阶段策略只执行与当前阶段匹配的集合；29 套策略始终独立执行，退潮期不会屏蔽策略选股。
- 自动运行永远不会自动加入持续跟踪；自定义策略、运行结果和跟踪记录均验证账号所有权。
- T+1 和 T+5 通知里程碑通过唯一约束保证只产生一次；T+3 只作为统计值，不生成提醒事件。

## 自动验收

- Ruff：通过。
- Pytest：69 项通过，覆盖 109 因子、36 套策略、公式确定性、缺失状态、Migration 前进/回退、账号隔离、追踪收益、事件唯一性和重复盘后执行。
- Vue TypeScript 检查：通过。
- Vitest：2 个文件、5 项通过。
- Vite 生产构建：通过，CSS 60.05 kB，JavaScript 218.25 kB。
- Playwright：8 项通过，覆盖阶段 4 至 9 全量回归；第 9 阶段覆盖三种选股模式、显式跟踪、非会员锁定、日夜主题、1920x1080 和 390x844。
- 浏览器控制台无未处理错误，390px 页面无横向溢出。
- 敏感值扫描：已提供账号密码和令牌未进入 `next/`。
- `git diff --check`：通过。

## 视觉证据

- `stage-light-1920x1080.jpg`：阶段选股日间桌面视图。
- `custom-dark-390x844.jpg`：自定义选股夜间移动视图。
- `tracking-dark-390x844.jpg`：策略持续跟踪夜间移动视图。

## 减法证据

- 未复制旧系统 2118 行选股实现；后端按目录、纯计算、技术因子、持久化和服务职责拆分，最长文件 448 行。
- 109 因子只有一份配置和一条标准化计算链，36 套策略只有一份版本化配置；前端不复制选股公式。
- 因子数据仍从唯一 `DataGateway` 进入；选股专属组装从网关主体拆出后，网关主体保持 500 行以内。
- 三种选股模式共用候选表、API 客户端、权限、主题和页面令牌；页面容器最长 169 行，选股样式 102 行。
- 没有新建通用 CRUD、缓存框架、模拟候选、旧系统兼容层或第二套调度入口。

## 剩余边界

- 自然语言转公式、模型调用、流式输出和智能调用计次统一留给阶段 10，不在选股模块建立临时 LLM 出口。
- 因子能否在指定交易日完整计算取决于管理员配置的数据权限；缺少权威数据时保持失败关闭。
- NAS 生产容器保持不变，最终切换仍需人工明确确认。
