Files
zhixing-system/.trellis/tasks/08-29-integrate-b1-scoring/implement.md
T
2026-08-31 16:14:16 +08:00

6.9 KiB

知行 B1 图形相似度评分实施计划

实施前门禁

  • 用户明确批准本次最终规划摘要;批准前不运行 task.py start,不修改产品代码。
  • 使用 trellis-before-dev 加载 backend、frontend 与跨层规格。
  • 确认当前工作区只包含用户已有修改和本任务规划文件,记录不可覆盖的改动。
  • 在 Python 3.12 下点验原 FastDTW 调用:依赖可安装/导入,但一维曲线配合 SciPy 欧氏距离稳定抛出 AxisError,原实现实际回退 _simple_dtw。
  • 用户确认版本一采用真正生效的 FastDTW,接受与旧 _simple_dtw 分数不兼容;版本固定为 zhixing_b1_pattern_fastdtw_v1、标量欧氏距离、radius=1。

1. 冻结兼容基线

  • 从原项目十个案例 CSV 中提取严格早于 breakout date 的最小 25 日窗口,并选取代表性的候选窗口,写入 zhixing-server/tests/fixtures/selection/zhixing_b1/pattern_scoring/;不复制完整生产数据。
  • 使用原项目实际特征、权重和容忍参数,以及修正后的 FastDTW 路径离线生成期望的案例特征、四个分项、最佳案例和总分 JSON;测试运行时不导入原项目。
  • fixture 覆盖最高分大于等于 60、低于 60、同分稳定顺序、窗口不足、空案例、非有限中间特征和十案例完整性。
  • 记录原实现中被保留的行为及有意收紧的行为:实际权重优先于过时文档;完整案例库失败时不使用部分库;持久化和 HTTP 禁止非有限值。

回滚点:如果无法生成稳定的有限期望值,停止实现并回到规划,不猜测算法结果。

2. 实现纯领域评分

  • 在 modules/selection/domain/ 增加版本化案例定义、评分值对象、特征提取器、经确认的 DTW matcher 与 ZhixingB1PatternScorer;公开类型写完整 docstring、参数、返回值、异常与设计原因。
  • 迁移十个案例、25 日窗口、四维特征、0.10/0.20/0.25/0.45 权重、原容忍参数、60 分阈值和稳定 best-match 规则。
  • 集中实现有限值兼容 helper,保证领域对象从不包含 NaN 或 Infinity。
  • 增加领域单元/golden 测试,证明固定输入与旧实现期望一致且多次运行确定。
  • 更新 pyproject.toml 与 uv.lock,只引入实际运行所需依赖。

验证:

cd zhixing-server
uv run pytest tests/unit/selection -q
uv run pyright
uv run ruff check .

3. 构建 PostgreSQL 案例库适配器

  • 定义 selection application/domain 所需的 case history port,不让领域层依赖 psycopg。
  • 在 selection infrastructure 中实现参数化批量查询:规范化 ts_code、source_adj='qfq'、严格 < breakout_date、升序、每案例最后 25 行。
  • 每个 run 只读取和构建一次完整案例库;验证十个案例各有 25 条有效 OHLCV,禁止静默部分成功。
  • 用 fake connection 测试 SQL 参数、日期边界、排序、代码映射、缺失案例和数据库错误转换;有测试库时补 PostgreSQL 集成测试。

回滚点:案例库 adapter 独立合入前不得改变现有 selection run 结果。

4. 接入选股应用编排

  • 给 RunZhixingB1 注入 scorer/case-library loader;在 run 开始时准备库,在已有 evaluator 返回 selected 后复用对应 StockHistory 评分一次。
  • 扩展 SelectionRunItem 承载股票级 score;保留 signals、signal_count、选股 status 和 reason 的原语义。
  • 评分 failed 或 below_threshold 不进入现有失败计数,不改变 run 的 success/partial_success/failed 聚合。
  • 单元测试 selected/no-signal/评估失败/案例库失败/单股评分失败/同股七 category 只评分一次/批次继续执行。
  • 增加 feature flag,并通过 Settings、依赖注入和 Compose 环境变量统一配置;业务代码不直接读取环境。

5. 扩展数据库与仓储

  • 新建 Alembic migration,为 selection_run_item 增加评分状态、数值、版本、案例、breakdown、原因及排序索引;同时更新声明式 schema。
  • 增加数据库 check constraints,拒绝越界或不完整 matched 结果;旧行安全回填 not_executed。
  • 更新 batch upsert、run loader、重跑级联和查询对象,保持 item 与 signal 同事务落盘。
  • 增加 code|score_desc|score_asc 的白名单排序,数据库分页使用 score_value 与 ts_code 稳定排序;不得拼接用户原始 SQL。
  • 仓储测试覆盖 round-trip breakdown、旧行空 score、排序分页、category 过滤仍返回全部 signals、重跑清理和 migration upgrade/downgrade SQL。

回滚点:迁移为 additive;应用回滚时保留列。执行 downgrade 前必须确认已保存评分允许删除。

6. 扩展 HTTP 与前端

  • 后端增加具名 Pydantic score/case/breakdown 响应模型,在 stocks[].score 返回股票级结果;failures[] 继续只表示选股评估失败。
  • HTTP 测试覆盖 matched、below-threshold、failed、旧 run score: null、多 category、三种排序和分页稳定性。
  • 同步更新 selection.types.ts、API query 参数和 React Query key,保持同源 /api/v1 请求。
  • 在 selection workbench 的股票级区域展示总分、案例、分项、低于阈值与评分失败状态;signals 原详情不变。
  • 增加可访问的评分排序控件,默认仍为代码排序;测试用户可见文本、控件行为和分页请求参数。

7. 全量验证与发布检查

  • 后端执行格式、lint、strict type-check、全量测试、migration offline SQL;设置 ZHIXING_TEST_DATABASE_URL 时执行 PostgreSQL 集成测试。
  • 前端执行格式、lint、type-check、测试和 build。
  • 根目录执行完整门禁,并记录实际结果,不能用计划命令冒充已验证。
  • 用固定 run fixture 或本地测试库核对:选中股票与七个 signals 在开关前后完全一致,只有股票级评分字段新增。
  • 核对一次 run 只读取一次案例库、每股只评分一次、没有按 category 重复计算;记录评分耗时和数据库查询数。
  • 验证关闭 ZHIXING_SELECTION_PATTERN_SCORING_ENABLED 后旧流程仍成功、HTTP 安全返回空 score。
cd zhixing-server
uv run ruff format --check .
uv run ruff check .
uv run pyright
uv run pytest
uv run alembic upgrade head --sql
uv run alembic downgrade -1 --sql

cd ../zhixing-web
pnpm format:check
pnpm lint
pnpm typecheck
pnpm test
pnpm build

cd ..
./dev.sh check
./dev.sh test

交付与后续

  • 交付时报告算法版本、案例完整性、数值 parity、测试结果、性能数据和是否运行真实 PostgreSQL 集成测试。
  • 将“评分筛选/代码导出”“独立评分重跑”“多评分器/版本并存”“1–5 主观视觉评分”保留为独立后续需求,不在本任务顺带实现。