非法除零是因子计算高频风险,需在表达式解析、dsl重载、动态上下文、sql层及可观测性五层嵌入防护机制。
在量化引擎中,非法除零不是偶发错误,而是因子计算链路中的高频风险点。它会导致因子值失真、信号失效,甚至引发批量回测中断或实盘下单异常。关键不在于“捕获后修复”,而在于把拦截机制嵌入因子生命周期的每个关键节点。
前置校验必须下沉到因子表达式层
不能依赖引擎主循环统一 catch——那样已晚。所有涉及除法、取模的因子公式,需在解析阶段就注入零值防护逻辑:
- 对原始字段(如成交量、流通股本、PE分母)做静态分布扫描,标记历史零值频次高的字段,自动添加 guard wrapper
- 在因子 DSL(如 TA-Lib 表达式或自研公式引擎)中强制要求除法操作符重载:/ → safe_div(a, b, default=NaN),内部第一行执行 b != 0 判定
- 使用 Pandas 的 where 或 NumPy 的 np.where 替代裸除法:result = np.where(denom == 0, np.nan, numer / denom)
动态上下文感知的零值熔断
某些除数为零是业务合理状态(如新股上市首日无成交),不能一概置 NaN。需结合行情上下文动态决策:
- 维护轻量级缓存(如 Caffeine 或 Redis),记录“股票代码+因子名→最近 5 日是否出现零分母”,命中则跳过本次校验(减少重复开销)
- 对分母字段打标:若字段语义为“计数类”(如交易天数、涨跌家数),零值即异常,直接熔断并告警;若为“比值类分母”(如市净率中的净资产),零值可能反映资不抵债,应保留并标注 special_flag
- 在因子计算 Pipeline 中插入 ContextGuard 节点,自动注入当日 market_status、is_new_stock、has_suspended 等上下文变量供判断
SQL 层与特征存储协同防御
因子常从数据库或特征平台拉取基础数据,防御要延伸至查询源头:
- 在特征 SQL 中统一使用 NULLIF(denominator, 0),再配合 COALESCE(..., 0) 或 CASE WHEN 返回业务可接受的默认值
- 对高频调用的基础宽表(如 stock_daily_basic),在物化时预计算 safe_ratio 字段,避免每次查询都重复判零
- 特征平台 API 响应体中增加 divisor_validity 字段,标识该批次数据中分母字段的有效率,供上层引擎决定是否降级使用
可观测性驱动的持续优化
拦截不是一次配置,而是闭环反馈过程:
- 每次触发零值拦截,记录完整 trace:factor_id、stock_code、date、numer_val、denom_val、context_hash、处理动作(drop / nan / default)
- 按日聚合拦截日志,生成“高危因子 Top10”看板,推动上游数据源治理(如修复财报中错误的零净资产)
- 将零值发生率作为因子稳定性指标,纳入因子淘汰机制——连续 3 日拦截率 > 5% 的因子自动进入观察期











