home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1993 #2 / Image.iso / finance / tas515dm.zip / TAS514.EXE / lha / DMI.TAS < prev    next >
Text File  |  1993-02-25  |  7KB  |  204 lines

  1. #TITLE Wilder's Directional Movement Trading System                   
  2. #MAX_QUOTES 150
  3. #OUTPUT_FILE 'DMI.LST+'
  4. { DMI.TAS :
  5.    Script to implement Wilder's Directional Movement Trading
  6.    System.
  7.    Source : "DMI Trading Rules",Jim Summers,
  8.     Technical Analysis of Stocks and Commodities, Dec 1988
  9.     and "New Concepts in Technical Trading Systems", Wilder
  10.     --------------------Rules----------------------------
  11.     Enter Position if all of the following are true:
  12.         1) +DI and -DI cross
  13.            if +DI > -DI enter LONG
  14.            if +DI < -DI enter SHORT
  15.         2) ADXR > 25
  16.         3) ADX not below both +DI and -DI
  17.         4) ADX not above both +DI and -DI
  18.         Set Extreme Point on entry to position as follows:
  19.             if LONG,  Extreme Point is LOW
  20.             if SHORT, Extreme Point is HIGH
  21.     Exit Position and either of the following:
  22.         1) ADX above both DI lines and then turns down
  23.         2) If DI lines cross against entry position AND
  24.            HIGH > Extreme Point (SHORT) or
  25.            LOW  < Extreme Point (LONG)
  26.   ------------SCRIPT IMPLEMENTATION DETAILS-------------
  27.    This script is somewhat complex, because Wilder's system
  28.    itself is complex. We are starting at the "current"
  29.    day, in each ticker file. If the entry conditions are
  30.    true, we put out a message indicating which position
  31.    we should take.
  32.    If, on the other hand, either of the Exit conditions are
  33.    true, the script does something you probably haven't
  34.    seen before. Imagine the ticker data is displayed on a
  35.    price bar chart. Using the pre-defined variable
  36.    "QUOTE_RANGE", it "slides" the "right" edge to the
  37.    left, one day at a time, until it finds an Entry
  38.    condition as shown in rules 1-4 of the Entry rules (above).
  39.    Each day is checked using a "subroutine" implemented using 
  40.    GOSUB to the CHECKRULES routine. 
  41.    This version works with TAS 3.62 or later only.
  42. }
  43. pdi_a : array;    { +DI array }
  44. mdi_a : array;    { -DI array }
  45. adx_a : array;    { ADX array }
  46. adxr_a : array;    { ADXR array }
  47. avg_adx : number;   { Average ADX value across all tickers}
  48. buy_signal : number;
  49. sell_signal : number;
  50. dmi_days = 14;    { Number of days in ADX and DI calculations }
  51. ADXR_limit = 20;   { lower limit for ADX }
  52. i     : number;   { Index for backing up in time }
  53. j     : number;   { Another index for backing up in time }
  54. rule1 : number;   { +/-DI crossing}
  55. rule2 : number;   { ADX >= 20}
  56. rule3 : number;   { ADX not below both +/-DI}
  57. rule4 : number;   { ADX not above both +/-DI}
  58. postype : number; { Position type LONG(+1), SHORT(-1) none(0)}
  59. opostype : number; {Open position type}
  60. epostype : number; {Exit position type}
  61. extreme_point : number;   { Extreme Point Rule value}
  62. oextreme_point : number;   { Open Extreme Point Rule value}
  63. warning : number;
  64. if first_ticker then
  65. begin
  66. writeln(
  67. '--------------------------------------------------------------');
  68. writeln(
  69. 'Signals based on Welles Wilders Directional Movement System');
  70. writeln(
  71. ' ');
  72. writeln(
  73. 'Action       Description  ');
  74. writeln(
  75. '------       --------------------------------------------------');
  76. writeln(
  77. 'Open         ADXR > 25, +DI crossed -DI, and ADX between +/-DI');
  78. writeln(
  79. 'Exit (ExP)   +DI crossed -DI and Extreme Point violated');
  80. writeln(
  81. 'Exit (ADX)   ADX above +DI and -DI and turned down');
  82. writeln(
  83. 'Warning      +DI and -DI crossed, but Extreme Point not ');
  84. writeln(
  85. '             violated');
  86. writeln(
  87. '--------------------------------------------------------------');
  88. writeln(
  89. '                          EXTREME  CURRENT      OPEN');
  90. writeln(
  91. 'TICKER  ACTION  POSITION    POINT    CLOSE      DATE');
  92. end;
  93. if quote_count < dmi_days * 3 then return;
  94. ticker_count = ticker_count + 1;
  95. pdi_a = pdi(dmi_days);
  96. mdi_a = mdi(dmi_days);
  97. adx_a = adx(dmi_days);
  98. adxr_a = adxr(dmi_days);
  99. postype = 0;
  100. warning = 0;
  101. opostype = 0;
  102. epostype = 0;
  103. j = quote_range;        { short name for index back in time}
  104. { check if adx has turned down}
  105. if adx_a > pdi_a and adx_a > mdi_a and
  106.     adx_a[0] < adx_a[-1] and adx_a[-1] > adx_a[-2] then begin
  107.     epostype = 2;
  108.     end;
  109. if epostype = 2 then   { adx turned down..see if we had open pos}
  110.     goto BACKCHECK;
  111. GOSUB CHECKRULES;
  112. :RETURN1                { this is where CHECKRULES returns if
  113.                           switch = 1}
  114. opostype = postype;
  115. oposition = position;
  116. oextreme_point = extreme_point;
  117. postype = 0;
  118. { Not entering a position..see if we should exit a prior one }
  119. IF rule1 = 0 THEN GOTO TICKDONE;  { DI lines did not cross today }
  120. { DI lines crossed..see if this is the time to exit a prior position}
  121. i = 1;
  122. :BACKCHECK
  123. quote_range = quote_count - i;  { lower top of array }
  124. j = quote_range;        { short name for index back in time}
  125. {Stop when we have less than twice the DMI period days left}
  126. if quote_range <= dmi_days * 2 then goto NOPRIOR;
  127. if isect(pdi_a,mdi_a) < 0 then goto NOPRIOR;
  128. GOSUB CHECKRULES;
  129. :RETURN2
  130. if postype <> 0 then GOTO EXITRULE;
  131. i = i + 1;
  132. GOTO BACKCHECK;
  133. :EXITRULE
  134. { we have found entry position }
  135. quote_range = quote_count;  { reset quote range back to present}
  136. if epostype = 2 then    { exit because of adx turning down}
  137.     goto TICKDONE;
  138. if postype = -1 then
  139.     if extreme_point < H then
  140.         epostype = postype
  141.     else
  142.         warning = 1;
  143. if postype = 1 then
  144.     if extreme_point > L then
  145.         epostype = postype;
  146.     else
  147.         warning = 1;
  148. :NOPRIOR
  149. GOTO TICKDONE;
  150. { This is a "subroutine" to check if a position should be entered.
  151.   It sets variable "position" to either LONG or SHORT if so}
  152. :CHECKRULES
  153. position = '     ';
  154. postype = 0;
  155. rule1 = isect(pdi_a,mdi_a) = 0; { if +DI intersected -DI today}
  156. rule2 = adxr_a[j] > ADXR_limit;
  157. rule3 = adx_a[j] >= pdi_a[j] OR adx_a[j] >= mdi_a[j];
  158. rule4 = adx_a[j] <= pdi_a[j] OR adx_a[j] <= mdi_a[j];
  159. IF rule1 AND rule2 AND rule3 AND rule4 THEN
  160. BEGIN
  161.     IF pdi_a[j] > mdi_a[j] THEN
  162.     BEGIN
  163.         position = 'LONG ';
  164.         postype  = 1;
  165.         extreme_point = l[j];      { if long, extreme point is low}
  166.     END
  167.     ELSE
  168.     BEGIN
  169.         position = 'SHORT';
  170.         postype  = -1;
  171.         extreme_point = h[j];      { if short, extreme point is high}
  172.     END;
  173. END;
  174. RETURN;        { to caller of CHECKRULES}
  175. :TICKDONE
  176. if warning <> 0 then    { If giving a warning, don't open position}
  177.     opostype = 0;
  178. if warning = 1 then
  179. writeln(TICKER,'Warning    ',position ,' ',extreme_point,' ',C,
  180.     '  ',datestr(dates[j]));
  181. if epostype <> 0 then
  182.     if epostype = 2 then
  183.         if postype <> 0 then
  184.         begin
  185.             emsg = 'Exit (ADX) '
  186.             eposition = position;
  187.             epostype = postype;
  188.         end
  189.         else
  190.             epostype = 0
  191.     else
  192.         emsg = 'Exit (ExP) ';
  193. if epostype <> 0 then
  194. writeln(TICKER,emsg,position ,' ',extreme_point ,' ',C,
  195.     '  ',DATESTR(DATES[j]));
  196. if opostype <> 0 then
  197. writeln(TICKER,'Open       ',oposition,' ',oextreme_point,' ',C,
  198.     '  ',DATE);
  199. avg_adx = avg_adx + adx_a;
  200. IF last_ticker then
  201. BEGIN
  202.     writeln('Average ADX is ',avg_adx/ticker_count);
  203. END;
  204.