Directional Movement DM
Read on formula, calculation steps and VBA Code. For naive backtest results and findings, visit here
Introduction
The directional movement index is based on the directional movement indicator which is in turn calculated from the directional movement of the period. Directional movement classifies market movements into positve and negative directional movements, represented by +DM and -DM respectively. Users must understand that both +DM and -DM some what like indices that seperately measure the day's upward movement or downward movement. As such, both +DM and -DM are positive numbers. In its current form, the DM serves mainly as an input to the calculation of the directional movement indicator.
+DM = (Hight– Hight-1) OR 0 if either of the following occurs
- (Hight-Hight-1) < (Lowt-1-Lowt) - Low fell more than high
- Both (Hight-Hight-1) and (Lowt-1-Lowt) are less than 0. - High fell and low rose
-DM = (Lowt-1-Lowt) OR 0 if either of the following occurs
- (Hight-Hight-1) > (Lowt-1-Lowt) - High rose more than low
- Both (Hight-Hight-1) and (Lowt-1-Lowt) are less than 0. - High fell and low rose
In both Scenario 1 and 2 below, the improvement in high is better than the change in low. Therefore, positive DM, +DM is equal to (Hight – Hight-1), while negative DM, -DM is 0.
In Scenario 3 below, Today’s High is lower than Yesterday’s High and Today’s Low is higher than Yesterday’s Low. Both +DM and –DM are 0.
Both +DM and -DM are either 0 or positive numbers. They reflect if the market is more bullish and bearish.
Signals are based on divergence between moving averages of the +DM and the -DM. For example, the moving average of the +DM will slope upwards in a bullish market, while the -DM remain flat.
The +DM and -DM is usually used in the computation of the directional index, DI and the average directional movement index, ADX. The +DM and the -DM generally measures ths strength of the upward and downward movements respectively.
VBA Code
Method A uses functions, while Method B uses sub procedures to calculate DM. Method B is faster and more flexible.
Method A
Do note that the DM function is actually an array function. To use it, enter into any cell "=DM([current high], [current low], [previous high], [previous low])". Select the cell and the neigbouring cell right next to it, press F2 and Crtl+Shift+Enter. +DM and -DM will be computed.
'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()
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:="DM", _
Description:="Returns Positive Directional Movement and Negative Directional Movement" & Chr(10) & Chr(10) & _
"Select current high, current low, last period's high and last period's low.", _
Category:="Technical Indicators"
End Sub
Public Function DM(high, low, highYesterday, lowYesterday)
high0 = high - highYesterday
low0 = lowYesterday - low
Dim result(0, 1 To 2)
If high0 < 0 And low0 < 0 Then
result(0, 1) = 0
result(0, 2) = 0
Else
If high0 > low0 Then
result(0, 1) = high0
result(0, 2) = 0
Else
If high0 < low0 Then
result(0, 1) = 0
result(0, 2) = low0
Else
result(0, 1) = high0
result(0, 2) = low0
End If
End If
End If
DM = result
End Function
Private Sub Workbook_Open()
AddUDF
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:="DM", _
Description:="Returns Positive Directional Movement and Negative Directional Movement" & Chr(10) & Chr(10) & _
"Select current high, current low, last period's high and last period's low.", _
Category:="Technical Indicators"
End Sub
Public Function DM(high, low, highYesterday, lowYesterday)
high0 = high - highYesterday
low0 = lowYesterday - low
Dim result(0, 1 To 2)
If high0 < 0 And low0 < 0 Then
result(0, 1) = 0
result(0, 2) = 0
Else
If high0 > low0 Then
result(0, 1) = high0
result(0, 2) = 0
Else
If high0 < low0 Then
result(0, 1) = 0
result(0, 2) = low0
Else
result(0, 1) = high0
result(0, 2) = low0
End If
End If
End If
DM = result
End Function
To use the DM function, enter into any cell "=DM([current high], [current low], [previous high], [previous low])". Select the cell and the neigbouring cell right next to it, press F2 and Crtl+Shift+Enter. +DM and -DM will be computed.
Method B
Run the DM_1 sub from the Runthis sub.
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 and output
'Setting close and volume is not necessary for the DM_1 sub alone.
Set high = Range("C2:C19632")
Set low = Range("D2:D19632")
Set close1 = Range("E2:E19632")
Set volume = Range("F2:F19632")
Set output = Range("H2:H19632")
DM_1 high, low, output
End Sub
Sub DM_1(high As Range, low As Range, output As Range)
high0 = high(1, 1).Address(False, False)
high1 = high(2, 1).Address(False, False)
low0 = low(1, 1).Address(False, False)
low1 = low(2, 1).Address(False, False)
output(0, 1).Value = "'High-High"
output(0, 2).Value = "'Low-Low"
output(0, 3).Value = "Positive DM"
output(0, 4).Value = "Negative DM"
output(2, 1).Value = "=" & high1 & "-" & high0
output(2, 2).Value = "=" & low0 & "-" & low1
high2 = output(2, 1).Address(False, False)
low2 = output(2, 2).Address(False, False)
output(2, 3).Value = "=IF(OR(" & high2 & "<" & low2 & ",AND(" & high2 & "<0," & low2 & "<0)),0," & high2 & ")"
output(2, 4).Value = "=IF(OR(" & high2 & ">" & low2 & ",AND(" & high2 & "<0," & low2 & "<0)),0," & low2 & ")"
Range(output(2, 1), output(2, 4)).Copy output
Range(output(1, 1), output(1, 4)).ClearContents
End Sub
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 and output
'Setting close and volume is not necessary for the DM_1 sub alone.
Set high = Range("C2:C19632")
Set low = Range("D2:D19632")
Set close1 = Range("E2:E19632")
Set volume = Range("F2:F19632")
Set output = Range("H2:H19632")
DM_1 high, low, output
End Sub
Sub DM_1(high As Range, low As Range, output As Range)
high0 = high(1, 1).Address(False, False)
high1 = high(2, 1).Address(False, False)
low0 = low(1, 1).Address(False, False)
low1 = low(2, 1).Address(False, False)
output(0, 1).Value = "'High-High"
output(0, 2).Value = "'Low-Low"
output(0, 3).Value = "Positive DM"
output(0, 4).Value = "Negative DM"
output(2, 1).Value = "=" & high1 & "-" & high0
output(2, 2).Value = "=" & low0 & "-" & low1
high2 = output(2, 1).Address(False, False)
low2 = output(2, 2).Address(False, False)
output(2, 3).Value = "=IF(OR(" & high2 & "<" & low2 & ",AND(" & high2 & "<0," & low2 & "<0)),0," & high2 & ")"
output(2, 4).Value = "=IF(OR(" & high2 & ">" & low2 & ",AND(" & high2 & "<0," & low2 & "<0)),0," & low2 & ")"
Range(output(2, 1), output(2, 4)).Copy output
Range(output(1, 1), output(1, 4)).ClearContents
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)
3 comments:
Hi Shinju,
Your blog is very informative. Thanks for sharing such info.
Regarding your VBA code for Directional Movement under Method A, your first If statement is missing some code. I think it intends to check if High falls and Low rises. Also, under your Else If statements, you should exclude the equality sign since your intention seems returning High0 and Low0 in case of an equality in "High rise" and "Low fall", which is handled by the last Else statement. Otherwise, your code would return High0 and 0 for this case.
I think your code needs to be modified as below:
'high fell and low rose
If high0 < 0 And low0 < 0 Then
result(0, 1) = 0
result(0, 2) = 0
'high rose more than low fell
ElseIf high0 > low0 Then
result(0, 1) = high0
result(0, 2) = 0
'low fell more than high rose
ElseIf high0 < low0 Then
result(0, 1) = 0
result(0, 2) = low0
'high rose and low fell by equal amounts
Else
result(0, 1) = high0
result(0, 2) = low0
End If
Correct me if I'm wrong.
First let me apologize for taking such a long time to reply to you. You are right. My initial code had some issues.
For the benefit of everyone. I have updated this page and tested the code to perform the simple back test. The code contained in this page has been corrected for known errors as at this date.
By the way....When i say that you are right, I mean your edits are correct. Thank you once again.
Post a Comment