Gordon Rose.afl
上传用户:shiqiang
上传日期:2009-06-12
资源大小:1289k
文件大小:30k
源码类别:

金融证券系统

开发平台:

Others

  1. //------------------------------------------------------------------------------
  2. //
  3. //  Formula Name:    Gordon Rose
  4. //  Author/Uploader: Gordon Rose 
  5. //  E-mail:          
  6. //  Date/Time Added: 2004-02-05 00:05:21
  7. //  Origin:          Strong desire to use pivots and patterns as basis for trading setups and trading.
  8. //  Keywords:        pivot fibonacci tcz
  9. //  Level:           semi-advanced
  10. //  Flags:           system,exploration,indicator
  11. //  Formula URL:     http://www.amibroker.com/library/formula.php?id=326
  12. //  Details URL:     http://www.amibroker.com/library/detail.php?id=326
  13. //
  14. //------------------------------------------------------------------------------
  15. //
  16. //  Both indicator and exploration code for combination of fibonacci
  17. //  retracements identified in "Fibonacci for the Active Trader" by Derrik
  18. //  Hobbes. Determines pivots, draws retracements, and explores for them.
  19. //
  20. //------------------------------------------------------------------------------
  21. // **************************
  22. // BEING EXPLORATION CODE
  23. // **************************
  24. // -- what will be our lookback range for the hh and ll?
  25. nBars = Param("Number of bars", 12, 5, 40);
  26. bTrace = Param("Include trace output", 1, 0, 1);
  27. nNoPivsInSetup = Param("No. Pivs in Setup", 4, 3, 4, 1);
  28. bShowTCZ = Param("Show TCZ", 1, 0, 1); 
  29. nMinBarsBtwPivs = Param("Min. number of bars btw. pivots", 1, 1, 10, 1);
  30. nMinPctBtwPivs = Param("Min. percent diff. btw. pivots", .05, .04, .2, .01);
  31. bLastBarCanBePiv = Param("Last bar can be a pivot", 1, 0, 1); 
  32. retrcTolerance = .01;
  33. tczTolerance = .005;
  34. nNumBarsToScan = 120;
  35. // -- added from exploration version 20040204
  36. nExploreBarIdx = 0;
  37. nExploreDate = 0;
  38. nCurDateNum = 0;
  39. DN = DateNum();
  40. DT = DateTime();
  41. // -- key exploration variables
  42. bTCZLong = False;
  43. bTCZShort = False;
  44. nAnchorPivIdx = 0;
  45. ADX8 = ADX(8);
  46. // 1 - INDICATOR, 2 - COMMENTARY, 3 - SCAN, 
  47. // 4 - EXPLORATION, 5 - BACKTEST / Optimize 
  48. if(Status("action")==1) {
  49. bDraw = True;
  50. bUseLastVis = Param("Use last visible bar", 1, 0, 1);
  51. } else {
  52. bDraw = False;
  53. bUseLastVis = False;
  54. bTrace = False;
  55. nExploreDate = Status("rangetodate");
  56. for (i=LastValue(BarIndex());i>=0;i--) {
  57. nCurDateNum = DN[i];
  58. if (nCurDateNum == nExploreDate) {
  59. nExploreBarIdx = i;
  60. }
  61. }
  62. // -- if(Status("action")==1...
  63. }
  64. GraphXSpace=7;
  65. // -- basic candle chart
  66. // -- if this appears inside if block, strange
  67. //    drawing results!
  68. PlotOHLC(Open, High, Low, Close, 
  69. "BIdx = " + BarIndex() + 
  70. "n" + "O = " + O + "n"+"H = "+ H + "n"+"L  = " + L 
  71. + "n"+"C ",
  72. colorBlack, styleCandle); 
  73. if (bDraw) {
  74. Plot(MA(C, 21), "21 bar MA", colorAqua, 
  75. styleLine+styleNoRescale+styleNoLabel);
  76. Plot(MA(C, 55), "55 bar MA", colorGreen, 
  77. styleLine+styleNoRescale+styleNoLabel);
  78. //Plot(MA(C, 233), "233 bar MA", colorDarkRed, 
  79. // styleLine+styleNoRescale+styleNoLabel);
  80. }
  81. // -- Create 0-initialized arrays the size of barcount
  82. aHPivs = H - H;
  83. aLPivs = L - L;
  84. aHPivHighs = H - H;
  85. aLPivLows = L - L;
  86. aHPivIdxs = H - H;
  87. aLPivIdxs = L - L;
  88. aAddedHPivs = H - H;
  89. aAddedLPivs = L - L;
  90. aLegVol = H - H;
  91. aRetrcVol = H - H;
  92. nHPivs = 0;
  93. nLPivs = 0;
  94. lastHPIdx = 0;
  95. lastLPIdx = 0;
  96. lastHPH = 0;
  97. lastLPL = 0;
  98. curPivBarIdx = 0;
  99. // -- looking back from the current bar, how many bars 
  100. //    back were the hhv and llv values of the previous 
  101. //    n bars, etc.?
  102. aHHVBars = HHVBars(H, nBars);
  103. aLLVBars = LLVBars(L, nBars);
  104. aHHV = HHV(H, nBars);
  105. aLLV = LLV(L, nBars);
  106. // -- Initialize value of curTrend
  107. nLastVisBar = LastValue(
  108. Highest(IIf(Status("barvisible"), BarIndex(), 0)));
  109. curBar = IIf(nlastVisBar > 0 AND bUseLastVis, nlastVisBar, 
  110. IIf(Status("action")==4 AND nExploreBarIdx > 0, nExploreBarIdx,
  111. LastValue(BarIndex())));
  112. curTrend = "";
  113. if (aLLVBars[curBar] < aHHVBars[curBar]) 
  114. curTrend = "D";
  115. else 
  116. curTrend = "U";
  117. // -- Loop through bars. Search for 
  118. //    entirely array-based approach
  119. //    in future version
  120. /* *******************
  121. Find main pivots
  122. ******************* */
  123. // -- Make sure there are enough bars!
  124. if (curBar >= nNumBarsToScan) {
  125. for (i=0; i<nNumBarsToScan; i++) {
  126. // -- value of curBar dependent on two parameters
  127. curBar = IIf(nlastVisBar > 0 AND bUseLastVis, 
  128. nlastVisBar-i, 
  129. IIf(Status("action")==4 AND nExploreBarIdx > 0, 
  130. nExploreBarIdx-i,
  131. LastValue(BarIndex())-i));
  132. // -- Have we identified a pivot? If trend is down...
  133. if (aLLVBars[curBar] < aHHVBars[curBar]) {
  134. // ... and had been up, this is a trend change
  135. if (curTrend == "U") {
  136. curTrend = "D";
  137. // -- Capture pivot information
  138. curPivBarIdx = curBar - aLLVBars[curBar];
  139. aLPivs[curPivBarIdx] = 1;
  140. aLPivLows[nLPivs] = L[curPivBarIdx];
  141. aLPivIdxs[nLPivs] = curPivBarIdx;
  142. nLPivs++;
  143. }
  144. // -- or current trend is up
  145. } else {
  146. if (curTrend == "D") {
  147. curTrend = "U";
  148. curPivBarIdx = curBar - aHHVBars[curBar];
  149. aHPivs[curPivBarIdx] = 1;
  150. aHPivHighs[nHPivs] = H[curPivBarIdx];
  151. aHPivIdxs[nHPivs] = curPivBarIdx;
  152. nHPivs++;
  153. }
  154. // --  If curTrend is up...else...
  155. }
  156. // -- loop through bars
  157. }
  158. /* *******************
  159. Found main pivots
  160. ******************* */
  161. /* *************************
  162. Finding missed pivot(s)
  163. ************************* */
  164. // -- Start at last bar. Reestablish curBar
  165. curBar = 
  166. IIf(nlastVisBar > 0 AND bUseLastVis, 
  167. nlastVisBar, 
  168. IIf(Status("action")==4 AND nExploreBarIdx > 0, 
  169. nExploreBarIdx,
  170. LastValue(BarIndex()))
  171. );
  172. // -- Make sure I found at least two of each above.
  173. if (nHPivs >= 2 AND nLPivs >= 2) {
  174. lastLPIdx = aLPivIdxs[0];
  175. lastLPL = aLPivLows[0];
  176. lastHPIdx = aHPivIdxs[0];
  177. lastHPH = aHPivHighs[0];
  178. nLastHOrLPivIdx = Max(lastLPIdx, lastHPIdx);
  179. nAddPivsRng = curBar - nLastHOrLPivIdx;
  180. aLLVAfterLastPiv = LLV(L, nAddPivsRng);  
  181. nLLVAfterLastPiv = aLLVAfterLastPiv[curBar];
  182. aLLVIdxAfterLastPiv = LLVBars(L, nAddPivsRng);  
  183. nLLVIdxAfterLastPiv = curBar - aLLVIdxAfterLastPiv[curBar];
  184. aHHVAfterLastPiv = HHV(H, nAddPivsRng); 
  185. nHHVAfterLastPiv = aHHVAfterLastPiv[curBar];
  186. aHHVIdxAfterLastPiv = HHVBars(H, nAddPivsRng); 
  187. nHHVIdxAfterLastPiv = curBar - aHHVIdxAfterLastPiv[curBar];
  188. // -- Later want to add last high pivot only if
  189. //    not in buy mode from last and still in trade
  190. /*
  191. Note - I'm only interested in adding pivots if I'm in 
  192. a higher-highs or lower-lows scenario
  193. */
  194. // -- OK, let's start where the last high pivot occurs after the
  195. //    last Low pivot
  196. if (lastHPIdx > lastLPIdx) {
  197. /* There are at least two possibilities here. One is that
  198.     the previous high was higher, indicating that this is a 
  199.     possible short retracement or one in the making.
  200.     The other is that the previous high was lower, indicating 
  201.     that this is a possible long retracement in the working. 
  202. However, both depend on opposing pivots. E.g., if I find 
  203. higher highs, what if I have lower lows?  
  204. If the highs are descending, then I can consider:
  205.     - a lower low, and leave it at that
  206.     - a higher high and higher low
  207.     - a lower low and another lower high
  208. */
  209. if (aHPivHighs[0] < aHPivHighs[1]) {
  210. if (nLLVAfterLastPiv < aLPivLows[0] AND 
  211. (nLLVIdxAfterLastPiv - lastHPIdx - 1) >= nMinBarsBtwPivs
  212. AND nLLVIdxAfterLastPiv != curBar ) {
  213. // -- OK, we'll add this as a pivot. 
  214. //    Mark it for plotting...
  215. aLPivs[nLLVIdxAfterLastPiv] = 1;
  216. aAddedLPivs[nLLVIdxAfterLastPiv] = 1;
  217. //    ...and then rearrange elements in the 
  218. //    pivot information arrays
  219. for (j=0; j<nLPivs; j++) {
  220. aLPivLows[nLPivs-j] = aLPivLows[nLPivs-(j+1)];
  221. aLPivIdxs[nLPivs-j] = aLPivIdxs[nLPivs-(j+1)];
  222. }
  223. aLPivLows[0] = nLLVAfterLastPiv;
  224. aLPivIdxs[0] = nLLVIdxAfterLastPiv;
  225. nLPivs++;
  226. // -- Test whether to add piv given last piv is high 
  227. //    AND we have lower highs
  228. }
  229. // -- Here, the last piv is a high piv, and we have 
  230. //    higher-highs. The most likely addition is a 
  231. //    Low piv that is a retracement.
  232. } else {
  233. if (nLLVAfterLastPiv > aLPivLows[0] AND 
  234. (nLLVIdxAfterLastPiv - lastHPIdx - 1) >= nMinBarsBtwPivs
  235. AND nLLVIdxAfterLastPiv != curBar ) {
  236. // -- OK, we'll add this as a pivot. 
  237. //    Mark it for plotting...
  238. aLPivs[nLLVIdxAfterLastPiv] = 1;
  239. aAddedLPivs[nLLVIdxAfterLastPiv] = 1;
  240. //    ...and then rearrange elements in the 
  241. //    pivot information arrays
  242. for (j=0; j<nLPivs; j++) {
  243. aLPivLows[nLPivs-j] = aLPivLows[nLPivs-(j+1)];
  244. aLPivIdxs[nLPivs-j] = aLPivIdxs[nLPivs-(j+1)];
  245. }
  246. aLPivLows[0] = nLLVAfterLastPiv;
  247. aLPivIdxs[0] = nLLVIdxAfterLastPiv;
  248. nLPivs++;
  249. // -- Test whether to add piv given last piv is high 
  250. //    AND we have lower highs
  251. }
  252. // -- The last piv is a high and we have higher highs 
  253. //    OR lower highs
  254. }
  255. /* ****************************************************************
  256. Still finding missed pivot(s). Here, the last piv is a low piv.
  257. **************************************************************** */
  258. } else {
  259. // -- First case, lower highs
  260. if (aHPivHighs[0] < aHPivHighs[1]) {
  261. if (nHHVAfterLastPiv < aHPivHighs[0] AND 
  262. (nHHVIdxAfterLastPiv - lastLPIdx - 1) >= nMinBarsBtwPivs
  263. AND nHHVIdxAfterLastPiv != curBar ) {
  264. // -- OK, we'll add this as a pivot. 
  265. //    Mark that for plotting
  266. aHPivs[nHHVIdxAfterLastPiv] = 1;
  267. aAddedHPivs[nHHVIdxAfterLastPiv] = 1;
  268. //    ...and then rearrange elements in the 
  269. //    pivot information arrays
  270. for (j=0; j<nHPivs; j++) {
  271. aHPivHighs[nHPivs-j] = aHPivHighs[nHPivs-(j+1)];
  272. aHPivIdxs[nHPivs-j] = aHPivIdxs[nhPivs-(j+1)];
  273. }
  274. aHPivHighs[0] = nHHVAfterLastPiv;
  275. aHPivIdxs[0] = nHHVIdxAfterLastPiv;
  276. nHPivs++;
  277. // -- Test whether to add piv given last piv is high 
  278. //    AND we have lower highs
  279. }
  280. // -- Second case when last piv is a low piv, higher highs 
  281. //    Most likely addition is high piv that is a retracement.
  282. //    Considering adding a high piv as long as it is higher
  283. } else {
  284. // -- Where I have higher highs,
  285. if (nHHVAfterLastPiv > aHPivHighs[0] AND 
  286. (nHHVIdxAfterLastPiv - lastLPIdx - 1) >= nMinBarsBtwPivs
  287. AND nHHVIdxAfterLastPiv != curBar ) {
  288. // -- OK, we'll add this as a pivot. 
  289. //    Mark it for plotting...
  290. aHPivs[nHHVIdxAfterLastPiv] = 1;
  291. aAddedHPivs[nHHVIdxAfterLastPiv] = 1;
  292. //    ...and then rearrange elements in the 
  293. //    pivot information arrays
  294. for (j=0; j<nHPivs; j++) {
  295. aHPivHighs[nHPivs-j] = aHPivHighs[nHPivs-(j+1)];
  296. aHPivIdxs[nHPivs-j] = aHPivIdxs[nhPivs-(j+1)];
  297. }
  298. aHPivHighs[0] = nHHVAfterLastPiv;
  299. aHPivIdxs[0] = nHHVIdxAfterLastPiv;
  300. nHPivs++;
  301. // -- Test whether to add piv given last piv is high 
  302. //    AND we have lower highs
  303. }
  304. }
  305. // -- If there are at least two of each
  306. }
  307. /* ****************************************
  308. // -- Done with finding pivots
  309. ***************************************** */ 
  310. if (bDraw) {
  311. // -- OK, let's plot the pivots using arrows
  312. PlotShapes(
  313. IIf(aHPivs==1, shapeDownArrow, shapeNone), 
  314. colorRed, 0,  High, Offset=-15);
  315. PlotShapes(
  316. IIf(aAddedHPivs==1, shapeDownArrow, shapeNone),
  317. colorDarkRed, 0, High, Offset=-15);
  318. PlotShapes(
  319. IIf(aLPivs==1, shapeUpArrow , shapeNone),
  320. colorGreen, 0, Low, Offset=-15);
  321. PlotShapes(
  322. IIf(aAddedLPivs==1, shapeUpArrow , shapeNone), 
  323. colorDarkGreen, 0, Low, Offset=-15);
  324. }
  325. /* ****************************************
  326. // -- Done with discovering and plotting pivots 
  327. ***************************************** */ 
  328. // -- I'm going to want to look for possible retracement
  329. risk = 0;
  330. profInc = 0;
  331. nLeg0Pts = 0;
  332. nLeg0Bars = 0;
  333. nLeg0Vol = 0;
  334. nLeg1Pts = 0;
  335. nLeg1Bars = 0;
  336. nLeg1Vol = 0;
  337. nLegBarsDiff = 0;
  338. nRtrc0Pts = 0;
  339. nRtrc0Bars = 0;
  340. nRtrc0Vol = 0;
  341. nRtrc1Pts = 0;
  342. nRtrc1Bars = 0;
  343. nRtrc1Vol = 0;
  344. minRtrc = 0;
  345. maxRtrc = 0;
  346. minLine = 0;
  347. maxLine = 0;
  348. triggerLine = 0;
  349. firstProfitLine = 0;
  350. triggerInc = 0;
  351. triggerPrc = 0;
  352. firstProfitPrc = 0;
  353. retrcPrc = 0;
  354. retrcBar = 0;
  355. retrcBarIdx = 0;
  356. retrcRng = 0;
  357. aRetrcPrc = H-H;
  358. aRetrcPrcBars = H-H;
  359. aRetrcClose = C;
  360. retrcClose = 0;
  361. // -- Do TCZ calcs. Arrangement of pivs very specific
  362. //    for this setup.
  363. if (nHPivs >= 2 AND 
  364. nLPivs >=2 AND  
  365. aHPivHighs[0] > aHPivHighs[1] AND
  366. aLPivLows[0] > aLPivLows[1]) {
  367. tcz500 = 
  368. (aHPivHighs[0] -
  369. (.5 * (aHPivHighs[0] - aLPivLows[1])));
  370. tcz618 = 
  371. (aHPivHighs[0] -
  372. (.618 * (aHPivHighs[0] - aLPivLows[1])));
  373. tcz786 = 
  374. (aHPivHighs[0] -
  375. (.786 * (aHPivHighs[0] - aLPivLows[0])));
  376. retrcRng = curBar  - aHPivIdxs[0];
  377. aRetrcPrc = LLV(L, retrcRng);
  378. retrcPrc = aRetrcPrc[curBar];
  379. aRetrcPrcBars  = LLVBars(L, retrcRng);
  380. retrcBarIdx = curBar - aRetrcPrcBars[curBar];
  381. retrcClose = aRetrcClose[retrcBarIdx];
  382. // -- bTCZLong setup?
  383. bTCZLong = (
  384. // -- Are retracement levels arranged in
  385. //    tcz order?
  386. tcz500 >= (tcz786 * (1 - tczTolerance))
  387. AND 
  388. // .681 is below .786 for long setups
  389. tcz618 <= (tcz786 * (1 + tczTolerance))
  390. AND
  391. // -- Is the low in the tcz range
  392. // -- Is the close >= low of tcz range
  393. //    and low <= high of tcz range
  394. retrcClose >= ((1 - retrcTolerance) *  tcz618)
  395. AND
  396. retrcPrc <= ((1 + retrcTolerance) *  tcz500)
  397. ); 
  398. // -- risk would be high of signal bar minus low of zone
  399. //risk = 0;
  400. // -- lower highs and lower lows
  401. } else if (nHPivs >= 2 AND nLPivs >=2 
  402. AND aHPivHighs[0] < aHPivHighs[1] 
  403. AND aLPivLows[0] < aLPivLows[1]) {
  404. tcz500 = 
  405. (aHPivHighs[1] -
  406. (.5 * (aHPivHighs[1] - aLPivLows[0])));
  407. tcz618 = 
  408. (aHPivHighs[0] -
  409. (.618 * (aHPivHighs[1] - aLPivLows[0])));
  410. tcz786 = 
  411. (aHPivHighs[0] -
  412. (.786 * (aHPivHighs[0] - aLPivLows[0])));
  413. retrcRng = curBar  - aLPivIdxs[0];
  414. aRetrcPrc = HHV(H, retrcRng);
  415. retrcPrc = aRetrcPrc[curBar];
  416. aRetrcPrcBars  = HHVBars(H, retrcRng);
  417. retrcBarIdx = curBar - aRetrcPrcBars[curBar];
  418. retrcClose = aRetrcClose[retrcBarIdx];
  419. bTCZShort = (
  420. // -- Are retracement levels arranged in
  421. //    tcz order?
  422. // .500 is below .786 for short setups
  423. tcz500 <= (tcz786 * (1 + tczTolerance))
  424. AND
  425. // .681 is above .786 for short setups
  426. tcz618 >= (tcz786 * (1 - tczTolerance)) 
  427. AND
  428. // -- Is the close <= high of tcz range
  429. //    and high >= low of tcz range
  430. retrcClose <= ((1 + retrcTolerance) *  tcz618)
  431. AND
  432. retrcPrc >= ((1 - retrcTolerance) *  tcz500)
  433. ); 
  434. // -- Risk would be top of zone - low of signal bar 
  435. //risk = 0;
  436. }
  437. Filter = (bTCZShort OR bTCZLong);
  438. AddColumn(C, "Close");
  439. AddColumn(IIf(bTCZLong, 76, 83), "L/S", formatChar);
  440. // **************************
  441. // END EXPLORATION CODE
  442. // **************************
  443. // **************************
  444. // BEGIN INDICATOR CODE
  445. // **************************
  446. // -- what will be our lookback range for the hh and ll?
  447. nBars = Param("Number of bars", 12, 5, 40);
  448. bTrace = Param("Include trace output", 1, 0, 1);
  449. nNoPivsInSetup = Param("No. Pivs in Setup", 4, 3, 4, 1);
  450. bShowTCZ = Param("Show TCZ", 1, 0, 1); 
  451. nMinBarsBtwPivs = Param("Min. number of bars btw. pivots", 1, 1, 10, 1);
  452. nMinPctBtwPivs = Param("Min. percent diff. btw. pivots", .05, .04, .2, .01);
  453. bLastBarCanBePiv = Param("Last bar can be a pivot", 1, 0, 1); 
  454. retrcTolerance = .01;
  455. tczTolerance = .005;
  456. nNumBarsToScan = 120;
  457. // -- added from exploration version 20040204
  458. nExploreBarIdx = 0;
  459. nExploreDate = 0;
  460. nCurDateNum = 0;
  461. DN = DateNum();
  462. DT = DateTime();
  463. // -- key exploration variables
  464. bTCZLong = False;
  465. bTCZShort = False;
  466. nAnchorPivIdx = 0;
  467. ADX8 = ADX(8);
  468. // 1 - INDICATOR, 2 - COMMENTARY, 3 - SCAN, 
  469. // 4 - EXPLORATION, 5 - BACKTEST / Optimize 
  470. if(Status("action")==1) {
  471. bDraw = True;
  472. bUseLastVis = Param("Use last visible bar", 1, 0, 1);
  473. } else {
  474. bDraw = False;
  475. bUseLastVis = False;
  476. bTrace = False;
  477. nExploreDate = Status("rangetodate");
  478. for (i=LastValue(BarIndex());i>=0;i--) {
  479. nCurDateNum = DN[i];
  480. if (nCurDateNum == nExploreDate) {
  481. nExploreBarIdx = i;
  482. }
  483. }
  484. // -- if(Status("action")==1...
  485. }
  486. GraphXSpace=7;
  487. // -- basic candle chart
  488. // -- if this appears inside if block, strange
  489. //    drawing results!
  490. PlotOHLC(Open, High, Low, Close, 
  491. "BIdx = " + BarIndex() + 
  492. "n" + "O = " + O + "n"+"H = "+ H + "n"+"L  = " + L 
  493. + "n"+"C ",
  494. colorBlack, styleCandle); 
  495. if (bDraw) {
  496. Plot(MA(C, 21), "21 bar MA", colorAqua, 
  497. styleLine+styleNoRescale+styleNoLabel);
  498. Plot(MA(C, 55), "55 bar MA", colorGreen, 
  499. styleLine+styleNoRescale+styleNoLabel);
  500. //Plot(MA(C, 233), "233 bar MA", colorDarkRed, 
  501. // styleLine+styleNoRescale+styleNoLabel);
  502. }
  503. // -- Create 0-initialized arrays the size of barcount
  504. aHPivs = H - H;
  505. aLPivs = L - L;
  506. aHPivHighs = H - H;
  507. aLPivLows = L - L;
  508. aHPivIdxs = H - H;
  509. aLPivIdxs = L - L;
  510. aAddedHPivs = H - H;
  511. aAddedLPivs = L - L;
  512. aLegVol = H - H;
  513. aRetrcVol = H - H;
  514. nHPivs = 0;
  515. nLPivs = 0;
  516. lastHPIdx = 0;
  517. lastLPIdx = 0;
  518. lastHPH = 0;
  519. lastLPL = 0;
  520. curPivBarIdx = 0;
  521. // -- looking back from the current bar, how many bars 
  522. //    back were the hhv and llv values of the previous 
  523. //    n bars, etc.?
  524. aHHVBars = HHVBars(H, nBars);
  525. aLLVBars = LLVBars(L, nBars);
  526. aHHV = HHV(H, nBars);
  527. aLLV = LLV(L, nBars);
  528. // -- Initialize value of curTrend
  529. nLastVisBar = LastValue(
  530. Highest(IIf(Status("barvisible"), BarIndex(), 0)));
  531. curBar = IIf(nlastVisBar > 0 AND bUseLastVis, nlastVisBar, 
  532. IIf(Status("action")==4 AND nExploreBarIdx > 0, nExploreBarIdx,
  533. LastValue(BarIndex())));
  534. curTrend = "";
  535. if (aLLVBars[curBar] < aHHVBars[curBar]) 
  536. curTrend = "D";
  537. else 
  538. curTrend = "U";
  539. // -- Loop through bars. Search for 
  540. //    entirely array-based approach
  541. //    in future version
  542. /* *******************
  543. Find main pivots
  544. ******************* */
  545. // -- Make sure there are enough bars!
  546. if (curBar >= nNumBarsToScan) {
  547. for (i=0; i<nNumBarsToScan; i++) {
  548. // -- value of curBar dependent on two parameters
  549. curBar = IIf(nlastVisBar > 0 AND bUseLastVis, 
  550. nlastVisBar-i, 
  551. IIf(Status("action")==4 AND nExploreBarIdx > 0, 
  552. nExploreBarIdx-i,
  553. LastValue(BarIndex())-i));
  554. // -- Have we identified a pivot? If trend is down...
  555. if (aLLVBars[curBar] < aHHVBars[curBar]) {
  556. // ... and had been up, this is a trend change
  557. if (curTrend == "U") {
  558. curTrend = "D";
  559. // -- Capture pivot information
  560. curPivBarIdx = curBar - aLLVBars[curBar];
  561. aLPivs[curPivBarIdx] = 1;
  562. aLPivLows[nLPivs] = L[curPivBarIdx];
  563. aLPivIdxs[nLPivs] = curPivBarIdx;
  564. nLPivs++;
  565. }
  566. // -- or current trend is up
  567. } else {
  568. if (curTrend == "D") {
  569. curTrend = "U";
  570. curPivBarIdx = curBar - aHHVBars[curBar];
  571. aHPivs[curPivBarIdx] = 1;
  572. aHPivHighs[nHPivs] = H[curPivBarIdx];
  573. aHPivIdxs[nHPivs] = curPivBarIdx;
  574. nHPivs++;
  575. }
  576. // --  If curTrend is up...else...
  577. }
  578. // -- loop through bars
  579. }
  580. /* *******************
  581. Found main pivots
  582. ******************* */
  583. /* *************************
  584. Finding missed pivot(s)
  585. ************************* */
  586. // -- Start at last bar. Reestablish curBar
  587. curBar = 
  588. IIf(nlastVisBar > 0 AND bUseLastVis, 
  589. nlastVisBar, 
  590. IIf(Status("action")==4 AND nExploreBarIdx > 0, 
  591. nExploreBarIdx,
  592. LastValue(BarIndex()))
  593. );
  594. // -- Make sure I found at least two of each above.
  595. if (nHPivs >= 2 AND nLPivs >= 2) {
  596. lastLPIdx = aLPivIdxs[0];
  597. lastLPL = aLPivLows[0];
  598. lastHPIdx = aHPivIdxs[0];
  599. lastHPH = aHPivHighs[0];
  600. nLastHOrLPivIdx = Max(lastLPIdx, lastHPIdx);
  601. nAddPivsRng = curBar - nLastHOrLPivIdx;
  602. aLLVAfterLastPiv = LLV(L, nAddPivsRng);  
  603. nLLVAfterLastPiv = aLLVAfterLastPiv[curBar];
  604. aLLVIdxAfterLastPiv = LLVBars(L, nAddPivsRng);  
  605. nLLVIdxAfterLastPiv = curBar - aLLVIdxAfterLastPiv[curBar];
  606. aHHVAfterLastPiv = HHV(H, nAddPivsRng); 
  607. nHHVAfterLastPiv = aHHVAfterLastPiv[curBar];
  608. aHHVIdxAfterLastPiv = HHVBars(H, nAddPivsRng); 
  609. nHHVIdxAfterLastPiv = curBar - aHHVIdxAfterLastPiv[curBar];
  610. // -- Later want to add last high pivot only if
  611. //    not in buy mode from last and still in trade
  612. /*
  613. Note - I'm only interested in adding pivots if I'm in 
  614. a higher-highs or lower-lows scenario
  615. */
  616. // -- OK, let's start where the last high pivot occurs after the
  617. //    last Low pivot
  618. if (lastHPIdx > lastLPIdx) {
  619. /* There are at least two possibilities here. One is that
  620.     the previous high was higher, indicating that this is a 
  621.     possible short retracement or one in the making.
  622.     The other is that the previous high was lower, indicating 
  623.     that this is a possible long retracement in the working. 
  624. However, both depend on opposing pivots. E.g., if I find 
  625. higher highs, what if I have lower lows?  
  626. If the highs are descending, then I can consider:
  627.     - a lower low, and leave it at that
  628.     - a higher high and higher low
  629.     - a lower low and another lower high
  630. */
  631. if (aHPivHighs[0] < aHPivHighs[1]) {
  632. if (nLLVAfterLastPiv < aLPivLows[0] AND 
  633. (nLLVIdxAfterLastPiv - lastHPIdx - 1) >= nMinBarsBtwPivs
  634. AND nLLVIdxAfterLastPiv != curBar ) {
  635. // -- OK, we'll add this as a pivot. 
  636. //    Mark it for plotting...
  637. aLPivs[nLLVIdxAfterLastPiv] = 1;
  638. aAddedLPivs[nLLVIdxAfterLastPiv] = 1;
  639. //    ...and then rearrange elements in the 
  640. //    pivot information arrays
  641. for (j=0; j<nLPivs; j++) {
  642. aLPivLows[nLPivs-j] = aLPivLows[nLPivs-(j+1)];
  643. aLPivIdxs[nLPivs-j] = aLPivIdxs[nLPivs-(j+1)];
  644. }
  645. aLPivLows[0] = nLLVAfterLastPiv;
  646. aLPivIdxs[0] = nLLVIdxAfterLastPiv;
  647. nLPivs++;
  648. // -- Test whether to add piv given last piv is high 
  649. //    AND we have lower highs
  650. }
  651. // -- Here, the last piv is a high piv, and we have 
  652. //    higher-highs. The most likely addition is a 
  653. //    Low piv that is a retracement.
  654. } else {
  655. if (nLLVAfterLastPiv > aLPivLows[0] AND 
  656. (nLLVIdxAfterLastPiv - lastHPIdx - 1) >= nMinBarsBtwPivs
  657. AND nLLVIdxAfterLastPiv != curBar ) {
  658. // -- OK, we'll add this as a pivot. 
  659. //    Mark it for plotting...
  660. aLPivs[nLLVIdxAfterLastPiv] = 1;
  661. aAddedLPivs[nLLVIdxAfterLastPiv] = 1;
  662. //    ...and then rearrange elements in the 
  663. //    pivot information arrays
  664. for (j=0; j<nLPivs; j++) {
  665. aLPivLows[nLPivs-j] = aLPivLows[nLPivs-(j+1)];
  666. aLPivIdxs[nLPivs-j] = aLPivIdxs[nLPivs-(j+1)];
  667. }
  668. aLPivLows[0] = nLLVAfterLastPiv;
  669. aLPivIdxs[0] = nLLVIdxAfterLastPiv;
  670. nLPivs++;
  671. // -- Test whether to add piv given last piv is high 
  672. //    AND we have lower highs
  673. }
  674. // -- The last piv is a high and we have higher highs 
  675. //    OR lower highs
  676. }
  677. /* ****************************************************************
  678. Still finding missed pivot(s). Here, the last piv is a low piv.
  679. **************************************************************** */
  680. } else {
  681. // -- First case, lower highs
  682. if (aHPivHighs[0] < aHPivHighs[1]) {
  683. if (nHHVAfterLastPiv < aHPivHighs[0] AND 
  684. (nHHVIdxAfterLastPiv - lastLPIdx - 1) >= nMinBarsBtwPivs
  685. AND nHHVIdxAfterLastPiv != curBar ) {
  686. // -- OK, we'll add this as a pivot. 
  687. //    Mark that for plotting
  688. aHPivs[nHHVIdxAfterLastPiv] = 1;
  689. aAddedHPivs[nHHVIdxAfterLastPiv] = 1;
  690. //    ...and then rearrange elements in the 
  691. //    pivot information arrays
  692. for (j=0; j<nHPivs; j++) {
  693. aHPivHighs[nHPivs-j] = aHPivHighs[nHPivs-(j+1)];
  694. aHPivIdxs[nHPivs-j] = aHPivIdxs[nhPivs-(j+1)];
  695. }
  696. aHPivHighs[0] = nHHVAfterLastPiv;
  697. aHPivIdxs[0] = nHHVIdxAfterLastPiv;
  698. nHPivs++;
  699. // -- Test whether to add piv given last piv is high 
  700. //    AND we have lower highs
  701. }
  702. // -- Second case when last piv is a low piv, higher highs 
  703. //    Most likely addition is high piv that is a retracement.
  704. //    Considering adding a high piv as long as it is higher
  705. } else {
  706. // -- Where I have higher highs,
  707. if (nHHVAfterLastPiv > aHPivHighs[0] AND 
  708. (nHHVIdxAfterLastPiv - lastLPIdx - 1) >= nMinBarsBtwPivs
  709. AND nHHVIdxAfterLastPiv != curBar ) {
  710. // -- OK, we'll add this as a pivot. 
  711. //    Mark it for plotting...
  712. aHPivs[nHHVIdxAfterLastPiv] = 1;
  713. aAddedHPivs[nHHVIdxAfterLastPiv] = 1;
  714. //    ...and then rearrange elements in the 
  715. //    pivot information arrays
  716. for (j=0; j<nHPivs; j++) {
  717. aHPivHighs[nHPivs-j] = aHPivHighs[nHPivs-(j+1)];
  718. aHPivIdxs[nHPivs-j] = aHPivIdxs[nhPivs-(j+1)];
  719. }
  720. aHPivHighs[0] = nHHVAfterLastPiv;
  721. aHPivIdxs[0] = nHHVIdxAfterLastPiv;
  722. nHPivs++;
  723. // -- Test whether to add piv given last piv is high 
  724. //    AND we have lower highs
  725. }
  726. }
  727. // -- If there are at least two of each
  728. }
  729. /* ****************************************
  730. // -- Done with finding pivots
  731. ***************************************** */ 
  732. if (bDraw) {
  733. // -- OK, let's plot the pivots using arrows
  734. PlotShapes(
  735. IIf(aHPivs==1, shapeDownArrow, shapeNone), 
  736. colorRed, 0,  High, Offset=-15);
  737. PlotShapes(
  738. IIf(aAddedHPivs==1, shapeDownArrow, shapeNone),
  739. colorDarkRed, 0, High, Offset=-15);
  740. PlotShapes(
  741. IIf(aLPivs==1, shapeUpArrow , shapeNone),
  742. colorGreen, 0, Low, Offset=-15);
  743. PlotShapes(
  744. IIf(aAddedLPivs==1, shapeUpArrow , shapeNone), 
  745. colorDarkGreen, 0, Low, Offset=-15);
  746. }
  747. /* ****************************************
  748. // -- Done with discovering and plotting pivots 
  749. ***************************************** */ 
  750. // -- I'm going to want to look for possible retracement
  751. risk = 0;
  752. profInc = 0;
  753. nLeg0Pts = 0;
  754. nLeg0Bars = 0;
  755. nLeg0Vol = 0;
  756. nLeg1Pts = 0;
  757. nLeg1Bars = 0;
  758. nLeg1Vol = 0;
  759. nLegBarsDiff = 0;
  760. nRtrc0Pts = 0;
  761. nRtrc0Bars = 0;
  762. nRtrc0Vol = 0;
  763. nRtrc1Pts = 0;
  764. nRtrc1Bars = 0;
  765. nRtrc1Vol = 0;
  766. minRtrc = 0;
  767. maxRtrc = 0;
  768. minLine = 0;
  769. maxLine = 0;
  770. triggerLine = 0;
  771. firstProfitLine = 0;
  772. triggerInc = 0;
  773. triggerPrc = 0;
  774. firstProfitPrc = 0;
  775. retrcPrc = 0;
  776. retrcBar = 0;
  777. retrcBarIdx = 0;
  778. retrcRng = 0;
  779. aRetrcPrc = H-H;
  780. aRetrcPrcBars = H-H;
  781. aRetrcClose = C;
  782. retrcClose = 0;
  783. // -- Do TCZ calcs. Arrangement of pivs very specific
  784. //    for this setup.
  785. if (nHPivs >= 2 AND 
  786. nLPivs >=2 AND  
  787. aHPivHighs[0] > aHPivHighs[1] AND
  788. aLPivLows[0] > aLPivLows[1]) {
  789. tcz500 = 
  790. (aHPivHighs[0] -
  791. (.5 * (aHPivHighs[0] - aLPivLows[1])));
  792. tcz618 = 
  793. (aHPivHighs[0] -
  794. (.618 * (aHPivHighs[0] - aLPivLows[1])));
  795. tcz786 = 
  796. (aHPivHighs[0] -
  797. (.786 * (aHPivHighs[0] - aLPivLows[0])));
  798. retrcRng = curBar  - aHPivIdxs[0];
  799. aRetrcPrc = LLV(L, retrcRng);
  800. aRetrcPrcBars  = LLVBars(L, retrcRng);
  801. retrcPrc = aRetrcPrc[curBar];
  802. retrcBarIdx = curBar - aRetrcPrcBars[curBar];
  803. retrcClose = aRetrcClose[retrcBarIdx];
  804. // -- bTCZLong setup?
  805. bTCZLong = (
  806. // -- Are retracement levels arranged in
  807. //    tcz order?
  808. // .500 is above .786 for long setups
  809. tcz500 >= (tcz786 * (1 - tczTolerance))
  810. AND 
  811. // .681 is below .786 for long setups
  812. tcz618 <= (tcz786 * (1 + tczTolerance))
  813. AND
  814. // -- Is the low in the tcz range
  815. // -- Is the close >= low of tcz range
  816. //    and low <= high of tcz range
  817. retrcClose >= ((1 - retrcTolerance) *  tcz618)
  818. AND
  819. retrcPrc <= ((1 + retrcTolerance) *  tcz500)
  820. ); 
  821. // -- risk would be high of signal bar minus low of zone
  822. //risk = 0;
  823. // -- lower highs and lower lows
  824. } else if (nHPivs >= 2 AND nLPivs >=2 
  825. AND aHPivHighs[0] < aHPivHighs[1] 
  826. AND aLPivLows[0] < aLPivLows[1]) {
  827. tcz500 = 
  828. (aHPivHighs[1] -
  829. (.5 * (aHPivHighs[1] - aLPivLows[0])));
  830. tcz618 = 
  831. (aHPivHighs[0] -
  832. (.618 * (aHPivHighs[1] - aLPivLows[0])));
  833. tcz786 = 
  834. (aHPivHighs[0] -
  835. (.786 * (aHPivHighs[0] - aLPivLows[0])));
  836. retrcRng = curBar  - aLPivIdxs[0];
  837. aRetrcPrc = HHV(H, retrcRng);
  838. retrcPrc = aRetrcPrc[curBar];
  839. aRetrcPrcBars  = HHVBars(H, retrcRng);
  840. retrcBarIdx = curBar - aRetrcPrcBars[curBar];
  841. retrcClose = aRetrcClose[retrcBarIdx];
  842. bTCZShort = (
  843. // -- Are retracement levels arranged in
  844. //    tcz order?
  845. // .500 is below .786 for short setups
  846. tcz500 <= (tcz786 * (1 + tczTolerance))
  847. AND
  848. // .681 is above .786 for short setups
  849. tcz618 >= (tcz786 * (1 - tczTolerance)) 
  850. AND
  851. // -- Is the close <= high of tcz range
  852. //    and high >= low of tcz range
  853. retrcClose <= ((1 + retrcTolerance) *  tcz618)
  854. AND
  855. retrcPrc >= ((1 - retrcTolerance) *  tcz500)
  856. ); 
  857. // -- Risk would be top of zone - low of signal bar 
  858. //risk = 0;
  859. }
  860. // -- Show zone if present
  861. if (bTCZShort OR bTCZLong) { 
  862. // -- Be prepared to see symmetry
  863. if (bTCZShort) {
  864. if (aLPivIdxs[0] > aHPivIdxs[0]) {
  865. // -- Valuable, useful symmetry information 
  866. nRtrc0Pts = aHPivHighs[0] - aLPivLows[1];
  867. nRtrc0Bars = aHPivIdxs[0] - aLPivIdxs[1] + 1;
  868. nRtrc1Pts = retrcPrc - aLPivLows[0];
  869. nRtrc1Bars = retrcBarIdx - aLPivIdxs[0] + 1;
  870. } else {
  871. nRtrc0Pts = aHPivHighs[1] - aLPivLows[1];
  872. nRtrc0Bars = aHPivIdxs[1] - aLPivIdxs[1] + 1;
  873. nRtrc1Pts = aHPivHighs[0] - aLPivLows[0];
  874. nRtrc1Bars = aHPivIdxs[0] - aLPivIdxs[0] + 1;
  875. }
  876. } else { // bLongSetup
  877. if (aLPivIdxs[0] > aHPivIdxs[0]) {
  878. nRtrc0Pts = aHPivHighs[0] - aLPivLows[1];
  879. nRtrc0Bars = aHPivIdxs[0] - aLPivIdxs[1] + 1;
  880. nRtrc1Pts = retrcPrc - aLPivLows[0];
  881. nRtrc1Bars = retrcBarIdx - aLPivIdxs[0] + 1;
  882. } else {
  883. nRtrc0Pts = aHPivHighs[1] - aLPivLows[0];
  884. nRtrc0Bars = aLPivIdxs[0] - aHPivIdxs[1] + 1;
  885. nRtrc1Pts = aHPivHighs[0] - aLPivLows[0];
  886. nRtrc1Bars = aLPivIdxs[0] - aHPivIdxs[0] + 1;
  887. }
  888. }
  889. if (bShowTCZ) {
  890. Plot(
  891. LineArray( IIf(bTCZLong, aHPivIdxs[0], aLPivIdxs[0]),
  892. tcz500, curBar, tcz500 , 0), 
  893. "tcz500", colorPaleBlue, styleLine);
  894. Plot(
  895. LineArray( IIf(bTCZLong, aHPivIdxs[0], aLPivIdxs[0]),
  896. tcz618, curBar, tcz618, 0), 
  897. "tcz618", colorPaleBlue, styleLine);
  898. Plot(
  899. LineArray( IIf(bTCZLong, aHPivIdxs[0], aLPivIdxs[0]),
  900. tcz786, curBar, tcz786, 0), 
  901. "tcz786", colorTurquoise, styleLine);
  902. }
  903. // -- if (bShowTCZ)
  904. }
  905. if (bDraw) {
  906. Title = Name() + " (" + StrLeft(FullName(), 10) + 
  907. ")  ATR: " + NumToStr(ATR(1), 4.2) + " ( " + 
  908. NumToStr((C - Ref(C, -1)), 4.2) + " / " +
  909. NumToStr((((C - Ref(C, -1)) / Ref(C, -1)) * 100), 2.1) +  "% )  " +
  910. WriteVal( SelectedValue( DateTime() ), formatDateTime) +
  911. " nO: " + Open + 
  912. ",  nH: " + High + 
  913. ",  nL: " + Low + 
  914. ", nC: " + Close +  ",  n" +
  915. // "Risk: " + WriteVal(risk, 2.1) + "%  n" +
  916. "Rtrc 0/1 Pts: " + WriteVal(nRtrc0Pts, 2.1) + "/" + 
  917. WriteVal(nRtrc1Pts, 2.1) + "  n" +
  918. "Rtrc 0/1 Bars: " + WriteVal(nRtrc0Bars, 2.0) + "/" +
  919. WriteVal(nRtrc1Bars, 2.0);
  920. }
  921. // **************************
  922. // END INDICATOR CODE
  923. // **************************