home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1993 #2 / Image.iso / finance / tas515dm.zip / EXAMPLES.ZIP / BASE-NH.TAS < prev    next >
Text File  |  1992-11-30  |  18KB  |  461 lines

  1. {BASE-NH.TAS   *Written 11/28/92 by Tom Rategan  -Prodigy PMGV10A
  2.                *Originally written 3/18/92. Script saw numerous
  3.                 revisions and improvements, which were documented
  4.                 prior to this version. Changes eventually made much
  5.                 of the original monolog obsolete, so the following
  6.                 monolog reflects only the script as it is now. The
  7.                 evolution of the script is no longer documented
  8.                 here.  Oh well <g>....
  9.     This script is geared toward investors who like to buy stocks which are
  10. showing unusual strength, with an emphasis on stocks emerging from
  11. price consolidation or "basing" patterns. There are four situations which
  12. the script will find:
  13.      1) Stocks closing at new 52 week highs, or closing at a 52 week
  14.         high which has been tested before.
  15.      2) Stocks closing within 5% of their 52 week high, which have also
  16.         been in a basing pattern for a minimum of 6 weeks (30 days).
  17.      3) Stocks which close more than 5% off their 52 week high, but
  18.         which have broken out of some sort of basing pattern.
  19.      4) Stocks which are below their yearly high, but which close
  20.         higher than any close in the prior 50 days.
  21.     Any base which the script finds will be defined with red lines on
  22. the stock's graph, and the dimensions of the base are given on top of
  23. the graph. Any stock which is making a 10+ week high but is below its
  24. yearly high, will be graphed with a grey resistance line extending from
  25. today to the last time the price was at today's level. The line will
  26. be at the level of the next highest close during the period, making it
  27. easier to see what resistance was broken with today's close. In cases
  28. where the script is unable to find a base, the top of the graph will
  29. report how long the stock has traded within a 15% range.
  30.     In searching for a basing pattern, the script looks for the longest,
  31. tightest (narrowest trading range) possible bases first, then it
  32. gradually loosens the search to consider shorter, looser bases. Any base
  33. initially found is tested for validity. To pass the test, the HIGH price
  34. of the stock must come to within 4% of the upper resistance line, at
  35. some point during the first 1/3 of the base period. So if the script
  36. finds a stock with a possible 15% base for 12 weeks, it checks if the
  37. stock's HIGH price nearly tested (4% forgiveness) the upper resistance
  38. line of the base, at some time in the first 4 weeks (ending 8 weeks ago).
  39. If the first possible base found does not pass the test, the script will
  40. continue to search and test other possibilities until its list of
  41. acceptable pre-defined base parameters is exhausted.
  42.     The volume graph tells today's volume, the value of the 50VMA, and
  43. how today's volume compares with the 50VMA. It then tells how each of
  44. the 4 prior weeks (actually 5 day periods) compares to the 50VMA. Each
  45. "week" is compared to the value of the 50VMA on the day before the
  46. week began. So "W1" averages the prior 5 days (5 days ago through
  47. yesterday) and compares that average to the value of the 50VMA 6 days
  48. ago- the day before the "week" began. "W2" averages the volume from
  49. 10 days ago through 6 days ago, and compares that to the 50VMA 11 days
  50. ago. "W3" and "W4" are similarly figured.
  51.     The last graph is a volume UP/DOWN graph. U/D ratio is the ratio
  52. of the sum of all volume on days when the price was up, to the sum of
  53. all volume on days when the price was down. Attempts to show whether
  54. a stock is seeing accumulation or distribution. A ratio of 1.0 means
  55. that there is an even balance of buying pressure and selling pressure.
  56. A value above 1.0 indicates buying pressure, a value below 1.0
  57. indicates selling pressure.
  58. The U/D is computed a unique way in this script. It attempts to show
  59. accumulation and distribution effectively, while filtering out the
  60. exagerations and distortions which U/D ratios can be subject to due
  61. to periods of extreme volume.
  62. 40 days are used in computing the ratio.  The "average price
  63. weighted toward the close" (  (H+L+C)/3  ) is used to determine whether
  64. the price was up or down from day to day. If more than 200% of the 40 day
  65. MA is traded, then only 200% of the average volume is added to the
  66. up side or the down side. In other words, there is a ceiling of 200%
  67. of normal volume which can be used in the U/D calculation. If a stock
  68. trades 300%, 700%, 1000% or more of its 40 day average volume, then
  69. only 200% of the 40MA on the day the volume took place is added.
  70. The legend on top of the U/D graph shows the current U/D, the change
  71. from yesterday, the percent of time in the past 40 days the ratio was
  72. greater than 1, and how many days ago the last cross of the 1 line
  73. took place. The percent above 1 figure is helpful if the ratio has been
  74. very close to the 1 line for awhile and it's difficult to tell which
  75. side it has been on more of the time. The 40U/D graph also gives the
  76. value of the the standard 50U/D. That is, 50 days used, close alone
  77. determines whether price was up or down, and no filtering of extreme
  78. volume. It can be interesting to see how the value compares to the
  79. modified 40 U/D value.
  80.     Most data is printed to the screen during scanning, and is saved
  81. in the output file "BASE-NH.LST". Stocks found which are breaking out
  82. of a base and are also making a 10+ week high which is more significant
  83. than the base period indicates, are listed with an asterisk (*) next
  84. to the base period figure. Also, if a stock closes at a new high,
  85. as opposed to a price which it has closed at before, the screen will
  86. report NH. If the close is a yearly high but not a new high, it is
  87. reported as 0% off high.
  88.     There are three "switches" which allow you to customize the script
  89. to your preferences.
  90.     The GRAPH_SWITCH allows you to turn off the graph feature, for
  91. unattended running of the script. Stocks found will only be listed to
  92. the screen and saved in the output file, and the script will not stop
  93. until it is finished with the ticker list.
  94.     The HIBASE_ONLY_SWITCH can be set to find only stocks at or near
  95. new highs, or else it will also find base breakouts and 10+ week
  96. highs reguardless of where the stock is relative to it's yearly high.
  97.     The UD_GRAPH_SWITCH can be set to turn off the 40U/D graph, and only
  98. show the price and volume graphs. This may be attractive because the
  99. U/D graph takes alot of time to compute, so turning it off will reduce
  100. scanning time. If it is turned off, the standard 50U/D value (which is
  101. very quick to compute) will appear in the volume graph, as well as on
  102. the screen during scanning.
  103. }
  104. GRAPH_SWITCH = 1;  { <<<<<< '1' SHOWS GRAPHS, '0' TURNS OFF GRAPHS}
  105. HIBASE_ONLY_SWITCH = 0;  { <<<<<< '1' FINDS ONLY HI BASES, 0 FINDS LO BASE}
  106.                                                            {BREAKOUTS ALSO}
  107. UD_GRAPH_SWITCH = 1;  {<<<<< '0' TURNS OFF 40U/D GRAPH AND INDICATES 50U/D}
  108.                                      {VALUE ONLY, '1' TURNS ON 40U/D GRAPH}
  109. #max_quotes 255
  110. #output_file 'BASE-NH.LST'
  111. if first_ticker then begin
  112. if hibase_only_switch = 1 then goto hi_header;
  113. writeln(
  114. '   **** New highs, high bases, 10+ week highs, & low base breakouts ****
  115. ');
  116. goto next_ln;
  117. :hi_header
  118. writeln(
  119. '         ******* New highs and possible near base breakouts *******
  120. ');
  121. :next_ln
  122. if ud_graph_switch = 1 then goto write_with_40;
  123. writeln(
  124. '                                      52 Week  |--Base-|               50')
  125. ;goto next_line;
  126. :write_with_40
  127. writeln(
  128. '                                      52 Week  |--Base-|               40')
  129. ;
  130. :next_line
  131. writeln(
  132. '    Name           Close  Change  %OH   High   %Rng  Wks   Vol    %V   U/D'
  133. );
  134. writeln(
  135. '    ----           -----  ------  ---   ----   ---- ----   ---    --   ---'
  136. );
  137. end;
  138. if quote_count < 65 then return;
  139. hiqc : array;
  140. qc = (quote_count-2);
  141. hiqc = hhv(c,qc);
  142. if hibase_only_switch = 0 then goto lb_also;
  143. if c < (hiqc*.95) then return;
  144. :lb_also
  145. hi30 : array;
  146. hi30 = hhv(c,31-1);
  147. if c[0] < (hiqc * .95) and c[0] <= hi30[-1] then return;
  148. hi50_switch = 0;
  149. hi40 : array;
  150. hi40 = hhv(c,41-1);
  151. hi50 : array;
  152. hi50 = hhv(c,51-1);
  153. hi60 : array;
  154. hi60 = hhv(c,61-1);
  155. if c[0] > hi50[-1] and c[0] < hiqc then hi50_switch = 1;
  156. if hi30[0] > hi30[-1] then hv30 = hi30[-1] else hv30 = hi30[0];
  157. if hi40[0] > hi40[-1] then hv40 = hi40[-1] else hv40 = hi40[0];
  158. if hi60[0] > hi60[-1] then hv60 = hi60[-1] else hv60 = hi60[0];
  159. lo30 : array;
  160. lo30 = llv(c,30);
  161. lo40 : array;
  162. lo40 = llv(c,40);
  163. lo60 : array;
  164. lo60 = llv(c,60);
  165. newhigh_switch = 0;
  166. r30 = (1-(lo30/hv30))*100;
  167. r40 = (1-(lo40/hv40))*100;
  168. r60 = (1-(lo60/hv60))*100;
  169. if hi50_switch =0 then goto find_base;
  170. c50 = -50;
  171. :count50
  172. if c[c50] >= c[0] then goto x50;
  173. c50 = c50 - 1; goto count50;
  174. :x50
  175. c50 = -(c50+1);
  176. next50: array;
  177. next50 = hhv(c,c50-1);
  178. :find_base
  179. nobase = 0;
  180. btest = 0;
  181. if r40 <= 2 then gosub b40;
  182. if btest = 1 then goto stats2;
  183. if r30 <= 2 then gosub b30;
  184. if btest = 1 then goto stats2;
  185. if r60 <= 4 then gosub b60;
  186. if btest = 1 then goto stats2;
  187. if r40 <= 4 then gosub b40;
  188. if btest = 1 then goto stats2;
  189. if r30 <= 4 then gosub b30;
  190. if btest = 1 then goto stats2;
  191. if r60 <= 6 then gosub b60;
  192. if btest = 1 then goto stats2;
  193. if r40 <= 6 then gosub b40;
  194. if btest = 1 then goto stats2;
  195. if r30 <= 6 then gosub b30;
  196. if btest = 1 then goto stats2;
  197. if r60 <= 8 then gosub b60;
  198. if btest = 1 then goto stats2;
  199. if r40 <= 8 then gosub b40;
  200. if btest = 1 then goto stats2;
  201. if r30 <= 8 then gosub b30;
  202. if btest = 1 then goto stats2;
  203. if r60 <= 10 then gosub b60;
  204. if btest = 1 then goto stats2;
  205. if r40 <= 10 then gosub b40;
  206. if btest = 1 then goto stats2;
  207. if r30 <= 10 then gosub b30;
  208. if btest = 1 then goto stats2;
  209. if r60 <= 12 then gosub b60;
  210. if btest = 1 then goto stats2;
  211. if r40 <= 12 then gosub b40;
  212. if btest = 1 then goto stats2;
  213. if r30 <= 12 then gosub b30;
  214. if btest = 1 then goto stats2;
  215. if r60 <= 14 then gosub b60;
  216. if btest = 1 then goto stats2;
  217. if r40 <= 14 then gosub b40;
  218. if btest = 1 then goto stats2;
  219. if r30 <= 14 then gosub b30;
  220. if btest = 1 then goto stats2;
  221. if r60 <= 16 then gosub b60;
  222. if btest = 1 then goto stats2;
  223. if r40 <= 16 then gosub b40;
  224. if btest = 1 then goto stats2;
  225. if r30 <= 15 then gosub b30;
  226. if btest = 1 then goto stats2;
  227. if r60 <= 18 then gosub b60;
  228. if btest = 1 then goto stats2;
  229. if r40 <= 18 then gosub b40;
  230. if btest = 1 then goto stats2;
  231. if r60 <= 20 then gosub b60;
  232. if btest = 1 then goto stats2;
  233. if r40 <= 20 then gosub b40;
  234. if btest = 1 then goto stats2;
  235. if r60 <= 25 then gosub b60;
  236. if btest = 1 then goto stats2;
  237. if r30 <= 16 then gosub b30;
  238. if btest = 1 then goto stats2;
  239. Nobase = 1;
  240. if hi50_switch = 1 then goto newhigh;
  241. if c[0] = hiqc then goto newhigh else return;
  242. :b30
  243. t = -30;
  244. rng = r30;
  245. lorg = lo30;
  246. hirg = hv30;
  247. goto count_days;
  248. :b40
  249. t = -40;
  250. rng = r40;
  251. lorg = lo40;
  252. hirg = hv40;
  253. goto count_days;
  254. :b60
  255. t = -60;
  256. rng = r60;
  257. lorg = lo60;
  258. hirg = hv60;
  259. goto count_days;
  260. :newhigh
  261. if c[0] = hiqc then newhigh_switch = 1;
  262. t = 0;
  263. lorg = c[0] * .85;
  264. hirg = c[0];
  265. :count_days
  266. gosub count;
  267. if t = -(qc) then goto stats;
  268. if c[t] < lorg or c[t] > hirg then goto stats else goto count_days;
  269. :count
  270. t = t-1;
  271. return;
  272. :stats
  273. t= -(t+1);
  274. if t= -0 then t =0;
  275. if nobase = 1 then goto stats2;
  276. hi_rng : array;
  277. lo_rng : array;
  278. hi_rng = hhv(c,(t-1));
  279. lo_rng = llv(c,t);
  280. if hi_rng[0] <= hi_rng[-1] and c[0] < (hiqc*.95) then return;
  281. if hi_rng[0] > hi_rng[-1] then rng = (1-(lo_rng/hi_rng[-1]))*100
  282. else rng = (1-(lo_rng/hi_rng))*100;
  283. basetest = -t; midbase = -t*.66; hbline = hi_rng[-1] *.96;
  284. :basecheck
  285. if basetest > midbase then return;
  286. if h[basetest] >= hbline then btest = 1;
  287. if btest = 1 then return;
  288. basetest = basetest +1;
  289. goto basecheck;
  290. :stats2
  291. if newhigh_switch = 1 then rng = 15;
  292. if hi50_switch = 1 and nobase = 1 then rng = 15;
  293. v50 : array;
  294. v50 = mov(v,50,'s');
  295. vv50 = ((v[0]/v50[-1])*100);
  296. v1 = (v[-1]+v[-2]+v[-3]+v[-4]+v[-5])/5;
  297. v1v50 = ((v1/v50[-6])*100);
  298. v2 = (v[-6]+v[-7]+v[-8]+v[-9]+v[-10])/5;
  299. v2v50 = ((v2/v50[-11])*100);
  300. v3 = (v[-11]+v[-12]+v[-13]+v[-14]+v[-15])/5;
  301. v3v50 = ((v3/v50[-16])*100);
  302. v4 = (v[-16]+v[-17]+v[-18]+v[-19]+v[-20])/5;
  303. v4v50 = ((v4/v50[-21])*100);
  304. oh = 100-((c/hiqc)*100);
  305. chg = c[0]-c[-1];
  306. if ud_graph_switch = 0 then goto ud40_not;
  307. v40 : array;
  308. v40 = mov(v,40,'s');
  309. ud2:array;
  310. up2:array;
  311. dn2:array;
  312. maup2:array;
  313. madn2:array;
  314. vo : array;
  315. vo = v;
  316. up2[1]:=0; dn2[1]:=0;
  317. for j := 2; j<= quote_count; j:=j+1;
  318. begin
  319. if j < 40 then v40[j] = v40[1];
  320. if vo[j] >= (v40[j]*2) then vo[j] = (v40[j]*2);
  321. py = (h[j-1]+l[j-1]+c[j-1])/3;
  322. pt = (h[j]+l[j]+c[j])/3;
  323. if pt > py then up2[j]:=vo[j] else
  324. up2[j]:=0;
  325. if pt < py then dn2[j]:=vo[j] else
  326. dn2[j]:=0
  327. end;
  328. maup2:=Mov(up2,40,'s');
  329. madn2:=Mov(dn2,40,'s');
  330. ud2:=div(maup2,madn2);
  331. ud_chg= ud2[0] - ud2[-1];
  332. da= -40;
  333. np = 0;
  334. :check_perc_one
  335. da = da + 1;
  336. if da = 1 then goto perc_one;
  337. if ud2[da]>=1 then np = np + 1;
  338. goto check_perc_one;
  339. :perc_one
  340. p_one = (np/40)*100;
  341. x_ago = 1;
  342. :check_cross
  343. x_ago = x_ago - 1;
  344. if x_ago = -(quote_count-41) then goto graphit;
  345. if ud2[x_ago] >1 and ud2[x_ago-1] <1 then goto graphit;
  346. if ud2[x_ago]<1 and ud2[x_ago-1] >1 then goto graphit else goto check_cross;
  347. :graphit
  348. if x_ago <> 0 then x_ago = -(x_ago);
  349. :ud40_not
  350. av = 0;
  351. dv = 0;
  352. d = -51;
  353. :loop
  354. gosub countit;
  355. if d = 0 then goto figure;
  356. if c[d] < c[d+1] then av = av + v[d+1];
  357. if c[d] > c[d+1] then dv = dv + v[d+1];
  358. goto loop;
  359. :countit
  360. d = d + 1;
  361. return;
  362. :figure
  363. ud = av/dv;
  364. if graph_switch <> 1 then goto no_graph;
  365. if ud_graph_switch = 1 then goto ud_yes;
  366. opengraph(2);
  367. sizegraph(5,2);
  368. goto start_graph;
  369. :ud_yes
  370. opengraph(3);
  371. sizegraph(6,2,2);
  372. :start_graph
  373. if hi50_switch = 1 and c50 <> t then goto hi50_graph;
  374. graph(1,' '+format(c[0],'$%5.2f')+' is '+format(oh,'%2.1f%')
  375. +' off '+format(hiqc[0],'$%5.2f')+' high.   Change= '+format(chg,'$%2.2f')
  376. +'   Base '+
  377. format(rng,'%2.1f%')+' for '+format((t/5),'%2.1f')+' weeks.');
  378. goto lines;
  379. :hi50_graph
  380. graph(1,' '+format(c[0],'$%5.2f')+' is '+format(oh,'%2.1f%')
  381. +' off '+format(hiqc[0],'$%5.2f')+' high.   Change= '+format(chg,'$%2.2f')
  382. +'   Base '+
  383. format(rng,'%2.1f%')+' for '+format((t/5),'%2.1f')+' weeks.  '+format
  384. ((c50/5),'%2.1f')+' week high.');
  385. :lines
  386. if newhigh_switch = 1 then goto graphvol;
  387. if hi50_switch = 0 then goto draw_base;
  388. drawline(7,0,next50[-1],0,next50[-1],-c50,-1);
  389. if nobase=1 then goto graphvol;
  390. :draw_base
  391. drawline(12,0,lorg,0,lorg,-t,-1);
  392. drawline(12,0,hirg,0,hirg,-t,-1);
  393. :graphvol
  394. if ud_graph_switch = 1 then goto udg_yes;
  395. graph(v,'Today='+format(v[0],'%5.f')+'   50MA='+format(v50[-1],'%5.f')
  396. +'   %Today='+format(vv50,'%4.f%')+'   50U/D='+format(ud,'%1.2f')
  397. +'     W1='+format(v1v50,'%3.f%')+'   W2='+format(v2v50,'%3.f%')
  398. +'   W3='+format(v3v50,'%3.f%')+' of',v50,' 50MA.');
  399. closegraph();
  400. goto no_graph;
  401. :udg_yes
  402. graph(v,'Today='+format(v[0],'%5.f')+'   50MA='+format(v50[-1],'%5.f')
  403. +'   %Today='+format(vv50,'%4.f%')+'      W1='+format(v1v50,'%3.f%')
  404. +'   W2='+format(v2v50,'%3.f%')+'   W3='+format(v3v50,'%3.f%')
  405. +'   W4='+format(v4v50,'%3.f%')+' of',v50,' 50MA.');
  406. graph(ud2,'40 U/D= '+format(ud2[0],'%1.2f')+'   Change= '
  407. +format(ud_chg,'%0.2f')+'   Above ONE (40 Days)= '+format(p_one,'%2.f%')
  408. +'   Last Cross '+format(x_ago,'%1.f')+' Days Ago.   50U/D= '
  409. +format(ud,'%1.2f'));
  410. drawline(7,0,1,0,1);closegraph();
  411. :no_graph
  412. if ud_graph_switch = 1 then ud3 = ud2[0];
  413. if ud_graph_switch = 0 then ud3 = ud;
  414. if c[0] = hiqc[-1] and nobase = 0 then goto write_no_bo;
  415. if c[0] >= hiqc[-1] then goto write_nobase;
  416. if hi50_switch = 1 and nobase = 1 then goto hi50_only;
  417. if hi50_switch = 1 and nobase = 0 and t = c50 then goto write_no_bo;
  418. if hi50_switch = 1 and nobase = 0 then goto base_and_hi50;
  419. :write_no_bo
  420. writeln(fullname,' ',format(c[0],'%7.2f'),'  ',format(chg,'%6.2f'),'  ',
  421. format(oh,'%2.f%'),' ',format(hiqc[0],'%7.2f'),' ',format(rng,'%3.f%')
  422. ,'  ',
  423. format(t/5,'%3.f'),' ',format(v[0],'%7.f'),'',format(vv50,'%5.f%'),'  ',
  424. format(ud3,'%3.1f'));
  425. return;
  426. :hi50_only
  427. writeln(fullname,' ',format(c[0],'%7.2f'),'  ',format(chg,'%6.2f'),'  ',
  428. format(oh,'%2.f%'),' ',format(hiqc[0],'%7.2f'),'   Hi  ',
  429. format(c50/5,'%3.f'),' ',format(v[0],'%7.f'),'',format(vv50,'%5.f%'),'  ',
  430. format(ud3,'%3.1f'));
  431. return;
  432. :base_and_hi50
  433. writeln(fullname,' ',format(c[0],'%7.2f'),'  ',format(chg,'%6.2f'),'  ',
  434. format(oh,'%2.f%'),' ',format(hiqc[0],'%7.2f'),' ',format(rng,'%3.f%')
  435. ,'  ',
  436. format(t/5,'%3.f'),'*',format(v[0],'%7.f'),'',format(vv50,'%5.f%'),'  ',
  437. format(ud3,'%3.1f'));
  438. return;
  439. :write_nobase
  440. if c[0] = hiqc[-1] and nobase = 1 then goto old_high;
  441. if c[0] > hiqc[-1] and nobase = 1 then goto nh_nobase;
  442. writeln(fullname,' ',format(c[0],'%7.2f'),'  ',format(chg,'%6.2f')
  443. ,'   NH ',format(hiqc[0],'%7.2f'),' ',format(rng,'%3.f%')
  444. ,'  ',
  445. format(t/5,'%3.f'),' ',format(v[0],'%7.f'),'',format(vv50,'%5.f%'),'  ',
  446. format(ud3,'%3.1f'));
  447. return;
  448. :nh_nobase
  449. writeln(fullname,' ',format(c[0],'%7.2f'),'  ',format(chg,'%6.2f')
  450. ,'   NH ',
  451. format(hiqc[0],'%7.2f'),'   No Base ',
  452. format(v[0],'%7.f'),'',format(vv50,'%5.f%'),'  ',
  453. format(ud3,'%3.1f'));
  454. return;
  455. :old_high
  456. writeln(fullname,' ',format(c[0],'%7.2f'),'  ',format(chg,'%6.2f'),'  ',
  457. format(oh,'%2.f%'),' ',format(hiqc[0],'%7.2f'),'   No Base ',
  458. format(v[0],'%7.f'),'',format(vv50,'%5.f%'),'  ',
  459. format(ud3,'%3.1f'));
  460. return;
  461.