#주식/투자

기술적지표 파헤치기 #8: ADX, DMI

SUNGWOO BAE
PRO

2023-02-02 · 9 MIN READ

ADX, DMI의 수식, 엑셀과 트레이딩뷰로 구현해보기

*2021-11-18 글


ADX란 Average Directional Movement Index의 약자로, 상승했을 때의 상승분과 하락했을 때의 하락분을 비교하여 추세를 정의하는 지표입니다. 



다음과 같이 추세에 따라 적색, 청색선이 교차되고, 그 강도가 검정색 선으로 표기되는 모습을 확인할 수 있습니다.

여기서 적색, 청색선을 DMI (Directional Movement Index)라고 정의하며, DMI+DI -DI로 구성되어있습니다.


TR = 고가 - 저가, abs(전일 종가 - 고가), abs(전일 종가 - 저가) 중, 가장 큰 값

+DI = eavg(전일 고가 < 금일 고가이고, 전일 저가 하락 폭 < 금일 고가 상승 폭일 때, 상승 폭, 아니라면 0) / TR

- DI = eavg(전일 저가 > 금일 저가이고, 전일 저가 하락 폭 > 금일 고가 상승 폭일 때, 하락 폭, 아니라면 0) / TR


ADX는 다음과 같습니다.

ADX = eavg(abs(N일간 +DI - N일간 -DI) / (N일간 +DI + N일간 -DI) * 100)


*abs는 절대값, eavg는 지수이동평균을 의미


상승과 하락의 기준을 고저점 갱신 여부 및 상대적인 등락폭으로 비교함을 알 수 있습니다.


어쩌면 단순한 모멘텀과 비슷한 양상을 띌 수도 있으나 - 수식 구조 상, 꼬리가 길게 생긴 경우 추세를 잘 설명하지 못할 수 있다는 한계가 존재합니다.

위 자료는 아래꼬리가 긴 경우입니다. - DI (청색)가 급증하였으나, 이후 큰 반등이 눈에 띕니다.

이렇듯 ADX와 DMI는 고가와 저가끼리만 비교하기 때문에, 최근 추세를 반영하지 못하는 경우가 생깁니다.



위 경우를 더 자세히 보면, 확실히 하락 이후의 추세는 바뀐 것이 보입니다. 다만 지표는 추세의 전환을 표시하는데 13 candles의 딜레이가 발생하였습니다. 



Backtest


카카오를 대상으로, 2000년 4월부터 2021년 11월까지 ADX & DMI를 사용한 "Long Only" 백테스팅 결과입니다.

모든 백테스트는 리스크 관리를 따로 하지 않았으며, 조건에 따라 자산의 100%를 전부 운용했을 때의 결과입니다.

ADX & DMI 설정 값은 14, 14입니다.


1.

매수 조건: +DI가 -DI를 상향 돌파하였을 때

매도 조건: +DI가 -DI를 하향 돌파하였을 때

Sharpe Ratio = 0.116

Sortino Ratio = 0.344


생각보다 결과가 잘나와서 당황스럽습니다. 카카오는 고저점의 갱신 여부와 추세의 상관관계가 높은 종목이었나 봅니다.


2.

매수 조건: +DI가 -DI를 상향 돌파하였을 때

매도 조건: ADX가 2일 연속 우하향하였을 때

Sharpe Ratio = 0.115

Sortino Ratio = 0.289


MDD를 줄이기 위해, 강도가 줄어들기 시작하면 바로 실현하는 조건으로 변경하였습니다.

확실히 MDD는 줄었으나 성과지표는 기존보다 안좋아졌습니다. 첫번째 백테스트의 수익률이 강하게 적용된 것이 원인으로 보입니다.


3.

매수 조건: +DI가 -DI를 상향 돌파하였을 때

매도 조건: +DI가 -DI보다 높고 ADX가 2일 연속 우하향하였을 때

Sharpe Ratio = 0.109

Sortino Ratio = 0.245


추세가 아직 끝나지 않은 상태일 때, 강도가 줄어들기 시작하면 실현하는 조건으로 변경해 보았습니다.

 MDD가 소폭 완화되었으나, 수익률이 더 줄어들어 성과지표가 악화되었습니다.



DMI는 ADX의 강도 추이를 살펴보는 것이 MDD관리에 효과적임을 알 수 있었습니다.



Excel


1. TR


먼저 +DI와 - DI에 적용될 값인 TR(True Range)을 먼저 만들어 줍니다.

TR = MAX(고가 - 저가, ABS(전일 종가 - 고가), ABS(전일 종가 - 저가))


=MAX(C3-D3,ABS(B2-C3),ABS(B2-D3))



2. 상승 & 하락폭


상승폭은 금일 고가 - 전일 고가

하락폭은 전일 저가 - 금일 저가

로 만들어줍니다.



3. +DI, -DI Source

고가가 전일보다 높고, 상승폭이 하락폭보다 크다면

상승폭,

아니라면 0


=IF(AND(C2<C3,G3<F3),F3,0)

저가가 전일보다 낮고, 하락폭이 상승폭보다 크다면

하락폭,

아니라면 0


=IF(AND(D2>D3,G3>F3),G3,0)


4. DI

먼저, 데이터 - 테이터분석 - 지수평활법을 통해 Source의 지수이동평균을 만듭니다.

만약 데이터분석이 보이지 않는다면 좌측 상단 시작 - 엑셀옵션 - 추가기능 - 분석도구 추가를 통해 추가기능을 받아주시면 됩니다.


이 때, 감쇠인수는 1-알파 입니다.

DI의 지수평균에서 사용되는 알파는 1/기간으로, 감쇠인수에는 1 - (1/기간)을 입력해주시면 됩니다.

저의 경우 14일을 기준으로 잡았기 때문에, 


1 - (1/14) = 0.92857


+DI -DI 모두 같은 방법으로 지수평균값을 만들어주시면 됩니다.

이후 

지수이동평균값 / TR = DI


5. ADX


DMI를 모두 완성하셨습니다. 이제 ADX를 만들 차례입니다.


+DI, -DI의 차의 절대값 / +DI, -DI의 합 * 100

=ABS(L14-M14)/SUM(L14:M14)*100



이후 같은 방법으로 지수이동평균 시켜주면 ADX가 완성됩니다. 이번에도 14일을 기준으로 하였습니다.



ADX와 DI간 격차때문에 DI에도 각각 100씩 곱하여 표현하였습니다.



확대샷

엑셀로 그리려니 지저분해보입니다.


TradingView


//@version=4

study(title="ADX & DMI")


al = input(14, title="ADX length")

l = input(14, title="DI Length")


up = change(high)

down = -change(low)

pDM = na(up) ? na : (up > down and up > 0 ? up : 0)

mDM = na(down) ? na : (down > up and down > 0 ? down : 0)


tru = rma(tr, l)

p = fixnan(100 * rma(pDM, l) / tru)

m = fixnan(100 * rma(mDM, l) / tru)

sum = p + m

adx = 100 * rma(abs(p - m) / (sum == 0 ? 1 : sum), al)


plot(adx, color=color.black, title="ADX")

plot(p, color=color.red, title="+DI")

plot(m, color=color.blue, title="-DI")