The Dual Moving Average Stochastic strategy attempts to identify trading opportunities using a combination of moving average indicators and the stochastic oscillator. It generates trade signals when the fast EMA crosses above or below the slow SMA, while also using the stochastic %K value to filter out signals when the market is overextended.
The strategy is primarily based on two technical indicators:
Moving Averages: It computes a fast EMA, slow SMA and slow VWMA using different parameters, and generates trade signals when the fast EMA crosses the slow SMA.
Stochastic Oscillator: It calculates the %K value and considers the market overbought or oversold when %K crosses preset upper or lower threshold levels, using this to filter some of the moving average signals.
Specifically, the logic for signal generation is:
When the fast EMA crosses above the slow SMA, and %K is below the oversold level, go long. When the fast EMA crosses below the slow SMA, and %K is above the overbought level, go short.
For existing long positions, close when %K re-enters the overbought zone or price breaches the stop loss. For short positions, close when %K re-enters the oversold zone or price breaches the stop loss.
By combining moving averages and the stochastic oscillator, the strategy attempts to identify high probability moving average signal points to enter trades, while using the stochastic to filter out some of the false signals.
The main advantages of this strategy are:
There are also some risks:
Mitigations:
The main optimization opportunities are:
The Dual Moving Average Stochastic Strategy utilizes a blend of moving averages and the stochastic oscillator to design a robust trend following system, but has some enhancement opportunities around parameters, stops etc. Further refinements like additional indicators and optimizations can potentially deliver more consistent alpha.
/*backtest start: 2023-01-22 00:00:00 end: 2024-01-28 00:00:00 period: 1d basePeriod: 1h exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ //@version=4 strategy("TVIX MEAN REV V2 TREND", overlay=true) length = input(16, minval=1) OverBought = input(80) OverSold = input(20) TradeLong = input (true) TradeShort = input (true) OverBoughtClose = input(80) OverSoldClose = input(20) smoothK = 3 smoothD = 3 trail_points = input(50) k = sma(stoch(close, high, low, length), smoothK) d = sma(k, smoothD) k2 = sma(stoch(close, high, low, length), smoothK) d2 = sma(k, smoothD) // === GENERAL INPUTS === // short Ema maFastSource = input(defval=close, title="Fast EMA Source") maFastLength = input(defval=1, title="Fast EMA Period", minval=1) // long Sma maSlowSource = input(defval=close, title="Slow SMA Source") maSlowLength = input(defval=100, title="Slow SMA Period", minval=1) // longer Sma maSlowerSource = input(defval=close, title="Slower SMA Source") maSlowerLength = input(defval=30, title="Slower SMA Period", minval=1) //ATR Stop Loss Indicator by Keith Larson atrDays = input(7, "ATR Days Lookback") theAtr = atr(atrDays) atrModifier = input(5.0, "ATR Modifier") //plot(atr * atrModifier, title="ATR") LstopLoss = close - (theAtr * atrModifier) SstopLoss = close + (theAtr * atrModifier) // === SERIES SETUP === /// a couple of ma's.. maFast = ema(maFastSource, maFastLength) maSlow = sma(maSlowSource, maSlowLength) maSlower = vwma(maSlowerSource, maSlowerLength) rsi = rsi(maSlowerSource, maSlowerLength) // === PLOTTING === fast = plot(maFast, title="Fast MA", color=color.red, linewidth=2, style=plot.style_line, transp=30) slow = plot(maSlow, title="Slow MA", color=color.green, linewidth=2, style=plot.style_line, transp=30) slower = plot(maSlower, title="Slower MA", color=color.teal, linewidth=2, style=plot.style_line, transp=30) // === LOGIC === Basic - simply switches from long to short and vice-versa with each fast-slow MA cross LongFilter = maFast > maSlow ShortFilter = maSlow > maFast BUY=crossover(k, d) and k < OverSold SELL=crossunder(k, d) and k > OverBought SELLCLOSE=crossover(k, d) and k < OverSoldClose BUYCLOSE=crossunder(k, d) and k > OverBoughtClose Open = open if not na(k) and not na(d) if crossover(k, d) and k < OverSold and LongFilter and TradeLong strategy.entry("$", strategy.long, limit = Open, comment="Long") strategy.close("$",when = crossunder(k, d) and k > OverBoughtClose or open < LstopLoss ) ///strategy.close("$",when = open < LstopLoss ) if not na(k) and not na(d) if crossunder(k, d) and k > OverBought and ShortFilter and TradeShort strategy.entry("$1", strategy.short, limit = Open, comment="S") strategy.close ("$1", when = crossover(k, d) and k < OverSoldClose or open > SstopLoss ) ///strategy.close ("$1", when = open < SstopLoss)template: strategy.tpl:40:21: executing "strategy.tpl" at <.api.GetStrategyListByName>: wrong number of args for GetStrategyListByName: want 7 got 6