ADX (average directional movement) is new to QP2, along with PDM and MDM (positive and minus directional movement). In QP2 they're scan functions. Here's an example of a PDM/MDM scan I use:
output="pdmmdm.lst"; input="canslim.lst";
daystoload=300;
set pdm = 14; set mdm = 14;
if pdm(0)>mdm(0) and pdm(-1)<mdm(-1) and qrs(0)>80 and eps>0 then println symbol:-6," BUY: Close: ", close(0):-6:3, ",", " Up/Down: ", close(0)-close(-1):4:3, ","," Volume: ", vol(0):-10, ",", " QRS: ", QRS(0):2, ","," Sharesfloat: ", Sharesfloat:6:3, ", ",Description:-12; endif;
Before the directional indicators became scan functions in the beta version of QP2, Jeff Grover wrote this mind-boggling scan for an earlier beta (the fixed font was a clue that something like this was about to be sprung on you in this message):
// // Scan Title : Directional Movement Indicators // (Welles Wilders' +DI, -DI, ADX) // // Written By : Jeffrey L. Grover // noman@gatech.edu // // Create Date: 31 Dec 1997 // // ********+-----------------------------------+******* // ********| NO WARRANTY EXPRESSED OR IMPLIED |******* // ********+-----------------------------------+******* //
input = "portfoli.lst"; output = "dmiscan.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; |