R1 大周期筛选连续 4 天无产出:单点数据源依赖的代价
本文最后更新于 2026年8月27日 凌晨
R1 策略的「大周期筛选」模块连续 4 天零产出。不是行情差,不是模型崩了,是它依赖的那个数据源悄悄挂了。我把整个排查过程捋了一遍,结论是:单点数据源依赖的代价,往往不是数据本身,而是你根本不知道它在什么时候断了。
问题是什么
R1 是我的一个中频量化策略,跑在 ModelBase 服务器上。它有个「大周期筛选」模块:每天收盘后,拉取日线数据,用 Qwen3.5-35B-A3B-Ornith 模型(Q4_K_M 量化,实测 104 t/s)跑一轮筛选,输出第二天的候选标的。
这个模块之前一直稳定,每天准点产出。8 月 23 日开始,它静默了。没有报错,没有告警,日志显示「运行完成」,但输出列表是空的。
我一开始以为是行情问题。那天确实波动不大,但连续 4 天空列表,不像市场风格问题。
定位过程
第一轮:怀疑模型
我先查了模型推理日志。llama.cpp 跑得正常,响应时间 900ms 左右,104 t/s 的输出速度,token 消耗正常。模型没有任何异常。
排除模型。
第二轮:怀疑策略逻辑
我翻了策略代码,大周期筛选 的过滤条件:市值 > 50 亿、60 日涨幅 > 20%、成交量放大 1.5 倍。把 8 月 23 到 26 日的 A 股全市场历史数据拉出来跑了一遍(使用 8 月 22 日前最后一次成功获取的完整行情数据)——有 17 只股票符合条件(基于 Wind 全A股成分股数据,筛选条件:市值>50亿元,60日涨幅>20%,当日成交量>5日均量1.5倍)。
策略逻辑没问题。那问题出在哪?
第三轮:发现真相
我把筛选模块的输入日志调出来,发现一个扎眼的事实:
1 | |
数据源返回空,但没有抛异常。策略拿到空数据,自然筛出空列表。我查了数据源服务商的状态页——它 8 月 22 日晚做了接口升级,旧的日线接口被废弃,只返回空数组。
我的代码还在调旧接口,没做兼容。
根因:单点依赖
我的数据链路是:
1 | |
数据源是唯一入口,挂了就全挂。而且这个依赖有几个致命弱点:
- 静默失败:接口不抛异常,返回空数组,上层无法区分「没有数据」和「数据源故障」
- 无超时监控:接口响应 0.3s,我从来没想过它会有问题
- 无重试机制:抓取失败就直接返回空,没有退避重试
- 无数据新鲜度检查:哪怕返回空,日志也只是「运行完成」
这些问题任何一个单独存在,都不至于 4 天无产出。但叠加在一起,就成了静默事故。
最终方案
1. 升级抓取层:多数据源冗余
1 | |
主源失败时,自动切备用源。备用源的数据格式可能不同,所以抓取层统一做格式转换。
我用了两个备用源:一个免费源,一个付费源。免费源慢一些,但关键时刻能顶上。
2. 加数据新鲜度检查
每次抓取完,检查返回的 data 里最后一根 K 线的日期,必须 >= 当前日期 - 1 个交易日,否则判定为「数据过期」,触发告警 + 切换备用源。
1 | |
3. 加告警
产出的候选列表为空时,不直接当「无信号」处理,而是先跑一遍「数据健康检查」:如果全市场股票 fetch_ohlcv 返回空的比例 > 90%,判定为数据源故障,发告警到钉钉。
1 | |
4. 加熔断
连续 3 次数据源返回异常,自动熔断该数据源 30 分钟,期间走备用源。熔断状态暴露在 /health 端点,我可以在 Grafana 里看到。
踩过的坑
坑 1:只监控产出,不监控依赖
我之前只在策略产出环节做了监控。产出为空就报警。但这次数据源是静默失败的,产出为空但我以为是市场原因。应该监控依赖本身,而不是监控最终结果。
坑 2:没设超时
旧接口稳定,我完全没想过超时。现在每个请求都有 5 秒超时,超时即熔断。
坑 3:把「空」当「无信号」
这是最蠢的一个。策略筛选出来的空列表,我直接当「今天没有候选」处理了。但其实「筛选结果为空」和「输入数据为空」完全是两回事。现在输入数据为空会明确抛异常,不会走进策略逻辑。
坑 4:数据源服务商的接口升级通知
服务商在升级前发了邮件通知,但发到了项目组的共享邮箱,没人看。现在我在代码里加了接口版本检查,如果返回结果里带 api_version 字段且和我期望的不一致,就告警。
怎么验证
改造完成后,我手动模拟了一次数据源故障:
1 | |
一切正常。我又把备用源也停了:
1 | |
这次是「明确的失败」而不是「静默的空结果」。我宁愿被告警吵醒,也不想 4 天后才发现。
最后说一句
单点依赖的代价不是数据本身,而是「你不知道它断了」。这次事故损失了 4 天的候选信号,但更值钱的是那 4 天里我意识到:任何没有监控的依赖,都等于没有依赖。
参考文献
- llama.cpp GitHub Repository - 推理引擎与多模型模式配置
- new-api GitHub Repository - 代理层配置与请求路由
- Qwen3.5-35B-A3B-Ornith Model Card - 模型参数与量化配置参考
- Grafana 告警文档 - 告警规则与熔断状态可视化