from __future__ import annotations import csv import hashlib import json from datetime import datetime, timezone, timedelta from pathlib import Path PROJECT_ROOT = Path(__file__).resolve().parents[4] RUN_ID = "RUN-ANA-WUJI-V1-FINAL-CONCLUSION-20260610-001" TASK_ID = "ANA-WUJI-V1-FINAL-CONCLUSION-20260610" SOURCE_RUN_ID = "RUN-ANA-WUJI-STRICT-SELL-ROLLING-REPAIR-20260609-001" SOURCE_DIR = PROJECT_ROOT / "ana-data" / "result" / SOURCE_RUN_ID OUT_DIR = PROJECT_ROOT / "ana-data" / "result" / RUN_ID SOURCE_AUDIT_ID = "AUDIT-ANA-WUJI-STRICT-SELL-ROLLING-REPAIR-20260610-EXEC-REREVIEW-003" DESIGN_AUDIT_ID = "AUDIT-ANA-WUJI-V1-FINAL-CONCLUSION-20260610-DESIGN-001" def now_iso() -> str: return datetime.now(timezone(timedelta(hours=8))).isoformat(timespec="seconds") def read_csv(path: Path) -> list[dict[str, str]]: with path.open("r", encoding="utf-8-sig", newline="") as f: return list(csv.DictReader(f)) def write_csv(path: Path, rows: list[dict[str, object]], fieldnames: list[str] | None = None) -> None: path.parent.mkdir(parents=True, exist_ok=True) if fieldnames is None: fieldnames = list(rows[0].keys()) if rows else [] with path.open("w", encoding="utf-8-sig", newline="") as f: writer = csv.DictWriter(f, fieldnames=fieldnames) writer.writeheader() for row in rows: writer.writerow(row) def write_json(path: Path, data: object) -> None: path.parent.mkdir(parents=True, exist_ok=True) path.write_text(json.dumps(data, ensure_ascii=False, indent=2) + "\n", encoding="utf-8") def sha256(path: Path) -> str: h = hashlib.sha256() with path.open("rb") as f: for chunk in iter(lambda: f.read(1024 * 1024), b""): h.update(chunk) return h.hexdigest() def file_row(path: Path, root: Path = PROJECT_ROOT) -> dict[str, object]: return { "path": path.relative_to(root).as_posix(), "size": path.stat().st_size, "sha256": sha256(path), } def source_manifest(paths: list[Path]) -> list[dict[str, object]]: rows = [] for p in paths: row = file_row(p) row["source_run_id"] = SOURCE_RUN_ID rows.append(row) return rows def copy_boundary(source_rows: list[dict[str, str]]) -> list[dict[str, object]]: rows = [] for r in source_rows: rows.append( { "boundary_id": r.get("boundary_id", ""), "boundary_level": r.get("boundary_level", ""), "case_id": r.get("case_id", ""), "source_lot_id": r.get("source_lot_id", ""), "symbol": r.get("symbol", ""), "boundary_category": r.get("boundary_category", ""), "boundary_reason": r.get("boundary_reason", ""), "source_table": "strict_boundary_table.csv", "readout_policy": "boundary_only_not_primary_return", } ) return rows def forbidden_claims(text: str) -> list[str]: claims = [ "完整 baseline 成功率为", "完整 baseline 收益率为", "无边界 baseline 成功率", "无边界 baseline 收益率", "策略有效性已证明", "策略有效性已经证明", ] return [c for c in claims if c in text] def main() -> None: OUT_DIR.mkdir(parents=True, exist_ok=True) source_paths = [ SOURCE_DIR / "summary.json", SOURCE_DIR / "summary.md", SOURCE_DIR / "strict_case_summary.csv", SOURCE_DIR / "strict_return_scope_case.csv", SOURCE_DIR / "strict_return_scope_lot.csv", SOURCE_DIR / "strict_boundary_table.csv", SOURCE_DIR / "manual_decision_external_draft.md", SOURCE_DIR / "manual_decision_external_source_ledger.csv", SOURCE_DIR / "manual_decision_ledger.csv", SOURCE_DIR / "strict_order_ledger.csv", SOURCE_DIR / "strict_position_lot_ledger.csv", SOURCE_DIR / "case_image_board.md", SOURCE_DIR / "manifest.json", ] missing_sources = [p for p in source_paths if not p.exists()] if missing_sources: raise FileNotFoundError("Missing source files: " + ", ".join(str(p) for p in missing_sources)) summary = json.loads((SOURCE_DIR / "summary.json").read_text(encoding="utf-8")) case_rows = read_csv(SOURCE_DIR / "strict_case_summary.csv") lot_rows = read_csv(SOURCE_DIR / "strict_return_scope_lot.csv") boundary_rows = read_csv(SOURCE_DIR / "strict_boundary_table.csv") order_rows = read_csv(SOURCE_DIR / "strict_order_ledger.csv") primary_cases = [r for r in case_rows if r.get("v1_primary_strict_closed_case_flag") == "1"] positive_cases = [r for r in primary_cases if r.get("v1_case_success_flag") == "1"] boundary_cases = [r for r in case_rows if r.get("v1_return_scope") != "V1_PRIMARY_STRICT_CLOSED_CASE"] closed_lots = [r for r in lot_rows if r.get("v1_lot_scope") == "V1_STRICT_CLOSED_LOT_RECALC_ONLY"] boundary_lots = [r for r in lot_rows if r.get("v1_lot_scope") != "V1_STRICT_CLOSED_LOT_RECALC_ONLY"] rolling_buy_orders = [ r for r in order_rows if r.get("action") == "BUY" and r.get("tranche_index") == "2" ] account_contribution = round(sum(float(r.get("account_return_closed_lots") or 0) for r in primary_cases), 8) success_rate = round(len(positive_cases) / len(primary_cases), 10) if primary_cases else 0 readouts = [ { "readout_id": "V1_PRIMARY_STRICT_CLOSED_CASE", "scope": "V1 主口径严格闭合 case", "case_count": len(primary_cases), "positive_case_count": len(positive_cases), "non_positive_case_count": len(primary_cases) - len(positive_cases), "success_rate": f"{success_rate:.10f}".rstrip("0").rstrip("."), "account_contribution_sum": f"{account_contribution:.8f}", "lot_count": "", "boundary_count": "", "source": "strict_case_summary.csv", "citation_boundary": "必须同时引用 V1 口径、执行复审审计 ID、v1_boundary_table.csv 和 MARKET_RISK_MINUTE_BREADTH_DATA_GAP_HELD。", }, { "readout_id": "V1_ALL_BUY_CASE_COVERAGE", "scope": "V1 有 BUY case 覆盖口径", "case_count": len(case_rows), "positive_case_count": "", "non_positive_case_count": "", "success_rate": "", "account_contribution_sum": "", "lot_count": "", "boundary_count": len(boundary_cases), "source": "strict_case_summary.csv", "citation_boundary": "只说明 V1 已买入 case 覆盖和边界,不替代主成功率分母。", }, { "readout_id": "V1_STRICT_CLOSED_LOT_RECALC_ONLY", "scope": "V1 lot 复算辅助口径", "case_count": "", "positive_case_count": "", "non_positive_case_count": "", "success_rate": "", "account_contribution_sum": "", "lot_count": len(lot_rows), "boundary_count": len(boundary_lots), "source": "strict_return_scope_lot.csv", "citation_boundary": "只用于 lot 复算和问题定位,不包装成 case 成功率。", }, { "readout_id": "V1_ROLLING_LOW_BUY", "scope": "滚动低吸 BUY 订单", "case_count": "", "positive_case_count": "", "non_positive_case_count": "", "success_rate": "", "account_contribution_sum": "", "lot_count": len(rolling_buy_orders), "boundary_count": "", "source": "strict_order_ledger.csv", "citation_boundary": "只说明滚动低吸执行数量,不单独构成策略有效性结论。", }, ] write_csv(OUT_DIR / "v1_final_readouts.csv", readouts) case_index = [] for r in case_rows: case_id = r.get("case_id", "") case_index.append( { "case_id": case_id, "v1_return_scope": r.get("v1_return_scope", ""), "primary_flag": r.get("v1_primary_strict_closed_case_flag", ""), "success_flag": r.get("v1_case_success_flag", ""), "buy_lot_count": r.get("buy_lot_count", ""), "closed_lot_count": r.get("closed_lot_count", ""), "unresolved_lot_count": r.get("unresolved_lot_count", ""), "account_return_closed_lots": r.get("account_return_closed_lots", ""), "boundary_reason": r.get("v1_boundary_reason", ""), "case_image_board": f"../{SOURCE_RUN_ID}/cases/{case_id}/case_image_board.md", "case_story_board": f"../{SOURCE_RUN_ID}/cases/{case_id}/case_story_board.md", } ) write_csv(OUT_DIR / "v1_case_readout_index.csv", case_index) v1_boundary = copy_boundary(boundary_rows) write_csv(OUT_DIR / "v1_boundary_table.csv", v1_boundary) src_manifest = source_manifest(source_paths) write_csv(OUT_DIR / "source_artifact_manifest.csv", src_manifest) top_positive = sorted(primary_cases, key=lambda r: float(r.get("account_return_closed_lots") or 0), reverse=True)[:3] top_negative = sorted(primary_cases, key=lambda r: float(r.get("account_return_closed_lots") or 0))[:3] boundary_example = boundary_cases[:1] def case_link(r: dict[str, str]) -> str: case_id = r.get("case_id", "") ret = r.get("account_return_closed_lots", "") return f"- `{case_id}`,收益贡献 `{ret}`,[图片板](../{SOURCE_RUN_ID}/cases/{case_id}/case_image_board.md),[故事板](../{SOURCE_RUN_ID}/cases/{case_id}/case_story_board.md)" human_review = f"""# 无忌 V1 最终结论人工审核第一入口 ## 先看这里 可以引用:当前 V1 执行包已通过执行复审。允许按 `V1_PRIMARY_STRICT_CLOSED_CASE` 主口径引用 250 个严格闭合 case 的读数:99 个为正收益,成功率读数为 0.396,账户贡献合计读数为 0.12970642。 必须同时引用:V1 口径、执行复审审计 ID `{SOURCE_AUDIT_ID}`、`v1_boundary_table.csv`,以及 `MARKET_RISK_MINUTE_BREADTH_DATA_GAP_HELD`。 不能引用:不能把 V1 读数写成旧 V0 包结论,不能写成无边界完整 baseline 结论,不能作出无忌策略有效性的证明结论,不能省略市场风险分钟广度数据缺口。 当前状态: | 项目 | 内容 | |---|---| | 当前 run | `{RUN_ID}` | | 来源 run | `{SOURCE_RUN_ID}` | | 来源执行复审审计 ID | `{SOURCE_AUDIT_ID}` | | 当前设计审核审计 ID | `{DESIGN_AUDIT_ID}` | | RETURN_STAT_READY | `false` | | 执行审核状态 | `待提交执行审核` | ## V1 三层读数 1. `V1_PRIMARY_STRICT_CLOSED_CASE`:250 个严格闭合 case,正收益 99 个,成功率读数 0.396,账户贡献合计 0.12970642。 2. `V1_ALL_BUY_CASE_COVERAGE`:251 个有 BUY case,其中 1 个 case 进入边界表;该口径不替代主成功率。 3. `V1_STRICT_CLOSED_LOT_RECALC_ONLY`:735 个 lot,其中 734 个闭合、1 个边界;lot 口径只用于复算和问题定位。 ## 第一入口链接 - 来源 V1 图片总入口:[case_image_board.md](../{SOURCE_RUN_ID}/case_image_board.md) - 来源 V1 摘要:[summary.md](../{SOURCE_RUN_ID}/summary.md) - 来源 V1 手工裁决草稿:[manual_decision_external_draft.md](../{SOURCE_RUN_ID}/manual_decision_external_draft.md) - 当前 V1 结论摘要:[v1_final_conclusion_summary.md](v1_final_conclusion_summary.md) - 当前 V1 读数表:[v1_final_readouts.csv](v1_final_readouts.csv) - 当前 V1 case 索引:[v1_case_readout_index.csv](v1_case_readout_index.csv) - 当前 V1 边界表:[v1_boundary_table.csv](v1_boundary_table.csv) ## 代表性 case 主口径正收益较高样例: {chr(10).join(case_link(r) for r in top_positive)} 主口径负收益较低样例: {chr(10).join(case_link(r) for r in top_negative)} 边界样例: {chr(10).join(case_link(r) for r in boundary_example)} ## 阅读提示 1. 先看本文件的可引用 / 不可引用边界。 2. 再看 `v1_final_conclusion_summary.md` 了解整体读数。 3. 需要追溯单个案例时,从 `v1_case_readout_index.csv` 找到 `case_id`,再打开对应图片板和故事板。 4. 对卖点和滚动低吸的人工裁决来源,优先看 `manual_decision_external_draft.md` 和 `manual_decision_ledger.csv`。源单 case 图板中的图片是主要证据入口;文字理由以本包摘要、手工裁决草稿和账本字段为准。 """ (OUT_DIR / "v1_final_human_review_index.md").write_text(human_review, encoding="utf-8") summary_md = f"""# 无忌 V1 最终结论引用包摘要 ## 当前可引用状态 当前包基于已通过执行复审的 V1 结果包生成,来源审计 ID 为 `{SOURCE_AUDIT_ID}`。本包仍需执行审核;执行审核通过前,不得把 V1 读数写入正式最终案例总结。 ## V1 主口径:V1_PRIMARY_STRICT_CLOSED_CASE | 指标 | 读数 | |---|---:| | V1 主口径严格闭合 case | {len(primary_cases)} | | V1 主口径正收益 case | {len(positive_cases)} | | V1 主口径非正收益 case | {len(primary_cases) - len(positive_cases)} | | V1 主口径成功率读数 | {success_rate:.10f} | | V1 主口径账户贡献合计读数 | {account_contribution:.8f} | ## 覆盖口径 | 指标 | 读数 | |---|---:| | V1 有 BUY case | {len(case_rows)} | | V1 边界 case | {len(boundary_cases)} | | 滚动低吸 BUY 订单 | {len(rolling_buy_orders)} | ## lot 辅助口径 | 指标 | 读数 | |---|---:| | V1 lot 总数 | {len(lot_rows)} | | V1 闭合 lot | {len(closed_lots)} | | V1 边界 lot | {len(boundary_lots)} | ## 边界 `v1_boundary_table.csv` 完整保留来源边界表,共 {len(v1_boundary)} 行。必须特别保留 `MARKET_RISK_MINUTE_BREADTH_DATA_GAP_HELD`,它表示本地数据源没有开盘 10 分钟全 A 下跌家数分钟级广度,市场风险卖点不能被无边界化。 ## 禁止外推 1. 不得把 V1 读数写成旧 V0 包结论。 2. 不得写成无边界完整 baseline 成功率、收益率、胜率或回撤。 3. 不得作出无忌策略有效性的证明结论。 4. 不得省略审计 ID、V1 口径、边界表和市场风险分钟广度数据缺口。 """ (OUT_DIR / "v1_final_conclusion_summary.md").write_text(summary_md, encoding="utf-8") summary_json = { "schema_version": "1.0", "task_id": TASK_ID, "run_id": RUN_ID, "source_run_id": SOURCE_RUN_ID, "source_execution_rereview_audit_id": SOURCE_AUDIT_ID, "design_audit_id": DESIGN_AUDIT_ID, "generated_at": now_iso(), "execution_review_status": "PENDING_EXECUTION_REVIEW", "return_stat_ready": False, "readouts": { "v1_buy_case_count": len(case_rows), "v1_primary_strict_closed_cases": len(primary_cases), "v1_positive_primary_cases": len(positive_cases), "v1_primary_success_readout": success_rate, "v1_primary_account_contribution_readout": account_contribution, "v1_lot_total": len(lot_rows), "v1_closed_lots": len(closed_lots), "v1_boundary_lots": len(boundary_lots), "rolling_low_buy_orders": len(rolling_buy_orders), "boundary_rows": len(v1_boundary), }, "required_citation_context": [ "V1 scope", SOURCE_AUDIT_ID, "v1_boundary_table.csv", "MARKET_RISK_MINUTE_BREADTH_DATA_GAP_HELD", ], "forbidden": [ "old V0 package as complete note baseline", "no-boundary complete baseline conclusion", "strategy validity proven", ], } write_json(OUT_DIR / "v1_final_conclusion_summary.json", summary_json) (OUT_DIR / "README.md").write_text( f"""# 无忌 V1 最终结论引用包 本包是 V1 执行复审通过后的引用层整理,不重跑候选池、买卖裁决、人工裁决或账本。 先看:[v1_final_human_review_index.md](v1_final_human_review_index.md) 来源审计 ID:`{SOURCE_AUDIT_ID}` 设计审核 ID:`{DESIGN_AUDIT_ID}` 当前状态:待执行审核。执行审核通过前,不得把 V1 读数写入正式最终案例总结。 """, encoding="utf-8", ) generated_text = "\n".join( [ human_review, summary_md, json.dumps(summary_json, ensure_ascii=False), ] ) forbidden_hits = forbidden_claims(generated_text) checks: list[dict[str, object]] = [] def check(name: str, passed: bool, detail: str) -> None: checks.append({"item": name, "status": "PASS" if passed else "FAIL", "detail": detail}) check( "SOURCE_EXECUTION_REVIEW_PASSED", bool(summary.get("v1_execution_review_passed")) and summary.get("execution_rereview_passed_audit_id") == SOURCE_AUDIT_ID, f"audit={summary.get('execution_rereview_passed_audit_id')}", ) check("SOURCE_ARTIFACTS_HASHED", all(Path(row["path"]).exists() for row in src_manifest), f"sources={len(src_manifest)}") check( "READOUTS_MATCH_SOURCE", len(primary_cases) == int(summary["scope"]["v1_primary_strict_closed_cases"]) and len(positive_cases) == int(summary["scope"]["v1_positive_primary_cases"]) and round(float(summary["scope"]["v1_primary_success_readout"]), 10) == success_rate and round(float(summary["scope"]["v1_primary_account_contribution_readout"]), 8) == account_contribution, f"primary={len(primary_cases)}, positive={len(positive_cases)}, success={success_rate}, contribution={account_contribution}", ) check("BOUNDARY_TABLE_PRESERVED", len(v1_boundary) == len(boundary_rows), f"boundary_rows={len(v1_boundary)}") check( "MARKET_RISK_BOUNDARY_PRESENT", any(r.get("boundary_category") == "MARKET_RISK_MINUTE_BREADTH_DATA_GAP_HELD" for r in boundary_rows), "MARKET_RISK_MINUTE_BREADTH_DATA_GAP_HELD", ) check( "SCOPE_SEPARATED", len(primary_cases) + len(boundary_cases) == len(case_rows) and len(closed_lots) + len(boundary_lots) == len(lot_rows), f"cases={len(case_rows)}, primary={len(primary_cases)}, boundary={len(boundary_cases)}, lots={len(lot_rows)}", ) check( "ROLLING_LOW_BUY_READOUT_MATCHES_ORDER_LEDGER", len(rolling_buy_orders) == int(summary["scope"].get("rolling_buy_lots", len(rolling_buy_orders))), f"readout={len(rolling_buy_orders)}, source_scope={summary['scope'].get('rolling_buy_lots')}", ) link_targets = [ SOURCE_DIR / "case_image_board.md", SOURCE_DIR / "manual_decision_external_draft.md", SOURCE_DIR / "strict_order_ledger.csv", SOURCE_DIR / "strict_position_lot_ledger.csv", ] check("HUMAN_REVIEW_ENTRY_LINKS_REACHABLE", all(p.exists() for p in link_targets), f"links={len(link_targets)}") check("NO_OVERREAD_ASSERTIONS", not forbidden_hits, "forbidden_hits=" + "|".join(forbidden_hits)) write_csv(OUT_DIR / "self_check_items.csv", checks, ["item", "status", "detail"]) fail_count = sum(1 for r in checks if r["status"] != "PASS") self_check = { "schema_version": "1.0", "run_id": RUN_ID, "generated_at": now_iso(), "status": "PASS_FOR_V1_FINAL_CONCLUSION_EXECUTION_REVIEW_READY" if fail_count == 0 else "FAIL", "pass_count": len(checks) - fail_count, "fail_count": fail_count, "items_path": "self_check_items.csv", } write_json(OUT_DIR / "self_check.json", self_check) (OUT_DIR / "self_check.md").write_text( f"""# 自检摘要 - status:`{self_check['status']}` - PASS:{self_check['pass_count']} - FAIL:{self_check['fail_count']} - 检查项:`self_check_items.csv` """, encoding="utf-8", ) # Build final package manifest last. package_files = [] for p in OUT_DIR.rglob("*"): if not p.is_file(): continue if p.name in {"manifest.csv", "manifest.json"}: continue package_files.append(file_row(p, OUT_DIR)) package_files.sort(key=lambda r: str(r["path"])) write_csv(OUT_DIR / "manifest.csv", package_files, ["path", "size", "sha256"]) write_json( OUT_DIR / "manifest.json", { "schema_version": "1.0", "run_id": RUN_ID, "generated_at": now_iso(), "files": package_files, }, ) print( json.dumps( { "run_id": RUN_ID, "status": self_check["status"], "primary_cases": len(primary_cases), "positive_cases": len(positive_cases), "success_rate": success_rate, "manifest_files": len(package_files), }, ensure_ascii=False, ) ) if __name__ == "__main__": main()