程序员量化交易实战 17:生成模拟盘账户快照
原创 · 约 7 分钟阅读 · 阅读 --
Last updated on

程序员量化交易实战 17:生成模拟盘账户快照

作者: Alex Xiang


程序员量化交易实战 17:生成模拟盘账户快照

古董级程序员,大厂出来后一直在创业公司,现在仍活跃在一线做 AI 相关的开发。这个专栏会把一个 A 股量化平台从 0 到 1 拆开写:数据、策略、回测、模拟盘、提醒和生产化,尽量用真实代码和真实运行结果说话。更完整的更新也会同步到微信公众号「字与码」。

第 16 篇有了模拟盘账本。账本适合更新状态,但不适合直接拿来做风控和展示。

第 17 篇新增账户快照,把现金、持仓、市值、浮盈浮亏和权重统一整理成一个结构。

ZiCode 工程师拍摄模拟盘权益快照

快照解决什么问题

模拟盘后续会有三个消费者:

  • 风控模块要看现金比例和单票权重。
  • 调仓模块要看当前权重和目标权重的差距。
  • 通知模块要把账户状态变成可读摘要。

如果每个模块都自己算一遍,很容易出现口径不一致。

账户快照和账本的区别很重要:账本回答“账户是怎么变成现在这样的”,快照回答“此刻账户长什么样”。复盘时两者都要保留。只看账本,读者需要自己计算市值和权重;只看快照,又很难解释为什么账户走到这个状态。

快照对象

第 17 章新增 app/paper_snapshots.py

@dataclass(frozen=True)
class PaperAccountSnapshot:
    trade_date: date
    cash: float
    market_value: float
    total_equity: float
    cash_ratio: float
    positions: tuple[PaperPositionSnapshot, ...]

每个持仓快照包含最新价、市值、成本、浮动盈亏和权重。

构建快照

入口函数是 build_paper_account_snapshot()

snapshot = build_paper_account_snapshot(
    account,
    trade_date=date(2026, 1, 9),
    last_prices={"000001.SZ": 11.0},
)

这里没有隐藏行情查询。调用方必须显式传入 last_prices,这样测试时不需要 mock 外部数据源,生产接入时也能清楚知道价格来自哪里。

缺失价格怎么处理

当前版本把缺失价格当成 0。

这不是最终生产策略,但对早期模拟盘有一个好处:它能把“缺行情”的问题暴露出来,而不是用旧价格悄悄延续错误状态。后续接入真实行情时,可以再增加缺失价格告警。

当前主线联动运行

同一条 paper-flow 命令会在账本成交后生成账户快照:

uv run python -m scripts.chapter_examples paper-flow

真实输出如下:

第 17 篇模拟盘账户快照真实运行截图

截图里总权益是 105031.28,现金比例 19.26%,000001.SZ 持仓权重 80.74%,浮动盈亏 5031.28。后续风控模块不再重新计算这些口径,而是直接消费这份快照。

本章更新与代码仓库

本章更新内容:

  • 新增 app/paper_snapshots.py
  • 实现账户快照和持仓快照。
  • 计算现金比例、持仓市值、总权益、浮动盈亏和持仓权重。
  • 新增 tests/test_paper_snapshots.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-17
uv sync --extra dev
uv run pytest tests/test_paper_snapshots.py

第 17 章提交为 8d53e39,tag 为 chapter-17

本篇小结

账本负责状态变更,快照负责统一口径。

第 17 篇把模拟盘账户转成可读、可测、可复用的快照对象。下一篇会基于这个快照实现第一版模拟盘风控检查。

微信公众号

欢迎关注「字与码」

如果这篇文章对你有用,也欢迎在微信里继续关注后续更新。

微信公众号字与码二维码