使用barstate.isconfirmed后仍触发多次策略警报的问题求助
Pine Script v5 STG1策略重复警报问题解决
我是Pine Script初学者,编写的STG1策略脚本(v5版本)在添加barstate.isconfirmed判断后,仍会在极短时间内触发多达6次重复警报。已尝试在入场、出场条件及声明中加入该判断,但问题依旧,附上脚本代码寻求解决方案。
原脚本代码
//@version=5 strategy('STG1', overlay=true, calc_on_order_fills = true) start = timestamp(2022, 12,01,0, 0) end = timestamp(2022, 12,30,0, 0) length = input(title='Length', defval=1) phase = input(title='Phase', defval=50) power = input(title='Power', defval=2) src = input(title='Source', defval=close) highlightMovements = input.bool(title='Highlight Movements ?', defval=true) phaseRatio = phase < -100 ? 0.45 : phase > 100 ? 2.5 : phase / 100 + 1.5 beta = 0.45 * (length - 1) / (0.5 * (length - 1) + 2) alpha = math.pow(beta, power) jma = 0.0 e0 = 0.0 e0 := (1 - alpha) * src + alpha * nz(e0[1]) e1 = 0.0 e1 := (src - e0) * (1 - beta) + beta * nz(e1[1]) e2 = 0.0 e2 := (e0 + phaseRatio * e1 - nz(jma[1])) * math.pow(1 - alpha, 2) + math.pow(alpha, 2) * nz(e2[1]) jma := e2 + nz(jma[1]) jmaColor = highlightMovements ? (jma > jma[1] ? color.green : color.red) : #e615e6 EnterLong = jma > jma[1] and strategy.opentrades == 0 ExitLong = jma < jma[1] and strategy.opentrades > 0 EnterShort = jma < jma[1] and strategy.opentrades == 0 ExitShort = jma > jma[1] and strategy.opentrades > 0 if time >= start and time < end strategy.entry('Long', strategy.long, 1, when=EnterLong and barstate.isconfirmed, comment= 'LE') strategy.close('Long', when=ExitLong and barstate.isconfirmed, comment= 'LX') strategy.entry('short', strategy.short, 1, when=EnterShort and barstate.isconfirmed, comment= 'SE' ) strategy.close('short', when=ExitShort and barstate.isconfirmed, comment='SX')
问题原因及解决方法
核心问题
calc_on_order_fills = true的副作用:这个参数会让策略在每一笔订单成交后重新执行整个脚本,导致同一根K线内多次触发信号逻辑,生成重复警报。- 无信号触发次数限制:入场/出场条件仅依赖JMA的方向变化,没有限制同一根确认K线内只触发一次信号,加上重新计算的机制,会重复触发警报。
修复方案
- 移除
calc_on_order_fills = true参数,除非你明确需要订单成交后立即重新计算逻辑。 - 添加信号触发标记变量,确保同一根确认K线内只触发一次入场/出场信号。
- 优化订单状态判断,避免因重新计算导致的重复下单。
修改后的脚本代码
//@version=5 strategy('STG1', overlay=true) // 移除calc_on_order_fills = true start = timestamp(2022, 12,01,0, 0) end = timestamp(2022, 12,30,0, 0) length = input(title='Length', defval=1) phase = input(title='Phase', defval=50) power = input(title='Power', defval=2) src = input(title='Source', defval=close) highlightMovements = input.bool(title='Highlight Movements ?', defval=true) phaseRatio = phase < -100 ? 0.45 : phase > 100 ? 2.5 : phase / 100 + 1.5 beta = 0.45 * (length - 1) / (0.5 * (length - 1) + 2) alpha = math.pow(beta, power) jma = 0.0 e0 = 0.0 e0 := (1 - alpha) * src + alpha * nz(e0[1]) e1 = 0.0 e1 := (src - e0) * (1 - beta) + beta * nz(e1[1]) e2 = 0.0 e2 := (e0 + phaseRatio * e1 - nz(jma[1])) * math.pow(1 - alpha, 2) + math.pow(alpha, 2) * nz(e2[1]) jma := e2 + nz(jma[1]) jmaColor = highlightMovements ? (jma > jma[1] ? color.green : color.red) : #e615e6 // 添加信号触发标记,防止同一根K线重复触发 var bool longTriggered = false var bool shortTriggered = false var bool exitLongTriggered = false var bool exitShortTriggered = false // 重置标记:新K线确认时重置所有触发标记 if barstate.isconfirmed longTriggered := false shortTriggered := false exitLongTriggered := false exitShortTriggered := false EnterLong = jma > jma[1] and strategy.opentrades == 0 and not longTriggered and barstate.isconfirmed ExitLong = jma < jma[1] and strategy.opentrades > 0 and not exitLongTriggered and barstate.isconfirmed EnterShort = jma < jma[1] and strategy.opentrades == 0 and not shortTriggered and barstate.isconfirmed ExitShort = jma > jma[1] and strategy.opentrades > 0 and not exitShortTriggered and barstate.isconfirmed if time >= start and time < end if EnterLong strategy.entry('Long', strategy.long, 1, comment= 'LE') longTriggered := true // 标记已触发多单 if ExitLong strategy.close('Long', comment= 'LX') exitLongTriggered := true // 标记已平多单 if EnterShort strategy.entry('short', strategy.short, 1, comment= 'SE') shortTriggered := true // 标记已触发空单 if ExitShort strategy.close('short', comment='SX') exitShortTriggered := true // 标记已平空单
修改说明
- 移除了
calc_on_order_fills = true,避免订单成交后重复计算脚本。 - 添加了4个变量作为信号触发标记,确保同一根确认K线内每个信号只触发一次。
- 在
barstate.isconfirmed时重置所有标记,保证下一根K线可以正常触发新信号。 - 将入场/出场条件与标记变量结合,防止重复触发。
内容的提问来源于stack exchange,提问作者Bhupen M
相关产品推荐
相关产品推荐

