基于CRSI指标的Pine Script策略二次/三次开仓失效问题排查
Pine Script CRSI策略二次/三次开仓故障排查
我编写了一个基于CRSI指标的Pine Script交易策略,计划通过CRSI指标触发开仓,且二次、三次开仓需满足指定等待时长和价格差值条件,但目前二次、三次开仓功能无法正常运行,请求协助排查故障原因。
原策略代码
//@version=5 strategy(title="1bln", overlay = true, initial_capital = 1000) src = close lenrsi = input(3, "RSI Length") lenupdown = input(1, "UpDown Length") lenroc = input(100, "ROC Length") updown(s) => isEqual = s == s[1] isGrowing = s > s[1] ud = 0.0 ud := isEqual ? 0 : isGrowing ? (nz(ud[1]) <= 0 ? 1 : nz(ud[1])+1) : (nz(ud[1]) >= 0 ? -1 : nz(ud[1])-1) rsi = ta.rsi(src, lenrsi) updownrsi = ta.rsi(updown(src), lenupdown) percentrank = ta.percentrank(ta.roc(src, 1), lenroc) crsi = math.avg(rsi, updownrsi, percentrank) // Connors rsi if crsi > 70 strategy.close_all() var first_entry_time = strategy.opentrades.entry_time(0) var second_entry_time = strategy.opentrades.entry_time(1) var make_first_entry = first_entry_time + 5 * 60 * 1000 // time out first take var make_second_entry = second_entry_time + 10 * 60 * 1000 // time out second take var initial_entry_price = strategy.opentrades.entry_price(0) var second_entry_price = strategy.opentrades.entry_price(1) lowestLow = ta.lowest(low, 100) var initial_price_decrease = initial_entry_price - initial_entry_price * 0.005 var second_price_decrease = second_entry_price - second_entry_price * 0.008 if(crsi == 15 and make_second_entry == time and second_price_decrease <= lowestLow) strategy.entry("take_3", strategy.long, limit = strategy.initial_capital * 0.25) else if(crsi < 20 and make_first_entry == time and initial_price_decrease <= lowestLow) strategy.entry("take_2", strategy.long, limit = strategy.initial_capital * 0.2) else strategy.entry("take_1", strategy.long, limit = strategy.initial_capital * 0.15)
核心故障点分析
var变量初始化逻辑错误:所有用var声明的变量(如first_entry_time、initial_entry_price)只会在脚本启动时初始化一次,后续不会随新仓更新,导致超时时间、价格阈值永远固定,无法触发后续开仓条件。- 精确时间匹配无效:
make_second_entry == time这种毫秒级精确匹配几乎不可能触发,K线时间是每根K线的结束时间,与计算的超时时间几乎不会完全重合。 - CRSI值精确判断不合理:
crsi == 15是浮点值精确等于判断,CRSI作为计算指标几乎不会刚好等于15,触发概率极低。 - 开仓逻辑顺序错误:else分支会在任何不满足前两个条件的情况触发
take_1,导致频繁重复开仓,干扰二次、三次开仓的状态判断。 - 价格阈值未动态更新:
initial_price_decrease用var声明后,只会计算首次开仓价格的跌幅,后续开仓的价格不会更新该值,价格条件判断失效。 - 未校验持仓状态:没有判断当前是否已持有对应仓位,会导致重复开仓,逻辑混乱。
修正后的策略代码
//@version=5 strategy(title="1bln", overlay = true, initial_capital = 1000, default_qty_type=strategy.cash) src = close lenrsi = input(3, "RSI Length") lenupdown = input(1, "UpDown Length") lenroc = input(100, "ROC Length") updown(s) => isEqual = s == s[1] isGrowing = s > s[1] ud = 0.0 ud := isEqual ? 0 : isGrowing ? (nz(ud[1]) <= 0 ? 1 : nz(ud[1])+1) : (nz(ud[1]) >= 0 ? -1 : nz(ud[1])-1) rsi = ta.rsi(src, lenrsi) updownrsi = ta.rsi(updown(src), lenupdown) percentrank = ta.percentrank(ta.roc(src, 1), lenroc) crsi = math.avg(rsi, updownrsi, percentrank) // Connors RSI // CRSI超70时平仓所有仓位 if crsi > 70 strategy.close_all() // 动态跟踪持仓状态与开仓信息 has_take1 = strategy.opentrades.size > 0 and strategy.opentrades.entry_id(0) == "take_1" has_take2 = strategy.opentrades.size > 1 and strategy.opentrades.entry_id(1) == "take_2" first_entry_time = has_take1 ? strategy.opentrades.entry_time(0) : na make_first_entry = first_entry_time + 5 * 60 * 1000 // 首次开仓后5分钟可二次开仓 initial_entry_price = has_take1 ? strategy.opentrades.entry_price(0) : na initial_price_decrease = initial_entry_price * 0.995 // 下跌0.5%阈值 second_entry_time = has_take2 ? strategy.opentrades.entry_time(1) : na make_second_entry = second_entry_time + 10 * 60 * 1000 // 二次开仓后10分钟可三次开仓 second_entry_price = has_take2 ? strategy.opentrades.entry_price(1) : na second_price_decrease = second_entry_price * 0.992 // 下跌0.8%阈值 lowestLow = ta.lowest(low, 100) // 分层开仓逻辑:先判断持仓状态,再判断时间、价格、CRSI条件 if not has_take1 and crsi < 20 strategy.entry("take_1", strategy.long, qty=strategy.initial_capital * 0.15) elif has_take1 and not has_take2 and time >= make_first_entry and initial_price_decrease <= lowestLow and crsi < 20 strategy.entry("take_2", strategy.long, qty=strategy.initial_capital * 0.2) elif has_take2 and time >= make_second_entry and second_price_decrease <= lowestLow and crsi <= 15 strategy.entry("take_3", strategy.long, qty=strategy.initial_capital * 0.25)
修正说明
- 移除不必要的
var声明,让开仓时间、价格等变量随K线循环动态更新 - 将精确时间匹配改为
time >= make_first_entry,确保超时后能触发条件 - 将
crsi ==15改为crsi <=15,提升条件触发概率 - 添加持仓状态判断(
has_take1、has_take2),避免重复开仓 - 调整开仓逻辑顺序,分层判断仓位状态与触发条件,消除else分支的误触发
- 优化价格跌幅计算方式,直接基于当前开仓价格动态生成阈值
内容的提问来源于stack exchange,提问作者Magish
相关产品推荐
相关产品推荐

