Identify The Start Of A Trend With DMI

The AIQ code based on BC Low’s article in the November issue of Stocks & Commodities, “Identify The Start Of A Trend With DMI,” is provided at the following website:, and is shown below.

Several of the terms used by the author had to be interpreted to be converted into signal code such as, “cluster drifts down below level 30,” “converging,” “turning up,” and so on. My interpretation may differ from what the author intended, and other interpretations are possible. In addition, I had to come up with exits for the signals as none were given. In testing using the NASDAQ 100 list of stocks, the long-only system was profitable over the test period, whereas I could not get the short-only system to be profitable.

To test the author’s 3x DMI system, I used the NASDAQ 100 list of stocks and AIQ’s Portfolio Manager. A long-only trading simulation was run with the following capitalization, cost, and exit settings:

  • Maximum of 10 open positions
  • Size each position at 10 % of mark-to-market total capital
  • Take no more than three new positions per day
  • Compute the mark-to-market capital each day
  • Three cents per share was deducted for each round-turn trade
  • Select trades based on the highest 14-bar ADX reading
  • Exit trades if the end-of-day stop-loss exceeds 3%
  • Exit trades by protecting 50% of profits once profit level reaches 10%.

In Figure 8, I show the resulting statistics and long-only equity curve compared to the NASDAQ 100 index. For the period 12/31/1999 to 9/17/2012, the system returned an average internal rate of return of 20.7% with a maximum drawdown of 58.2% on 3/9/2009.

FIGURE 8: AIQ, EQUITY CURVE. This long-only equity curve is compared to the
NASDAQ 100 for the test period 12/31/1999 to 9/17/2012 trading the NASDAQ 100 list of stocks.
!Author: BC Low, TASC Nov 2012
!Coded by: Richard Denning 09/17/12

   wLen is 14.
   wLen3 is 3.
   wLen4 is 4.
   wLen5 is 5.
   wLen8 is 8. 
   blvl is 30.
   slvl is 70.

   H is [high].
   L is [low].
   C is [close].
   C1 is valresult(C,1).
   H1 is valresult(H,1).
   L1 is valresult(L,1).

!NOTE: Wilder to expontential averaging the formula is:
!  Wilder length * 2 – 1 = exponential averaging length
   eLen is wLen * 2 – 1.
   eLen3 is wLen3 * 2 – 1.
   eLen4 is wLen4 * 2 – 1.
   eLen5 is wLen5 * 2 – 1.
   eLen8 is wLen8 * 2 – 1.

   TR  is Max(H-L,max(abs(C1-L),abs(C1-H))).
   ATR  is expAvg(TR,eLen).
   ATR3  is expAvg(TR,eLen3).
   ATR4  is expAvg(TR,eLen4).
   ATR5  is expAvg(TR,eLen5).
   ATR8  is expAvg(TR,eLen8).

   rhigh is (H-H1).
   rlow is (L1-L).
   DMplus is iff(rhigh > 0 and rhigh > rlow, rhigh, 0).
   DMminus is iff(rlow > 0 and rlow >= rhigh, rlow, 0).

   AvgPlusDM is expAvg(DMplus,eLen).
   AvgPlusDM3 is expAvg(DMplus,eLen3).
   AvgPlusDM4 is expAvg(DMplus,eLen4).
   AvgPlusDM5 is expAvg(DMplus,eLen5).
   AvgPlusDM8 is expAvg(DMplus,eLen8).
   AvgMinusDM is expavg(DMminus,eLen).
   AvgMinusDM3 is expavg(DMminus,eLen3).
   AvgMinusDM4 is expavg(DMminus,eLen4).
   AvgMinusDM5 is expavg(DMminus,eLen5).
   AvgMinusDM8 is expavg(DMminus,eLen8).

   PlusDMI is (AvgPlusDM/ATR)*100.
   PlusDMI3 is (AvgPlusDM3/ATR)*100.
   PlusDMI4 is (AvgPlusDM4/ATR)*100.
   PlusDMI5 is (AvgPlusDM5/ATR)*100.
   PlusDMI8 is (AvgPlusDM8/ATR)*100.

   MinusDMI is AvgMinusDM/ATR*100.
   MinusDMI3 is AvgMinusDM3/ATR*100.
   MinusDMI4 is AvgMinusDM4/ATR*100.
   MinusDMI5 is AvgMinusDM5/ATR*100.
   MinusDMI8 is AvgMinusDM8/ATR*100.

!ADX INDICATOR as defined by Wells Wilder 
   DIdiff is PlusDMI-MinusDMI.
   ZERO if PlusDMI = 0 and MinusDMI =0.
   DIsum is PlusDMI+MinusDMI.
   DX is iff(ZERO,100,abs(DIdiff)/DIsum*100).
   ADX is ExpAvg(DX,eLen).

   DIdiff3 is PlusDMI3-MinusDMI3.
   ZERO3 if PlusDMI3 = 0 and MinusDMI3 =0.
   DIsum3 is PlusDMI3+MinusDMI3.
   DX3 is iff(ZERO3,100,abs(DIdiff3)/DIsum3*100).
   ADX3 is ExpAvg(DX3,eLen3).

   DIdiff4 is PlusDMI4-MinusDMI4.
   ZERO4 if PlusDMI4 = 0 and MinusDMI4 =0.
   DIsum4 is PlusDMI4+MinusDMI4.
   DX4 is iff(ZERO4,100,abs(DIdiff4)/DIsum4*100).
   ADX4 is ExpAvg(DX4,eLen4).

   DIdiff5 is PlusDMI5-MinusDMI5.
   ZERO5 if PlusDMI5 = 0 and MinusDMI5 =0.
   DIsum5 is PlusDMI5+MinusDMI5.
   DX5 is iff(ZERO5,100,abs(DIdiff5)/DIsum5*100).
   ADX5 is ExpAvg(DX5,eLen5).

   Converge if (ADX3 < ADX4 Or ADX3 < ADX5) and ADX4 < ADX5.
   Below if ADX3 < blvl And ADX4 < blvl And ADX5 < blvl.
   TurnUp if  ADX3 > ADX4 And ADX3 > ADX5 And ADX4 > ADX5.
   Peak if (ADX3 > ADX4 Or ADX3 > ADX5) And ADX4 > ADX5.
   Above if ADX3 > slvl And ADX4 > slvl And ADX5 > slvl.
   TurnDn if ADX3 < ADX4 And ADX3 < ADX5 And ADX4 < ADX5.
   PlusBottom if PlusDMI5 <= 5 And PlusDMI8 <= 10 And PlusDMI <= 10.
   AbovePlus if ADX3 > Min(slvl+20,90).
   PlusUp if PlusDMI5 > PlusDMI8 And PlusDMI5 > PlusDMI And PlusDMI8 > PlusDMI.
   MinusBottom if MinusDMI5 <= 5 And MinusDMI8 <= 10 And MinusDMI <= 10.
   MinusUp if MinusDMI5 > MinusDMI8 And MinusDMI5 > MinusDMI And MinusDMI8 > MinusDMI.
   BuySig1 if countof(Below,5,0)>=1 And countof(Converge,5,0)>=1 And TurnUp.
   SellSig2 if countof(Above,5,0)>=1 And countof(Peak,5,0)>=1 And TurnDn.
   BuySig3 if countof(PlusBottom,5,0)>=1 And countof(AbovePlus,5,0)>=1 And TurnDn And PlusUp.
   SellSig4 if countof(MinusBottom,5,0)>=1 And countof(AbovePlus,5,0)>=1 And TurnDn And MinusUp.

   Buy if BuySig1 or BuySig3.
   Sell if SellSig2 or SellSig4.

Leave a Reply