Dual Moving Average Reversal Strategy

Author: ChaoZhang, Date: 2023-11-03 16:51:18
Tags:

img

Overview

This strategy uses 2 indicators to generate trading signals: 2/20 Exponential Moving Average and Average True Range Reversal. It combines the ideas of trend following and short-term reversal, aiming to capture reversal opportunities.

Principle

The strategy consists of 2 parts:

  1. 2/20 Exponential Moving Average. It calculates 20-day EMA and generates signals when price crosses EMA up or down.

  2. Average True Range Reversal Indicator. It calculates stop loss level based on ATR, and generates signals when price breaks through the stop loss level. Here 3.5 x ATR is used as the stop level.

The strategy combines the signals from both. It goes short when 2/20 EMA gives long signal while ATR reversal gives short signal. It goes long when opposite signals generated.

Advantage Analysis

The strategy combines trend following and reversal ideas, aiming to capture reversals. The advantages are:

  1. 2/20 EMA identifies mid-term trend, avoids market noise.

  2. ATR reversal captures short-term reversals and opportunities.

  3. Combining the signals captures trend reversal ahead of time and improves profitability.

  4. Reasonable ATR stop loss provides certain risk control.

  5. Customizable ATR multiplier adapts to different products.

  6. Reversal option adapts to different market environments.

Risk Analysis

The risks are:

  1. 2/20 EMA is slow and may miss short-term chances.

  2. ATR stop loss may be penetrated easily. Wider stop loss is needed.

  3. Single indicator signal is unreliable. More filters are needed.

  4. Beware of over-trading.

  5. Parameter tuning and backtest are needed to fit the product.

  6. Strict capital management is needed to control risk per trade.

Optimization Directions

The strategy can be improved from:

  1. Tuning EMA parameters for best combination.

  2. Optimizing ATR multiplier for better stop loss.

  3. Adding filter conditions like volume and volatility.

  4. Adding capital management model for dynamic position sizing.

  5. Adding other stop loss strategies like Chandelier Exit.

  6. Testing parameters across different products.

  7. Adding machine learning models for better performance.

  8. Combining multiple sub-strategies for more Alpha.

Conclusion

The strategy combines two major ideas and has certain advantage of capturing reversals. But inappropriate parameter selection can also introduce risks. Further improvements on stop loss strategy and adding filters can enhance stability and profitability.


/*backtest
start: 2022-10-27 00:00:00
end: 2023-11-02 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=5
////////////////////////////////////////////////////////////
//  Copyright by HPotter v1.0 05/04/2022
// This is combo strategies for get a cumulative signal. 
//
// First strategy
// This indicator plots 2/20 exponential moving average. For the Mov 
// Avg X 2/20 Indicator, the EMA bar will be painted when the Alert criteria is met.
//
// Second strategy
// Average True Range Trailing Stops Strategy, by Sylvain Vervoort 
// The related article is copyrighted material from Stocks & Commodities Jun 2009 
// Please, use it only for learning or paper trading. Do not for real trading.
//
//
// WARNING:
// - For purpose educate only
// - This script to change bars colors.
////////////////////////////////////////////////////////////
EMA20(Length) =>
    pos = 0.0
    xPrice = close
    xXA = ta.ema(xPrice, Length)
    nHH = math.max(high, high[1])
    nLL = math.min(low, low[1])
    nXS = nLL > xXA or nHH < xXA ? nLL : nHH
    iff_1 = nXS < close[1] ? 1 : nz(pos[1], 0)
    pos := nXS > close[1] ? -1 : iff_1
    pos


ATRR(nATRPeriod,nATRMultip) =>
    pos = 0.0
    xATR = ta.atr(nATRPeriod)
    nLoss = nATRMultip * xATR
    xATRTrailingStop = 0.0
    xATRTrailingStop := close > nz(xATRTrailingStop[1], 0) and close[1] > nz(xATRTrailingStop[1], 0) ? math.max(nz(xATRTrailingStop[1]), close - nLoss) :
                          close < nz(xATRTrailingStop[1], 0) and close[1] < nz(xATRTrailingStop[1], 0) ? math.min(nz(xATRTrailingStop[1]), close + nLoss) : 
                          close > nz(xATRTrailingStop[1], 0) ? close - nLoss : close + nLoss
    pos:= close[1] < nz(xATRTrailingStop[1], 0) and close > nz(xATRTrailingStop[1], 0) ? 1 :
    	     close[1] > nz(xATRTrailingStop[1], 0) and close < nz(xATRTrailingStop[1], 0) ? -1 : nz(pos[1], 0) 
    pos

strategy(title='Combo 2/20 EMA & Average True Range Reversed', shorttitle='Combo', overlay=true)
var I1 = '●═════ 2/20 EMA ═════●'
Length = input.int(14, minval=1, group=I1)
var I2 = '●═════ Average True Range Reversed  ═════●'
nATRPeriod = input.int(5, group=I2)
nATRMultip = input.float(3.5, group=I2)
var misc = '●═════ MISC ═════●'
reverse = input.bool(false, title='Trade reverse', group=misc)
var timePeriodHeader = '●═════ Time Start ═════●'
d = input.int(1, title='From Day', minval=1, maxval=31, group=timePeriodHeader)
m = input.int(1, title='From Month', minval=1, maxval=12, group=timePeriodHeader)
y = input.int(2005, title='From Year', minval=0, group=timePeriodHeader)
StartTrade = time > timestamp(y, m, d, 00, 00) ? true : false
posEMA20 = EMA20(Length)
prePosATRR = ATRR(nATRPeriod,nATRMultip)
iff_1 = posEMA20 == -1 and prePosATRR == -1 and StartTrade ? -1 : 0
pos = posEMA20 == 1 and prePosATRR == 1 and StartTrade ? 1 : iff_1
iff_2 = reverse and pos == -1 ? 1 : pos
possig = reverse and pos == 1 ? -1 : iff_2
if possig == 1
    strategy.entry('Long', strategy.long)
if possig == -1
    strategy.entry('Short', strategy.short)
if possig == 0
    strategy.close_all()
barcolor(possig == -1 ? #b50404 : possig == 1 ? #079605 : #0536b3)

More