6.4 KiB
知行 B1 集成原项目评分
Goal
在不改变知行 B1 选股语义的前提下,复用原项目的案例、特征、权重和阈值,并修正曲线距离为真正生效的 FastDTW,为每只 B1 命中股票提供可解释、可持久化、可验证的 0–100 最佳案例匹配结果。
Background
当前系统已具备 POST /api/v1/selection/runs、后台批量评估、PostgreSQL 结果持久化、结果查询与前端轮询展示;策略固定为 zhixing_b1,按显式目标交易日读取 qfq OHLCV,并独立保留七种子信号(.trellis/spec/backend/selection.md:12-49,85-152,docs/adr/0005-selection-formula-semantics-and-independent-subsignals.md:7-23)。评分尚未接入。
用户已明确本任务只迁移 Python 可执行的 0–100 图形相似度评分,不迁移 prompt 中依赖图片和大模型的 1–5 主观视觉评分。
实施门禁发现原源码的一维 FastDTW 调用实际抛错并回退 _simple_dtw;用户进一步确认版本一直接修正为真正生效的 FastDTW,因为允许局部时间对齐更符合评分要求。新分数使用独立版本,不承诺兼容旧 _simple_dtw 历史结果。
原可执行评分在候选信号产生后运行,对候选最近 25 个交易日与十个固定案例比较趋势结构、KDJ、量能和价格形态,实际权重为 0.10/0.20/0.25/0.45,总分为加权和乘以 100;每股只保留最高分案例,达到 60.0 才 enrichment(/Users/yuxuanhui/bcc-github/quant-project/zgnb/zgnb-project/src/zgnb/domain/pattern/config.py:8-38,/Users/yuxuanhui/bcc-github/quant-project/zgnb/zgnb-project/src/zgnb/domain/pattern/matcher.py:19-128,/Users/yuxuanhui/bcc-github/quant-project/zgnb/zgnb-project/src/zgnb/application/pipeline.py:168-220)。原文档权重与运行代码不一致,YAML 动态权重也未真正注入,迁移以实际运行代码为兼容基线。
原案例行情与缓存均未被 Git 跟踪,缓存没有版本或失效校验且已与当前行情漂移;原项目也没有评分数值 golden 测试。完整证据记录在 research/scoring-analysis.md。
Requirements
- R1:评分必须是 B1 命中后的 enrichment,不参与七个 mask 的判断,不改变股票是否选中、同股多 category、signals 顺序或
(ts_code, target_trade_date, strategy, category)稳定身份。 - R2:版本一固定使用原运行代码的十个案例、25 日升序窗口、四维特征、
0.10/0.20/0.25/0.45权重、容忍参数、最佳案例规则和>= 60.0阈值;曲线距离使用真正生效、显式半径的 FastDTW,版本标识为zhixing_b1_pattern_fastdtw_v1。算法、案例、FastDTW 半径或阈值变化必须升级评分版本。 - R3:案例定义属于代码中的版本化业务规则;案例特征在每次 run 中从 PostgreSQL 最新 qfq 行情完整构建,严格使用突破日前最后 25 个交易日,不依赖旧项目、本地 CSV、Tushare 或旧磁盘缓存。
- R4:每个 run 只加载一次完整案例库,每只
selected股票只评分一次;同股七个 category 共享股票级评分,不能复制成 category 级规则。 - R5:评分结果存入
selection_run_item,与选股 evaluation status 分离;结果包含状态、有限的 0–100 总分、60 分阈值、评分版本、最佳案例、四个有限分项和安全原因。旧 run 保持可读。 - R6:案例库缺失、单股评分异常、低于阈值或关闭评分都不得使选股失败,也不得进入现有选股失败计数;状态必须能区分
not_executed、matched、below_threshold和failed。 - R7:HTTP 在
stocks[].score返回可空的股票级评分,现有stocks[].signals[]与failures[]语义不变;后端支持稳定的代码、评分升序和评分降序数据库分页。 - R8:前端在股票级区域展示匹配分数、案例、四个分项以及低于阈值/评分失败状态,并提供评分排序;任何评分状态都不能遮挡已命中的 signals。
- R9:所有持久化和 HTTP 数值必须有限;原 25 日窗口产生的非有限中间特征必须通过离线兼容 fixture 锁定最终行为,不能把
NaN或Infinity写入数据库或响应。 - R10:提供
ZHIXING_SELECTION_PATTERN_SCORING_ENABLED运行开关;关闭后选股链维持原行为,新结果不产生评分。
Acceptance Criteria
- 离线 fixture 不依赖原项目或网络,数值 golden 覆盖十案例最佳匹配、四分项、总分、阈值边界、稳定同分、窗口不足和非有限中间值,并锁定修正后 FastDTW 版本一的确定结果。
- 对同一固定 B1 run,开启和关闭评分得到完全相同的选中股票、七个 category、signal details 和选股批次状态,差异只在股票级评分字段。
- 一只同时命中多个 category 的股票只调用一次 scorer,只保存和返回一个
stocks[].score,全部 signals 仍按既有顺序返回。 - 十个案例均存在时,最高分
>= 60的股票返回完整 matched score、案例、版本和四个分项;低于 60 时返回明确的 below-threshold 状态而不伪装成匹配。 - 任一案例缺失或单股评分抛错时,选股继续并保留 signals;评分返回 failed/不可用状态,现有
failed_count与failures[]不增加。 - 旧 run 和关闭评分产生的 run 可由新后端与前端安全读取,
score为空或 not-executed,不影响原页面功能。 code、score_desc和score_asc排序在 PostgreSQL 分页前执行,并以ts_code作为稳定次级键;前端不会只重排当前页。- 一次 run 只读取一次案例库且不按股票/category 重复查询;验证记录包含评分耗时和查询/调用次数。
- Alembic upgrade/downgrade SQL、后端 Ruff/Pyright/pytest、前端 format/lint/typecheck/test/build 和根目录门禁全部通过;未配置 PostgreSQL 测试库时明确报告跳过项。
Out of Scope
- prompt 中的 1–5 主观视觉评分、图片生成、视觉模型调用和
PASS/WATCH/FAIL。 - 改写知行 B1 公式、合并七个子信号、让评分反向决定是否入选或用于自动交易。
- 评分独立重跑、同股多评分器或多版本并存、通用评分平台。
- 评分阈值筛选、只导出高分股票代码和独立排名页面;MVP 只提供结果展示与排序。
- 兼容原项目实际回退的
_simple_dtw历史分数;FastDTW v1 是用户明确选择的新评分版本。