이중 이동 평균 역전 전략 (Dual Moving Average Reversal Strategy) 은 단기 및 장기 트렌드를 식별하기 위해 이중 이동 평균을 활용하는 양적 거래 전략이다. 이 전략은 10일 간 간편 이동 평균 (SMA) 과 200일 간 간편 이동 평균 (SMA) 을 결합하여 기본 장기 상승 추세 내에서 단기 인기를 끌 수 있다. 또한 트렌드 추적 및 위험 관리 메커니즘을 갖추고 있다.
이중 이동평균 반전 전략은 다음과 같은 가정에 기초합니다.
200일 SMA는 시장의 지배적인 장기 트렌드를 식별합니다. 가격이 200일 라인을 넘으면 시장이 장기 상승 추세에 있음을 신호합니다.
10일 SMA는 가격의 단기적 인 인기를 나타냅니다. 가격이 10일 라인 아래로 떨어지면 일시적인 인기를 나타냅니다.
계속되는 상승 추세에서, 단기적 인 인하는 상승 추세를 효율적으로 잡을 수있는 구매 기회로 간주 될 수 있습니다.
위의 가정에 근거하여, 거래 신호는 다음과 같이 생성됩니다.
닫기 가격이 200일 SMA를 넘고 동시에 10일 SMA를 넘을 때, 장기 트렌드가 긍정적이지만 단기적 인퇴가 나타났다는 것을 보여주는 구매 신호를 유발합니다.
장기 포지션에서 가격이 10일 SMA를 넘어서면 단기 트렌드가 반전되어 즉시 포지션이 닫힐 것입니다. 또한 시장이 스톱 로스 위반으로 크게 떨어지면 포지션이 닫힐 것입니다.
큰 침체 (예정된 기준을 초과) 가 있을 때마다, 그것은 반대 신호로 하락을 구매 할 수있는 기회를 제공합니다.
이 설계로, 전략은 지속적인 상승 추세에서 상승 스냅백을 효율적으로 활용하는 동시에 스톱 손실을 사용하여 위험을 제어하는 것을 목표로합니다.
이중 이동 평균 역전 전략은 다음과 같은 주요 장점을 가지고 있습니다.
이 전략은 일반적으로 효과적이지만 다음과 같은 한계를 가지고 있습니다.
이 전략에 대한 추가 개선 사항은 다음과 같습니다.
요약하자면, 이중 이동 평균 역전 전략은 매우 실용적인 접근법이다. 이는 상류 추세와 결합된 이동 평균 분석을 사용하여 지속적인 상승 추세 동안 수익성있는 회귀 추세를 가능하게합니다. 또한 시장 체제 탐지 기능과 위험 통제를 제공합니다. 지속적인 향상으로 전략은 차별화된 성과를 낼 수있는 강력한 잠재력을 제공합니다.
/*backtest start: 2023-11-24 00:00:00 end: 2023-12-24 00:00:00 period: 1h basePeriod: 15m 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/ // © Gold_D_Roger //note: spreading 1 statement over multiple lines needs 1 apce + 1 tab | multi line function is 1 tab //Recommended tickers: SPY (D), QQQ (D) and big indexes, AAPL (4H) //@version=5 strategy("Davin's 10/200MA Pullback on SPY Strategy v2.0", overlay=true, initial_capital=10000, default_qty_type=strategy.percent_of_equity, default_qty_value=10, // 10% of equity on each trade commission_type=strategy.commission.cash_per_contract, commission_value=0.1) //Insert your broker's rate, IB is 0.005USD or tiered //Best parameters // SPY D // Stop loss 0.15 // commission of 0.005 USD using Interactive brokers // Exit on lower close // Buy more when x% down --> 14% // DO NOT include stop condition using MA crossover // Get User Input i_ma1 = input.int(title="MA Length 1", defval=200, step=10, group="Strategy Parameters", tooltip="Long-term MA 200") i_ma2 = input.int(title="MA Length 2", defval=10, step=10, group="Strategy Parameters", tooltip="Short-term MA 10") i_ma3 = input.int(title="MA Length 3", defval=50, step=1, group="Strategy Parameters", tooltip="MA for crossover signals`") i_stopPercent = input.float(title="Stop Loss Percent", defval=0.15, step=0.01, group="Strategy Parameters", tooltip="Hard stop loss of 10%") i_startTime = input(title="Start filter", defval=timestamp("01 Jan 2013 13:30 +0000"), group="Time filter", tooltip="Start date and time to begin") i_endTime = input(title="End filter", defval=timestamp("01 Jan 2099 19:30 +0000"), group="Time filter", tooltip="End date and time to stop") i_lowerClose = input.bool(title="Exit on lower close", defval=true, group="Strategy Parameters", tooltip="Wait for lower close after above 10SMA before exiting") // optimise exit strat, boolean type creates tickbox type inputs i_contrarianBuyTheDip = input.bool(title="Buy whenever more than x% drawdown", defval=true, group="Strategy Parameters", tooltip="Buy the dip! Whenever x% or more drawdown on SPY") i_contrarianTrigger = input.int(title="Trigger % drop to buy the dip", defval=14, step=1, group="Strategy Parameters", tooltip="% drop to trigger contrarian Buy the Dip!") //14% to be best for SPY 1D //20% best for AMZN 1D i_stopByCrossover_MA2_3 = input.bool(title="Include stop condition using MA crossover", defval=false, group="Strategy Parameters", tooltip="Sell when crossover of MA2/1 happens") // Get indicator values ma1 = ta.sma(close,i_ma1) //param 1 ma2 = ta.sma(close,i_ma2) //param 2 ma3 = ta.sma(close,i_ma3) //param 3 ma_9 = ta.ema(close,9) //param 2 ma_20 = ta.ema(close,20) //param 3 // Check filter(s) f_dateFilter = true //make sure date entries are within acceptable range // Highest price of the prev 52 days: https://www.tradingcode.net/tradingview/largest-maximum-value/#:~:text=()%20versus%20ta.-,highest(),max()%20and%20ta. highest52 = ta.highest(high,52) overall_change = ((highest52 - close[0]) / highest52) * 100 // Check buy/sell conditions var float buyPrice = 0 //intialise buyPrice, this will change when we enter a trade ; float = decimal number data type 0.0 buyCondition = (close > ma1 and close < ma2 and strategy.position_size == 0 and f_dateFilter) or (strategy.position_size == 0 and i_contrarianBuyTheDip==true and overall_change > i_contrarianTrigger and f_dateFilter) // higher than 200sma, lower than short term ma (pullback) + avoid pyramiding positions sellCondition = close > ma2 and strategy.position_size > 0 and (not i_lowerClose or close < low[1]) //check if we already in trade + close above 10MA; // third condition: EITHER i_lowerClose not turned on OR closing price has to be < previous candle's LOW [1] stopDistance = strategy.position_size > 0 ? ((buyPrice - close)/close) : na // check if in trade > calc % drop dist from entry, if not na stopPrice = strategy.position_size > 0 ? (buyPrice - (buyPrice * i_stopPercent)) : na // calc SL price if in trade, if not, na stopCondition = (strategy.position_size > 0 and stopDistance > i_stopPercent) or (strategy.position_size > 0 and (i_stopByCrossover_MA2_3==true and ma3 < ma1)) // Enter positions if buyCondition strategy.entry(id="Long", direction=strategy.long) //long only if buyCondition[1] // if buyCondition is true prev candle buyPrice := open // entry price = current bar opening price // Exit position if sellCondition or stopCondition strategy.close(id="Long", comment = "Exit" + (stopCondition ? "Stop loss=true" : "")) // if condition? "Value for true" : "value for false" buyPrice := na //reset buyPrice // Plot plot(buyPrice, color=color.lime, style=plot.style_linebr) plot(stopPrice, color=color.red, style=plot.style_linebr, offset = -1) plot(ma1, color=color.blue) //defval=200 plot(ma2, color=color.white) //defval=10 plot(ma3, color=color.yellow) // defval=50