Moving Average Crossover Trading Strategy

Author: ChaoZhang, Date: 2023-11-06 16:38:22



This strategy is based on the crossover principle of moving averages to trade. It uses two moving averages, generating buy signals when the short term moving average crosses above the long term moving average from below. Sell signals are generated when the price breaks below another moving average. This strategy is suitable for trending markets, able to effectively filter out some noise trades and capture the main trend.

Strategy Logic

This strategy uses user-customizable short term and long term moving average periods, exit moving average period, and moving average calculation methods.

When the short term moving average crosses above the long term moving average from below, a buy signal is generated. This indicates the short term trend has switched to an uptrend, and we can buy.

When the close price breaks below the exit moving average, a sell signal is generated. This indicates a trend reversal, so we should exit the position.

Therefore, the strategy’s trading signals come from the crossover of the short term and long term moving averages, and the relationship between the closing price and the exit moving average.

Advantage Analysis

The advantages of this strategy are:

  1. Simple and easy to implement.

  2. Customizable parameters suit different market conditions.

  3. Moving averages filter out noise and capture the main trend.

  4. Can incorporate other technical indicators like trend, support/resistance to further optimize.

  5. Controllable risk-reward ratio, has stop loss mechanism.

Risk Analysis

The risks are:

  1. Prone to false signals in non-trending consolidation markets.

  2. Improper parameter settings may cause missing trends or too many invalid trades.

  3. Improper stop loss placement could increase losses.

  4. Failed breakouts may cause losses.

  5. Parameters need timely adjustment to suit market changes.

Solutions include optimizing parameters, incorporating other filters, adjusting stops, waiting for trend confirmation before trading, etc.

Optimization Directions

This strategy can be improved by:

  1. Developing trend determination mechanisms and only trading after trend confirmation.

  2. Adding filters like volume or volatility to filter signals.

  3. Dynamic optimization of moving average periods.

  4. Optimizing the stop loss mechanism to use a trailing stop.

  5. Incorporating support/resistance and other indicators to further confirm signals.

  6. Adjusting parameters based on different products and timeframes.


Overall this moving average crossover strategy is a simple and practical trend following system. It can be adjusted to market conditions by tweaking parameters and catch the main trend direction in trending markets. But risks like trend misidentification should be noted, and constant optimization is needed to adapt to changing markets. In general, this strategy has good viability.

start: 2022-10-30 00:00:00
end: 2023-11-05 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]

// This source code is subject to the terms of the Mozilla Public License 2.0 at
// © TwoChiefs

strategy("John EMA Crossover Strategy", overlay=true)
// From Date Inputs
fromDay = input(defval = 1, title = "From Day", minval = 1, maxval = 31)
fromMonth = input(defval = 1, title = "From Month", minval = 1, maxval = 12)
fromYear = input(defval = 2020, title = "From Year", minval = 1970)
// To Date Inputs
toDay = input(defval = 1, title = "To Day", minval = 1, maxval = 31)
toMonth = input(defval = 1, title = "To Month", minval = 1, maxval = 12)
toYear = input(defval = 2021, title = "To Year", minval = 1970)
// Calculate start/end date and time condition
startDate = timestamp(fromYear, fromMonth, fromDay, 00, 00)
finishDate = timestamp(toYear, toMonth, toDay, 00, 00)
time_cond = true


periodShort = input(13, minval=1, title="Enter Period for Short Moving Average")
smoothingShort = input(title="Choose Smoothing Type for Short Moving Average", defval="EMA", options=["RMA", "SMA", "EMA", "WMA", "VWMA", "SMMA", "DEMA", "TEMA", "HullMA", "LSMA"])

periodLong = input(48, minval=1, title="Enter Period for Long Moving Average")
smoothingLong = input(title="Choose Smoothing Type for Long Moving Average", defval="EMA", options=["RMA", "SMA", "EMA", "WMA", "VWMA", "SMMA", "DEMA", "TEMA", "HullMA", "LSMA"])

periodExit = input(30, minval=1, title="Enter Period for Exit Moving Average")
smoothingExit = input(title="Choose Smoothing Type for Exit Moving Average", defval="EMA", options=["RMA", "SMA", "EMA", "WMA", "VWMA", "SMMA", "DEMA", "TEMA", "HullMA", "LSMA"])

src1 = close
pivot = (high + low + close) / 3

ma(smoothing, src, length) => 
    if smoothing == "RMA"
        rma(src, length)
        if smoothing == "SMA"
            sma(src, length)
            if smoothing == "EMA"
                ema(src, length)
                if smoothing == "WMA"
                    wma(src, length)
					if smoothing == "VWMA"
						vwma(src, length)
						if smoothing == "SMMA"
							na(src[1]) ? sma(src, length) : (src[1] * (length - 1) + src) / length
							if smoothing == "HullMA"
								wma(2 * wma(src, length / 2) - wma(src, length), round(sqrt(length)))

shortMA=ma(smoothingShort, pivot, periodShort)
longMA=ma(smoothingLong, pivot, periodLong)
exitMA=ma(smoothingExit, pivot, periodExit)

plot(shortMA, linewidth=4, color=color.yellow,title="The Short Moving Average")
plot(longMA, linewidth=4,,title="The Long Moving Average")
plot(exitMA, linewidth=1,,title="The Exit CrossUnder Moving Average")

buy = crossover(shortMA,longMA) ? true : na
exit = crossunder(close,exitMA) ? true : na

strategy.entry("long",true,when=buy and time_cond)
strategy.close("long",when=exit and time_cond)

if (not time_cond)