edit | blame | history | raw

股票估值端到端协调层 V2 编码方案 V002

创建人员:dev.developer.project.secondary / infodev-2
文件职责:在不修改、不复制 ana-dev V1 计算内核的前提下,冻结 project 级股票估值端到端协调层的接口、证据、缓存、失败、报告、性能和验收合同。
关联事项:DEV-ANA-STOCK-VALUATION-PIPELINE-V2-20260801-001
上游依据:用户关于日常开发员接手 V2 的原生任务委派;dev-doc/ana-doc/开发方案/CODE-DESIGN-ANA-STOCK-VALUATION-PIPELINE-V2-V001.md;股票价格合理性评估操作手册;V1 流水线与铖昌科技既有结果。
管理规范/模板:../../../common/dev-doc/编码规范.md../../编码规范.md../../开发审计规范.md
引用文件:../开发工作区说明.md../../../dev/ana-dev/stock_valuation_pipeline/README.md../../../outputs/20260730_stock_valuation_guide/股票价格合理性评估操作手册_v1.0.md
记录方式:重型编码方案;dev.reviewer.projectdev-doc/开发审计报告.md 给出方案 PASS 前不得实施重型代码。

1. 接手、重分类与方案继承

  1. 原 V001 已冻结业务目标,但实现落点为 dev/ana-dev/stock_valuation_pipeline/,负责人和审核员分别是 dev.developer.ana.caidev.reviewer.ana.cai;后者会话失效,未产生独立 PASS。
  2. 本次由项目日常开发池明确将事项交给空闲的 dev.developer.project.secondary。合法实现落点改为 dev/project-dev/stock_valuation_pipeline_v2/,测试落点为 dev/project-dev/test/stock_valuation_pipeline_v2/,审核员改为共享 dev.reviewer.project
  3. V001 的业务目标、状态、四类来源、性能指标和验收底线继续作为输入;V002 取代 V001 成为本次实现方案。V001 保留为历史证据,不改写、不冒充已审核方案。
  4. dev/ana-dev/stock_valuation_pipeline/ 及其测试、Schema、注册表和 README 在本事项中全部只读。V2 通过稳定 Python 入口调用 V1,不复制公式、校验或报告计算逻辑。
  5. 如后续发现必须修改 V1 公共合同,立即停止相关实现并向 project.admin 申请一事项范围调整;未获调整前不得写 ana-dev

2. 问题、目标与非目标

2.1 问题

V1 只能在人工准备好 valuation_snapshot.json 后执行毫秒级计算。用户从提出 ticker/as-of 请求到收到完整报告的主要时间仍消耗在资料取得、来源校验、快照构建、报告扩写和人工终检,现有引擎耗时不能代表总墙钟。

2.2 目标

  1. 新增 ticker + as-of 端到端入口,同时保留 V1 --input 兼容入口。
  2. 并发取得公开行情、法定公告索引、结构化财务和机构预测,并在预算内结束或降级。
  3. 保存原始响应哈希、请求索引、来源元数据、A1 回链、公司基线和增量水位。
  4. 有判断覆盖层时构造合法 V1 快照并调用 V1 计算核心;无覆盖层时不伪造情景或方向性结论。
  5. 固定生成 16 节 Markdown、自动 QA、原子提交、运行 manifest 和从用户任务起点开始的总墙钟。

2.3 非目标

  1. 不连接付费数据库,不绕过登录、验证码、反爬或访问控制。
  2. 不修改 V1 计算公式、Schema、注册表、缓存或报告实现。
  3. 不复制 V1 核心到 project 目录,不建立第二套估值公式实现。
  4. 不自动推断未披露客户、订单、型号或敏感军工事实。
  5. 不输出交易指令、收益承诺或自动批准的投资结论。
  6. 不引入 GUI、常驻服务、数据库、定时任务或第三方 Python 依赖。

3. 代码、测试与文档落点

dev/project-dev/
  stock_valuation_pipeline_v2/
    __init__.py
    __main__.py
    cli.py
    telemetry.py
    http_client.py
    cache.py
    providers.py
    acquisition.py
    snapshot_builder.py
    judgment.py
    v1_bridge.py
    full_report.py
    report_qa.py
    workflow.py
    provider_registry.json
    judgment_overlay.schema.json
    README.md
  test/stock_valuation_pipeline_v2/
    test_*.py
    fixtures/chengchang_20260801/

dev-doc/project-doc/
  股票估值端到端协调层V2.md
  开发方案/CODE-DESIGN-PROJECT-INFO-STOCK-VALUATION-PIPELINE-V2-V002.md

现有操作手册位于角色常规写入范围之外。实现和审核期间先在 project 文档中维护 V2 使用说明;正式修改原操作手册前需由 project.admin 明确授予该单文件写入范围,或由其根据本事项证据代为同步。不得用“用户委派”静默扩大目录权限。

4. CLI 与兼容合同

4.1 V1 兼容入口

python -m stock_valuation_pipeline_v2 `
  --input <valuation_snapshot.json> `
  --output-dir <output-dir> `
  [--force]

该模式只做参数校验和 V1 桥接,调用 V1 run_pipeline,保留 GENERATED/REUSED、退出码和三件套产物语义。不得改变传入快照或追加 V2 结论。

4.2 ticker/as-of 入口

python -m stock_valuation_pipeline_v2 `
  --ticker 001270.SZ `
  --as-of 2026-08-01 `
  --output-dir <output-dir> `
  --cache-dir <cache-dir> `
  [--judgment <judgment_overlay.json>] `
  [--fixture-dir <fixture-dir>] `
  [--task-start <ISO-8601>] `
  [--force]

硬合同:

  1. --input--ticker 互斥;ticker 模式必须给 as-of、output-dir、cache-dir。
  2. ticker 规范化为 NNNNNN.SZ/SH/BJ;无法确定市场时在网络前失败。
  3. as-of 不得晚于当前本地日期;所有来源按发布日期和数据日期双重过滤。
  4. fixture 模式禁止打开网络;夹具缺失是显式合同错误。
  5. stdout 只输出结构化终态摘要,进度写 stderr 和 runtime.log

5. 两阶段数据与判断合同

V1 的 valuation.scenarios 必须非空且必须包含唯一基准情景。因此 V2 不得在无 judgment 时捏造机械场景来强行调用 V1。

5.1 无 judgment

  1. 采集、证据、字段级来源、公司基线和数据快照照常完成。
  2. 生成 data_snapshot.jsonsnapshot_build_report.json、16 节数据就绪报告、QA、gap、遥测和 manifest。
  3. 情景、结论、触发器等判断章节明确写 GAP:需要人工判断覆盖层,不得出现方向性价格结论。
  4. 终态固定为 DATA_READY_NEEDS_JUDGMENT;不生成伪 V1 valuation_snapshot.jsonvaluation_results.json

5.2 有 judgment

  1. judgment_overlay.schema.json 仅允许业务摘要、归一化调整、三情景、主模型、交叉验证、风险、上下调触发器、持有期和结论边界。
  2. 覆盖层不得写价格、股本、法定利润、财务期间、来源日期或 A1 文档身份;出现禁写字段立即 E_JUDGMENT_CONFLICT
  3. 覆盖层与数据快照合并后生成合法 V1 valuation_snapshot.json,通过 v1_bridge.py 调用 V1 load_snapshotcompute_valuation
  4. V1 计算结果是所有数值章节的唯一来源;V2 报告模板不得重新计算 PE、PB、PS、情景、反向 PE 或持有期结果。

6. 统一提供者合同

四类适配器统一返回:

{
  "provider_id": "market",
  "adapter_version": "1.0.0",
  "status": "OK|GAP|BLOCKED",
  "fetched_at": "ISO-8601",
  "as_of_date": "YYYY-MM-DD",
  "records": [],
  "sources": [],
  "gaps": [],
  "warnings": [],
  "raw_artifact_hashes": []
}

6.1 法定公告索引

取得交易所或巨潮公开公告索引,登记证券代码、标题、公告日期、报告期、公告 ID、原文 URL、修订状态和支持字段。财务核心字段必须能回链至 A1 原文;公告索引不负责凭叙事直接填利润。

6.2 行情

取得不晚于 as-of 的最近交易日收盘价、价格时间、总股本和平台市值。自动检查 价格×股本 与平台市值差异;当前股本晚于历史 as-of 时不得回填历史快照。

6.3 结构化财务

取得最近完整年度、本期累计、上年同期累计、资产负债和现金流字段;每个记录带报告期、公告日期、单位、币种和 A1 公告 ID。结构化字段无法回链 A1 时为 gap;与 A1 明示数值超容差时阻断受影响字段。

6.4 机构预测

保存汇总机构数和可见明细两套记录。汇总 4 家、明细 3 家只形成一个 W_FORECAST_COVERAGE gap;最多查询两个登记来源,不为未知第四家无限搜索。明细日期晚于 as-of 的记录排除。

7. HTTP、并发与网络预算

  1. 仅允许 provider_registry.json 登记的 HTTPS 域名;巨潮如需 HTTP 回退必须在注册表明确标识并只用于公开公告查询。
  2. 连接超时 8 秒、单请求总读取超时 20 秒、单响应上限 20 MiB。
  3. 仅对超时、连接重置和 5xx 最多重试 2 次;4xx、解析错误和字段变化不盲重试。
  4. ThreadPoolExecutor(max_workers=4) 并发运行四类适配器。单个失败不取消其他来源,异常统一转 gap 或 blocked。
  5. 机械网络阶段总预算默认 90 秒;到达预算后取消未开始任务,等待中的请求依自身超时结束,不再发起新搜索。
  6. 进度日志记录 provider、开始、缓存命中、请求次数、完成、失败和耗时。

8. 可信信源停止规则与 as-of 安全

同一数字满足以下全部条件即停止搜索:

  1. 已取得 A1 原文或与 A1 公告 ID 可核对的结构化记录;
  2. 公司、报告期、币种、单位和口径明确;
  3. as-of 之前没有后续修正或替代版本;
  4. 报表勾稽或 价格×股本EPS×股本 等数量关系无异常;
  5. 数量级合理且足以支持估值用途。

任何 publish_date > as_ofdata_date > as_of、历史 as-of 使用当前不可历史化字段的行为均为 E_ASOF_VIOLATION,不得仅警告后继续。

9. 内容寻址缓存与公司增量基线

<cache-dir>/
  blobs/<sha256>.bin
  requests/<provider>/<request_fingerprint>.json
  companies/<market-code>/baseline.json
  companies/<market-code>/source_index.json

请求索引至少包含规范化请求、provider、ticker、as-of、请求/响应时间、状态、内容类型、字节数、SHA-256、适配器版本、来源发布日期和 complete=true

复用必须同时通过请求指纹、blob 哈希、适配器版本、as-of 安全和完成标记;任一失败只废弃逻辑索引并重取,不删除其他 blob。fixture 响应也走同一缓存路径,以便机械验证缓存合同。

公司基线只在核心采集完成且基线自身哈希正确后原子提交。新 as-of 只刷新价格、最新公告状态、机构预测、股本、现金债务和公司行动;未重述历史报告按内容哈希复用。

10. 快照构建、字段来源与缺口

  1. snapshot_builder.py 从统一提供者结果建立唯一数据主记录,不直接读取网页模板字段。
  2. 金额统一为元、股本为股、价格为元/股;原始值和原始单位保留在证据包。
  3. TTM 输入固定为最近完整年度、本期累计、上年同期累计;由 V1 负责正式计算。
  4. snapshot_build_report.json 对每个 V1 字段记录来源 provider、source_id、raw_hash、转换、as-of 判断和状态。
  5. 核心行情、股本、TTM 三期利润或资产负债核心字段缺失时 BLOCKED_CORE_INPUT;机构、辅助说明或单一非核心来源缺失允许 COMPLETE_WITH_GAPS
  6. gap 必须包含 gap_id、provider、字段、原因、影响、是否阻断、已用预算和建议人工补充,不得用 0、空字符串或测试值掩盖。

11. 16 节 Markdown 报告

固定章节顺序:

  1. 结论摘要;2. 市场和资本结构;3. 信源优先级;4. 业务及利润来源;5. 历史盈利;6. TTM 与归一化;7. 机构预期;8. 利润质量与现金流;9. 模型选择;10. 三情景;11. 反向隐含条件;12. 交叉验证;13. 持有期测试;14. 风险与触发器;15. 复评清单;16. 数据局限和复算摘要。

所有数值表格读取数据主记录或 V1 结果对象。无 judgment 的判断章节写明确 GAP 和需要的覆盖层字段,不得出现 TODO、TBD、待计算、默认倍数、默认方向性评级或伪价格区间。

12. 自动 QA

硬 gate:

  1. 16 个标题齐全、顺序唯一;Markdown 围栏成对;表格列数一致。
  2. 无 TODO/TBD/待计算/NaN/Infinity;本地产物链接存在。
  3. 报告关键数字与统一数据或 valuation_results.json 一致。
  4. 所有核心字段有来源,A1 回链存在,来源和数据日期不晚于 as-of。
  5. judgment 不得改写受保护字段;无 judgment 不得出现方向性估值结论。
  6. 不包含“买入、卖出、加仓、减仓”等交易指令或收益承诺。
  7. manifest 声明的每个正式产物哈希和字节数可复算。

外部 URL 在线可达性是警告,不因临时网络抖动改写已经生成的正式结果。

13. 状态、错误与降级

终态/错误 处理
COMPLETE judgment、V1 计算、报告和 QA 全部完成
COMPLETE_WITH_GAPS 非核心数据缺口已披露,硬 gate 通过
DATA_READY_NEEDS_JUDGMENT 数据和证据就绪,无方向性结论
BLOCKED_CORE_INPUT 价格、股本、核心财务或 A1 回链不足
E_INPUT_CONTRACT 网络前 fail-fast
E_ASOF_VIOLATION 阻断并保留失败证据
E_SOURCE_CONFLICT 阻断受影响核心字段
E_JUDGMENT_CONFLICT 覆盖层越权,阻断
FAILED 内部异常或提交失败

非核心提供者失败转换为一个有预算记录的 gap;不得 silent fallback,不得无限换站搜索。

14. 暂存、原子提交与失败证据

  1. 所有本次正式产物先写输出目录同级的唯一暂存目录。
  2. 每个 JSON 先写同目录临时文件、flush 后原子 replace;manifest 最后生成并含 complete=true
  3. QA 全部通过后,暂存目录以一次 rename 提交到尚不存在的正式输出目录。
  4. 输出已存在时默认拒绝;--force 先形成完整新目录,再以备份交换,失败时恢复旧目录。
  5. 失败时暂存目录改名为 <output>.failed-<run_id>,只含 failure.json、runtime.log 和已形成的诊断产物;不得存在 COMPLETE manifest。
  6. 网络原始缓存可保留,但只有哈希、版本和完成标记都正确的索引才能复用。

15. 遥测与性能

runtime_metrics.json 必须包含:run_id、task_start、process_start、commit_ready_at、每阶段 started_at/finished_at/elapsed_seconds/status、provider 请求/缓存命中计数、task_wall_secondsprocess_wall_seconds

性能验收:

  1. 铖昌 fixture 冷运行 <5 s;相同缓存复跑 <2 s
  2. 真实网络机械阶段目标 <90 s;外站异常也必须在预算内结束并形成 gap。
  3. V1 原 10 项测试全部通过;V1 --input 桥接输出关键结果与直接调用一致。
  4. 性能只比较同机、同夹具、同输出模式;不得用 V1 毫秒级计算时间冒充完整任务耗时。

16. 验收分层

16.1 L0

全包 py_compile/import、JSON Schema/注册表解析、V1 10/10 回归。

16.2 L1

覆盖 HTTP 超时/4xx/5xx/超大响应、fixture 禁网、缓存哈希篡改/版本变化/未完成标记/as-of 不安全、判断层禁写字段、报告结构和原子写。

16.3 L2 铖昌 fixture

  1. ticker/as-of 单命令生成全部适用产物;网络访问为 0。
  2. 有 judgment 时,市值、TTM 收入、TTM 归母、TTM 扣非、PB、PS、情景、反向 PE 和持有期关键数值与既有 fixture 一致。
  3. 无 judgment 时为 DATA_READY_NEEDS_JUDGMENT,不生成方向性价格区间。
  4. 汇总 4 家、明细 3 家只出现一个 forecast coverage gap。
  5. 冷运行 <5 s、缓存 <2 s

16.4 L3 失败与回归

未来来源阻断;A1 与结构化财务冲突阻断;缓存篡改重取;无预测允许 gap;输出冲突、强制替换失败和中断不留下伪 COMPLETE;V1 --input 直接与桥接结果一致。

16.5 L4 真实网络 smoke

使用 001270.SZ 或另一只深市股票受控运行一次,核对请求索引、官方公告链接、价格日期、股本、市值、财务期间、机构日期、A1 回链和 90 秒预算。第二次运行证明历史 blob/公司基线复用;真实网络缺口如实记录,不把临时站点故障升级成伪成功。

17. 高风险点与控制

  1. V1 双实现:只允许 v1_bridge.py 解析并调用既有公共函数,测试比较直接与桥接结果。
  2. 无判断伪结论:无覆盖层不构造 V1 valuation 分组,不生成方向性结论。
  3. 未来信息:provider、builder、QA 三层检查 publish/data/as-of。
  4. 接口缩放变化:注册表版本化、原始响应归档、数量级和市值勾稽。
  5. 缓存误复用:请求、哈希、版本、as-of、完成标记联合门禁。
  6. 汇总/明细差异无限搜索:两个来源上限和单 gap 合同。
  7. 半成品冒充完成:暂存目录、manifest-last、目录级原子提交。
  8. 角色越权:实现和正式文档只写 project target;V1 与原操作手册分别保持只读,直到项目管理员明确调整单事项范围。

18. 审核门禁

本方案状态为 PENDING_DEV_REVIEWER_PROJECT_DESIGN_REVIEW。只有 dev.reviewer.projectdev-doc/开发审计报告.md 给出明确 PASS 后,才能创建 V2 代码、测试和 fixture。开发者不自审。