ADX 스마트 트렌드 추종 전략


생성 날짜: 2023-11-28 14:04:00 마지막으로 수정됨: 2023-11-28 14:04:00
복사: 0 클릭수: 490
1
집중하다
1166
수행원

ADX 스마트 트렌드 추종 전략

개요

ADX 지능형 트렌드 추적 전략은 평균 트렌드 지수 ((ADX) 를 사용하여 트렌드의 힘을 판단하고, 트렌드가 약할 때 트렌드 캡처하고, 강한 트렌드에서 추적 수익을 낸다. 이 전략은 트렌드 힘을 판단하면서 가격 돌파구를 결합하여 거래 신호를 생성하며, 트렌드 추적 전략의 일종이다.

전략 원칙

이 전략은 주로 평균 트렌드 지수 ((ADX) 를 기반으로 현재 트렌드 힘을 판단한다. ADX는 일정 기간 동안 가격 변동의 DIRECTIONAL INDICATOR의 평균값을 계산하여 트렌드의 힘을 나타낸다. ADX 값이 설정된 하위값보다 낮을 때, 우리는 상황이 정리되고 있다고 생각하며, 이 때 칸막이 범위를 판단하고, 가격이 칸막이를 뚫고 상향으로 내려가면 거래 신호를 발생시킨다.

구체적으로, 전략은 먼저 14주기의 ADX값을 계산하고, 18기가 낮으면 트렌드가 약하다고 생각한다. 그리고는 지난 20개의 K선에서 최고 가격과 최저 가격이 형성된 칸의 범위를 계산한다. 가격이 이 칸을 뚫었을 때, 구매 및 판매 신호를 발생시킨다.

이 전략은 동시 트렌드 강도 판단과 브레이크 신호를 결합하여, 트렌드가 약할 때 정리할 수 있도록 캡처할 수 있으며, 무질서한 상황에서 자주 거래되는 것을 피한다. 강한 트렌드가 발생했을 때, 정지 범위가 더 커서 더 많은 이익을 얻을 수 있다.

전략적 이점

  1. 트렌드 파워 판단과 결합하여 무질서한 상황에서 자주 거래되는 것을 피할 수 있습니다.
  2. 쿼드 브레이크는 흔들림의 경우 을 피하기 위해 필터를 추가합니다.
  3. 트렌드 상황에서는 더 큰 휴식 공간을 얻을 수 있다.
  4. 사용자 정의 ADX 변수, 칸 변수, 손해 차단 계수 등이 다양하게 적용된다.

전략적 위험

  1. ADX 파라미터를 잘못 설정하면 트렌드를 놓치거나 판단 오류가 발생할 수 있다.
  2. 크기가 너무 크거나 너무 작으면 효과가 떨어질 수 있습니다.
  3. 부적절한 정지연속수는 너무 작은 정지 또는 너무 이른 정지를 초래할 수 있다.

ADX 변수, 쿼드 변수, 손해제지수 등을 조정하여 최적화하여 다양한 품종과 시장 환경에 더 적합하게 만들 수 있습니다. 또한 엄격한 자금 관리도 중요합니다. 단일 손실 비율을 제어하여 단일 손실을 피하십시오.

전략 최적화 방향

  1. ADX 파라미터는 다른 주기 효과를 테스트할 수 있다.
  2. 쿼드 파라미터는 다양한 길이의 테스트를 통해 최적의 범위 크기를 판단할 수 있다.
  3. 손해 차단 계수는 리스크 수익률을 최적화하기 위해 미세하게 조정할 수 있다.
  4. 한방 거래의 효과를 테스트할 수 있습니다.
  5. 다른 지표와 결합할 수 있다. 예를 들어, 증가량 에너지 지표 등이다.

요약하다

ADX 지능형 트렌드 추적 전략은 전반적으로 보다 안정적인 트렌드 전략이다. 그것은 동시적으로 트렌드 힘 판단과 가격 돌파 신호를 결합하여, 일반적인 트렌드 추적 전략에서 상하를 추적하는 문제를 어느 정도 피한다. 매개 변수 최적화 및 엄격한 자금 관리를 통해 이 전략이 안정적으로 수익을 낼 수 있다.

전략 소스 코드
/*backtest
start: 2023-11-20 00:00:00
end: 2023-11-27 00:00:00
period: 5m
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//Developer: Andrew Palladino. 
//Creator: Rob Booker.
//Date: 9/29/2017
//@version=5
//Date: 08/10/2022
//Updated to V5 from V1, default cash settings added and indicators made more easily visible by:
// @ Powerscooter

strategy("Rob Booker - ADX Breakout", shorttitle="ADX Breakout V5", overlay=true, default_qty_type = strategy.cash, default_qty_value = 100000, initial_capital = 100000)

adxSmoothPeriod = input(14, title="ADX Smoothing Period", group = "ADX Settings")
adxPeriod = input(14, title="ADX Period", group = "ADX Settings")
adxLowerLevel = input(18, title="ADX Lower Level", group = "ADX Settings")
boxLookBack = input(20, title="BreakoutBox Lookback Period", group = "BreakoutBox")
profitTargetMultiple = input(1.0, title="Profit Target Box Width Multiple", group = "Take Profit and Stop Loss")
stopLossMultiple = input(0.5, title="Stop Loss Box Width Multiple", group = "Take Profit and Stop Loss")
enableDirection = input(0, title="Both(0), Long(1), Short(-1)", group = "Trade Direction")


// When the ADX drops below threshold limit, then we consider the pair in consolidation. 
// Set Box around highs and lows of the last 20 candles. with upper and lower boundaries. 
// When price breaks outside of box, a trade is taken. (on close or on touch?)
// Stop is placed, default 50%, of the size of the box. So if box is 200 pips, stop is at 100 pips. 
// Profit target is 100% of the size of the box. Default. User can set a profit target of 0.5, 1 full size, 2 or 3. 


dirmov(len) =>
	up = ta.change(high)
	down = -ta.change(low)
	truerange = ta.rma(ta.tr, len)
	plus = fixnan(100 * ta.rma(up > down and up > 0 ? up : 0, len) / truerange)
	minus = fixnan(100 * ta.rma(down > up and down > 0 ? down : 0, len) / truerange)
	[plus, minus]

adx(dilen, adxlen) => 
	[plus, minus] = dirmov(dilen)
	sum = plus + minus
	adx = 100 * ta.rma(math.abs(plus - minus) / (sum == 0 ? 1 : sum), adxlen)

adxHigh(dilen, adxlen) => 
	[plus, minus] = dirmov(dilen)
	plus
	
adxLow(dilen, adxlen) => 
	[plus, minus] = dirmov(dilen)
	minus
	
sig = adx(adxSmoothPeriod, adxPeriod)
//sigHigh = adxHigh(dilen, adxlen)
//sigLow = adxLow(dilen, adxlen)

isADXLow = sig < adxLowerLevel

//boxUpperLevel = ta.highest(high, boxLookBack)[1]
//boxLowerLevel = ta.lowest(low, boxLookBack)[1]

var float boxUpperLevelCarry = 0
var float boxLowerLevelCarry = 0

boxUpperLevel = strategy.position_size == 0 ? ta.highest(high, boxLookBack)[1] : boxUpperLevelCarry
boxUpperLevelCarry := boxUpperLevel
boxLowerLevel = strategy.position_size == 0 ? ta.lowest(low, boxLookBack)[1] : boxLowerLevelCarry
boxLowerLevelCarry := boxLowerLevel

boxWidth = boxUpperLevel - boxLowerLevel

profitTarget = strategy.position_size > 0  ? strategy.position_avg_price + profitTargetMultiple*boxWidth : strategy.position_size < 0 ?  strategy.position_avg_price - profitTargetMultiple*boxWidth : na
stopLoss = strategy.position_size > 0 ? strategy.position_avg_price - stopLossMultiple*boxWidth : strategy.position_size < 0 ? strategy.position_avg_price + stopLossMultiple*boxWidth : na

plot(strategy.position_size == 0 ? boxUpperLevel : na, color=color.white, style = plot.style_linebr)
plot(strategy.position_size == 0 ? boxLowerLevel : na, color=color.white, style = plot.style_linebr)


bgcolor(isADXLow ? color.purple : na, transp=72, title = "ADX limit")
plot(stopLoss, color=color.red, linewidth=2, style = plot.style_linebr, title="StopLossLine")
plot(profitTarget, color=color.blue, linewidth=2, style = plot.style_linebr, title="ProfitTargetLine")

isBuyValid = strategy.position_size == 0 and ta.cross(close, boxUpperLevel) and isADXLow

//Long Entry Condition
strategy.exit("close_long", from_entry="open_long", limit = profitTarget, stop = stopLoss)
if isBuyValid and strategy.opentrades == 0 and (enableDirection == -1 or enableDirection == 0)
    strategy.entry("open_long", strategy.long)

isSellValid = strategy.position_size == 0 and ta.cross(close, boxLowerLevel) and isADXLow

//Short Entry condition
strategy.exit(id="close_short", from_entry="open_short", limit = profitTarget, stop = stopLoss)
if isSellValid and strategy.opentrades == 0 and (enableDirection == 1 or enableDirection == 0)
    strategy.entry("open_short", strategy.short)