Gary and all,
Yes, +DMI, -DMI, and ADX were a bear to implement. Attached is my cut at it. I have only done nominal comparisons to the MS indicator so do not guarantee this to be 100% accurate.
This version has some upfront parameters to define different report formats and to provide header info. There is also a "day" variable to define how far back to look for a buy/sell signal (not really back testing, just most recent trade and current profit/loss).
I did this without the book (anyone care to loan me one while the publisher decides if they want to print some more?), so I'm not sure I use the right moving average. There are of two different MAs in there, I believe I have the 14 day EMA active right now.
BTW: This version has comments to help me remember what the code does, I remove them to make the scan run faster.
*****************************************************************
What I'd really like to do is get an equation for Wilder's Commodity Selection Index (CSI) so I can make sure I'm applying this scan to he right pool of stocks. I'd gladly repay you with a scan Tuesday for a formula today....
Hope this scan is informative of R2's power if nothing else.
*****************************************************************
// // Scan Title : Directional Movement Indicators // (Welles Wilders' +DI, -DI, ADX) // // Written By : Jeffrey L. Grover // noman@gatech.edu // // Create Date: 31 Dec 1997 // // ********+-----------------------------------+******* // ********| NO WARRENTY EXPRESSED OR IMPLIED |******* // ********+-----------------------------------+******* //
input = "watch.lst"; output = "dmi_scan.lst";
// TrueRange Variables
float H, Hp, L, Lp, Cp, TrueRange, ExtremePT; integer cday, pday, day, i, header, details, summary; integer buy, sell, alert, trigger;
// DMI Variables
float PlusDM, MinusDM, DMIPlus, DMIMinus; float PlusDMI, MinusDMI, DMI, ADX, TRange, MyRange; float TRen, MDMen, PDMen, en, DMIen, PlusDM14, MinusDM14; float PlusDMIen, MinusDMIen; integer EMAn, Length, EMA;
// Setup scan and reporting parameters
EMA := 1; // EMA vs Standard average summary := 1; // Summarize stock performance results at end header := 0; // Column headers details := 0; // Daily performance for duration Length := 100; // Number of days to fun scan for EMAn := 14.0; // Number of days in average
// Initialize some variables
MyRange := EMAn; // TrueRange := 0.01; // True Trading Range for consec days PlusDM14 := 0.01; // MinusDM14 := 0.01; // PlusDMI := 0; // MinusDMI := 0; // TRange := 0; // True Range Running Total day := 0; // buy := 0; // = 1 when buy condition active sell := 0; // = 1 when sell condition active alert := 0; // = 1 when buy/sell set, cleared next day trigger := 0; // set to 1 when buy/sell is triggered ExtremePT := 0.0; // price point where buy/sell would be triggered
// initialize the EMA seeds
en := 2.0 / (EMAn + 1.0 ); // EMA weighting percentage TRen := 0.01; // EMA(TrueRange, n) DMIen := 0.01; // EMA(DMI,n) PDMen := 0.01; // EMA(DM+,n) MDMen := 0.01; // EMA(DM-,n)
for i = Length+EMAn to 0 step -1 do // calc for last 100 days
if i=Length+EMAn and header = 1 then println " Close +DI -DI DX "; println " ----- ----- ----- ----- "; endif;
// Set up the loop variables
cday := day - i; pday := cday - 1;
L := low(cday); Lp := low(pday); H := high(cday); Hp := high(pday); Cp := close(pday);
// Calculate TrueRange of action over two days
TrueRange := H - L; if TrueRange < H - Cp then TrueRange:= H - Cp; endif; if TrueRange < Cp - L then TrueRange:= Cp - L; endif; TRen := (TRen * (1.0-en)) + (TrueRange * en);
// Compute DM+ and DM-
if H - Hp < 0 then PlusDM := 0; else PlusDM := H - Hp; endif;
if Lp - L < 0 then MinusDM := 0; else MinusDM := Lp - L; endif;
if PlusDM >= MinusDM then MinusDM := 0; endif; if MinusDM >= PlusDM then PlusDM := 0; endif;
TRange := TRange + TrueRange; PlusDM14 := PlusDM14 + PlusDM; MinusDM14 := MinusDM14 + MinusDM; if MyRange > 0 then TRange := TRange - ( TRange / MyRange ) + TrueRange; PlusDM14 := PlusDM14 - ( PlusDM14 / MyRange ) + PlusDM; MinusDM14 := MinusDM14 - ( MinusDM14 / MyRange ) + MinusDM; endif;
if TRange = 0 then DMIPlus := 0; DMIMinus := 0; else DMIPlus := 100 * PlusDM14 / TRange; DMIMinus := 100 * MinusDM14 / TRange; endif;
PDMen := (PDMen * (1.0-en)) + (PlusDM * en); MDMen := (MDMen * (1.0-en)) + (MinusDM * en);
// Freeze some up front values
if i >= Length then TRange := TRange + TrueRange; MinusDM14 := MinusDM14 + MinusDM; PlusDM14 := PlusDM14 + PlusDM; endif;
// Compute EMA of DM+ and DM- PlusDMIen := PDMen / TRen; MinusDMIen := MDMen / TRen;
// Calculate DMI
if DMIPlus + DMIMinus = 0 then DMI := 0; else DMI := 100 * (abs(DMIPlus - DMIMinus) / (DMIPlus + DMIMinus)); endif;
DMIen := (DMIen * (1.0-en)) + (DMI * en);
// Set buy/sell alerts
if PlusDMIen > MinusDMIen and buy = 0 then buy := 1; alert := 1; sell := 0; trigger := 0; ExtremePT := high(cday); endif; if MinusDMIen > PlusDMIen and sell = 0 then alert := 1; buy := 0; sell := 1; trigger := 0; ExtremePT := low(cday); endif;
if buy > 0 and high(0) > ExtremePT then trigger := 1; endif; if sell > 0 and low(0) < ExtremePT then trigger := 1; endif;
// Print Detail Lines
if i <= length and details = 1 then if EMA = 0 then print close(cday):6:2," , ",PlusDMen:6:2," , ",MinusDMen:6:2," , ",DMI:6:2; else print close(cday):6:2," , ",DMIPlus:6:2," , ",DMIMinus:6:2," , ",DMI:6:2; endif; if alert = 1 then if sell = 1 then println " , Sell @ ",ExtremePT:6:2; else println " , Buy @ ",ExtremePT:6:2; endif; alert := 0; else println; endif;
endif; if alert > 0 then alert := alert + 1; endif; next i;
// Print Summary
if summary = 1 then if details = 1 then println " ----- ----- ----- ----- ";endif;
if EMA = 0 then //print Symbol:-7," , ",DMIPlus:6:2," , ",DMIMinus:6:2," , ",DMIen:6:2; print Symbol:-7," , "; else //print Symbol:-7," , ",DMIPlus:6:2," , ",DMIMinus:6:2," , ",DMI:6:2; print Symbol:-7," , "; endif;
if trigger = 0 then print "*"; else print " "; endif;
if sell = 1 then print " Sell @ ",ExtremePT:6:2," , ", alert-2:3," days ago , now at ", close(0):6:2," , "; if trigger = 1 then println (ExtremePT- close(0))/ExtremePT*100:6:2,"%"; else println; endif; endif;
if buy = 1 then print " Buy @ ",ExtremePT:6:2," , ", alert-2:3," days ago , now at ", close(0):6:2," , "; if trigger = 1 then println (close(0)-ExtremePT)/ExtremePT*100:6:2,"%"; else println; endif; endif;
if buy = 0 and sell = 0 then println; endif; endif; |