程序员量化交易实战 34:识别行情数据缺口
原创 · 约 9 分钟阅读 · 阅读 --
Last updated on

程序员量化交易实战 34:识别行情数据缺口

作者: Alex Xiang


程序员量化交易实战 34:识别行情数据缺口

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

第 33 篇开始从历史角度看模拟盘是否稳定。

第 34 篇回到每日运行前的输入检查:如果目标股票里有价格缺失,系统应该明确报出缺口,而不是让策略在 None0 或旧价格上继续跑。

ZiCode 工程师检查行情数据缺口

缺价格不是小事

模拟盘里最危险的 bug 往往不是程序直接崩溃,而是数据缺了但程序继续运行。

如果某只股票没有最新价格,调仓金额、风险敞口、权益快照都会跟着失真。早期系统宁可保守一点,把这类问题标成 blocker。

缺口对象

第 34 章新增 app/data_gaps.py

@dataclass(frozen=True)
class DataGap:
    symbol: str
    trade_date: date
    field: str
    severity: str


@dataclass(frozen=True)
class DataGapPlan:
    gaps: tuple[DataGap, ...]
    severity: str

第一版只检查 last_price,后面可以继续扩展到成交量、复权因子、停牌状态等字段。

构造缺口计划

函数输入是价格快照和必需 symbol 列表:

def build_price_gap_plan(
    price_snapshot: PriceSnapshot,
    *,
    required_symbols: list[str],
) -> DataGapPlan:

实现时先去重,再比较必需列表和快照里已有价格。

required = list(dict.fromkeys(required_symbols))
missing = sorted(set(required) - set(price_snapshot.prices))

每个缺失 symbol 都变成一个 blocker:

DataGap(
    symbol=symbol,
    trade_date=price_snapshot.trade_date,
    field="last_price",
    severity="blocker",
)

这个设计很朴素,但它让缺口从“日志里可能有一行”变成了可测试、可汇总、可进入运维检查清单的数据结构。

常见的数据缺口不只有价格缺失。日频策略里还可能遇到成交量缺失、复权因子缺失、停牌状态缺失、股票池成分更新延迟等问题。第一版只检查 last_price,是因为价格缺口会直接影响权益、仓位和调仓金额,是模拟盘最该先挡住的一类问题。

当前联动运行结果

paper-ops-check 会故意构造一个缺价格场景:必需 symbol 包含 000001.SZ600519.SH,但价格源只返回 000001.SZ

uv run python -m scripts.chapter_examples paper-ops-check

paper-ops-check 命令生成的数据缺口检查结果

因此缺口计划输出 severity=blockergap_symbols=['600519.SH']。这类结果会直接进入第 35 篇的运维检查清单,阻止系统在行情不完整时继续执行。

测试缺口输出

测试场景里,价格快照只有 000001.SZ,必需列表还有 600000.SH300001.SZ

uv run pytest tests/test_data_gaps.py

断言结果:

assert plan.severity == "blocker"
assert gap_symbols(plan) == ["300001.SZ", "600000.SH"]
assert plan.gaps[0].field == "last_price"

如果所有必需价格都存在,则返回 severity == "ok"gaps == ()

本章更新与代码仓库

本章更新内容:

  • 新增 app/data_gaps.py
  • 实现 DataGapDataGapPlan
  • 对必需 symbol 和价格快照做缺口检查。
  • 缺失价格统一标记为 blocker。
  • 新增 gap_symbols() 便于测试和展示。
  • 增加 paper-ops-check 联动示例,展示缺价格如何变成 blocker 级别数据缺口。
  • 补充价格、成交量、复权因子、停牌状态等常见数据缺口背景。
  • 新增 tests/test_data_gaps.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-34
uv sync --extra dev
uv run pytest tests/test_data_gaps.py

第 34 章提交为 5c94461,tag 为 chapter-34

本篇小结

行情缺口要尽早变成结构化结果。

第 34 篇把缺失价格从隐性风险变成 DataGapPlan。下一篇会把运行时间窗、历史摘要、数据缺口和健康报告组合成一张最终的运维检查清单。