ATR 및 브레이크아웃에 기반한 ETF 거래 전략

저자:차오장, 날짜: 2023-12-26 16:05:55
태그:

img

전반적인 설명

이 ETF는 평균 참 범위 (ATR) 와 가격 브레이크아웃을 기반으로 한 알고리즘 거래 전략이다. ATR을 사용하여 스톱 로스 및 영업 수준을 계산하고 가격이 특정 기간의 최고 또는 최저 가격을 통과 할 때 긴 또는 짧은 포지션을 개척합니다.

전략 논리

이 전략은 주로 다음과 같은 원칙에 기초합니다.

  1. 특정 기간의 가장 높고 가장 낮은 가격 (예: 20 개의 촛불) 을 사용하여 가격 추세와 방향을 결정합니다. 가격이 기간의 가장 높은 가격을 통과 할 때 길고 가격이 가장 낮은 가격을 통과 할 때 짧습니다.

  2. 동적으로 스톱 로스 레벨을 계산하기 위해 ATR을 사용한다. 스톱 로스는 입상 가격에서 ATR 값의 거리 (예: 2) 로 곱한 ATR 값에 배치된다.

  3. ATR을 사용해서 취익 수준을 결정합니다. 취익은 입시 가격에서 ATR 값과 계수 (예: 1) 를 곱한 거리에 위치합니다.

  4. ATR 트레일러 인수 인수를 사용하여 손실을 추적합니다. 가격이 불리한 방향으로 트레일러 인 손실 수준을 넘을 때 손실을 멈추고 포지션을 닫습니다.

전략은 간단하고 신뢰할 수 있습니다. 가격 트렌드 방향을 고려하여 가격 움직임을 적시에 파악하고 수익을 취하고 위험을 통제하기 위해 손해를 멈추고 이익을 취하는 것을 설정합니다.

이점 분석

이 전략의 장점은 다음과 같습니다.

  1. 전략 논리는 간단하고 명확하고 이해하기 쉽고 실행하기 쉽습니다.

  2. ATR을 사용하여 적응적인 스톱 로스 및 수익 수치를 계산하면 유연한 포지션 크기와 위험 통제가 가능합니다.

  3. 브레이크아웃 전략은 가격 트렌드를 잘 파악하고 좋은 수익을 창출합니다.

  4. 트레일러 스톱 손실은 과도한 손실을 피하여 적시에 포지션을 닫을 수 있습니다.

  5. ETF와 주식 같은 명백한 추세를 보이는 상품에 적합합니다.

위험 분석

이 전략의 위험은 다음과 같습니다.

  1. 더 많은 잘못된 신호와 역 개척이 가격 통합 중에 발생할 수 있습니다.

  2. 부적절한 매개 변수 조정으로 인해 가격 트렌드가 누락되거나 불필요한 거래가 너무 많을 수 있습니다.

  3. 극단적인 매개 변수 값은 지나치게 공격적이거나 지나치게 보수적인 스톱 러스 및 영업으로 이어질 수 있으며 전략 수익성에 영향을 줄 수 있습니다.

  4. 정책 및 프리미엄 위험과 같은 ETF의 기본 위험도 전략 성과에 영향을 줄 수 있습니다.

대응 솔루션:

  1. 불필요한 거래를 줄이기 위해 매개 변수를 최적화합니다.
  2. 거래 신호를 확인하기 위해 더 많은 요소와 필터를 추가합니다.
  3. 다른 시장에 맞게 매개 변수를 조정합니다.
  4. 단일 ETF의 투자 및 제어 지점 크기를 다양화합니다.

최적화 방향

이 전략은 다음 측면에서 더 이상 최적화 될 수 있습니다.

  1. 거짓 신호를 필터링하기 위해 이동 평균과 같은 지표를 추가합니다.

  2. 다양한 기간과 제품에 대한 자동 조정 매개 변수 최적화 모듈 개발.

  3. 기계 학습 모델을 채택하여 다음 촛불의 가장 높고 가장 낮은 가격을 예측하여 브레이크오웃 신호를 결정합니다.

  4. 가짜 브레이크오프를 피하기 위해 거래량 오버플로우를 고려하십시오.

  5. 초기 포지션 크기와 할당 비율을 다양한 제품과 시장 체제에 맞게 최적화합니다.

결론

이 전략은 명확하고 간단한 논리를 가지고 있다. 브레이크아웃 및 적응형 ATR 스톱 로스/프로프트의 핵심 메커니즘은 위험을 효과적으로 제어하고 이익을 잠금할 수 있다. 매개 변수 최적화와 더 많은 필터를 통합함으로써 이익 요소와 위험 통제 기능을 더욱 향상시키는 것이 수익성 있고 최적화 가능한 양적 전략이 될 수 있다.


/*backtest
start: 2023-12-18 00:00:00
end: 2023-12-21 03:00:00
period: 1m
basePeriod: 1m
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/
// © FX_minds

//@version=4
strategy("ETF tradedr", overlay=true, pyramiding=100, default_qty_type=strategy.percent_of_equity, default_qty_value=100)

//------------------------------ get user input
lookback                   = input(title="HH LL lookback", type=input.integer, defval=20)
ATR_periode                = input(title="ATR period", type=input.integer, defval=14)
ATR_SL_multiplier          = input(title="ATR SL multiplier", type=input.float, defval=2)
ATR_TP_multiplier          = input(title="ATR TP multiplier", type=input.float, defval=1)
trailing_SL_ATR_multiplier = input(title="ATR trailing SL multiplier", type=input.float, defval=3.5)
lookback_trailing_SL       = input(title="trailing SL lookback", type=input.integer, defval=4)
max_sequel_trades          = input(title="max sequel trades", type=input.float, defval=1)
trade_long                 = input(title= "trade long ?", type=input.bool, defval=true)
trade_short                = input(title= "trade short ?", type=input.bool, defval=false)

//------------------------------ determine entry conditions
long_condition   = barstate.isconfirmed and crossover(high, highest(high, lookback)[1])
short_condition  = barstate.isconfirmed and crossunder(low, lowest(low, lookback)[1])


//------------------------------ count open long trades
count_open_longs = 0
count_open_longs := nz(count_open_longs[1])

if (long_condition) 
    count_open_longs := count_open_longs +1
    //label.new(bar_index, low, tostring(count_open_longs, "#"), xloc.bar_index, yloc.belowbar, color.green, label.style_none, color.green, size.large)

if (short_condition)
    count_open_longs := 0


//------------------------------ count open short trades
count_open_shorts = 0
count_open_shorts := nz(count_open_shorts[1])

if (short_condition)
    count_open_shorts := count_open_shorts +1
    //label.new(bar_index, low, tostring(count_open_shorts, "#"), xloc.bar_index, yloc.belowbar, color.red, label.style_none, color.red, size.large)

if (long_condition)
    count_open_shorts := 0


//------------------------------ calculate entryprice
entryprice_long = long_condition ? close : na
entryprice_short = short_condition ? close : na


//------------------------------ calculate SL & TP
SL_distance = atr(ATR_periode) * ATR_SL_multiplier
TP_distance  = atr(ATR_periode) * ATR_TP_multiplier
trailing_SL_distance = atr(ATR_periode) * trailing_SL_ATR_multiplier

SL_long = entryprice_long - SL_distance
SL_short = entryprice_short + SL_distance

trailing_SL_short = lowest(close, lookback_trailing_SL) + trailing_SL_distance
trailing_SL_long  = highest(close, lookback_trailing_SL) - trailing_SL_distance

trailing_SL_short_signal = crossover(high, trailing_SL_short[1])
trailing_SL_long_signal = crossunder(low, trailing_SL_long[1])


//------------------------------ plot entry price & SL  
plot(entryprice_long, style=plot.style_linebr, color=color.white)
plot(SL_long, style=plot.style_linebr, color=color.red)
plot(SL_short, style=plot.style_linebr, color=color.green)
plot(trailing_SL_short, style=plot.style_linebr, color=color.red)
plot(trailing_SL_long, style=plot.style_linebr, color=color.green)


//------------------------------ submit entry orders
if (long_condition) and (count_open_longs <= max_sequel_trades) and (trade_long == true)
    strategy.entry("Long" + tostring(count_open_longs, "#"), strategy.long)
    strategy.exit("SL Long"+ tostring(count_open_longs, "#"), 
     from_entry="Long" + tostring(count_open_longs, "#"), stop=SL_long)

if (short_condition) and (count_open_shorts <= max_sequel_trades) and (trade_short == true)
    strategy.entry("Short" + tostring(count_open_shorts, "#"), strategy.short)
    strategy.exit("SL Short" + tostring(count_open_shorts, "#"), 
     from_entry="Short" + tostring(count_open_shorts, "#"), stop=SL_short)
    

//------------------------------ submit exit conditions
if (trailing_SL_long_signal)
    strategy.close("Long" + tostring(count_open_longs, "#"))
    strategy.close("Long" + tostring(count_open_longs-1, "#"))
    strategy.close("Long" + tostring(count_open_longs-2, "#"))
    strategy.close("Long" + tostring(count_open_longs-4, "#"))
    strategy.close("Long" + tostring(count_open_longs-5, "#"))
    strategy.close("Long" + tostring(count_open_longs-6, "#"))
    strategy.close("Long" + tostring(count_open_longs-7, "#"))
    strategy.close("Long" + tostring(count_open_longs-8, "#"))
    strategy.close("Long" + tostring(count_open_longs-9, "#"))
    
if (trailing_SL_short_signal)
    strategy.close("Short" + tostring(count_open_shorts, "#"))
    strategy.close("Short" + tostring(count_open_shorts-1, "#"))
    strategy.close("Short" + tostring(count_open_shorts-2, "#"))
    strategy.close("Short" + tostring(count_open_shorts-3, "#"))
    strategy.close("Short" + tostring(count_open_shorts-4, "#"))
    strategy.close("Short" + tostring(count_open_shorts-5, "#"))
    strategy.close("Short" + tostring(count_open_shorts-6, "#"))
    strategy.close("Short" + tostring(count_open_shorts-7, "#"))
    strategy.close("Short" + tostring(count_open_shorts-8, "#"))
    strategy.close("Short" + tostring(count_open_shorts-9, "#"))



더 많은