다중 기간 SMA 지표를 기반으로 한 추세 추종 전략


생성 날짜: 2024-02-04 14:50:24 마지막으로 수정됨: 2024-02-04 14:50:24
복사: 0 클릭수: 680
avatar of ChaoZhang ChaoZhang
1
집중하다
1617
수행원

다중 기간 SMA 지표를 기반으로 한 추세 추종 전략

개요

이 전략은 여러 개의 다른 기간의 SMA 평균을 조합하여 트렌드를 판단하고 추적합니다. 핵심 아이디어는 다음과 같습니다. 다른 기간의 SMA의 상승과 하락 방향을 비교하여 트렌드를 판단합니다. 짧은 기간의 SMA에서 더 긴 기간의 SMA를 밟을 때, 더 많이하십시오.

전략 원칙

  1. 5개의 다른 주기의 SMA 평균선을 사용한다. 각각 10주기, 20주기, 50주기, 100주기 및 200주기이다.
  2. 이 5개의 평균선의 상승과 하락 방향을 비교하여 트렌드 방향을 판단한다. 예를 들어, 10주기, 20주기, 100주기 및 200주기 SMA 평균선이 동시에 상승하면 상승 트렌드로 판단한다. 평균선이 동시에 하락하면 하락 트렌드로 판단한다.
  3. 서로 다른 주기 SMA의 수치를 비교하여 거래 신호를 형성한다. 예를 들어, 10 주기 SMA 상에서 20 주기 SMA를 통과할 때 더 많이 하면 입문 신호를 형성한다. 10 주기 SMA 아래에서 20 주기 SMA를 통과할 때 공백을 하면 입문 신호를 형성한다.
  4. 진입 확인 및 출전 신호로 ZeroLagEMA를 사용한다. 빠른 주기 ZeroLagEMA에 서서히 진입할 때 더 많이 하고, 낮은 주기 평평할 때 더 많은 포지션을 한다. 공백 신호의 판단 방식은 반대로 있다.

전략적 이점

  1. 여러 개의 다른 주기 SMA 평균선 조합을 사용하여 시장 추세 방향을 효과적으로 판단 할 수 있습니다.
  2. 주기적 SMA 값의 비교는 거래 신호를 생성하여 입출금 규칙을 양성할 수 있다.
  3. 제로 라게마 (Zero LagEMA) 은 불필요한 거래를 방지하고 전략의 안정성을 향상시킵니다.
  4. 트렌드 판단과 거래 신호를 결합하여 트렌드 추적 거래가 가능합니다.

전략적 위험과 해결책

  1. 시장이 충격적인 정리 단계로 들어갔을 때, SMA 평균선 신호는 자주 교차할 수 있으며, 더 많은 무효 거래와 손실의 위험을 초래한다.
    • 해결 방법: 제로 라게마의 파수를 증가시켜 무효 신호의 입력을 방지한다.
  2. 더 많은 주기를 참고한 SMA를 기준으로, 신호가 다소 지연적이라고 판단하여, 단기간에 급격한 가격 변화에 대해 적시에 대응할 수 없다.
    • 해결 방법: MACD와 같은 더 민감한 지표와 결합하여 보조 판단.

전략 최적화 방향

  1. SMA 주기 변수를 최적화하여 최적의 변수 조합을 찾습니다.
  2. 단편적 손실을 더욱 통제하기 위해 단편적 손실을 추적하는 것과 같은 손실을 막는 전략을 추가하십시오.
  3. 포지션 수를 관리하는 메커니즘을 추가하여 전략이 강할 때 포지션을 늘리고, 흔들릴 때 포지션을 줄일 수 있도록 한다.
  4. 더 많은 보조 지표 판단과 함께 MACD, KDJ 등으로 전략의 전반적인 안정성을 향상시킵니다.

요약하다

이 전략은 여러 주기 SMA 평균선을 조합하여 시장 추세 방향에 대한 효과적인 판단을 구현하고 양적 거래 신호를 생성한다. 동시에, ZeroLagEMA의 응용은 전략의 순조율을 향상시킨다. 전반적으로, 전략은 추세 추적에 기반한 양적 거래 아이디어를 구현하고, 효과는 눈에 띄다.

전략 소스 코드
/*backtest
start: 2024-01-04 00:00:00
end: 2024-02-03 00:00:00
period: 2h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=2
strategy("Forex MA Racer - SMA Performance /w ZeroLag EMA Trigger", shorttitle = "FX MA Racer (5x SMA, 2x zlEMA)", overlay=false )

// === INPUTS ===
hr0             = input(defval = true, title = "=== SERIES INPUTS ===")
smaSource       = input(defval = close, title = "SMA Source")
sma1Length      = input(defval = 10, title = "SMA 1 Length")
sma2Length      = input(defval = 20, title = "SMA 2 Length")
sma3Length      = input(defval = 50, title = "SMA 3 Length")
sma4Length      = input(defval = 100, title = "SMA 4 Length")
sma5Length      = input(defval = 200, title = "SMA 5 Length")
smaDirSpan      = input(defval = 4, title = "SMA Direction Span")
zlmaSource      = input(defval = close, title = "ZeroLag EMA Source")
zlmaFastLength  = input(defval = 9, title = "ZeroLag EMA Fast Length")
zlmaSlowLength  = input(defval = 21, title = "ZeroLag EMA Slow Length")
hr1             = input(defval = true, title = "=== PLOT TIME LIMITER ===")
useTimeLimit    = input(defval = true, title = "Use Start Time Limiter?")
// set up where we want to run from
startYear       = input(defval = 2018, title = "Start From Year", minval = 0, step = 1)
startMonth      = input(defval = 02, title = "Start From Month", minval = 0,step = 1)
startDay        = input(defval = 01, title = "Start From Day", minval = 0,step = 1)
startHour       = input(defval = 00, title = "Start From Hour", minval = 0,step = 1)
startMinute     = input(defval = 00, title = "Start From Minute", minval = 0,step = 1)
hr2             = input(defval = true, title = "=== TRAILING STOP ===")
useStop     = input(defval = false, title = "Use Trailing Stop?")
slPoints    = input(defval = 200, title = "Stop Loss Trail Points", minval = 1)
slOffset    = input(defval = 400, title = "Stop Loss Trail Offset", minval = 1)
// === /INPUTS ===

// === SERIES SETUP ===
// Fast ZeroLag EMA
zema1=ema(zlmaSource, zlmaFastLength)
zema2=ema(zema1, zlmaFastLength)
d1=zema1-zema2
zlemaFast=zema1+d1

// Slow ZeroLag EMA
zema3=ema(zlmaSource, zlmaSlowLength)
zema4=ema(zema3, zlmaSlowLength)
d2=zema3-zema4
zlemaSlow=zema3+d2

// Simple Moving Averages
period10 = sma(close, sma1Length)
period20 = sma(close, sma2Length)
period50 = sma(close, sma3Length)
period100 = sma(close, sma4Length)
period200 = sma(close, sma5Length)
// === /SERIES SETUP ===

// === PLOT ===
// colors of plotted MAs
p1 = (close < period10) ? #FF0000 : #00FF00
p2 = (close < period20) ? #FF0000 : #00FF00
p3 = (close < period50) ? #FF0000 : #00FF00
p4 = (close < period100) ? #FF0000 : #00FF00
p5 = (close < period200) ? #FF0000 : #00FF00

plot(period10, title='10 Period', color = p1, linewidth=1)
plot(period20, title='20 Period', color = p2, linewidth=2)
plot(period50, title='50 Period', color = p3, linewidth=4)
plot(period100, title='100 Period', color = p4, linewidth=6)
plot(period200, title='200 Period', color = p5, linewidth=10)
// === /PLOT ===

//BFR = BRFIB ? (maFast+maSlow)/2 : abs(maFast - maSlow)

// === STRATEGY ===
// calculate SMA directions
direction10 = rising(period10, smaDirSpan) ? +1 : falling(period10, smaDirSpan) ? -1 : 0
direction20 = rising(period20, smaDirSpan) ? +1 : falling(period20, smaDirSpan) ? -1 : 0
direction50 = rising(period50, smaDirSpan) ? +1 : falling(period50, smaDirSpan) ? -1 : 0
direction100 = rising(period100, smaDirSpan) ? +1 : falling(period100, smaDirSpan) ? -1 : 0
direction200 = rising(period200, smaDirSpan) ? +1 : falling(period200, smaDirSpan) ? -1 : 0

// conditions
// SMA Direction Trigger
dirUp = direction10 > 0 and direction20 > 0 and direction100 > 0 and direction200 > 0
dirDn = direction10 < 0 and direction20 < 0 and direction100 < 0 and direction200 < 0

longCond = (period10>period20) and (period20>period50) and (period50>period100) and  dirUp//and (close > period10) and (period50>period100) //and (period100>period200)
shortCond = (period10<period20) and (period20<period50) and dirDn//and (period50<period100) and (period100>period200)

longExit = crossunder(zlemaFast, zlemaSlow) or crossunder(period10, period20)
shortExit = crossover(zlemaFast, zlemaSlow) or crossover(period10, period20)


// entries and exits
startTimeOk() =>
    // get our input time together
    inputTime   = timestamp(syminfo.timezone, startYear, startMonth, startDay, startHour, startMinute)
    // check the current time is greater than the input time and assign true or false
    timeOk      = time > inputTime ? true : false
    // last line is the return value, we want the strategy to execute if..
    // ..we are using the limiter, and the time is ok -OR- we are not using the limiter
    r = (useTimeLimit and timeOk) or not useTimeLimit


if( true )
    // entries
    strategy.entry("long", strategy.long, when = longCond)
    strategy.entry("short", strategy.short, when = shortCond)

        
    // trailing stop
    if (useStop)
        strategy.exit("XL", from_entry = "long", trail_points = slPoints, trail_offset = slOffset)
        strategy.exit("XS", from_entry = "short", trail_points = slPoints, trail_offset = slOffset)

    // exits
    strategy.close("long", when = longExit)
    strategy.close("short", when = shortExit)
// === /STRATEGY ===