Triple EMA Crossover Breakout Strategy

Author: ChaoZhang, Date: 2023-12-28 15:56:54



The Triple EMA Crossover Breakout strategy uses triple exponential moving average (EMA) indicators to determine market trend direction and enter at trend breakout points. It also combines candlestick patterns to filter signal reliability.

Strategy Logic

The strategy is mainly based on the following principles:

  1. Use three EMAs with different periods (200-day, 50-day, 20-day) to determine major, medium-term and short-term market trends.

  2. When the short-term EMA (20-day) crosses above the medium-term EMA (50-day), a buy signal is generated. When it crosses below, a sell signal is generated.

  3. Combine candlestick patterns to check signal reliability. Only when the closing price of the second candle is higher (lower) than the previous candle’s high (low) price, the breakout is considered reliable.

  4. Set stop loss and take profit levels to limit risks beyond reasonable price fluctuations.

Advantage Analysis

  1. Using multiple EMAs improves trend judgment accuracy.

  2. Filtering fake signals with candlestick patterns avoids unnecessary trading risks.

  3. Stop loss and take profit controls single trade loss effectively.

Risk Analysis

  1. In ranging markets, EMAs may generate excessive fake signals and fail to determine market direction.

  2. The single indicator system has limited capacity in complex market situations.

  3. It ignores trading costs which could lead to unprofitability in high-fee markets.


  1. Introduce other indicators like MACD and KDJ to form a combined system and improve judgment accuracy.

  2. Optimize parameters through backtesting for specific symbols and timeframes to make the strategy fit better.

  3. Add trading volume to avoid low-volume fake signals.


The Triple EMA Crossover Breakout Strategy has clear, easy-to-understand logic to determine market trends and find entry timing using EMA crossovers. But it also has some limitations in dealing with complex market situations. It’s recommended to combine with other indicators and optimize parameters to adapt to more diverse trading environments.

start: 2022-12-21 00:00:00
end: 2023-12-27 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]

strategy("GHG RETRACEMENT MODE 1", overlay=true)

entryLevel1 = input(0.5, "ENTRY LEVEL 1")
entryLevel2 = input(0.25, "ENTRY LEVEL 2")
entryLevel3 = input(0.0, "ENTRY LEVEL 3")

stopLevel = input(-0.35, "STOP LEVEL")
tpLevel = input(0.88, "TP LEVEL")
dontUseEma = input(false, "Don't Use EMA")

get_level(level, level100, level0) =>
    level * (level100 - level0) + level0

buySignal = close[2] < open[2] and close[1] > open[1] and close[0] > open[0] and high[0] > open[2] and high[1] < high[2]
sellSignal = close[2] > open[2] and close[1] < open[1] and close[0] < open[0] and low[0] < open[2] and low[1] > low[2]

if buySignal and (close[0] > ta.ema(close, 200) or dontUseEma)
    l =, na)
    entryPrice1 = get_level(entryLevel1, high[0], low[2])
    entryPrice2 = get_level(entryLevel2, high[0], low[2])
    entryPrice3 = get_level(entryLevel3, high[0], low[2])
    exitPrice = get_level(tpLevel, high[0], low[2])
    stopPrice = get_level(stopLevel, high[0], low[2])
    strategy.order("BUY 1", strategy.long, comment="BUY 1", limit=entryPrice1)
    strategy.exit("exit", "BUY 1", limit=high[0], stop=stopPrice)
    strategy.order("BUY 2", strategy.long, comment="BUY 2", limit=entryPrice2)
    strategy.exit("exit", "BUY 2", limit=high[0], stop=stopPrice)

    label.set_text(l, "Buy => " + str.tostring(close[2]) + "\nSL=> " + str.tostring(stopPrice) + "\nTP => " + str.tostring(exitPrice) )
    label.set_yloc(l, yloc.belowbar)
    label.set_style(l, label.style_label_up)
if sellSignal and (close[0] < ta.ema(close, 200) or dontUseEma)
    a =, na)
    entryPrice1 = get_level(entryLevel1, low[0], high[2])
    entryPrice2 = get_level(entryLevel2, low[0], high[2])
    entryPrice3 = get_level(entryLevel3, low[0], high[2])
    exitPrice = get_level(tpLevel, low[0], high[2])
    stopPrice = get_level(stopLevel,low[0], high[2])
    strategy.order("SELL 1", strategy.short, comment="SELL 1", limit=entryPrice1)
    strategy.exit("exit", "SELL 1", limit=low[0], stop=stopPrice) 
    strategy.order("SELL 2", strategy.short, comment="SELL 2", limit=entryPrice2)
    strategy.exit("exit", "SELL 2", limit=low[0], stop=stopPrice) 

    label.set_text(a,"Sell => " + str.tostring(close[2]) + "\nSL=> " + str.tostring(stopPrice) + "\nTP => " + str.tostring(exitPrice) )
    label.set_yloc(a, yloc.abovebar)
    label.set_style(a, label.style_label_down)