STS:一个策略从设计到上线的完整过程
6 月 23 日是单日 commit 最多的一天——24 个。大部分围绕一个策略:STS(Surge Trailing Short,放量追踪做空)。
这个策略的开发过程有一个反直觉的特点:前半段加功能,后半段删功能。
时间线
00:26 DI rank(趋势强度排行)完成
12:35 STS 设计文档定稿
13:27 设计评审:8 个实现前置条件
13:51 拓扑审计:调用图、不变量、死代码
16:13 Phase 1 实现
16:19 修复:最小名义金额 $5 → $30
16:35 删除 STOP_LOSS 退出
16:45 删除 TOTAL_LOSS_LIMIT 退出
16:49 修改 TOTAL_DURATION → 仅在盈利时退出
16:51 删除 TREND_REVERSAL 退出
16:55 删除 MAX_CYCLES 退出
17:04 新增 SUPPORT_LEVEL 退出
17:11 COIN_TREND_GATE 方向性阻止
18:41 STS v2:周期级趋势收割 + 两层支撑 + 重入
20:52 Owner-Safe Mutex:UUID token + Lua 原子释放
一天内:设计 → 实现 → 评审 → 删 5 个退出条件 → v2 重写 → 并发安全。
为什么删的比加的多
Phase 1 实现时,照着设计文档加了 6 个退出条件。实现完一跑,发现 5 个有问题:
- STOP_LOSS:和网格策略的止损逻辑冲突,两个止损同时触发会重复平仓
- TOTAL_LOSS_LIMIT:按总亏损限退出会过早平仓——亏损可能是暂时的
- TREND_REVERSAL:STS 本身就是趋势追踪,趋势反转不应该退出(应该反过来做多)
- MAX_CYCLES:人为限制网格周期数没有意义——只要还在赚钱就应该继续
- TOTAL_DURATION 改条件:只在盈利时退出,亏损时不限时
最后只保留了 1 个退出条件(SUPPORT_LEVEL:价格接近 7 日支撑位且盈利时退出)加上修改后的 TOTAL_DURATION。
设计文档 + 实现 + 反思 = 更好的设计。文档的价值不是让你照着写,是让你写完之后发现哪些是多余的。
Owner-Safe Mutex
并发安全的关键设计:多个 STS 实例可能同时操作同一个标的。
-- Redis Lua 脚本
local token = ARGV[1]
local owner = redis.call('GET', KEYS[1])
if owner == false or owner == token then
redis.call('SET', KEYS[1], token, 'PX', 30000)
return 1 -- 获取锁成功
end
return 0 -- 被其他实例占用
Token 不是线程 ID,是 UUID——即使进程重启,token 也不会冲突。30 秒 TTL 防止死锁。
这和广告系统的竞价锁一样——同一个广告位的同一个 impression,不能有两个策略同时出价。
一句话
24 个 commit 里最有价值的是那 5 个 delete——删掉不需要的退出条件,比加 10 个新功能更需要判断力。