Dual Moving Average Reversal Trading Strategy

Author: ChaoZhang, Date: 2023-12-04 16:39:13



This is a reversal trading strategy based on dual moving average indicators. By calculating two groups of moving averages with different parameter settings and judging the price trend according to their directional changes, trading signals can be generated by setting the sensitivity parameter for directional changes.


The core indicator of this strategy is the dual moving average. The strategy allows selecting the type (SMA, EMA, etc.), length and price source (close price, typical price, etc.) of the moving average. After calculating two groups of moving averages, their directions are determined by defining the reaction parameter. A buy signal is generated when the fast line crosses above the slow line, and a sell signal is generated when it crosses below. The reaction parameter is used to adjust the sensitivity to identify turning points.

In addition, the strategy also sets the conditions to determine the change of direction and continued rise/fall to avoid generating wrong signals. And it visualizes the rise and fall of prices in different colors. When prices continue to rise, the movavg line is displayed in green, and in red when prices fall.

Advantage Analysis

The dual movavg strategy combines fast and slow lines with different parameter settings, which can effectively filter the noise in the trading market and identify stronger trends. Compared with a single movavg strategy, it reduces wrong signals and allows entering the market when the trend is more distinct, thereby obtaining a higher win rate.

The reaction parameter allows the strategy to be flexible and adaptable to different cycles and varieties. The strategic process is intuitive and simple, easy to understand and optimize.

Risk Analysis

The biggest risk of this strategy is missing the turning point and losing money or taking a reverse position. This relates to the reaction parameter setting. If the reaction is too small, wrong signals are prone to occur. If the reaction is too large, it may miss better entry points.

Another risk is the inability to effectively control losses. When prices fluctuate violently, it cannot quickly stop losses, leading to enlarged losses. This requires the use of stop-loss strategies to control risks.

Optimization Directions

The main optimization directions of this strategy focus on selecting reaction parameters, types and lengths of moving averages. Increasing reaction appropriately can reduce wrong signals. Moving average parameters can be tested according to different cycles and varieties to select the best combination for generating signals.

In addition, confirming trading signals with other auxiliary indicators such as RSI and KD is also an optimization idea. Or use machine learning methods to automatically optimize parameters.


Overall, this strategy is relatively simple and practical. By filtering with dual moving averages and generating trading signals, it can effectively identify trend reversals and is a typical trend-following strategy. After optimizing the parameter portfolio, its ability to capture trends and hold positions against the market will be improved. Using it with stop loss and position management mechanisms works better.

start: 2023-11-03 00:00:00
end: 2023-12-03 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]

strategy(shorttitle="MA_color strategy", title="Moving Average Color", overlay=true)

// === INPUTS

ma_type   = input(defval="HullMA", title="MA Type: ", options=["SMA", "EMA", "WMA", "VWMA", "SMMA", "DEMA", "TEMA", "HullMA", "ZEMA", "TMA", "SSMA"])
ma_len    = input(defval=32, title="MA Lenght", minval=1)
ma_src    = input(close, title="MA Source")
reaction  = input(defval=2, title="MA Reaction", minval=1)

// SuperSmoother filter
// © 2013  John F. Ehlers
variant_supersmoother(src,len) =>
    a1 = exp(-1.414*3.14159 / len)
    b1 = 2*a1*cos(1.414*3.14159 / len)
    c2 = b1
    c3 = (-a1)*a1
    c1 = 1 - c2 - c3
    v9 = 0.0
    v9 := c1*(src + nz(src[1])) / 2 + c2*nz(v9[1]) + c3*nz(v9[2])
variant_smoothed(src,len) =>
    v5 = 0.0
    v5 := na(v5[1]) ? sma(src, len) : (v5[1] * (len - 1) + src) / len

variant_zerolagema(src,len) =>
    ema1 = ema(src, len)
    ema2 = ema(ema1, len)
    v10 = ema1+(ema1-ema2)
variant_doubleema(src,len) =>
    v2 = ema(src, len)
    v6 = 2 * v2 - ema(v2, len)

variant_tripleema(src,len) =>
    v2 = ema(src, len)
    v7 = 3 * (v2 - ema(v2, len)) + ema(ema(v2, len), len)              
variant(type, src, len) =>
    type=="EMA"     ? ema(src,len) : 
      type=="WMA"   ? wma(src,len): 
      type=="VWMA"  ? vwma(src,len) : 
      type=="SMMA"  ? variant_smoothed(src,len) : 
      type=="DEMA"  ? variant_doubleema(src,len): 
      type=="TEMA"  ? variant_tripleema(src,len): 
      type=="HullMA"? wma(2 * wma(src, len / 2) - wma(src, len), round(sqrt(len))) :
      type=="SSMA"  ? variant_supersmoother(src,len) : 
      type=="ZEMA"  ? variant_zerolagema(src,len) : 
      type=="TMA"   ? sma(sma(src,len),len) : sma(src,len)

// === Moving Average
ma_series = variant(ma_type,ma_src,ma_len)

direction = 0
direction := rising(ma_series,reaction) ? 1 : falling(ma_series,reaction) ? -1 : nz(direction[1])
change_direction= change(direction,1)
change_direction1= change(direction,1)

pcol = direction>0 ? lime : direction<0 ? red : na
plot(ma_series, color=pcol,style=line,join=true,linewidth=3,transp=10,title="MA PLOT")

/////// Alerts ///////

alertcondition(change_direction,title="Change Direction MA",message="Change Direction MA")

longCondition = direction>0
shortCondition = direction<0
if (longCondition)
    strategy.entry("BUY", strategy.long)
if (shortCondition)
    strategy.entry("SELL", strategy.short)