"策略失效"虚惊一场:159915 卖出得分骤降 89.3→38.1 的澄清实录——评分口径波动与真实失效的判别法

本文最后更新于 2026年10月21日 凌晨

监控大屏突然跳红,159915 的卖出得分直接从 89.3 砸到 38.1。

我盯着屏幕,手里的咖啡差点洒在键盘上。

量化交易里最怕的就是这种断崖式下跌,它不像连续阴跌那样给你调仓时间,而是直接把风控红线踩爆。

暂停策略、回测历史、检查数据源,一套标准动作做完,心里却越来越没底。

难道核心因子集体失效了?还是模型遭遇了黑天鹅?

折腾到凌晨三点,我才发现这只是一场虚惊。

评分系统正常运转时,数据流向非常清晰。

底层行情模块负责清洗 tick 数据,过滤掉停牌和极端跳空。

中层因子引擎按日频计算量价指标,把原始序列转成标准化截面数据。

顶层聚合器给每个因子分配动态权重,用加权求和得出最终信号。

归一化函数负责把结果压到 0 到 100 的区间,方便风控模块直读。

这套流水线跑了半年,分数曲线一直贴着均线平滑上行。

159915 的得分稳定在 85 到 92 之间,交易信号精准得像上了发条。

5 月 12 日的盘后结算,流水线突然卡壳。

卖出得分的仪表盘指针直接掉到 38.1,触发自动熔断协议。

我顺着日志往下扒,把每个中间变量都打印成 CSV 文件。

底层行情数据完整无缺,没有断点也没有脏数据。

中层因子读数全在历史分位数区间内,没有异常偏移。

问题一定卡在顶层聚合环节,或者归一化映射函数出了问题。

我把聚合器的原始加权和导出来,发现数值根本没有变。

真正变动的,是归一化模块里的滚动阈值参数。

动态归一化模块上线时,为了兼容不同因子的量纲,用了滚动窗口极差法。

它默认取过去 30 个交易日的最大值和最小值做线性映射。

这次 159915 的行情恰好踩中了历史极值区间。

过去 30 个交易日内,该 ETF 的累计收益率创下阶段新高。

滚动窗口的最大值被大幅拉高,分母瞬间膨胀了三倍。

原本 89.3 分的原始得分,被重新映射成了 38.1 分。

策略逻辑没有任何变化,只是分母变大了。

这种口径漂移在震荡市里几乎不可见,一旦遇到单边突破,分数就会原地跳水。

分数跳水不等于策略失效,但风控系统不认眼泪。

下次再遇到断崖式得分,不能只盯着最终数字看。

我总结了一套三步判别法,专门用来隔离口径干扰和真实风险。

第一步,核对原始信号与归一化分数的偏离度。

如果原始信号平稳,只有归一化分数剧烈波动,说明是映射规则在作祟。

第二步,交叉验证同类资产。

把 510300 和 159919 拉出来跑同一套逻辑,分数走势应该高度同步。

如果只有单只标的跳水,大概率是特征工程里的样本外漂移。

第三步,检查因子衰减曲线。

真实失效会伴随 IC 值连续多日跌破零轴,且换手率异常放大。

口径波动只会影响绝对分数,不会改变因子的排序能力。

把这三道滤网叠在一起,基本能过滤掉九成以上的误报。

我在归一化模块前面加了一层防抖逻辑,引入指数移动平均线平滑阈值。

新窗口长度设为 60 日,权重衰减因子取 0.94。

既能跟踪趋势又不会过度敏感,分数曲线终于不再乱跳。

同时把极值处理从线性映射换成 Winsorize 缩尾,把上下 1% 的极端值截断到正态分布区间。

改造后的系统上线,回测分数曲线平滑了不少。

实盘跑了一周,159915 得分始终在 82 到 91 之间震荡,再也没有出现过 38.1 分的奇观。

策略执行节奏也恢复了,不再因为误报信号而频繁撤单。

监控大屏的红字终于暗下去了,代码跑在后台安静地迭代。

下次再看到分数断崖式下跌,我会先深呼吸,去查数据映射逻辑。

市场永远在变,评分规则也得跟着长肌肉。

把口径波动和真实失效拆分开,策略才能活得久一点。


"策略失效"虚惊一场:159915 卖出得分骤降 89.3→38.1 的澄清实录——评分口径波动与真实失效的判别法
https://normdist.com/2026/10/20/ND-20261014-002-strategy-false-positive-clarification/
作者
小瑞
发布于
2026年10月20日
许可协议