이중 이동 평균 크로스오버 거래 전략

저자:차오장, 날짜: 2023-10-13 15:40:49
태그:

전반적인 설명

이중 이동 평균 크로스오버 거래 전략은 서로 다른 매개 변수 설정을 가진 두 개의 이동 평균을 계산하고 이동 평균이 교차 할 때 거래함으로써 거래 신호를 생성합니다. 이 간단하고 직설적인 전략은 중장기 거래에 적합합니다.

전략 논리

이 전략의 핵심 논리는 다음과 같습니다.

  1. 입력 매개 변수: 빠른 MA 기간 maLen1, 느린 MA 기간 maLen2, MA 유형 maTypeChoice

  2. 입력 매개 변수에 기초하여 더 빠른 MA maValue1 및 더 느린 MA maValue2를 계산합니다.

  3. 두 MA를 비교하여 구매 및 판매 조건을 정의합니다.

    • maValue1가 maValue2를 넘을 때 구매

    • maValue1이 maValue2보다 낮을 때 판매

  4. 구매 및 판매 신호로 거래를 실행

  5. 관계에 따라 다른 색으로 MA를 시각화

  6. 구매 및 판매 경고 신호를 보내

장점

  • 듀얼 MA 크로스오버 시스템을 사용 하 여 단일 MA에서 잘못된 신호를 피합니다.

  • 사용자 정의 가능한 MA 기간은 다른 거래 지평선에 적합합니다.

  • 단순하고 직설적인 논리, 이해하기 쉽고 실행하기 쉬운

  • 적시 실행을 위해 사용자 정의 가능한 신호 알림

  • 시각화 된 MA 트렌드는 직관적인 거래 지표를 형성합니다.

  • 최적화 가능한 매개 변수

  • 백테스팅 및 라이브 거래에 적용됩니다.

위험성

  • MA 교차는 잘못된 신호를 생성 할 수 있으며 추가 트렌드 및 패턴 확인이 필요합니다.

  • MA의 크로스오버에 대한 윙사 (Whipsaws) 는 불필요한 거래 비용을 초래합니다.

  • 부적절한 매개 변수들은 과도한 거래 또는 희박한 거래로 이어집니다.

  • 극단적 인 사건 은 엄청난 가격 변동 을 초래 하며 손실 을 제한 할 수 없다

  • 장기적인 트렌드 중단은 단기 지표를 무효화합니다.

  • 빈번한 모니터링이 필요하고 완전히 자동화 할 수 없습니다.

위험 관리:

  • 트렌드 필터를 추가하여 트렌드 상거래를 피합니다.

  • 신호 유효성을 확인하기 위해 패턴 필터를 추가합니다

  • 합리적인 거래 빈도를 위한 매개 변수를 최적화

  • 손실을 제한하기 위해 스톱 로스/이익을 설정

  • 긴 시간 프레임에 대한 견고성 테스트

  • 가짜 파장을 방지하기 위한 가격 및 시간 필터

최적화 방향

  • 최적을 찾기 위해 다른 MA 매개 변수를 테스트합니다.

  • 가장 정확한 신호를 위해 다른 MA 유형을 테스트합니다.

  • 트렌드 필터를 추가하여 트렌드 반대 거래를 피합니다.

  • 적절한 출구 지점을 식별하기 위해 변동성 필터를 추가합니다.

  • 잘못된 신호를 줄이기 위해 가격/시간 필터를 추가합니다.

  • 실제 거래에 대한 미끄러짐 통제를 구현

  • 기기 및 시간 프레임에 걸쳐 견고성 테스트

  • 자동 중지 손실/이익을 통합

  • 전략을 개선하기 위해 기계 학습을 탐구

결론

이중 이동 평균 크로스오버 (Dual Moving Average Crossover) 는 고전적인 기술 지표 전략이다. 그것은 MA 크로스로부터 신호를 생성하고 최적화를 통해 좋은 백테스트 결과를 생성할 수 있다. 그러나 잘못된 신호와 같은 위험이 남아 추가 필터를 필요로 한다. 실제 거래는 또한 미끄러짐 제어와 같은 실행 세부 사항이 필요하다. 전반적으로, 전략은 중장기 거래에 간단하고 직관적인 선택으로 적합하다. 지속적인 개선과 견고성 검증으로, 이 전략은 라이브 거래에서 안정적인 수익을 얻을 수 있다.


/*backtest
start: 2023-10-05 00:00:00
end: 2023-10-05 22:00:00
period: 15m
basePeriod: 5m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
// © sehweijun
//study( title="Arch1tect's New Toy", shorttitle="Arch1tect's New Toy", overlay=true, resolution="")
// strategy( title="Arch1tect's New Toy (Strategy Tester Version)", shorttitle="Arch1tect's New Toy (Strategy Tester Version)", overlay=true, initial_capital = 100000, commission_value=0.07, commission_type=strategy.commission.cash_per_contract)

maTypeChoice = input( "EMA", title="MA Type", options=["EMA", "WMA", "SMA"] )
maSrc = input( close, title="MA Source" )
maLen1 = input( 15, minval=1, title="MA Length" )
maLen2 = input( 95, minval=1, title="MA Length" )

maValue1 = if ( maTypeChoice == "EMA" )
    ema( maSrc, maLen1 )
else if ( maTypeChoice == "WMA" )
    wma( maSrc, maLen1 )
else if ( maTypeChoice == "SMA" )
    sma( maSrc, maLen1 )
else
    0
    
maValue2 = if ( maTypeChoice == "EMA" )
    ema( maSrc, maLen2 )
else if ( maTypeChoice == "WMA" )
    wma( maSrc, maLen2 )
else if ( maTypeChoice == "SMA" )
    sma( maSrc, maLen2 )
else
    0

buySignal = crossover( maValue1, maValue2 )
sellSignal = crossunder( maValue1, maValue2 )

mainMAColour = ( maValue1 > maValue2 ) ? color.green : color.red 

plot( maValue1, title="Arch1tect's New Toy", color=mainMAColour, offset=0, linewidth=4 )
//plot( maValue2, title="Arch1tect's Filter", color=color.black, offset=0, linewidth=2 )

var color buyCandleColour = #00ff0a
var color sellCandleColour = #ff1100

barcolor( buySignal ? buyCandleColour : sellSignal ? sellCandleColour : na, title="Signal Bar Colour" )
bgcolor( color=buySignal ? buyCandleColour : sellSignal ? sellCandleColour : na, transp=85, title="Signal Background Colour")

alertcondition( buySignal or sellSignal, title="Signal change!", message="Signal change!")
alertcondition( buySignal, title="Buy signal!", message="Buy signal!")
alertcondition( sellSignal, title="Sell signal!", message="Sell signal!")

// Strategy Tester
stratTesterOn    = input( title="Strategy Tester [ON/OFF]", group="Strategy Tester", type=input.bool, defval=true)
entryTime        = input( "2200-1200", title = "Daily trading time session (in Exchange GMT)", group="Strategy Tester", type = input.session )
startTime        = input( "2200-2201", title = "Start Time", group="Strategy Tester", type = input.session )
maxDailyLoss     = input( 2500, title = "Max daily loss", group="Strategy Tester", type = input.integer )
maxTotalDrawdown = input( 12000, title = "Max daily loss", group="Strategy Tester", type = input.integer )
contractSize     = input( 1, title = "Contract size", group="Strategy Tester", type = input.integer )

tradeOnStartSess = input( title="First trade on session start [ON/OFF]", group="Strategy Tester", type=input.bool, defval=true)

fixedTPSL        = input( title="Fixed TP/SL PIPS [ON/OFF]", group="Strategy Tester", type=input.bool, defval=false)
fixedTPValue     = input ( 10.00, minval=0.01, type=input.float, title="TP", group="Strategy Tester" )
fixedSLValue     = input ( 10.00, minval=0.01, type=input.float, title="SL", group="Strategy Tester" )

fromDay          = input(defval = 1,    title = "From Day", group="Date Range", type = input.integer, minval = 1, maxval = 31)
fromMonth        = input(defval = 1,    title = "From Month", group="Date Range", type = input.integer, minval = 1, maxval = 12)
fromYear         = input(defval = 2020, title = "From Year", group="Date Range", type = input.integer, minval = 1970)
thruDay          = input(defval = 1,    title = "Thru Day", group="Date Range", type = input.integer, minval = 1, maxval = 31)
thruMonth        = input(defval = 1,    title = "Thru Month", group="Date Range", type = input.integer, minval = 1, maxval = 12)
thruYear         = input(defval = 2112, title = "Thru Year", group="Date Range", type = input.integer, minval = 1970)

start     = timestamp(fromYear, fromMonth, fromDay, 00, 00)        // backtest start window
finish    = timestamp(thruYear, thruMonth, thruDay, 23, 59)        // backtest finish window
window()  => time >= start and time <= finish ? true : false       // create function "within window of time"

// strategy.risk.max_intraday_loss( maxDailyLoss, strategy.cash )
// strategy.risk.max_drawdown( maxTotalDrawdown, strategy.cash )

isTime(_position) =>
    range = time( timeframe.period, _position + ':1234567' )
bgcolor( color=isTime( entryTime ) and stratTesterOn and window() ? color.yellow : na, title="Daily trading time session (in Exchange GMT)", transp=75 )

if ( stratTesterOn and window() )
    if ( buySignal and isTime( entryTime ) )
        if ( not fixedTPSL )
            strategy.close_all()
            strategy.entry( "Buy", strategy.long, contractSize )
        
        if ( fixedTPSL and strategy.position_size == 0 )
            strategy.entry( "Buy", strategy.long, contractSize )
            strategy.exit( "TP/SL", "Buy", stop=close[0]-fixedSLValue, limit=close[0]+fixedTPValue )
        
    if ( sellSignal and isTime( entryTime ))
        if ( not fixedTPSL )
            strategy.close_all()
            strategy.entry( "Sell", strategy.short, contractSize )
        
        if ( fixedTPSL and strategy.position_size == 0  )
            strategy.entry( "Sell", strategy.short, contractSize )
            strategy.exit( "TP/SL", "Sell", stop=close[0]+fixedSLValue, limit=close[0]-fixedTPValue )
    
    if ( isTime( startTime ) and tradeOnStartSess and strategy.position_size == 0 )
        if ( maValue1 > maValue2 )
            strategy.entry( "Buy", strategy.long, contractSize )
            
            if ( fixedTPSL )
                strategy.exit( "TP/SL", "Buy", stop=close[0]-fixedSLValue, limit=close[0]+fixedTPValue )
        else
            strategy.entry( "Sell", strategy.short, contractSize ) 
            
            if ( fixedTPSL )
                strategy.exit( "TP/SL", "Sell", stop=close[0]+fixedSLValue, limit=close[0]-fixedTPValue )
    
    strategy.close_all( when=not isTime( entryTime ) )

plot( strategy.equity )

더 많은