程序员量化交易实战 34:识别行情数据缺口
程序员量化交易实战 34:识别行情数据缺口
古董级程序员,大厂出来后一直在创业公司,现在仍活跃在一线做 AI 相关的开发。这个专栏会把一个 A 股量化平台从 0 到 1 拆开写:数据、策略、回测、模拟盘、提醒和生产化,尽量用真实代码和真实运行结果说话。更完整的更新也会同步到微信公众号「字与码」。
第 33 篇开始从历史角度看模拟盘是否稳定。
第 34 篇回到每日运行前的输入检查:如果目标股票里有价格缺失,系统应该明确报出缺口,而不是让策略在 None、0 或旧价格上继续跑。

缺价格不是小事
模拟盘里最危险的 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.SZ 和 600519.SH,但价格源只返回 000001.SZ。
uv run python -m scripts.chapter_examples paper-ops-check

因此缺口计划输出 severity=blocker,gap_symbols=['600519.SH']。这类结果会直接进入第 35 篇的运维检查清单,阻止系统在行情不完整时继续执行。
测试缺口输出
测试场景里,价格快照只有 000001.SZ,必需列表还有 600000.SH 和 300001.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。 - 实现
DataGap和DataGapPlan。 - 对必需 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。下一篇会把运行时间窗、历史摘要、数据缺口和健康报告组合成一张最终的运维检查清单。