이중 이동 평균 역전 전략

저자:차오장, 날짜: 2023-12-25 13:24:14
태그:

img

전반적인 설명

이중 이동 평균 역전 전략 (Dual Moving Average Reversal Strategy) 은 단기 및 장기 트렌드를 식별하기 위해 이중 이동 평균을 활용하는 양적 거래 전략이다. 이 전략은 10일 간 간편 이동 평균 (SMA) 과 200일 간 간편 이동 평균 (SMA) 을 결합하여 기본 장기 상승 추세 내에서 단기 인기를 끌 수 있다. 또한 트렌드 추적 및 위험 관리 메커니즘을 갖추고 있다.

전략 논리

이중 이동평균 반전 전략은 다음과 같은 가정에 기초합니다.

  1. 200일 SMA는 시장의 지배적인 장기 트렌드를 식별합니다. 가격이 200일 라인을 넘으면 시장이 장기 상승 추세에 있음을 신호합니다.

  2. 10일 SMA는 가격의 단기적 인 인기를 나타냅니다. 가격이 10일 라인 아래로 떨어지면 일시적인 인기를 나타냅니다.

  3. 계속되는 상승 추세에서, 단기적 인 인하는 상승 추세를 효율적으로 잡을 수있는 구매 기회로 간주 될 수 있습니다.

위의 가정에 근거하여, 거래 신호는 다음과 같이 생성됩니다.

  1. 닫기 가격이 200일 SMA를 넘고 동시에 10일 SMA를 넘을 때, 장기 트렌드가 긍정적이지만 단기적 인퇴가 나타났다는 것을 보여주는 구매 신호를 유발합니다.

  2. 장기 포지션에서 가격이 10일 SMA를 넘어서면 단기 트렌드가 반전되어 즉시 포지션이 닫힐 것입니다. 또한 시장이 스톱 로스 위반으로 크게 떨어지면 포지션이 닫힐 것입니다.

  3. 큰 침체 (예정된 기준을 초과) 가 있을 때마다, 그것은 반대 신호로 하락을 구매 할 수있는 기회를 제공합니다.

이 설계로, 전략은 지속적인 상승 추세에서 상승 스냅백을 효율적으로 활용하는 동시에 스톱 손실을 사용하여 위험을 제어하는 것을 목표로합니다.

장점

이중 이동 평균 역전 전략은 다음과 같은 주요 장점을 가지고 있습니다.

  1. 전략 논리는 간단하고 쉽게 이해할 수 있습니다.
  2. 이중 이동 평균 필터는 단기 및 장기 트렌드를 효과적으로 식별합니다.
  3. 단기적 역행에 활용함으로써 좋은 시간 효율성을 제공합니다.
  4. 내장된 스톱 로스 메커니즘은 개별 포지션의 리스크를 엄격하게 제어합니다.
  5. 유연한 매개 변수는 이 전략이 지수와 주식에서 광범위하게 적용되도록 합니다.

위험성

이 전략은 일반적으로 효과적이지만 다음과 같은 한계를 가지고 있습니다.

  1. 시장이 범위에 묶여있는 경우 윙사와 잘못된 신호가 발생할 수 있습니다. 전략은 확장 된 통합 중 비활성화되어야합니다.
  2. 이동 평균에만 의존하는 것은 신호 정확성의 한계를 가지고 있습니다. 더 많은 지표가 성능을 증가시킬 수 있습니다.
  3. 고정 스톱 로스 방법론은 유연성이 부족합니다. 다른 스톱 로스 기술을 테스트 할 수 있습니다.
  4. 최적의 매개 변수들은 다른 시장에 맞게 캘리브레이션되어야 합니다. 열등한 설정은 신뢰성을 감소시킵니다.

더 나은 기회

이 전략에 대한 추가 개선 사항은 다음과 같습니다.

  1. 최적의 조합을 찾기 위해 다른 이동 평균 길이를 테스트합니다.
  2. 더 신뢰할 수 있는 신호를 생성하기 위해 지원 지표를 추가합니다. 예를 들어 볼륨, 변동성 메트릭.
  3. 다른 스톱 러스 기술을 탐구합니다.
  4. 변화하는 시장 역동성에 적응할 수 있는 입시 규칙과 스톱 로스 매개 변수에 적응 능력을 구축합니다.
  5. 기계 학습 알고리즘을 통합하여 더 많은 역사적 데이터를 활용하여 매개 변수를 더 최적화합니다.

결론

요약하자면, 이중 이동 평균 역전 전략은 매우 실용적인 접근법이다. 이는 상류 추세와 결합된 이동 평균 분석을 사용하여 지속적인 상승 추세 동안 수익성있는 회귀 추세를 가능하게합니다. 또한 시장 체제 탐지 기능과 위험 통제를 제공합니다. 지속적인 향상으로 전략은 차별화된 성과를 낼 수있는 강력한 잠재력을 제공합니다.


/*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






더 많은