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

EMA斜率+EMA交叉策略回测异常:双向订单同时执行求助

EMA斜率+EMA交叉策略订单执行问题修复

问题描述

回测EMA斜率+EMA交叉策略时,触发买入或卖出信号警报后,系统未执行对应订单,反而同时执行买入和卖出订单:触发买入信号时,买入和卖出订单同时生成;触发卖出信号时同理。需修复该问题,确保仅执行警报对应的订单,维持策略“始终持仓(多单或空单)”的设定。

原策略代码

//@version=3
strategy("EMA Slope + EMA Cross Strategy (by ChartArt)", shorttitle="CA_-_EMA_slope_cross", overlay=true)

// ChartArt's EMA Slope + EMA Cross Strategy
//
// Version 1.0
// Idea by ChartArt on March 10, 2018.
//
// This strategy uses divergences between
// three moving averages and their slope
// directions as well as crosses between
// the price and the moving averages
// to switch between long/short positions.
//
// The strategy is non-stop in the market
// and always either long or short.
// 
// In addition the moving averages are colored
// depending if they are trending up or down.

// Input
price = input(close)
MA1_Length = input(2,step=1, title="EMA 1 Length")
MA2_Length = input(4,step=1, title="EMA 2 Length")
MA3_Length = input(20,step=1, title="EMA 3 Length")

switch1=input(true, title="Show Bar Color?")
switch2=input(true, title="Show Moving Averages?")

// Calculation
MA1 = ema(price, MA1_Length)
MA2 = ema(price, MA2_Length)
MA3 = ema(price, MA3_Length)

// Strategy
long = crossunder(price, MA3) or ( change(price)<0 and change(MA1)<0 and crossunder(price,MA1) and change(MA2)>0 )
short = crossover(price, MA3) or ( change(price)>0 and change(MA1)>0 and crossover(price,MA1)  and change(MA2)<0 ) 

if long
    strategy.entry("Long", strategy.long, comment="Long")

if short
    strategy.entry("Short", strategy.short, comment="Short")

// Strategy Alert
alertcondition(long, title='EMA Slope + EMA Cross Strategy, Long Alert', message='Go Long!')
alertcondition(short, title='EMA Slope + EMA Cross Strategy, Short Alert', message='Go Short!')

// MA trend bar color
up =  change(MA2)>0 and change(MA3)>0
dn =  change(MA2)<0 and change(MA3)<0
bar_color = up?green:dn?red:blue
barcolor(switch1?bar_color:na)

// MA trend output color
MA2_color = change(MA2)>0?lime:change(MA2)<0?red:blue
MA3_color = change(MA3)>0?lime:change(MA3)<0?red:blue

// MA output
EMA2 = plot(switch2?MA2:na, title="EMA 2", style=linebr, linewidth=2, color=MA2_color)
EMA3 = plot(switch2?MA3:na, title="EMA 3", style=linebr, linewidth=4, color=MA3_color)
fill(EMA2, EMA3, color=silver, transp=50)

//plot(strategy.equity, title="equity", color=red, linewidth=2, style=areabr)

问题原因

  1. 原代码未处理仓位切换逻辑:当新信号触发时,未先平仓相反方向的现有仓位,导致策略同时持有多空订单;
  2. 极端行情下,long和short条件存在极小概率同时满足的可能(如价格剧烈波动导致指标信号冲突),进而触发双向订单。

修复后的策略代码

//@version=3
strategy("EMA Slope + EMA Cross Strategy (Fixed)", shorttitle="CA_-_EMA_slope_cross_FIXED", overlay=true)

// ChartArt's EMA Slope + EMA Cross Strategy
//
// Version 1.0 (Fixed)
// Idea by ChartArt on March 10, 2018.
//
// This strategy uses divergences between
// three moving averages and their slope
// directions as well as crosses between
// the price and the moving averages
// to switch between long/short positions.
//
// The strategy is non-stop in the market
// and always either long or short.
// 
// In addition the moving averages are colored
// depending if they are trending up or down.

// Input
price = input(close)
MA1_Length = input(2,step=1, title="EMA 1 Length")
MA2_Length = input(4,step=1, title="EMA 2 Length")
MA3_Length = input(20,step=1, title="EMA 3 Length")

switch1=input(true, title="Show Bar Color?")
switch2=input(true, title="Show Moving Averages?")

// Calculation
MA1 = ema(price, MA1_Length)
MA2 = ema(price, MA2_Length)
MA3 = ema(price, MA3_Length)

// Strategy
long = crossunder(price, MA3) or ( change(price)<0 and change(MA1)<0 and crossunder(price,MA1) and change(MA2)>0 )
short = crossover(price, MA3) or ( change(price)>0 and change(MA1)>0 and crossover(price,MA1)  and change(MA2)<0 ) 

// 修复逻辑:触发新信号时先平仓相反仓位,再开新仓位
if long
    // 平掉现有空单
    strategy.close("Short")
    // 开多单
    strategy.entry("Long", strategy.long, comment="Long")

if short
    // 平掉现有多单
    strategy.close("Long")
    // 开空单
    strategy.entry("Short", strategy.short, comment="Short")

// Strategy Alert
alertcondition(long, title='EMA Slope + EMA Cross Strategy, Long Alert', message='Go Long!')
alertcondition(short, title='EMA Slope + EMA Cross Strategy, Short Alert', message='Go Short!')

// MA trend bar color
up =  change(MA2)>0 and change(MA3)>0
dn =  change(MA2)<0 and change(MA3)<0
bar_color = up?green:dn?red:blue
barcolor(switch1?bar_color:na)

// MA trend output color
MA2_color = change(MA2)>0?lime:change(MA2)<0?red:blue
MA3_color = change(MA3)>0?lime:change(MA3)<0?red:blue

// MA output
EMA2 = plot(switch2?MA2:na, title="EMA 2", style=linebr, linewidth=2, color=MA2_color)
EMA3 = plot(switch2?MA3:na, title="EMA 3", style=linebr, linewidth=4, color=MA3_color)
fill(EMA2, EMA3, color=silver, transp=50)

//plot(strategy.equity, title="equity", color=red, linewidth=2, style=areabr)

修复说明

  1. 仓位切换逻辑:在触发新方向订单前,先调用strategy.close平掉相反方向的持仓订单,确保同一时间仅持有单方向仓位;
  2. 信号互斥保障:通过先平仓再开仓的操作,即使极端行情下long和short条件同时触发,也只会保留最后执行的订单(实际中因change(price)的正负互斥,这种情况不会发生);
  3. 保留原策略的所有指标、视觉展示和警报逻辑,仅修改订单执行部分,不改变策略核心逻辑。

内容的提问来源于stack exchange,提问作者Ravi Kiran

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 01:15:46