모멘텀 이동 평균 크로스오버 전략

저자:차오장, 날짜: 2023-09-21 21:29:22
태그:

전반적인 설명

이 전략은 시장 트렌드 방향을 결정하고 구매 및 판매 신호를 생성하기 위해 빠르고 느린 이동 평균 사이의 교차 원칙을 활용합니다. 전략은 간단하고 구현하기 쉽고 중장기 거래에 적합합니다.

전략 논리

이 전략은 두 개의 이동 평균, 한 개의 빠른 라인 및 한 개의 느린 라인을 사용합니다. 빠른 라인은 3 일간의 EMA를 사용하고 느린 라인은 15 일간의 EMA를 사용합니다. 빠른 라인이 아래에서 느린 라인의 위를 넘을 때 상승 추세를 나타내고 구매 신호를 제공합니다. 반대로 빠른 라인이 위에서 느린 라인의 아래를 넘을 때 하락 추세를 나타내고 판매 신호를 제공합니다.

이 전략은 또한 빠른 출구선으로 더 빠른 3일 EMA를 설정합니다. 가격이 이 빠른 출구선 아래로 넘어갈 때, 트렌드가 역전되었다고 판단하고 기존의 긴 포지션을 빠져나가야 합니다. 마찬가지로, 가격이 출구선 위에 다시 넘어갈 때, 그것은 새로운 상승 추세를 나타내고 다시 긴 진입 신호를 제공합니다.

특정 작동 신호는 다음과 같이 설정됩니다.

  1. 빠른 선은 아래에서 느린 선의 위를 가로지르며, 길게 이동합니다.

  2. 빠른 선이 아래를 가로질러 느린 선이 위에서, 단축

  3. 빠른 출구선 아래로 가격 파업, 긴 포지션을 닫습니다.

  4. 가격이 빠른 출구선 위에 다시 돌파하고, 다시 긴

장점

  • 사용하기 간단, 단지 두 이동 평균 매개 변수를 구성해야 합니다, 구현하기 쉽습니다

  • 충분한 백트테스팅 데이터, 실행 가능성을 평가하기 위해 공통 지표를 사용합니다.

  • 최적화를 위한 많은 구성 가능한 매개 변수

  • 빠른 출구 라인을 스톱 로스로 채택하여 위험을 더 잘 제어합니다.

  • 명확한 전략 논리, 명확한 구매 및 판매 신호

  • 적절한 운영 빈도, 과잉 거래 방지

위험성

  • 트렌드가 명확하지 않은 경우 트렌드를 따르는 전략보다 더 많은 잘못된 신호에 유연합니다.

  • 이동 평균은 지연적인 성격을 가지고 있으며 전환점을 놓칠 수 있습니다.

  • 고정된 매개 변수는 시장 변화에 적응할 수 없으며 최적화가 필요합니다.

  • 손실 중지 너무 부드럽고 시간에 손실을 중지 할 수 없습니다

  • 빈번한 신호는 더 높은 거래 비용으로 이어질 수 있습니다.

  • 신호는 다른 신호와 일치하지 않을 수 있습니다.

위험은 매개 변수 최적화, 필터 추가, 휴식 스톱 손실, 매개 변수 적시에 업데이트 등을 통해 관리 될 수 있습니다.

강화

  • 시장 조건에 더 잘 맞도록 매개 변수를 테스트하고 최적화합니다.

  • 강력한 시스템을 형성하기 위해 더 많은 지표를 도입

  • 실시간 시장에 기반한 적응 파라미터 설정을 구축

  • 더 똑똑한 최적화를 위해 기계 학습 모델을 적용

  • 더 나은 위험 통제를 위해 동적 또는 후속 스톱 손실을 설정

  • 분리를 피하기 위해 부피 지표를 결합합니다.

결론

이 전략은 비교적 간단한 이중 이동 평균 크로스오버 전략이다. 빠른 이동 평균과 느린 이동 평균의 상호 작용을 기반으로 시장 추세와 거래 신호를 결정한다. 전략은 구현하기 쉽고 최적화를 통해 적응할 수 있다. 그러나 또한 약간의 위험이 있다. 신호를 확인하고 위험을 관리하기 위해 더 많은 필터가 필요하다. 적절하게 최적화되고 중장기 거래에 적용되면 매우 실용적인 양적 거래 시스템으로 변할 수 있다.


/*backtest
start: 2023-01-01 00:00:00
end: 2023-02-03 00:00:00
period: 1d
basePeriod: 1h
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/
// © ehaarjee, ECHKAY, JackBauer007

//@version=4
//study(title="Tale_indicators", overlay=true)
strategy("Tale Indicators Strategy", overlay=true, precision=8, max_bars_back=200, pyramiding=0, initial_capital=20000, commission_type="percent", commission_value=0.1)

len_fast = input(3, minval=1, title="FAST EMA")
src_fast = input(close, title="Source for Fast")
fastMA = ema(src_fast, len_fast)
plot(fastMA, title="Slow EMA", color=color.orange)

len_slow = input(15, minval=1, title="SLOW EMA")
src_slow = input(close, title="Source for Slow")
slowMA = ema(src_slow, len_slow)
plot(slowMA, title="Fast EMA", color=color.blue)

len_fast_exit = input(3, minval=1, title="FAST EMA Exit")
src_fast_exit = input(close, title="Source for Fast Exit")
fastMAE = ema(src_fast_exit, len_fast_exit)
plot(fastMAE, title="Fast EMA Ex", color=color.red)


src_slow_enter_short = input(low, title="Source for Short Entry")
slowMASEn = ema(src_slow_enter_short, len_slow)

src_slow_enter_long = input(high, title="Source for Long Entry")
slowMALEn = ema(src_slow_enter_long, len_slow)

src_slow_exit_short = input(low, title="Source for Short Exit")
slowMASEx = ema(src_slow_enter_short, len_slow)

src_slow_exit_long = input(high, title="Source for Long Exit")
slowMALEx = ema(src_slow_enter_long, len_slow)

enter_long = crossover(fastMA, slowMALEn)
enter_short = crossunder(fastMA, slowMASEn)
exit_long = crossunder(fastMAE, slowMALEx)
exit_short = crossover(fastMAE, slowMALEx)

out_enter = iff(enter_long == true, 1, iff(enter_short == true, -1, 0))
plotarrow(out_enter, "Plot Enter Points", colorup=color.green, colordown=color.red, maxheight = 30)

bull = fastMA > slowMALEn
bear = fastMA < slowMASEn

c = bull ? color.green : bear ? color.red  : color.white
bgcolor(c)

exit_tuner = input(0.005, title="Exit Tuner to touch slowEMA")

bull_exit = (bull and (low>(fastMAE*(1+exit_tuner)))) or exit_long or (not(bear) and (fastMAE>high))
bear_exit = (bear and ((fastMAE*(1-exit_tuner))>high)) or exit_short or (not(bull) and (low>fastMAE))

bull_r = (bull and ((bull_exit[1]) or (bull_exit[2] and bull_exit[1])) and (low<=fastMAE))
bear_r = (bear and ((bear_exit[1]) or (bull_exit[2] and bull_exit[1])) and (fastMAE<=high))

bull_re = (bull and (low<slowMALEn)) and not(enter_long)
bear_re = (bear and (high>slowMASEn)) and not(enter_short)

bull_ree = (bull and ((low<slowMALEn) and not(bull_re[1] or enter_long[1]))) 
bear_ree = (bear and ((high>slowMASEn) and not(bear_re[1] or enter_short[1])))

bull_reenter =  (bull_r) and not(enter_long)
bear_reenter =  (bear_r) and not(enter_short)

plotshape(bull_exit, "Plot Bull Exit", style = shape.arrowdown, color=color.green, size=size.small, text="ExL", location=location.abovebar)
plotshape(bear_exit, "Plot Bear Exit", style = shape.arrowup, color=color.red, size=size.small, text="ExS", location=location.belowbar)

plotshape(bull_reenter, "Plot Bull ReEnter", style = shape.arrowup, color=color.green, size=size.small, text="ReL", location=location.belowbar)
plotshape(bear_reenter, "Plot Bear ReEnter", style = shape.arrowdown, color=color.red, size=size.small, text="ReS", location=location.abovebar)

run_strategy = input(true, title="Run Strategy")
// === INPUT BACKTEST RANGE ===
fromMonth = input(defval = 1,    title = "From Month",      type = input.integer, minval = 1, maxval = 12)
fromDay   = input(defval = 1,    title = "From Day",        type = input.integer, minval = 1, maxval = 31)
fromYear  = input(defval = 2020, title = "From Year",       type = input.integer, minval = 2000)
thruMonth = input(defval = 1,    title = "Thru Month",      type = input.integer, minval = 1, maxval = 12)
thruDay   = input(defval = 1,    title = "Thru Day",        type = input.integer, minval = 1, maxval = 31)
thruYear  = input(defval = 2100, title = "Thru Year",       type = input.integer, minval = 2000)

// === INPUT SHOW PLOT ===
showDate  = input(defval = true, title = "Show Date Range", type = input.bool)
// === FUNCTION EXAMPLE ===
start     = timestamp(fromYear, fromMonth, fromDay, 00, 00)        // backtest start window
finish    = timestamp(thruYear, thruMonth, thruDay, 23, 59)        // backtest finish window
window()  => true       // create function "within window of time"

var long_position_open = false
var short_position_open = false


if (enter_long and not(bull_exit) and not(long_position_open))
//    strategy.entry("LO", strategy.long, qty=4)
    long_position_open := true
    if (short_position_open)
//        strategy.close("SO")
        short_position_open := false

if (bull_reenter and not(long_position_open))  
//    strategy.entry("LO", strategy.long, qty=1)
    long_position_open := true

if (bull_exit and long_position_open)
//  strategy.close("LO")
    long_position_open := false
    
if (enter_short and not(bear_exit) and not(short_position_open))
//    strategy.entry("SO", strategy.short, qty=4)
    short_position_open := true
    if(long_position_open)
//        strategy.close("LO")
        long_position_open := false

if (bear_reenter and not(short_position_open))  
//    strategy.entry("SO", strategy.long, qty=1)
    long_position_open := true

if (bear_exit and short_position_open)
//    strategy.close("SO")
    short_position_open := false

if(run_strategy)
    strategy.entry("LO", strategy.long, when=(window() and enter_long), qty=4)
    strategy.entry("LO", strategy.long, when=(window() and bull_reenter and not(long_position_open)), qty=1)
    strategy.close("LO", when=(window() and bull_exit and long_position_open))
    strategy.entry("SO", strategy.short, when=(window() and enter_short), qty=4)
    strategy.entry("SO", strategy.short, when=(window() and bear_reenter and not(short_position_open)), qty=1)
    strategy.close("SO", when=(window() and bear_exit and short_position_open))


더 많은