모멘텀 존 ATR 역전 주문 양적 전략


생성 날짜: 2023-11-24 15:55:36 마지막으로 수정됨: 2023-11-24 15:55:36
복사: 0 클릭수: 646
avatar of ChaoZhang ChaoZhang
1
집중하다
1617
수행원

모멘텀 존 ATR 역전 주문 양적 전략

개요

이 전략의 주요 아이디어는 동력 영역과 ATR 지표를 결합하여 금 포크가 발생했을 때 더 많이하고, 죽은 포크가 발생했을 때 공백을 낸다. 동시에 중지 손실과 중지 가격을 설정한다. 가격이 반전 신호가 발생했을 때, 역으로 포지션을 열고, 반전 주문 기능을 구현한다.

원칙

  1. 빠른 EMA와 느린 EMA를 사용하여 다공 신호를 계산한다. 빠른 EMA가 느린 EMA보다 높으면 부진, 반대로 부진이다.
  2. 지점이 없을 때, 금강이 생기면 더 많이 하고, 죽은 이 생기면 공백하게 한다.
  3. 이미 포지션을 열었을 때, 반전 신호가 발생하면, 먼저 현재의 포지션을 평정하고, 반대 방향으로 새로운 포지션을 열립니다.
  4. ATR 지표를 사용하여 중지 및 중지 가격을 계산하십시오. 중지 가격은 ATR 통로에 따라 조정되며, 중지 위험이 작다는 것을 보장합니다.
  5. 가격이 오버 바이 오버 셀 영역에 들어갔을 때, K 라인의 마지막 K 라인의 최고 가격 또는 최저 가격으로 스톱 로스를 조정합니다.

장점

  1. 동력 영역과 ATR을 결합하여, 트렌드에 따라 상향상승을 할 수 있고, 또한 정시적으로 상쇄를 할 수 있다.
  2. 반전 주문 기능을 구현하여 가격 반전 시 빠르게 방향을 전환하여 가격의 양방향 변동을 최대한 활용하여 더 높은 수익을 얻을 수 있습니다.
  3. ATR 상쇄 메커니즘은 개별 상쇄 위험을 효과적으로 제어하여 전체적으로 높은 승률을 달성합니다.
  4. 이 경우, 과매매 판단과 함께, 갑작스러운 사건에 휘말리지 않도록 해야 합니다.

위험과 해결

  1. 역전 주문은 불안정한 상황에서 너무 자주 거래되어 거래 비용과 스톱 손실률을 증가시킬 수 있습니다.
    • 해결 방법: 최소 지분 기간을 늘리고, 불안정한 상황에서는 역전을 줄여라.
  2. ATR 값의 변화는 너무 큰 또는 너무 작은 중지 범위를 만들 수 있습니다.
    • 해결 방법: ATR 값에 따라 실시간으로 스탠드 거리 조정.
  3. 잘못된 매개 변수 설정으로 인해 거래 빈도가 너무 높거나 신호 효과는 떨어질 수 있습니다.
    • 해결 방법: 다양한 품종에 따라 합리적인 선택 파라미터 조합.

최적화 방향

  1. 최적화된 파라미터 설정을 통해 최적의 파라미터 조합을 찾습니다.
  2. 보조 기술 지표 필터링을 추가하여 신호 품질을 향상시킵니다.
  3. 재원 관리 모듈을 추가하여 포지션을 계좌 총 자산에 연결합니다.
  4. 시간 주기 분석을 추가하여 더 많은 정보를 활용하여 전략의 효과를 향상시킵니다.

요약하다

이 전략은 동력 구역과 ATR 지표의 장점을 통합하여 효율적인 쌍방향 거래를 구현한다. 반전 주문 메커니즘과 ATR 지능형 중지, 가격 변동을 최대한 활용할 수 있다. 최적화 파라미터 설정과 더 많은 지표의 결합은 전략의 효과를 더욱 향상시킬 수 있다. 이 전략은 고주파 쌍방향 거래에 적합하며 보조 의사 결정 도구로도 사용할 수 있다.

전략 소스 코드
/*backtest
start: 2023-10-24 00:00:00
end: 2023-11-23 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/
// © fenirlix

//@version=5
// Strategy parameter incl. position size, commission and initial capital
strategy("ACTIONZONE-ATR REVERSEORDER STRATEGY", "ACTIONZONEATR-REVERSEORDER", overlay=true
     )

// User Input Variable
fastMaInput     = input.int(12, "Fast MA Period", minval=2, step=1)
slowMaInput     = input.int(26, "Fast MA Period", minval=2, step=1)

atrLengthInput  = input.int(14, "ATR length", minval=2,step=1)
atrInnerMultInput = input.float(1, "atr inner multiplier", minval=0.1, step=0.1)
atrMidMultInput = input.float(2, "atr inner multiplier", minval=0.1, step=0.1) //***** MOST OF RISK MANAGEMENT LOGIC BASE ON THIS INPUT *****//
atrOuterMultInput = input.float(3, "atr inner multiplier", minval=0.1, step=0.1)

// Backtesting Date range
startYearInput      = input.int(2021, "Start Year", minval=1900, maxval=2100, step=1)
startMonthInput     = input.int(12, "Start Month", minval=1, maxval=12, step=1)
startDateInput      = input.int(1, "Start Day", minval=1, maxval=31, step=1)
setEndRangeInput    = input.bool(false, "Using Specific End Test Date") //Set specific End date or use present(end of candle) data
endYearInput        = input.int(2022, "End Year", minval=1900, maxval=2100, step=1)
endMonthInput       = input.int(1, "End Month", minval=1, maxval=12, step=1)
endDateInput        = input.int(31, "End Day", minval=1, maxval=31, step=1)

startDate = timestamp(syminfo.timezone, startYearInput, startMonthInput, startDateInput)
endDate = timestamp(syminfo.timezone, endYearInput, endMonthInput, endDateInput)
inDateRange = time >= startDate //Set backtest date range to present data
if setEndRangeInput
    inDateRange and time <= endDate //set backtest date range to specific date

// minimum position hold period (to get rid of false signal in sideway trend)
minHoldInput = input.int(8, 'Minimum position Hold Limit', minval=1, maxval=365, step=1) // Set Minimum Position Hold

var bool reverseToLong = false // Assign reverse order operator
var bool reverseToShort = false // Assign reverse order operator

// Indicator Declaration
fastEma = ta.ema(close, fastMaInput)
slowEma = ta.ema(close, slowMaInput)
atr = ta.atr(atrLengthInput)

// Declare trend of asset
isBullish = fastEma > slowEma
isBearish = fastEma <= slowEma

// Record position hold length, to limit minimum hold period(candle)
var int hold_length = 0
if strategy.opentrades > 0 or strategy.opentrades < 0
    hold_length := hold_length + 1
else
    hold_length := 0

// create permanent variable of stop price
var float longStopPrice = na
var float shortStopPrice = na
    
// Chart-Indicator COLOR declaration
REDBEAR     = color.new(color.red, 80)
GREENBULL   = color.new(color.green, 80)

greenLong = isBullish and close > fastEma
yellowLong = isBullish and close < fastEma
blueShort = isBearish and close > fastEma
redShort = isBearish and close < fastEma

// assign oversold, overbought condition(in this case, price over middle atr plus/minus fastEma)
overBand = high[1] > fastEma + (2*atr)
underBand = low[1] < fastEma - (2*atr)

// Strategy

// Main Entry Condition
goLong = isBullish and isBullish[1] == 0
goShort = isBearish and isBearish[1] == 0

inPosition = strategy.position_size != 0
minHoldPeriod = hold_length > minHoldInput ? true : false

// Entry Condition
if not inPosition and inDateRange and barstate.isconfirmed == true //compute after close of the bar to avoid repainting
    if goLong or reverseToLong // Long if longcondition or reverse order receive.
        strategy.entry('long', strategy.long)
        longStopPrice := fastEma - (atr * 2) // Set stop loss price
        reverseToLong := false // Reset reverse order status
    
    else if goShort or reverseToShort
        strategy.entry('short', strategy.short)
        shortStopPrice := fastEma + (atr * 2)
        reverseToShort := false
// Take profit and Set Higher Stop 
if inPosition and minHoldPeriod and barstate.isconfirmed == true // check if we're in position and pass minimum hold period, confirm no repainting
    if strategy.position_size > 0
        // if exit position by Sellcondition(which is the same as ShortCondition), Exit Long position and make Short order(by set reverse order to true)
        strategy.close('long', when=goShort, comment='exitLong(' + str.tostring(hold_length) + ')')
        reverseToShort := true
        if overBand //If overbought condition met, set Stop price to LAST LOW, and not reverse any position
            longStopPrice := low[1]
            reverseToShort := false
    else if strategy.position_size < 0
        strategy.close('short', when=goLong, comment='exitShort(' + str.tostring(hold_length) + ')')
        reverseToLong := true
        if underBand
            shortStopPrice := high[1]
            reverseToLong := false
// Stop Loss and Set calculate stop loss using Atr Channel
if inPosition 
    if strategy.position_size > 0
        if fastEma - (atr * atrMidMultInput) > longStopPrice // set long stop price to the higher of latest long stop price and ATR lower channel
            longStopPrice := fastEma - (atr * atrMidMultInput)
        strategy.exit('Long Stop atr ', 'long', stop=longStopPrice)
    else if strategy.position_size < 0
        if fastEma + (atr * atrMidMultInput) < shortStopPrice
            shortStopPrice := fastEma + (atr * atrMidMultInput)
        strategy.exit('Short Stop atr ', 'short', stop=shortStopPrice)

// Plotting
fastLine = plot(fastEma, title='fast ema line', linewidth=1, color=isBullish ? color.green : color.red)
slowLine = plot(slowEma, title='slow ema line', linewidth=2, color= isBullish? color.green : color.red)
atrUpperLine1 = plot(fastEma + (atr * atrInnerMultInput), title='ATR Upperline1', color=color.new(color.black,85))
atrLowerLine1 = plot(fastEma - (atr * atrInnerMultInput), title='ATR Lowerline1', color=color.new(color.black,85))
atrUpperLine2 = plot(fastEma + (atr * atrMidMultInput), title='ATR Upperline2', color=color.new(color.black,75))
atrLowerLine2 = plot(fastEma - (atr * atrMidMultInput), title='ATR Lowerline2', color=color.new(color.black,75))
atrUpperLine3 = plot(fastEma + (atr * atrOuterMultInput), title='ATR Upperline3', color=color.new(color.black,50))
atrLowerLine3 = plot(fastEma - (atr * atrOuterMultInput), title='ATR Lowerline3', color=color.new(color.black,50))

plot(longStopPrice, color=strategy.position_size > 0 ? color.red : na, linewidth=2)
plot(shortStopPrice, color=strategy.position_size < 0 ? color.red : na, linewidth=2)

//  Filling
fill(fastLine, slowLine, color=isBullish ? GREENBULL : REDBEAR)
fill(atrUpperLine3, atrLowerLine3, color=inPosition and (minHoldInput - hold_length > 0) ? color.new(color.blue,90): na)

barColor = switch
    greenLong => color.green
    yellowLong =>  color.yellow
    blueShort => color.blue
    redShort => color.red
    => color.black
barcolor(color=barColor)

// Fill background to distinguish inactive time(Zulu time)
nightTime = time(timeframe.period, "1500-0100") ? color.new(color.black, 95): na
bgcolor(nightTime)