Trend Following EMA and RSI Strategy

Author: ChaoZhang, Date: 2023-09-26 15:39:48


This strategy takes full advantage of moving averages and relative strength index to identify and follow trends. It only needs two indicators to determine the trend and find proper entry/exit timing. The strategy aims to capture medium-to-long term price trends while avoiding short-term market noise.

Strategy Logic

The strategy uses three EMAs with different periods, with EMA-A having the shortest period, EMA-B medium, and EMA-C the longest. When the shorter EMA-A crosses above the longer EMA-B, it signals an upward trend, thus going long. Conversely, when EMA-A crosses below EMA-B, it signals a downward trend, thus going short. To filter false signals, it also uses the longest EMA-C - only considering entry after the price breaks EMA-C.

The strategy also uses RSI to locate exit points. When long, it closes the position if RSI crosses above 70. When short, it exits if RSI falls below 30. This locks in trend profits and prevents losses from expanding further.

Advantage Analysis

  • Utilizes EMA’s strength in trend identification
  • RSI assists in entry and exit timing
  • Simple strategy with only 2 indicators
  • Customizable parameters to adjust strategy style
  • Profits from early, mid and late trend stages

Risk Analysis

  • Pullbacks in major trends may generate false signals
  • Vulnerable to whipsaws in ranging markets
  • Improper RSI parameters may cause premature exits
  • EMA periods need careful selection, too short may be noise sensitive, too long may miss trends

These risks can be reduced by optimizing RSI parameters, adding filters, and combining with trend analysis.

Optimization Directions

  • Optimize RSI parameters for better profit taking and risk control
  • Test different EMA period combinations
  • Add volume or other confirmation indicators
  • Use ATR for stop loss sizing
  • Consider reducing position size mid-trend
  • Optimize entry timing with breakouts, volume, etc
  • Explore re-entry mechanisms


This strategy combines trend following and oscillator indicators for trend identification and capturing. With simple parameter and logic optimization, it can be greatly improved while keeping simplicity. It is a very practical trend following template suitable for medium-to-long term investors.

start: 2023-08-26 00:00:00
end: 2023-09-25 00:00:00
period: 2h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]

// This source code is subject to the terms of the Mozilla Public License 2.0 at
//@author Alorse

// strategy(title='Tendency EMA + RSI [Alorse]', shorttitle='Tendece EMA + RSI [Alorse]', overlay=true, pyramiding=0, currency=currency.USD, default_qty_type=strategy.percent_of_equity, initial_capital=1000, default_qty_value=20, commission_type=strategy.commission.percent, commission_value=0.01)

// Bollinger Bands
len =, minval=1, title='Length', group='RSI')
src = input.source(close, 'Source', group='RSI')
rsi = ta.rsi(src, len)

// Moving Averages
len_a =, minval=1, title='EMA A Length', group='Moving Averages')
out_a = ta.ema(close, len_a)
plot(out_a, title='EMA A', color=color.purple)

len_b =, minval=1, title='EMA B Length', group='Moving Averages')
out_b = ta.ema(close, len_b)
plot(out_b, title='EMA B',

len_c =, minval=1, title='EMA C Length', group='Moving Averages')
out_c = ta.ema(close, len_c)
plot(out_c, title='EMA B',

// Strategy Conditions
stratGroup = 'Strategy'
showLong = input.bool(true, title='Long entries', group=stratGroup)
showShort = input.bool(false, title='Short entries', group=stratGroup)
closeAfterXBars = input.bool(true, title='Close after X # bars', tooltip='If trade is in profit', group=stratGroup)
xBars =, title='# bars')

entryLong = ta.crossover(out_a, out_b) and out_a > out_c and close > open
exitLong = rsi > 70

entryShort = ta.crossunder(out_a, out_b) and out_a < out_c and close < open
exitShort = rsi < 30

bought = strategy.opentrades[0] == 1 and strategy.position_size[0] > strategy.position_size[1]
entry_price = ta.valuewhen(bought, open, 0)
var int nPastBars = 0
if strategy.position_size > 0
    nPastBars := nPastBars + 1
if strategy.position_size == 0
    nPastBars := 0
if closeAfterXBars
    exitLong := nPastBars >= xBars and close > entry_price ? true : exitLong
    exitShort := nPastBars >= xBars and close < entry_price ? true : exitShort

// Long Entry
strategy.entry('Long', strategy.long, when=entryLong and showLong)
strategy.close('Long', when=exitLong)

// Short Entry
strategy.entry('Short', strategy.short, when=entryShort and showShort)
strategy.close('Short', when=exitShort)