You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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')

问题原因及解决方法

核心问题

  1. calc_on_order_fills = true的副作用:这个参数会让策略在每一笔订单成交后重新执行整个脚本,导致同一根K线内多次触发信号逻辑,生成重复警报。
  2. 无信号触发次数限制:入场/出场条件仅依赖JMA的方向变化,没有限制同一根确认K线内只触发一次信号,加上重新计算的机制,会重复触发警报。

修复方案

  1. 移除calc_on_order_fills = true参数,除非你明确需要订单成交后立即重新计算逻辑。
  2. 添加信号触发标记变量,确保同一根确认K线内只触发一次入场/出场信号。
  3. 优化订单状态判断,避免因重新计算导致的重复下单。

修改后的脚本代码

//@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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 20:50:28