This strategy is a typical moving average crossover strategy that uses two sets of moving averages, one fast and one slow. When the fast moving average crosses over the slow moving average, a buy signal is generated. When the fast crosses below the slow, a sell signal is generated. The strategy uses both EMA and SMA for the moving averages, with EMAs as the fast lines and SMAs as the slow lines. Using multiple moving averages can help filter out false signals and improve reliability.
The core logic relies on crossovers between fast and slow moving average lines to determine entries and exits.
Specifically, two sets of fast and slow moving averages are calculated:
Crossovers are then checked between the fast EMAs and slow SMAs:
To filter false signals, a second EMA/SMA crossover is required for confirmation:
By requiring two fast/slow MA crossovers, many false signals can be filtered out and reliability improved.
When buy signal triggers, go long. When sell signal triggers, go short.
The strategy also sets profit taking and stop loss based on input percentage from entry price once in a position.
The advantages of this strategy include:
Risks of the strategy:
To control risks:
The strategy can be further optimized by:
In summary, the dual MA crossover strategy generates signals with fast/slow MA crosses, sets take profit and stop loss to control risks, and is simple, intuitive and easy to implement. The parameters can be tuned and combined with other indicators for better performance. It has great utility in quantitative trading.
/*backtest start: 2023-02-20 00:00:00 end: 2024-02-26 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 https://mozilla.org/MPL/2.0/ // © JMLSlop //@version=4 src = close strategy("Crossover moving averages", shorttitle="Cross MA-EMA", overlay=true, calc_on_order_fills=false) // first fast EMA len = input(8, "Length", type=input.integer, minval=1) doma1 = input(true, title="EMA") out1 = ema(src, len) //Second fast EMA len2 = input(21, minval=1, title="Length") doma2 = input(true, title="EMA") out2 = ema(src, len2) //First slow MA len3 = input(50, minval=1, title="Length") doma3 = input(true, title="SMA") out3 = sma(src, len3) //Second slow MA len4 = input(200, minval=1, title="Length") doma4 = input(true, title="SMA") out4 = sma(src, len4) // Profit profit = input(8, "Profit/lost %", type=input.float, minval=1) * 0.01 plot(doma1 and out1 ? out1: na, color=color.blue, linewidth=1, title="1st EMA") plot(doma2 and out2 ? out2: na, color=color.red, linewidth=1, title="2nd EMA") plot(doma3 and out3 ? out3: na, color=color.green, linewidth=2, title="1st MA") plot(doma4 and out4 ? out4: na, color=color.orange, linewidth=3, title="2nd MA") // Orders config takeProfitPrice = (strategy.position_size > 0) ? strategy.position_avg_price + open*profit : (strategy.position_size < 0) ? strategy.position_avg_price - (open*profit) : na longStopPrice = strategy.position_avg_price * (1 - profit) shortStopPrice = strategy.position_avg_price * (1 + profit) longCondition2 = (out2>out3 and (crossover(out1, out4) or crossover(out1[1], out4[1]) or crossover(out1[2], out4[2]) or (crossover(out1[3], out4[3]))) or (out2>out3 and (crossover(out1, out3) or crossover(out1[1], out3[1]) or crossover(out1[2], out3[2]) or crossover(out1[3], out3[3])))) if (longCondition2) strategy.entry("Enter L", strategy.long) shortCondition2 = (out2<out3 and (crossunder(out1, out4) or crossunder(out1[1], out4[1]) or crossunder(out1[2], out4[2]) or crossunder(out1[3], out4[3]))) or (out2<out3 and (crossunder(out1, out3) or crossunder(out1[1], out3[1]) or crossunder(out1[2], out3[2]) or crossunder(out1[3], out3[3]))) if (shortCondition2) strategy.entry("Enter S", strategy.short) if (strategy.position_size > 0) strategy.exit("Exit L", limit=takeProfitPrice, stop=longStopPrice) if (strategy.position_size < 0) strategy.exit("Exit S", limit=takeProfitPrice, stop=shortStopPrice)