Overview
This strategy is a quantitative trading system based on multiple moving average crossover signals. It combines seven different types of moving average indicators, including Simple Moving Average (SMA), Exponential Moving Average (EMA), Weighted Moving Average (WMA), Volume Weighted Moving Average (VWMA), Hull Moving Average (HMA), Rough Moving Average (RMA) and Arnold Legacy Moving Average (ALMA). The strategy supports two-line or three-line crossover systems, and can flexibly choose to go long or short according to market conditions.
Strategy Principle
The core logic of the strategy is to judge the market trend by observing the crossover relationship between moving averages of different periods. When the fast moving average crosses the slow moving average upward, a long signal is generated; otherwise, a short signal is generated. The system provides two ways to enter the market: one is based on the direct crossover of the moving average, and the other is based on the position relationship of the closing price relative to the moving average. The three-line system increases the reliability and stability of the signal by introducing the medium-term moving average.
Strategy Advantages
- Strong adaptability: By integrating seven different moving averages, the strategy can adapt to different market environments and trading products
- Stable signal: multiple confirmation mechanisms are used to avoid false signals
- Flexible parameters: support custom cycle settings, easy to optimize and backtest
- Risk controllable: Provide short selling mechanism to help seize two-way trading opportunities
- Clear visualization: The strategy provides an intuitive graphical interface, including visual aids such as trend area filling
Strategy Risks
- Lag: Moving averages are essentially lagging indicators and may miss the best entry point in a volatile market.
- Not suitable for volatile markets: Frequent false signals may be generated in a sideways and volatile market
- Parameter dependence: The performance of different parameter combinations varies greatly and needs to be continuously optimized
- Systemic risk: It may not be possible to stop losses in time when market events occur.
Strategy Optimization Direction
- Introducing volatility indicators: It is recommended to combine volatility indicators such as ATR to dynamically adjust the position size
- Add market environment filter: You can add trend strength indicators to filter trading signals in volatile markets
- Optimize the stop loss mechanism: It is recommended to add a trailing stop loss function to improve risk control capabilities
- Add volume analysis: It is recommended to combine volume changes to confirm the validity of the trend
Summary
This strategy is a comprehensive trend tracking system. By integrating multiple moving average indicators and flexible parameter settings, it provides traders with a reliable quantitative trading framework. Although there is a certain lag, the strategy still has good practical value through reasonable parameter optimization and risk control measures. It is recommended that traders perform targeted optimization according to specific market characteristics in real trading.
Strategy source code
/*backtest
start: 2019-12-23 08:00:00
end: 2025-01-04 08:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
//@version=5
strategy("Total Average Crossing", overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=100,max_bars_back=1000)
// Input parameters
period_fast = input.int(50, title="Periods for fast average", minval=1)
period_slow = input.int(200, title="Periods for slow medium", minval=1)
// Selecting the moving average type
media_type = input.string(title="Choose the type of moving average", defval="Simple sma", options=["Simple sma", "Exponential ema", "Weighted wma", "Volume weighted vwma", "Hull hma", "Smoothed average rma", "Arnaud Legoux alma average"])
// Possibility of a strategy with a crossover of three moving averages
three_averages = input.bool(false, title="Strategy with crossing of 3 moving averages")
periodo_media = input.int(100, title="Periods for average average", minval=1)
// Short trading option
allow_short = input.bool(false, title="Allow short trades")
// Option when to buy
when_to_buy = input.string(title="When to buy", defval="Crossing of averages", options=["Previous candle closes above the averages", "Crossing of averages"])
// Option of when to sell
when_to_sell = input.string(title="When to sell", defval="Crossing of averages", options=["Previous candle closes below the averages", "Crossing of averages"])
float media_mov_rapida = na
float media_mov_media = na
float media_mov_lenta = na
// Definition of moving averages
if media_type == "Simple sma"
fast_moving_average := ta.sma(close, fast_period)
average_moving_average := ta.sma(close, average_period)
slow_moving_average := ta.sma(close, slow_period)
else if tipo_de_media == "Exponencial ema"
media_mov_rapida := ta.ema(close, periodo_rapida)
media_mov_media := ta.ema(close, periodo_media)
media_mov_lenta := ta.ema(close, periodo_lenta)
else if tipo_de_media == "Ponderada wma"
media_mov_rapida := ta.wma(close, periodo_rapida)
media_mov_media := ta.wma(close, periodo_media)
media_mov_lenta := ta.wma(close, periodo_lenta)
else if tipo_de_media == "Volumen ponderada vwma"
media_mov_rapida := ta.vwma(close, periodo_rapida)
media_mov_media := ta.vwma(close, periodo_media)
media_mov_lenta := ta.vwma(close, periodo_lenta)
else if tipo_de_media == "Hull hma"
media_mov_rapida := ta.hma(close, periodo_rapida)
media_mov_media := ta.hma(close, periodo_media)
media_mov_lenta := ta.hma(close, periodo_lenta)
else if tipo_de_media == "Media suavizada rma"
media_mov_rapida := ta.rma(close, periodo_rapida)
media_mov_media := ta.rma(close, periodo_media)
media_mov_lenta := ta.rma(close, periodo_lenta)
else if tipo_de_media == "Media de Arnaud Legoux alma"
offset = input.int(0, title="Desfase para ALMA", minval=-100, maxval=100)
sigma = input.float(6, title="Sigma para ALMA", minval=0.1, maxval=10)
media_mov_rapida := ta.alma(close, periodo_rapida, offset, sigma)
media_mov_media := ta.alma(close, periodo_media, offset, sigma)
media_mov_lenta := ta.alma(close, periodo_lenta, offset, sigma)
// Plotting moving averages on the chart
plot_rapida = plot(media_mov_rapida, color=color.green, linewidth=2, title="Media Móvil Rápida")
plot_media = plot(tres_medias ? media_mov_media : na, color=color.blue, linewidth=2, title="Media Móvil Media")
plot_lenta = plot(media_mov_lenta, color=color.red, linewidth=2, title="Media Móvil Lenta")
// Fill the area between the moving averages with conditioned color
fill(plot_rapida, plot_lenta, media_mov_rapida > media_mov_lenta ? color.new(color.green, 90) : color.new(color.red, 90), title="Relleno entre Medias")
// Logic of the strategy for crossing averages
comprado = strategy.position_size > 0 // Verifica si ya hay una posición abierta
vendido = strategy.position_size < 0
if not bought // Only buy if there is no open position
if tres_medias and cuando_comprar == "Cruce de medias"
if media_mov_rapida > media_mov_media and media_mov_media > media_mov_lenta
strategy.entry("Largo", strategy.long)
label.new(bar_index, low, "Largo", style=label.style_label_up, color=color.green, textcolor=color.white)
else if not tres_medias and cuando_comprar == "Cruce de medias"
if ta.crossover(media_mov_rapida, media_mov_lenta)
strategy.entry("Largo", strategy.long)
label.new(bar_index, low, "Largo", style=label.style_label_up, color=color.green, textcolor=color.white)
else if tres_medias and cuando_comprar == "Vela anterior cierra por encima de las medias"
if close[1] > media_mov_rapida and close[1] > media_mov_media and close[1] > media_mov_lenta
strategy.entry("Largo", strategy.long)
label.new(bar_index, low, "Largo", style=label.style_label_up, color=color.green, textcolor=color.white)
else if not tres_medias and cuando_comprar == "Vela anterior cierra por encima de las medias"
if close[1] > media_mov_rapida and close[1] > media_mov_lenta
strategy.entry("Largo", strategy.long)
label.new(bar_index, low, "Largo", style=label.style_label_up, color=color.green, textcolor=color.white)
// Condition for closing the position
if comprado
if tres_medias and cuando_vender == "Cruce de medias"
if media_mov_rapida < media_mov_media and media_mov_media < media_mov_lenta
strategy.close("Largo")
label.new(bar_index, high, "Cierre Largo", style=label.style_label_down, color=color.red, textcolor=color.white)
else if not tres_medias and cuando_vender == "Cruce de medias"
if ta.crossunder(media_mov_rapida, media_mov_lenta)
strategy.close("Largo")
label.new(bar_index, high, "Cierre Largo", style=label.style_label_down, color=color.red, textcolor=color.white)
else if tres_medias and cuando_vender == "Vela anterior cierra por debajo de las medias"
if close[1] < media_mov_rapida and close[1] < media_mov_media and close[1] < media_mov_lenta
strategy.close("Largo")
label.new(bar_index, high, "Cierre Largo", style=label.style_label_down, color=color.red, textcolor=color.white)
else if not tres_medias and cuando_vender == "Vela anterior cierra por debajo de las medias"
if close[1] < media_mov_rapida and close[1] < media_mov_lenta
strategy.close("Largo")
label.new(bar_index, high, "Cierre Largo", style=label.style_label_down, color=color.red, textcolor=color.white)
// Condition of entering short
if not vendido and permitir_corto
if tres_medias
if media_mov_rapida < media_mov_media and media_mov_media < media_mov_lenta
strategy.entry("Short", strategy.short)
label.new(bar_index, low, "Short", style=label.style_label_up, color=color.blue, textcolor=color.white)
else
if ta.crossunder(media_mov_rapida, media_mov_lenta)
strategy.entry("Short", strategy.short)
label.new(bar_index, low, "Short", style=label.style_label_up, color=color.blue, textcolor=color.white)
// Short position closing condition
if vendido
if tres_medias
if media_mov_rapida > media_mov_media and media_mov_media > media_mov_lenta
strategy.close("Short")
label.new(bar_index, high, "Cierre Short", style=label.style_label_down, color=color.purple, textcolor=color.white)
else
if ta.crossover(media_mov_rapida, media_mov_lenta)
strategy.close("Short")
label.new(bar_index, high, "Cierre Short", style=label.style_label_down, color=color.purple, textcolor=color.white)
Strategy Parameters
The original address: Multi-Indicator Dynamic Moving Average Crossover Quantitative Strategy