Sharing investing and trading ideas. Helping traders get started.

Friday, June 19, 2009

Accumulation/Distribution Line

Accumulation/Distribution Line ADL
Read on for formula, calculation steps and VBA code. For naive backtest results and findings, visit here


The accumulation/distribution line, ADL, is calculated the following way.

ADLt = ADLt-1 + CLV x Volume,
where CLV = [(Close – Low) – (High – Close)] / (High – Low)

,where the subscript t is used to denote time e.g. t-1 refers to the period before t. CLV stands for close location value and represents where the closing price is located relatively to the high and low prices of the day or any other time frame preferred by the user. When the closing price is near the high, CLV will approximate 1 and vice versa. The ADL is in turn a cumulative measure of CLV weighted by volume. As prices multipled by volume is a better proxy of money flow compared to prices alone, ADL estimates if money has been moving in or out of a stock. At the beginning of each dataset, (the first) ADL is simply CLV x Volume.

Signals are generated when ADL diverges from prices e.g. when ADL moves up and prices move down. Divergences typically occur because CLV is not calculated using any data from previous periods while price movements are relative to prior prices.

VBA Code

There are two ways where you can code this indicator. Method A creates user defined functions where you can call these indicators from your formula bar, while Method B creates sub procedures to calculate them. I prefer Method B because

1) Execution of Method B was completed within a second, while Method A takes approximately two and a half minutes to calculate 12,000 values on a 1.7Ghz laptop.

2) Method B shows you the calculation steps within the cells, but Method A does not.

Method A 

'Paste this code into your ThisWorkBook code window in VBA. Right Click This WorkBook in Project Explorer and click View Code.

Private Sub Workbook_Open()
End Sub

'The rest belong to any module
Sub AddUDF()
'Tells Excel to includes these in list of functions, add descriptions to them and create a new category called Technical Indicators.
Application.MacroOptions macro:="CLV", _
Description:="Returns the Close Location Value." & Chr(10) & Chr(10) & _
"Note: CLV will return an error value if high and low are the same.", _
Category:="Technical Indicators"

Application.MacroOptions macro:="ADL", _
Description:="Returns the Accumulation/Distribution Line." & Chr(10) & Chr(10) & _
"Select last period's ADL or 0 if current period is the first," & Chr(10) & _
"followed by current high, low, close and volume", _
Category:="Technical Indicators"
End Sub

Public Function ADL(ADLYesterday, high, low, close_, volume)
ADL = ADLYesterday + CLV(high, low, close_) * volume
End Function Public Function CLV(high, low, close_)
CLV = ((close_ - low) - (high - close_)) / (high - low)
End Function

Once you are done with the above, compute CLV by entering into any cell "=CLV([Current High], [Current Low], [Current Close])", or compute ADL by entering "=ADL([Last period ADL],[Current High], [Current Low], [Current Close],[Current Volume])". [Can be a value or a Cell].

Method B

'Define your inputs and where they are located.
'You only need to run this sub procedure
'This sub will call the right indicator
Sub Runthis()
Dim high As Range, low As Range, close1 As Range
Dim volume As Range, output As Range, n As Long
Dim k As Long

'These are the location of your respective historic data
Set high = Range("C2:C11955")
Set low = Range("D2:D11955")
Set close1 = Range("E2:E11955")
Set volume = Range("F2:F11955")
Set output = Range("H2:H11955")

n = 5 'number of historical periods to look at
'needed for certain indicators
k = 10 'number of historical periods to look at
'needed for certain indicators as slow average
'Only select one sub to run from for each indicator.
'Mark the rest as comments with a single quote.
'CLV_1 high, low, close1, output
ADL_1 high, low, close1, volume, output
End Sub

Sub ADL_1(high As Range, low As Range, close1 As Range, volume As Range, output As Range)
'Calculate CLV
CLV_1 high, low, close1, output

'Calculate ADL
output(0, 3).Value = "ADL"
output(2, 3).Value = "=" & output(1, 3).Address(False, False) & "+" & output(2, 2).Address(False, False) & "*" & volume(2, 1).Address(False, False)
output(2, 3).Copy output.Offset(0, 2)
output(1, 3).Value = "=" & output(1, 2).Address(False, False) & "*" & volume(1, 1).Address(False, False)
'In this case, your final ADL comes out in Column J when your
'original output is in Column H
End Sub

Sub CLV_1(high As Range, low As Range, close1 As Range, output As Range)
output(0, 1).Value = "Trial CLV"
output(0, 2).Value = "Final CLV"
high0 = high(1, 1).Address(False, False)
low0 = low(1, 1).Address(False, False)
close0 = close1(1, 1).Address(False, False)
output0 = output(1, 1).Address(False, False)
'Calculate CLV
output(1, 1).Value = "=((" & close0 & "-" & low0 & ")-(" & high0 & "-" & close0 & "))/(" & high0 & "-" & low0 & ")"
output(1, 1).Copy output
output(1, 2).Value = "=IF(ISERROR(" & output0 & ")=TRUE," & output(0, 2).Address(False, False) & "," & output0 & ")"
output(1, 2).Copy output.Offset(0, 1)
End Sub

Other References

Like what you have just read? Digg it or Tip'd it.
The objective of Finance4Traders is to help traders get started by bringing them unbiased research and ideas. Since late 2005, I have been developing trading strategies on a personal basis. Not all of these models are suitable for me, but other investors or traders might find them useful. After all, people have different investment/trading goals and habits. Thus, Finance4Traders becomes a convenient platform to disseminate my work...(Read more about Finance4Traders)


Post a Comment