이동 평균 교차 추세 전략


생성 날짜: 2023-10-27 16:19:00 마지막으로 수정됨: 2023-10-27 16:19:00
복사: 0 클릭수: 662
avatar of ChaoZhang ChaoZhang
1
집중하다
1617
수행원

이동 평균 교차 추세 전략

개요

이동 평균 크로스 전략 (영어: Moving average cross strategy) 은 쌍 이동 평균의 교차 신호를 사용하여 트렌드 방향을 판단하여 구매 및 판매 신호를 생성하는 모멘텀 전략이다. 이 전략은 2개의 간단한 이동 평균과 1개의 지수 이동 평균을 사용하여, 그들의 교차 상황에 따라 다리가 있다고 판단하며, 중단기 거래 전략에 속한다.

전략 원칙

이 전략은 3가지 이동 평균을 사용합니다.

  • EMA1: 단기적인 지수 이동 평균, 즉 빠른 선
  • SMA1: 느린 선을 나타내는 더 긴 기간의 간단한 이동 평균
  • SMA2: 트렌드 방향을 판단하는 더 긴 기간의 간단한 이동 평균

전략은 EMA1, SMA1, SMA2의 크기와 관계를 통해 트렌드를 판단합니다.

  • 상승 추세: EMA1 > SMA1 > SMA2
  • 하향 추세: EMA1 < SMA1 < SMA2

입력 신호:

  • “다중 접속: 빠른 선에서 느린 선을 통과할 때 더 많이 해라”
  • 공백으로 들어갑니다: 빠른 선 아래의 느린 선을 통과할 때 공백을 둡니다.

출구 신호:

  • 많은 사람들이 탈퇴했다: 빠른 선 아래에서 느린 선을 통과할 때 평정
  • 빈 머리로 탈퇴: 빠른 선에서 느린 선을 통과할 때 평지

이 전략은 여러 가지 변수 구성을 제공하며, 진입과 퇴출을 판단하기 위해 다른 이동 평균을 선택할 수 있습니다.

우위 분석

이 전략은 다음과 같은 장점을 가지고 있습니다.

  1. 모멘텀 캡처 (Capture Momentum): 시장의 변화와 동향을 캡처하는 전략
  2. 유연한 구성: 다양한 이동 평균 옵션을 제공하여 유연하게 구성할 수 있습니다.
  3. 트렌드 필터링: 트렌드 방향을 판단하기 위해 긴 주기 이동 평균을 사용하여 역동 거래를 피합니다.
  4. 리스크 관리: 단편 거래의 위험을 제어하기 위해 중지 및 정지를 구성할 수 있습니다.

위험 분석

이 전략에는 다음과 같은 위험도 있습니다.

  1. 위프사우스 (whipsaws): 여러번의 가짜 돌파구로 인해 돌파구에 도달하기 전에 계속되는 흔들림이 발생할 수 있습니다.
  2. sensitive to MA parameters: 이동 평균 파라미터 설정이 잘못되면 너무 자주 또는 민감하지 않을 수 있습니다.
  3. lagging: 이동 평균은 본질적으로 지연성이 있으며, 가장 좋은 시점을 놓칠 수 있습니다.
  4. no fundamentals: 기초적인 것을 고려하지 않고 기술적인 지표로만 움직입니다.

위프사우스 위험에는 이동 평균 주기를 적절하게 조정할 수 있습니다. 매개 변수에 민감한 위험에는 매개 변수를 최적화 할 수 있습니다. 지연 위험에는 다른 선행 지표와 함께 최적화 할 수 있습니다.

최적화 방향

이 전략은 다음과 같은 부분에서 최적화될 수 있습니다.

  1. 다른 기술 지표 필터, 예를 들어 RSI, 브린 밴드 등이 추가되어 신호 품질이 향상됩니다.
  2. 이동 평균 주기 변수를 최적화하여 최적의 변수를 찾습니다.
  3. 트렌드를 판단하고 신호 신뢰성을 판단하는 기계 학습 모형을 추가합니다.
  4. 거래량과 결합하여 낮은 양의 가격에서 가짜 돌파구를 피하십시오.
  5. 기본적 요소와 결합하여 역경제적 거래를 피하십시오.

요약하다

이동 평균 경로 전략은 전반적으로 간단하고 직접적이며, 빠른 속도 평균 경로의 경로로 트렌드 방향과 참여 시간을 결정한다. 이 전략의 장점은 Momentum를 잡을 수 있고, 유연한 구성 파라미터를 사용할 수 있지만, 특정 휘파람 위험, 지연 위험 등의 문제가 있습니다. 다른 지표를 도입하여 필터링 최적화를 수행하면 이 전략은 매우 실용적인 정량 거래 전략이 될 수 있습니다.

전략 소스 코드
/*backtest
start: 2023-09-26 00:00:00
end: 2023-10-26 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/
// © Decam9

//@version=5
strategy(title = "Moving Average Crossover", shorttitle = "MA Crossover Strategy", overlay=true,
     initial_capital = 100000,default_qty_type = strategy.percent_of_equity, default_qty_value = 10)

//Moving Average Inputs
EMA1 = input.int(title="Fast EMA", group = "Moving Averages:", 
     inline = "EMAs", defval=5, minval = 1)
isDynamicEMA = input.bool(title = "Dynamic Exponential Moving Average?", defval = true,
     inline = "EMAs", group = "Moving Averages:", tooltip = "Changes the source of the MA based on trend")

SMA1 = input.int(title = "Slow SMA", group = "Moving Averages:",
     inline = "SMAs", defval = 10, minval = 1)
isDynamicSMA = input.bool(title = "Dynamic Simple Moving Average?", defval = false,
     inline = "SMAs", group = "Moving Averages:", tooltip = "Changes the source of the MA based on trend")

SMA2 = input.int(title="Trend Determining SMA", group = "Moving Averages:",
     inline = "MAs", defval=13, minval = 1)

//Moving Averages
Trend = ta.sma(close, SMA2)
Fast = ta.ema(isDynamicEMA ? (close > Trend ? low : high) : close, EMA1)
Slow = ta.sma(isDynamicSMA ? (close > Trend ? low : high) : close, SMA1)

//Allowed Entries
islong = input.bool(title = "Long", group = "Allowed Entries:",
     inline = "Entries",defval = true)
isshort = input.bool(title = "Short", group = "Allowed Entries:",
     inline = "Entries", defval= true)

//Entry Long Conditions
buycond = input.string(title="Buy when", group = "Entry Conditions:", 
     inline = "Conditions",defval="Fast-Slow Crossing", 
     options=["Fast-Slow Crossing", "Fast-Trend Crossing","Slow-Trend Crossing"])
     
intrendbuy = input.bool(title = "In trend", defval = true, group = "Entry Conditions:",
     inline = "Conditions", tooltip = "In trend if price is above SMA 2")

//Entry Short Conditions
sellcond = input.string(title="Sell when", group = "Entry Conditions:", 
     inline = "Conditions2",defval="Fast-Slow Crossing", 
     options=["Fast-Slow Crossing", "Fast-Trend Crossing","Slow-Trend Crossing"])
     
intrendsell = input.bool(title = "In trend",defval = true, group = "Entry Conditions:",
     inline = "Conditions2", tooltip = "In trend if price is below SMA 2?")

//Exit Long Conditions
closebuy = input.string(title="Close long when", group = "Exit Conditions:", 
     defval="Fast-Slow Crossing", options=["Fast-Slow Crossing", "Fast-Trend Crossing","Slow-Trend Crossing"])

//Exit Short Conditions
closeshort = input.string(title="Close short when", group = "Exit Conditions:", 
     defval="Fast-Slow Crossing", options=["Fast-Slow Crossing", "Fast-Trend Crossing","Slow-Trend Crossing"])
     

//Filters
filterlong =input.bool(title = "Long Entries", inline = 'linefilt', group = 'Apply Filters to', 
     defval = true)
filtershort =input.bool(title = "Short Entries", inline = 'linefilt', group = 'Apply Filters to', 
     defval = true)
filterend =input.bool(title = "Exits", inline = 'linefilt', group = 'Apply Filters to', 
     defval = true)
usevol =input.bool(title = "", inline = 'linefiltvol', group = 'Relative Volume Filter:', 
     defval = false)
rvol = input.int(title = "Volume >", inline = 'linefiltvol', group = 'Relative Volume Filter:', 
     defval = 1)
len_vol = input.int(title = "Avg. Volume Over Period", inline = 'linefiltvol', group = 'Relative Volume Filter:', 
     defval = 30, minval = 1,
     tooltip="The current volume must be greater than N times the M-period average volume.")
useatr =input.bool(title = "", inline = 'linefiltatr', group = 'Volatility Filter:', 
     defval = false)
len_atr1 = input.int(title = "ATR", inline = 'linefiltatr', group = 'Volatility Filter:', 
     defval = 5, minval = 1)
len_atr2 = input.int(title = "> ATR", inline = 'linefiltatr', group = 'Volatility Filter:', 
     defval = 30, minval = 1,
     tooltip="The N-period ATR must be greater than the M-period ATR.")
usersi =input.bool(title = "", inline = 'linersi', group = 'Overbought/Oversold Filter:', 
     defval = false)
rsitrhs1 = input.int(title = "", inline = 'linersi', group = 'Overbought/Oversold Filter:', 
     defval = 0, minval=0, maxval=100)
rsitrhs2 = input.int(title = "< RSI (14) <", inline = 'linersi', group = 'Overbought/Oversold Filter:', 
     defval = 100, minval=0, maxval=100,
     tooltip="RSI(14) must be in the range between N and M.")
issl =  input.bool(title = "SL", inline = 'linesl1', group = 'Stop Loss / Take Profit:', 
     defval = false)
slpercent =  input.float(title = ", %", inline = 'linesl1', group = 'Stop Loss / Take Profit:', 
     defval = 10, minval=0.0)
istrailing =  input.bool(title = "Trailing", inline = 'linesl1', group = 'Stop Loss / Take Profit:', 
     defval = false)
istp =  input.bool(title = "TP", inline = 'linetp1', group = 'Stop Loss / Take Profit:', 
     defval = false)
tppercent =  input.float(title = ", %", inline = 'linetp1', group = 'Stop Loss / Take Profit:', 
     defval = 20)
     
//Conditions for Crossing
fscrossup = ta.crossover(Fast,Slow)
fscrossdw = ta.crossunder(Fast,Slow)
ftcrossup = ta.crossover(Fast,Trend)
ftcrossdw = ta.crossunder(Fast,Trend)
stcrossup = ta.crossover(Slow,Trend)
stcrossdw = ta.crossunder(Slow,Trend)

//Defining in trend
uptrend = Fast >= Slow and Slow >= Trend
downtrend = Fast <= Slow and Slow <= Trend
justCrossed = ta.cross(Fast,Slow) or ta.cross(Slow,Trend)


//Entry Signals
crosslong = if intrendbuy
    (buycond =="Fast-Slow Crossing" and uptrend ? fscrossup:(buycond =="Fast-Trend Crossing" and uptrend ? ftcrossup:(buycond == "Slow-Trend Crossing" and uptrend ? stcrossup : na))) 
else
    (buycond =="Fast-Slow Crossing"?fscrossup:(buycond=="Fast-Trend Crossing"?ftcrossup:stcrossup))

crossshort = if intrendsell
    (sellcond =="Fast-Slow Crossing" and downtrend ? fscrossdw:(sellcond =="Fast-Trend Crossing" and downtrend ? ftcrossdw:(sellcond == "Slow-Trend Crossing" and downtrend ? stcrossdw : na))) 
else
    (sellcond =="Fast-Slow Crossing"?fscrossdw:(buycond=="Fast-Trend Crossing"?ftcrossdw:stcrossdw))
crossexitlong = (closebuy =="Fast-Slow Crossing"?fscrossdw:(closebuy=="Fast-Trend Crossing"?ftcrossdw:stcrossdw))
crossexitshort = (closeshort =="Fast-Slow Crossing"?fscrossup:(closeshort=="Fast-Trend Crossing"?ftcrossup:stcrossup))


// Filters
rsifilter = usersi?(ta.rsi(close,14) > rsitrhs1 and ta.rsi(close,14) < rsitrhs2):true
volatilityfilter = useatr?(ta.atr(len_atr1) > ta.atr(len_atr2)):true
volumefilter = usevol?(volume > rvol*ta.sma(volume,len_vol)):true
totalfilter = volatilityfilter and volumefilter and rsifilter

//Filtered signals
golong  = crosslong  and islong  and (filterlong?totalfilter:true) 
goshort = crossshort and isshort and (filtershort?totalfilter:true)
endlong  = crossexitlong and (filterend?totalfilter:true)
endshort = crossexitshort and (filterend?totalfilter:true)

// Entry price and TP
startprice = ta.valuewhen(condition=golong or goshort, source=close, occurrence=0)
pm = golong?1:goshort?-1:1/math.sign(strategy.position_size)
takeprofit = startprice*(1+pm*tppercent*0.01)
// fixed stop loss
stoploss = startprice * (1-pm*slpercent*0.01)
// trailing stop loss
if istrailing and strategy.position_size>0
    stoploss := math.max(close*(1 - slpercent*0.01),stoploss[1])
else if istrailing and strategy.position_size<0
    stoploss := math.min(close*(1 + slpercent*0.01),stoploss[1])
    
if golong and islong
    strategy.entry("long",   strategy.long )
if goshort and isshort
    strategy.entry("short",  strategy.short)
if endlong
    strategy.close("long")
if endshort
    strategy.close("short")

// Exit via SL or TP
strategy.exit(id="sl/tp long", from_entry="long", stop=issl?stoploss:na, 
              limit=istp?takeprofit:na)
strategy.exit(id="sl/tp short",from_entry="short",stop=issl?stoploss:na, 
              limit=istp?takeprofit:na)