
도니 트렌드 추적 전략은 Black Box Trend Following Lifting the Veil 에서 설명한 도니 채널 원칙에 따라 개발된 트렌드 추적 전략이다. 이 전략은 도니 채널을 사용하여 가격 트렌드를 판단하고 가격 혁신 고 또는 혁신 저에 따라 포지션을 더하거나 공백을 설정한다.
전략은 도니 채널 지표에 기반하여 트렌드 방향을 판단한다. 도니 채널은 더 긴 주기의 채널과 더 짧은 주기의 채널로 구성된다. 가격이 더 긴 주기의 채널을 뚫었을 때, 추세로 판단하기 시작하며, 가격이 더 짧은 주기의 채널을 뚫었을 때, 추세로 판단하기 끝난다.
구체적으로, 더 긴 주기 통로의 길이는 50일 또는 20일, 더 짧은 주기 통로의 길이는 50일, 20일 또는 10일이다. 가격이 50일 내 최고 가격과 같으면 더 많은 주문을 열고, 가격이 50일 내 최저 가격과 같으면 빈 주문을 열고. 가격이 20일 내 최저 가격과 같으면 더 많은 주문을 없애고, 가격이 20일 내 최고 가격과 같으면 더 많은 주문을 없애고, 가격이 20일 내 최고 가격과 같으면 더 많은 주문을 없애고.
이렇게 두 개의 서로 다른 주기 도니 채널의 조합을 통해 트렌드가 시작될 때 방향을 정하고, 트렌드가 끝날 때 적시에 손해를 막아낼 수 있다.
이 전략은 다음과 같은 장점을 가지고 있습니다.
트렌드를 포착하는 능력이 강하다. 도니 채널을 뚫고 트렌드의 시작과 끝을 판단하여 트렌드를 효과적으로 추적할 수 있다.
리스크 관리가 이루어졌다. 이동식 스톱을 사용하여 단편 손실을 통제했다.
매개 변수 조정 유연성. 다양한 품종과 시장 환경에 맞게 채널의 주기 조합을 자유롭게 선택할 수 있다.
간단한 명확한 거래 논리. 이해하기 쉽고 실행하기 쉽다.
이 전략에는 다음과 같은 위험도 있습니다.
흔들리는 시장에 적응할 수 없다. 추세가 명확하지 않을 때, 여러 개의 작은 조정이 발생하여 손실을 막는다.
브레이크 실패 위험. 가격이 채널을 뚫고 다시 회수될 수 있어 스톱 손실이 발생한다.
주기 선택 위험. 통로 주기 설정이 잘못되면, trading in noise로 이어진다.
샤프 비율이 떨어질 위험이 있다. 만약 포지션을 늘리고도 스톱 손실을 조정하지 않는다면 샤프 비율이 떨어질 위험이 있다.
대응방법:
이 전략은 다음과 같은 방향으로 최적화될 수 있습니다.
필터링 조건을 추가하고, whipsaws를 피한다. 예를 들어 결합량 능력 지표와 같은 판단 진짜 돌파구.
채널 사이클의 조합과 포지션 컨트롤을 최적화하고, 당기 손실 비율을 높인다. 적응적 손실 중지 메커니즘을 도입할 수 있다.
브레이크포인트 최적화를 시도하고, 최적의 파라미터 조합을 찾습니다.
기계 학습 알고리즘을 추가하여 파라미터의 동적 최적화 및 조정.
도니 트렌드 추적 전략은 가격 트렌드의 시작과 끝을 두 경로로 판단하여 트렌드 추적의 거래 방식을 채택하여 단위 손실을 효과적으로 제어한다. 이 전략의 매개 변수를 조정하는 것은 유연하고, 실행하기 쉬운, 매우 실용적인 트렌드 추적 전략이다. 그러나 또한 충격적 인 상황에서 수익성 부족과 매개 변수 선택으로 인한 위험을 주의해야 한다. 추가적인 최적화를 통해 더 나은 전략 효과를 얻을 수 있다.
/*backtest
start: 2023-12-01 00:00:00
end: 2023-12-31 23:59:59
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
//@version=5
strategy(title="Donchian", overlay=true,
pyramiding=0, initial_capital=1000,
commission_type=strategy.commission.cash_per_order,
commission_value=2, slippage=2)
// =============================================================================
// VARIABLES
// =============================================================================
donch_string = input.string(title="Length", options = ['20/10','50/20', '50/50', '20/20', '100/100'], defval='50/50')
permit_long = input.bool(title = 'Permit long', defval = true)
permit_short = input.bool(title = 'Permit short', defval = true)
risk_percent = input.float(title="Position Risk %", defval=0.5, step=0.25)
stopOffset = input.float(title="ATR mult", defval=2.0, step=0.5)
atrLen = input.int(title="ATR Length", defval=20)
close_in_end = input.bool(title = 'Close in end', defval = true)
permit_stop = input.bool(title = 'Permit stop', defval = false)
// =============================================================================
// CALCULATIONS
// =============================================================================
donch_len_big =
donch_string == '50/20' ? 50 :
donch_string == '50/50' ? 50 :
donch_string == '20/20' ? 20 :
donch_string == '20/10' ? 20 :
donch_string == '100/100' ? 100 :
na
donch_len_small =
donch_string == '50/20' ? 20 :
donch_string == '50/50' ? 50 :
donch_string == '20/20' ? 20 :
donch_string == '20/10' ? 10 :
donch_string == '100/100' ? 100 :
na
big_maxclose = ta.highest(close, donch_len_big)
big_minclose = ta.lowest(close, donch_len_big)
small_maxclose = ta.highest(close, donch_len_small)
small_minclose = ta.lowest(close, donch_len_small)
atrValue = ta.atr(atrLen)[1]
tradeWindow = true
// =============================================================================
// NOTOPEN QTY
// =============================================================================
risk_usd = (risk_percent / 100) * strategy.equity
atr_currency = (atrValue * syminfo.pointvalue)
notopen_qty = risk_usd / (stopOffset * atr_currency)
// =============================================================================
// LONG STOP
// =============================================================================
long_stop_price = 0.0
long_stop_price :=
strategy.position_size > 0 and na(long_stop_price[1]) ? strategy.position_avg_price - stopOffset * atrValue :
strategy.position_size > 0 and strategy.openprofit > risk_usd ? strategy.position_avg_price:
strategy.position_size > 0 ? long_stop_price[1] :
na
// =============================================================================
// SHORT STOP
// =============================================================================
short_stop_price = 0.0
short_stop_price :=
strategy.position_size < 0 and na(short_stop_price[1]) ? strategy.position_avg_price + stopOffset * atrValue :
strategy.position_size < 0 and strategy.openprofit > risk_usd ? strategy.position_avg_price :
strategy.position_size < 0 ? short_stop_price[1] :
na
// =============================================================================
// PLOT VERTICAL COLOR BAR
// =============================================================================
cross_up = strategy.position_size <= 0 and close == big_maxclose and close >= syminfo.mintick and tradeWindow and permit_long
cross_dn = strategy.position_size >= 0 and close == big_minclose and close >= syminfo.mintick and tradeWindow and permit_short
bg_color = cross_up ? color.green : cross_dn ? color.red : na
bg_color := color.new(bg_color, 70)
bgcolor(bg_color)
// =============================================================================
// PLOT DONCHIAN LINES
// =============================================================================
s1 = cross_up ? na : cross_dn ? na : strategy.position_size != 0 ? strategy.position_avg_price : na
s2 = cross_up ? na : cross_dn ? na : strategy.position_size > 0 ? small_minclose : strategy.position_size < 0 ? small_maxclose : na
s3 = cross_up ? na : cross_dn ? na : not permit_stop ? na :
strategy.position_size > 0 ? long_stop_price : strategy.position_size < 0 ? short_stop_price : na
plot(series=big_maxclose, style=plot.style_linebr, color=color.black, linewidth=1, title="Donch Big Maxclose Black")
plot(series=big_minclose, style=plot.style_linebr, color=color.black, linewidth=1, title="Donch Big Minclose Black")
plot(series=s1, style=plot.style_linebr, color=color.yellow, linewidth=2, title="Entry Yellow")
plot(series=s2, style=plot.style_linebr, color=color.red, linewidth=1, title="Donch Small Red")
plot(series=s3, style=plot.style_linebr, color=color.fuchsia, linewidth=2, title="Stop Fuchsia")
// =============================================================================
// ENTRY ORDERS
// =============================================================================
if strategy.position_size <= 0 and close == big_maxclose and close >= syminfo.mintick and tradeWindow and permit_long
strategy.entry("Long", strategy.long, qty=notopen_qty)
if strategy.position_size >= 0 and close == big_minclose and close >= syminfo.mintick and tradeWindow and permit_short
strategy.entry("Short", strategy.short, qty=notopen_qty)
// =============================================================================
// EXIT ORDERS
// =============================================================================
if strategy.position_size > 0 and permit_stop
strategy.exit(id="Stop", from_entry="Long", stop=long_stop_price)
if strategy.position_size < 0 and permit_stop
strategy.exit(id="Stop", from_entry="Short", stop=short_stop_price)
// ==========
if strategy.position_size > 0 and close == small_minclose and not barstate.islast
strategy.close(id="Long", comment='Donch')
if strategy.position_size < 0 and close == small_maxclose and not barstate.islast
strategy.close(id="Short", comment='Donch')
// ==========
if close_in_end
if not tradeWindow
strategy.close_all(comment='Close in end')
// =============================================================================
// END
// =============================================================================