ADX 지능형 트렌드 추적 전략

저자:차오장, 날짜: 2023-11-28 14:04:00
태그:

img

전반적인 설명

ADX 지능형 트렌드 추적 전략은 트렌드의 강도를 판단하고 약할 때 트렌드를 포착하고 수익을 위해 강한 트렌드를 따르기 위해 평균 방향 지표 (ADX) 를 사용합니다. 이 전략은 가격 돌파구를 결합하면서 트렌드의 강도를 판단하여 거래 신호를 생성하며 트렌드 추적 전략의 일종에 속합니다.

전략 원칙

이 전략의 핵심은 주로 현재 트렌드 강도를 판단하기 위해 평균 방향 지표 (ADX) 를 기반으로 합니다. ADX는 트렌드의 강도를 나타내는 특정 기간 동안 가격 변동의 방향 지표의 평균 값을 계산합니다. ADX 값이 설정된 임계치 이하일 때 시장이 통합되고 있다고 믿습니다. 이 시점에서 박스 범위가 결정됩니다. 가격이 박스의 상부 및 하부 레일을 통과하면 거래 신호가 생성됩니다.

특히, 전략은 먼저 14 사이클 ADX 값을 계산합니다. 18보다 낮을 때 트렌드가 약하다고 간주됩니다. 그 다음 지난 20 K 라인의 가장 높고 가장 낮은 가격으로 형성된 박스의 범위를 계산합니다. 가격이이 박스를 통과하면 구매 및 판매 신호가 생성됩니다. 중지 손실 거리는 박스 크기의 50%이며, 수익 거리는 박스 크기의 100%입니다.

이 전략은 트렌드 강도 판단과 돌파구 신호를 결합하여 트렌드가 약해지고 통합에 들어갈 때 트렌드를 포착하고, 불규칙한 시장에서 빈번한 거래를 피합니다. 그리고 강한 트렌드가 나타나면 더 넓은 수익 목표가 더 많은 수익을 얻을 수 있습니다.

전략 의 장점

  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)

더 많은