程序员量化交易实战 38:给日报归档建立索引
第 32 篇已经能把每日运行结果写成 JSON第 33 篇能做简单历史汇总。第 38 篇补一个夹在中间的小工具给归档目录建立索引。后面无论做 CLI 展示、页面列表还是人工排查都不应该每次手写 glob 和 JSON 读取逻辑。索引项包含什么日报索引不需要复制完整报告只保留列表页真正需要的信息。字段含义trade_date交易日status当日健康状态path归档文件路径完整报告仍然留在 JSON 文件里需要详情时再读。索引对象第 38 章新增app/report_index.py。dataclass(frozenTrue) class ReportIndexEntry: trade_date: str status: str path: Path这个对象以后可以直接用于命令行表格也可以喂给一个简单的 Web 页面。扫描归档目录实现逻辑复用第 32 章的读取函数。for path in sorted(Path(directory).glob(*-paper-report.json)): payload read_archived_report(path) entries.append( ReportIndexEntry( trade_datepayload[trade_date], statuspayload[health][status], pathpath, ) )排序基于文件名。归档文件名本身以交易日开头所以这个排序稳定且直观。获取最新报告索引为空时返回None不要让调用方处理下标异常。def latest_report_entry(entries: tuple[ReportIndexEntry, ...]) - ReportIndexEntry | None: if not entries: return None return entries[-1]这类小函数看起来简单但在生产代码里能减少很多重复判断。当前联动运行结果paper-run-plan会在临时目录里写入三天日报归档然后生成索引uv run python -m scripts.chapter_examples paper-run-plan索引里能看到2026-03-04、2026-03-05、2026-03-06三条记录其中中间一天是 blocker。索引不读取完整正文只保留列表页和排障入口需要的最小字段。测试索引顺序运行本章测试uv run pytest tests/test_report_index.py tests/test_report_archive.py tests/test_run_history.py关键断言assert [entry.trade_date for entry in entries] [2026-02-05, 2026-02-06] assert [entry.status for entry in entries] [ok, blocker] assert latest_report_entry(entries) entries[-1]这说明索引能稳定列出归档报告并能取到最新一条。本章更新与代码仓库本章更新内容新增app/report_index.py。实现ReportIndexEntry。从归档目录生成报告索引。实现latest_report_entry()。增加paper-run-plan联动示例展示三天归档如何变成可查询索引。新增tests/test_report_index.py覆盖索引顺序和空索引。代码仓库https://github.com/ax2/zi-quant-platform本章代码git clone https://github.com/ax2/zi-quant-platform.git cd zi-quant-platform git checkout chapter-38 uv sync --extra dev uv run pytest tests/test_report_index.py tests/test_report_archive.py tests/test_run_history.py第 38 章提交为6d848cetag 为chapter-38。本篇小结日报归档有了索引历史文件就不再只是散落在目录里的 JSON。第 38 篇把交易日、状态和路径抽成轻量列表。下一篇会处理 blocked 结果检查失败以后系统应该给出明确处理动作而不是只告诉你失败了。