Pine Script变量值异常回滚、同K线警报误触发问题求解
问题原因
Pine Script在未收盘的K线上会逐tick重复执行脚本,只要tick数据满足if判断条件就会触发alert,但K线收盘时,引擎会以最终收盘价为基准重算整根K线的逻辑,盘中临时给变量赋的值如果不符合最终收盘时的判断条件,就会被回滚。varip关键字只能保留同一根未收盘K线内逐tick更新的变量值,一旦K线收盘进入历史K线序列,所有非最终状态的临时赋值都会被清除,这就是用了varip还是出现变量回滚的原因。
修复方法
根据交易逻辑选对应方案即可:
方案1:规避假信号,仅K线收盘确认后触发交易
这是普通趋势策略最常用的写法,从根源避免盘中波动触发无效信号,加barstate.isconfirmed判断,只有K线走完、指标值固定后才执行开平仓逻辑:
currentRSI = ta.rsi(close,14) var tradeExists = 0 // 开仓逻辑:K线收盘确认RSI在50以上且无持仓 if (currentRSI > 50 and tradeExists == 0 and barstate.isconfirmed) tradeExists := 1 alert("Long trade") // 平仓逻辑:K线收盘确认RSI在50以下且有持仓 if (currentRSI < 50 and tradeExists == 1 and barstate.isconfirmed) tradeExists := 0 alert("Close long trade")
方案2:捕捉盘中信号,同时识别信号失效自动平仓
如果需要做盘中进场的策略,不想等K线收盘,就要单独用varip变量记录当前K线的盘中触发状态,同时区分盘中临时信号和收盘确认的持仓状态,就能识别“盘中触发开仓后又跌回阈值”的场景,自动触发平仓:
currentRSI = ta.rsi(close,14) varip intraBarLongTrigger = 0 // 记录当前K线盘中是否触发过开多信号 var tradeExists = 0 // 记录确认后的持仓状态 // 每根新K线开盘时,重置盘中触发标记 if barstate.isnew intraBarLongTrigger := 0 // 盘中只要RSI首次突破50且无持仓,就触发开仓警报,标记已触发 if currentRSI > 50 and tradeExists == 0 and intraBarLongTrigger == 0 intraBarLongTrigger := 1 alert("Long trade", freq=alert.freq_once_per_bar) // K线收盘时统一校验状态 if barstate.isconfirmed // 收盘RSI仍在50以上,确认持仓 if currentRSI > 50 and intraBarLongTrigger == 1 tradeExists := 1 // 收盘RSI跌破50:要么是盘中触发过开仓后跌回,要么是已有持仓跌回阈值,都触发平仓 else if currentRSI < 50 and (intraBarLongTrigger == 1 or tradeExists == 1) tradeExists := 0 alert("Close long trade", freq=alert.freq_once_per_bar)
实盘运行盘中策略时,需要在脚本设置页把「计算」选项改为「逐tick计算」,否则脚本不会在盘中实时更新;回测阶段默认按K线收盘价成交,盘中信号的回测结果会和实盘存在偏差。
内容的提问来源于stack exchange,提问作者Asstoped
相关产品推荐
相关产品推荐

