EMA Trend Following Trading Strategy

Author: ChaoZhang, Date: 2023-09-19 19:38:53


This strategy is a typical EMA trend following strategy. It uses the golden cross of a fast EMA and slow EMA to determine uptrends, and the death cross to determine downtrends, for long and short trades accordingly. The strategy reliably tracks medium- to long-term trends and is suitable for swing trading.

Strategy Logic

The core logic is:

  1. Calculate fast EMA, e.g. 12-period EMA
  2. Calculate slow EMA, e.g. 26-period EMA
  3. When fast EMA crosses above slow EMA, determine uptrend for long entry
  4. When fast EMA crosses below slow EMA, determine downtrend for short entry
  5. Exit current position when fast EMA crosses back below slow EMA

Using EMAs of different speeds can effectively detect trend changes. The fast EMA reacts quickly to price changes for early trend detection, while the slow EMA filters out false signals to ensure trend confirmation. Together they form a reliable trend system.

Golden crosses signal the start of an uptrend for longs, while death crosses signal the start of a downtrend for shorts. Exiting on fast EMA death crosses helps stop losses in a timely manner.


  • EMAs effectively identify medium- to long-term trends
  • Fast and slow EMAs combine for reliable trend system
  • Simple logic easy to implement
  • Configurable EMA parameters suit different instruments
  • Fast EMA crossover stop loss controls risk

Risks and Mitigations

  • Unable to predict trend reversal points upfront, some losses
  • Poor EMA parameter selection may miss trend change points
  • EMA parameters need adjustment for market condition changes


  1. Use range stops to limit losses
  2. Add other indicators to detect potential trend reversals
  3. Optimize parameters for better trend identification

Enhancement Opportunities

The strategy can be enhanced in areas like:

  1. Machine learning to auto-tune EMA parameters for better adaptability

  2. Volatility-based position sizing to adjust with market volatility

  3. Oscillators like RSI to fine-tune entry points

  4. Adding trailing stops, profit-taking stops for better risk management

  5. Volume analysis to gauge fund inflows/outflows for trend verification

  6. Portfolio combinations with non-correlated strategies to lower drawdowns and increase return stability


The EMA trend following strategy is a simple and practical way to track medium- to long-term trends. It uses fast and slow EMA crosses for entry timing. Easy to implement, it can also be extended in multiple dimensions for greater adaptability. A great fit for swing trading trending markets.

start: 2023-09-11 00:00:00
end: 2023-09-18 00:00:00
period: 10m
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © HomoDeus666


strategy("EMA12/26 with date backtest range (BTCpair)", overlay=true,initial_capital = 1,commission_type = strategy.commission.percent,currency = currency.BTC)

//input date and time
useDateFilter = input.bool(true, title="Filter Date Range of Backtest",
     group="Backtest Time Period")
backtestStartDate = input(timestamp("1 Jan 2021"), 
     title="Start Date", group="Backtest Time Period",
     tooltip="This start date is in the time zone of the exchange " + 
     "where the chart's instrument trades. It doesn't use the time " + 
     "zone of the chart or of your computer.")
backtestEndDate = input(timestamp("1 Jan 2022"),
     title="End Date", group="Backtest Time Period",
     tooltip="This end date is in the time zone of the exchange " + 
     "where the chart's instrument trades. It doesn't use the time " + 
     "zone of the chart or of your computer.")
//check date and time option
inTradeWindow =  true
/// plot and indicator
fastEMA = ta.ema(close,12), slowEMA=ta.ema(close,26)
plot(fastEMA,color=color.green,linewidth = 2)

//entry when condition
longCondition = ta.crossover(fastEMA,slowEMA)
if (longCondition) and inTradeWindow
    strategy.entry("buy", strategy.long)

if ta.crossunder(ta.ema(close, 12), ta.ema(close, 26)) and inTradeWindow
// trades and cancel all unfilled pending orders
if not inTradeWindow and inTradeWindow[1]
    strategy.close_all(comment="Date Range Exit")