Calculation of ADX

Hi.

I try to calculate ADX(14) manually but so far I did not succeed in reproducing the values of chartprograms like WealthLab.

Which formula is th one I need and what periods are normally used ?

Thanks !

pri
 
Not sure why you would want to calculate this by hand. There is no simple formula. If you are truly interested in how most technical indicators are calculated, I would suggest that you get the book "Trading for a Living" by Dr. Alexander Elder. You will find the ADX calculation method in pages 135-139. Or, you can get "New Concepts in Technical Trading Systems" by J. Welles Wilder, who developed the idea of ADX.

The calculation method is simply too lenthy to reproduce here.

You can use any time period that you want, but most use a 14 period calculation.

Charles
 
The following post appeared on the xltrader list on 08-08-2001. I don't know if the statements and the code are correct, but it may help you anyway.

Andreas

+++ Snip +++

I discovered, in dissecting the ADX algorithm, that Welles Wilder
isn't as smart as he thinks. Either that or he diliberately
incorporated True Range to ADX confuse or impress people.

You see, with all his talk about discovering True Range and what a
deep market truth it is, and after developing his ADX indicator that
has True Range as part of the calculation, he doesn't seem to realize
that ALL the True Range terms cancel out! Do the math, or test it
yourself. You can substitute random numbers and get identital
results.

Here's the VB source. Note the final calculation for DX uses terms
which are all ratios having ATR in the denominator, and they all
cancel out.

Enjoy.
Alex

--------------------------------------------------------------------
Option Explicit

'Exponential moving average
'Closely approximates true moving average
'Arguments:
' last_ema = previous period's ema result
' a = new value to incorporate into ema
' n = number of periods
'Return value: current ema

Function ema(ByVal last_ema As Double, ByVal a As Double, ByVal n As
Integer) As Double
Dim w As Double
w = 2# / (n + 1)
ema = (1# - w) * last_ema + w * a
End Function


'Wilder's ADX
'Arguments:
' last_adx = value of ADX from previous period
' n = number of periods to use
' init = initialize averages (set to TRUE on 1st call)
' H, L = current high and low
' Hp, Lp, Cp = previous high, low, close
'Return value: current ADX

Function ADX(last_adx As Double, n As Integer, init As Boolean, _
H As Double, L As Double, _
Hp As Double, Lp As Double, Cp As Double) As Double

Dim i As Integer, tmp1 As Double, tmp2 As Double, TR As Double
Dim PDM As Double, MDM As Double, PDI As Double, MDI As Double
Dim DX As Double
Static ATR As Double, APDM As Double, AMDM As Double 'averages

If init Then ATR = 0#: APDM = 0#: AMDM = 0#

'step 1: calculation of directional movements
' DM is the largest part of the current trading range that
' is outside the previous trading range
'
' PDM = max(0, H - Hp) (plus direction movment)
' MDM = min(0, L - Lp) (minus direction movment)
'
'For an outside day:
' if |PDM| < |MDM| then PDM=0
' if |PDM| > |MDM| then MDM=0
' else PDM=MDM=0
'
'Here's a better alternative that works just as well or better:
'tmp1 = (H - Hp + L - Lp) / 2#
'If tmp1 > 0# Then PDM = tmp1: MDM = 0# Else MDM = tmp1: PDM = 0#
'...but we'll use Wilder's way for now.

PDM = Application.WorksheetFunction.Max(0, H - Hp)
MDM = Application.WorksheetFunction.Min(0, L - Lp)
tmp1 = Abs(PDM): tmp2 = Abs(MDM)
If tmp1 < tmp2 Then
PDM = 0#
ElseIf tmp2 < tmp1 Then
MDM = 0#
Else
PDM = 0#: MDM = 0# 'inside day
End If

'step 2: calculation of true range (TR)
' TR = max(H-L, Cp-L, H-Cp) where Cp=previous close

TR = Application.WorksheetFunction.Max(H - L, Cp - L, H - Cp)

'step 3: plus and minus directional indicators PDI and MDI
'
' The average plus and minus directional movement values are
' divided by the average TR to get PDI and MDI. An exponential
' moving average closely approximates the true average.
'
' ema(|PDM|, n) ema(|MDM|, n)
' PDI = ------------- MDI = -------------
' ema(TR, n) ema(TR, n)

ATR = ema(ATR, TR, n) 'average true range
If ATR = 0# Then 'special case ATR=0
PDI = APDM: MDI = AMDM 'use previous average values
Else
APDM = ema(APDM, Abs(PDM), n)
AMDM = ema(AMDM, Abs(MDM), n)
PDI = APDM / ATR
MDI = AMDM / ATR
End If

'step 4: calculation of direction movement index DX
' Step 3 isn't necessary for calculation of DX, because the
' ATR term cancels out here. Then PDI=APDM and MDI=AMDM.
'
' PDI - MDI
' DX = ----------- '* 100
' PDI + MDI
'
' we won't multiply by 100, so our ADX will be from 0 to 1.

tmp1 = PDI + MDI
If tmp1 = 0# Then
DX = last_adx
Else
DX = Abs(PDI - MDI) / tmp1
End If

'step 5: calculation of average directional movement index ADX
' ADX = ema(|DX|, n)

ADX = ema(last_adx, Abs(DX), n)
End Function

+++ End Snip +++
 
Charles,

I would like a VisualBasic-program to give me my trading-signals and one of the conditions involves the ADX(14).

Don't you know of any web-site, which describes the formula in detail ?

Pri
 
Here is some VB code I wrote a couple of years ago to calculate ADX/DMI. It is based on the formula in the Achelis "Technical Analysis from A to Z". If you are serious about programming your own formulas, I would suggest getting the companion spreadsheet at http://www.atozbook.com/spreadsheet.htm.

I don't have time to go through and document this code snippet, but if you have specific questions, let me know. Basically, you load up the structure with your data and it calculates it.
 

Attachments

From the Metastock list sometime in May 1999. This may speed up your calculation time, in case it matters.

Andreas

N.B. Ref(C,-1) means previous day's Close

+++ Snip +++

Martin,

A friend showed that TrueRange required no comparisons; the algorithm in MS'ese is

TR = (H - L + Abs(H - Ref(C,-1)) + Abs(L - Ref(C,-1)) )/2


Regards,
Bob

+++ End Snip +++
 
Back
Top