发现
S0017 是一个寻找支撑位回踩买点的缠论策略。简单说就是:价格跌回前期支撑区域,出现反转信号,就买入。
今天在审查这组策略代码时,发现了一个隐蔽的问题:信号扫描的边界条件遗漏了半确认状态。
策略在扫描买入信号时,需要知道"什么时候该停下来"——当前向下笔结束了,就该停止扫描,不能把下一根向上笔的 K 线也算进来。
问题就出在这个"停下来"的判断上。
Bug:只认 1.0,不认 0.5
缠论中,一笔的形成有两个阶段:
0.5 | |
1.0 |
修复前的代码只检查了 1.0:
BUG// 只在向上笔"完全确认"时才停止扫描if (wave_sigs[i] == 1.0f) break;这意味着:当向上笔已经初步成立(信号值为 0.5),但还没走完时,代码不会停止扫描。
这会导致向上笔已经成立的 K 线被错误地当作当前向下笔的延续来检查,可能产生不该出现的买入信号。
影响:这个 Bug 不会导致信号缺失,而是可能导致不该出现的信号——在向上笔已经开始走了一段之后,仍然回过头来标记买入点。
修复
修正方案很简单——在停止条件里加上半确认状态:
FIX// 向上笔成立(无论半确认还是全确认)就停止扫描if (wave_sigs[i] == 1.0f || wave_sigs[i] == 0.5f) break;卖出侧同理,补上 -0.5f。
修改后,扫描在向上笔初步成立时就立刻停止,不再越界。
修复范围:S0017 策略的买入信号扫描和卖出信号扫描,共 2 处。
顺便清理
审查同一个函数时,还发现了两处永远不会执行的死代码,一并清理:
一个 i > cur.extreme_pos一个收盘价检查——被前面更严格的支撑区下沿检查提前覆盖,执行流根本走不到这行,已删除。
这些不是 Bug,但对阅读代码的人是干扰——每一行多余的条件都会让人多想一秒:"这里是不是有什么边界情况?"
总结
今天的修复,核心改动只有一行:在信号扫描的停止条件里加上 0.5f。
但这个 Bug 的特征值得记住:代码只处理了"确认"状态,遗漏了"半确认"状态。单独看确认状态的处理,逻辑完全正确——笔确实在 1.0 时确认。但"逻辑正确"和"业务完整"之间,差了一个中间状态。
教训:审查条件语句时,不仅问"这个条件对不对",还要问"有没有遗漏的状态"。信号值 0.5 和 1.0 的区别,在策略上线时可能无人在意,但它决定了扫描范围的边界。边界差一格,信号就可能多一个或少一个。
量化实战手记
本系列记录作者用代码理解市场的真实历程——每个想法如何变成设计,每个设计如何变成可运行的系统。不谈理论,只聊实战。
夜雨聆风