CCI(20) Divergence Indicator.afl
上传用户:shiqiang
上传日期:2009-06-12
资源大小:1289k
文件大小:30k
源码类别:

金融证券系统

开发平台:

Others

  1. //------------------------------------------------------------------------------
  2. //
  3. //  Formula Name:    CCI(20) Divergence Indicator
  4. //  Author/Uploader: Dennis Skoblar 
  5. //  E-mail:          DennisAndLisa@sbcglobal.net
  6. //  Date/Time Added: 2006-02-12 09:28:43
  7. //  Origin:          Divergence Indicator for CCI(20)
  8. //  Keywords:        
  9. //  Level:           semi-advanced
  10. //  Flags:           indicator
  11. //  Formula URL:     http://www.amibroker.com/library/formula.php?id=586
  12. //  Details URL:     http://www.amibroker.com/library/detail.php?id=586
  13. //
  14. //------------------------------------------------------------------------------
  15. //
  16. //  This is a diveregence indeicator for the CCI(20)...I did not write this
  17. //  excellent program and take no credit for it. I just modified the params a
  18. //  bit to work with the cci. Thank you to the author for the excellent work!
  19. //
  20. //------------------------------------------------------------------------------
  21. /*
  22.   FileName: Mod - Osc-Price Divergence31
  23.   October 25, 2005
  24.   Version 1.0
  25.   ====================================
  26.   Use with MACD or Stochastics
  27.   program detects and plots trendlines on oscillators
  28.   generates price divergence data
  29.   ====================================
  30.   Program is built as an include module
  31.   Program does not return anything. It plots the divergence area.
  32.   The global variables below are available to controlling code
  33.   ===============================================================
  34.   - Modify divergence detection to account for continuation cases properly
  35.   - Currently case #18 useed for continuation
  36. */
  37. // Parameters needed to be defined before calling this module
  38.  Issue   = CCI(20);
  39.  Middle  = 0;
  40. //Middle: MACD=0, Stoc=50, RSI=50
  41. Div_Version = 32;
  42. Pattern =  Diverge = "";
  43. //Parameters
  44. Trendlines     = Param("Trendlines",3,0,3,1);
  45. TradeON        = Param("TradeON",1,0,1,1);
  46. Diag_Trace     = Param("Diag_Trace",0,0,1,1);
  47. Alerts         = Param("Alerts",0,0,1,1);
  48. function ParameterSetup(Osc_Issue)
  49. {
  50. //Variables are defined here if they are assigned values in more than one location
  51. global Pattern, Diverge, PlotDiverge;
  52. global PlotOver1, PLotOver2, Line1, Line2;
  53. global Backtest, explore;
  54. global Sel_BarIndex, Sel_Osc_Issue;
  55. pattern        = "";
  56. diverge        = "";
  57. PlotDiverge    = 0;
  58. Plotover1 = Plotover2 = Line1 = Line2 = 0;
  59. Backtest       = Status("action") == 5;
  60. Explore        = Status("action") == 4;
  61. Sel_OscIssue        = IIf(TradeON==1,LastValue(Osc_Issue),SelectedValue(Osc_Issue));
  62. Sel_BarIndex        = IIf(TradeON==1,LastValue(BarIndex()),SelectedValue(BarIndex()));
  63. // verify this segment
  64. if (Backtest ==1)
  65. {
  66. TradeON = 0;
  67. Sel_OscIssue = Osc_Issue;
  68. Sel_BarIndex = BarIndex();
  69. }
  70. } // end ParameterSetup
  71. // ****************************************************************************************** //
  72. //                                        Functions
  73. //
  74. //Determine Peaks  - Bearish Reversal
  75. function DetectLastHigh(Osc_Issue)
  76. {
  77. global LastHigh, LastHighBars, TurnDn_OK, Sel_TurnDn_OK;
  78. TurnDn_OK       = False;
  79. Sel_TurnDn_OK   = False;
  80. Def_Peak1       = 0;
  81. Def_Peak2       = 0;
  82. LastHigh        = 0;
  83. LastHighBars    = 0;
  84. Def_Peak1       = Osc_Issue < Ref(Osc_Issue,-1) AND Ref(Osc_Issue,-1) > Ref(Osc_Issue,-2) AND Osc_Issue < Ref(Osc_Issue,-2);
  85. Def_Peak2       = Osc_Issue < Ref(Osc_Issue,-1) AND Ref(Osc_Issue,-1) < Ref(Osc_Issue,-2) AND Ref(Osc_Issue,-2) > Ref(Osc_Issue,-3) 
  86.  AND Osc_Issue < Ref(Osc_Issue,-3);
  87. TurnDn_OK       = Def_Peak1 OR Def_Peak2;
  88. Sel_TurnDn_OK   = IIf(TradeON==1,LastValue(TurnDn_OK),SelectedValue(TurnDn_OK));
  89. HighBar1        = IIf(Def_Peak1==1,1,0);
  90. HighBar2        = IIf(Def_Peak2==1,1,0);
  91. HighBar         = IIf(HighBar1==1,3,4);
  92. LastHigh        = HHV(Osc_Issue,HighBar);
  93. LastHighBars    = HHVBars(Osc_issue,HighBar);
  94. _TRACE("Sel_TurnDn_OK "  + WriteVal(Sel_TurnDn_OK));
  95. if (Diag_Trace==1)
  96. {
  97. _TRACE("Detect LastHigh - " + WriteVal(LastHigh,1.2) + " Def Peak1 " + WriteVal(Def_Peak1,1.0)
  98. + " Def Peak2 " + WriteVal(Def_Peak2,1.0) + "  TurnDn " + WriteVal(TurnDn_OK,1.0));
  99. _TRACE("Detect LastHigh - Osc " + WriteVal(Osc_Issue,1.2) +  "   Ref Osc -2 " + WriteVal(Ref(Osc_Issue,-2))
  100. + "   Ref Osc -3 " + WriteVal(Ref(Osc_Issue,-3)));
  101. }
  102. return  Sel_TurnDn_OK;
  103. } // end DetectLastHigh
  104. function DetectBearishReversal(Osc_Issue,Middle)
  105. {
  106. global SDiv_Code, BT_SDiv_Code, Bear_Diverge;
  107. SDiv_Code = BT_SDiv_Code = Bear_Diverge = 0;
  108. Sel_TurnDn_OK   = DetectLastHigh(Osc_Issue);
  109. _TRACE("Bear Reversal - Enter Bear Diverge");
  110. if (Sel_TurnDn_OK ==1 OR Backtest==1)
  111. {
  112. //Find Current Peak
  113. FirstBar_CurrGroup   = BarsSince(Cross(Osc_Issue,Middle))+1;
  114. CurrPeak             = HHV(Osc_Issue,FirstBar_Currgroup);
  115. CurrPeakBars         = HHVBars(Osc_Issue,FirstBar_Currgroup)+0;
  116. Sel_CurrPeak         = IIf(TradeON==1,LastValue(CurrPeak),SelectedValue(CurrPeak));
  117. _TRACE("Bear Reversal 02-0 - CPeak " + WriteVal(Sel_CurrPeak,1.2));
  118. //Determine Prior Peak
  119. //Distances computed relative to selected bar
  120. i=0;
  121. _TRACE("Bear Reversal 00 - start of loop  ------- ");
  122. do
  123. {
  124. i++;
  125. LastBar_PriorGroup       = Sel_BarIndex-ValueWhen(Cross(Middle,Osc_Issue),BarIndex(),i);
  126. FirstBar_PriorGroup      = Sel_BarIndex-ValueWhen(Cross(Osc_Issue,Middle),BarIndex(),i+1);
  127. Sel_LastBar_PG           = IIf(TradeON==1,LastValue(LastBar_PriorGroup),SelectedValue(LastBar_PriorGroup));
  128. Sel_FirstBar_PG          = IIf(TradeON==1,LastValue(FirstBar_PriorGroup),SelectedValue(FirstBar_PriorGroup));
  129. //Lines below need the selected variable to function correctly
  130. Peak_PriorGroup          = Ref(HHV(Osc_Issue,Sel_FirstBar_PG - Sel_LastBar_PG+1),-Sel_LastBar_PG+1);
  131. PeakBars_PriorGroup      = Ref(HHVBars(Osc_Issue,Sel_FirstBar_PG - Sel_LastBar_PG+1),-Sel_LastBar_PG+1);
  132. Sel_LastBar_PriorGroup   = IIf(TradeON==1,LastValue(LastBar_PriorGroup),SelectedValue(LastBar_PriorGroup));
  133. Sel_PeakBars_PriorGroup  = IIf(TradeON==1,LastValue(PeakBars_PriorGroup),SelectedValue(PeakBars_PriorGroup));
  134. Sel_Peak_PriorGroup      = IIf(TradeON==1,LastValue(Peak_PriorGroup),SelectedValue(Peak_PriorGroup));
  135. Final_Bars               = Sel_PeakBars_PriorGroup + Sel_LastBar_PriorGroup;
  136. // Diagnostic
  137. _TRACE("Bear Reversal - loop 01  - i= " + WriteVal(i,1.0) + " FB_PrGr " + WriteVal(Sel_FirstBar_PG,1.0) + "  LB_PrGr " + WriteVal(Sel_LastBar_PG,1.0));
  138. _TRACE("Bear Reversal - loop 02 - CPeak " + WriteVal(Sel_CurrPeak,1.2));
  139. _TRACE("Bear Reversal - loop 03 - Pk_PG " + WriteVal(Sel_Peak_PriorGroup,1.2) + " Pk_PGBars "  + WriteVal(Sel_PeakBars_PriorGroup,1.0) + " F Bars " + WriteVal(Final_Bars));
  140. _TRACE("Bear Reversal - loop 04 - While1= " + WriteVal((SelectedValue(Peak_PriorGroup)-Middle),1.2) + "  Compare= " + WriteVal(((SelectedValue(CurrPeak)-Middle) / 3),1.2));
  141. } while (((Sel_Peak_PriorGroup-Middle) < (Sel_CurrPeak-Middle) / 3) AND i<10);
  142. _TRACE("Bear Reversal 05 - end of loop  ------- ");
  143. PriorPeak            = Peak_PriorGroup;
  144. PriorPeakBars        = Final_Bars;
  145. Sel_LastHigh       = IIf(TradeON==1,LastValue(LastHigh),SelectedValue(LastHigh));
  146. Sel_CurrPeak       = IIf(TradeON==1,LastValue(CurrPeak),SelectedValue(CurrPeak));
  147. Sel_PriorPeak      = IIf(TradeON==1,LastValue(PriorPeak),SelectedValue(PriorPeak));
  148. Sel_LastHighBars   = IIf(TradeON==1,LastValue(LastHighBars),SelectedValue(LastHighBars));
  149. Sel_CurrPeakBars   = IIf(TradeON==1,LastValue(CurrPeakBars),SelectedValue(CurrPeakBars));
  150. Sel_PriorPeakBars  = IIf(TradeON==1,LastValue(PriorPeakBars),SelectedValue(PriorPeakBars));
  151. //Needed for Backtest Arrays
  152. SR1    = CurrPeak > PriorPeak AND LastHigh == CurrPeak;                         //Curr Peak Higher - Divergence not possible
  153. SR2    = CurrPeak < PriorPeak AND LastHigh == CurrPeak;                         //Curr Peak Lower
  154. SR3    = Osc_Issue > Middle AND CurrPeak > PriorPeak AND LastHigh < CurrPeak;   //Curr Peak Higher - Last High Lower
  155. SR4    = Osc_Issue > Middle AND CurrPeak < PriorPeak AND LastHigh < CurrPeak;   //Curr Peak Lower  - Best
  156. SR5    = LastHigh  < Middle   AND LastHigh < CurrPeak AND SR4==0 AND SR3==0;    //Continuation signal with Osc_Issue < Middle
  157. //Needed for display
  158. Sel_SR1    = IIf(TradeON==1,LastValue(SR1),SelectedValue(SR1));
  159. Sel_SR2    = IIf(TradeON==1,LastValue(SR2),SelectedValue(SR2));
  160. Sel_SR3    = IIf(TradeON==1,LastValue(SR3),SelectedValue(SR3));
  161. Sel_SR4    = IIf(TradeON==1,LastValue(SR4),SelectedValue(SR4));
  162. Sel_SR5    = IIf(TradeON==1,LastValue(SR5),SelectedValue(SR5));
  163. //Determine Price Divergence
  164. if (Sel_SR1==1)
  165. {
  166. Bear_Diverge = 0;
  167. SDiv_Code    = 11;
  168. Diverge      = "";
  169. Pattern      = "Higher High";
  170. }
  171. if (Sel_SR2==1)
  172. {
  173. Curr_HighPrice     = HHV(High,5);
  174. Prior_PeakPrice    = Ref(HHV(High,6),-(Sel_PriorPeakBars-3));
  175. Sel_CHighPrice     = IIf(TradeON==1,LastValue(Curr_HighPrice),SelectedValue(Curr_HighPrice));
  176. Sel_PPeakPrice     = IIf(TradeON==1,LastValue(Prior_PeakPrice),SelectedValue(Prior_PeakPrice));
  177. Sel_Bear_Diverge   = Sel_CHighPrice >= Sel_PPeakPrice;
  178. if (Sel_Bear_Diverge==1)
  179. {
  180. Bear_Diverge = 1;
  181. SDiv_Code    = 13;
  182. Diverge      = "Bearish";
  183. Pattern      = "Lower High";
  184. }
  185. else
  186. {
  187. Bear_Diverge = 0;
  188. SDiv_Code    = 12;
  189. Diverge      = "";
  190. Pattern      = "Lower High";
  191. }
  192. }
  193. if (Sel_SR3==1)
  194. {
  195. _TRACE("Bear Reversal - SR3 - True");
  196. Curr_HighPrice   = HHV(High,5);
  197. Curr_PeakPrice   = Ref(HHV(High,6),-(Sel_CurrPeakBars-3));
  198. Sel_CHighPrice   = IIf(TradeON==1,LastValue(Curr_HighPrice),SelectedValue(Curr_HighPrice));
  199. Sel_CPeakPrice   = IIf(TradeON==1,LastValue(Curr_PeakPrice),SelectedValue(Curr_PeakPrice));
  200. Sel_Bear_Diverge = Sel_CHighPrice >= Sel_CPeakPrice;
  201. if (Sel_Bear_Diverge==1)
  202. {
  203. Bear_Diverge = 1;
  204. SDiv_Code    = 15;
  205. Diverge      = "Bearish";
  206. Pattern      = "Higher High";
  207. }
  208. else
  209. {
  210. Bear_Diverge = 0;
  211. SDiv_Code    = 14;
  212. Diverge      = "";
  213. Pattern      = "Higher High";
  214. }
  215. }
  216. if (Sel_SR4==1)
  217. {
  218. _TRACE("Bear Reversal - SR4 - True");
  219. Curr_HighPrice   = HHV(High,5);
  220. Curr_PeakPrice   = Ref(HHV(High,6),-(Sel_CurrPeakBars-3));
  221. Sel_CHighPrice   = IIf(TradeON==1,LastValue(Curr_HighPrice),SelectedValue(Curr_HighPrice));
  222. Sel_CPeakPrice   = IIf(TradeON==1,LastValue(Curr_PeakPrice),SelectedValue(Curr_PeakPrice));
  223. Sel_Bear_Diverge = Sel_CHighPrice >= Sel_CPeakPrice;
  224. if (Sel_Bear_Diverge==1)
  225. {
  226. Bear_Diverge = 1;
  227. SDiv_Code    = 17;
  228. Diverge      = "Bearish";
  229. Pattern      = "Lower High";
  230. }
  231. else
  232. {
  233. Bear_Diverge = 0;
  234. SDiv_Code    = 16;
  235. Diverge      = "";
  236. Pattern      = "Lower High";
  237. }
  238. }  // end  Sel_Bear_Diverge
  239. if (Sel_SR5==1)
  240. {
  241. Bear_Diverge = 0;
  242. SDiv_Code    = 18;
  243. Diverge      = "";
  244. Pattern      = "Continuation";
  245. }
  246. BT_SDiv_Code = IIf(SR1==1,11,
  247.                IIf(SR2==1 AND Bear_Diverge==0,12,IIf(SR2==1 AND Bear_Diverge==1,13,
  248.                IIf(SR3==1 AND Bear_Diverge==0,14,IIf(SR3==1 AND Bear_Diverge==1,15,
  249.                IIf(SR4==1 AND Bear_Diverge==0,16,IIf(SR4==1 AND Bear_Diverge==1,17,
  250.                IIf(SR5==1 AND SR4==0 AND SR3==0,18,0))))))));
  251. if (Diag_trace)
  252. {
  253. _TRACE("Bear Reversal #00 - Div_Code " + WriteVal(SDiv_Code,1.0) + " --  SR1 " + WriteVal(Sel_SR1,1.0)
  254.              + " SR2 " + WriteVal(Sel_SR2,1.0) + " SR3 " + WriteVal(Sel_SR3,1.0) + " SR4 " + WriteVal(Sel_SR4,1.0));
  255. _TRACE("Bear Reversal #00 - LastHigh " +  WriteVal(Sel_LastHigh,1.2) + " CurrPeak " +  WriteVal(Sel_CurrPeak,1.2)
  256.                         + " PriorPeak " +  WriteVal(Sel_PriorPeak,1.2) );
  257. }
  258. if (Backtest == 0)
  259. {
  260. //Assign Values to coordinates
  261. y10=Sel_CurrPeak;
  262. y11=Sel_LastHigh; 
  263. x10=BarCount - 1 - Sel_CurrPeakBars - (LastValue(BarIndex()) - Sel_BarIndex);
  264. x11=BarCount - 1 - Sel_LastHighBars - (LastValue(BarIndex()) - Sel_BarIndex);
  265. Line1  = LineArray( x10, y10, x11, y11, 0 );
  266. y20=Sel_PriorPeak;
  267. y21=Sel_CurrPeak;
  268. x20=BarCount - 1 - SelectedValue(Final_Bars)  - (LastValue(BarIndex())- Sel_BarIndex);
  269. //x20=BarCount - 1 - Sel_PriorPeakBars  - (LastValue(BarIndex())- Sel_BarIndex);
  270. x21=BarCount - 1 - Sel_CurrPeakBars   - (LastValue(BarIndex())- Sel_BarIndex);
  271. Line2 = LineArray( x20, y20, x21, y21, 0 );
  272. //Compute area to paint, based on MACD / Stochastic
  273. if (Middle==50)
  274. {
  275. Area_MaxValue = 100;
  276. PlotOver2 = IIf(BarIndex()  >= Sel_BarIndex  - (x21-x20)-(x11-x10) -1 AND
  277.      BarIndex() <= Sel_BarIndex  - (x11-x10),Area_MaxValue,0);
  278. PlotOver1 = IIf(BarIndex()  >= Sel_BarIndex  - (x11-x10) -1 AND BarIndex() <= Sel_BarIndex,Area_MaxValue,0);
  279. if (SelectedValue(SDiv_Code)==15)
  280. {
  281. //Limit the blue bar for divergence to 2nd half of area for code 15
  282. PlotDiverge = IIf(BarIndex() >= Sel_BarIndex - (x11-x10) -1
  283.                         AND BarIndex() <= Sel_BarIndex AND Diverge=="Bearish",10,0);
  284. }
  285. if (SelectedValue(SDiv_Code)==13 OR SelectedValue(SDiv_Code)==17)
  286. {
  287. PlotDiverge = IIf(BarIndex() >= Sel_BarIndex - (x21-x20)-(x11-x10) -1
  288.                         AND BarIndex() <= Sel_BarIndex AND Diverge=="Bearish",10,0);
  289. }
  290. }
  291. else
  292. {
  293. Area_MinValue = Max(y10,y20);
  294. PlotOver2 = IIf(BarIndex()  >= Sel_BarIndex  - (x21-x20)-(x11-x10) -1 AND
  295.      BarIndex() <= Sel_BarIndex  - (x11-x10),Area_MinValue,0);
  296. PlotOver1 = IIf(BarIndex()  >= Sel_BarIndex  - (x11-x10) -1 AND BarIndex() <= Sel_BarIndex,Area_MinValue,0);
  297. }
  298. } // end if backtest
  299. if (Diag_Trace==1)
  300. {
  301. _TRACE("Bear Reversal #0 - Backtest " + WriteVal(Backtest,1.0));
  302. _TRACE("Bear Reversal #1 - Sel_TurnDn_OK " + WriteVal(Sel_TurnDn_OK,1.0));
  303. _TRACE("Bear Reversal #2 - CurrPeak " + WriteVal(Sel_CurrPeak,1.2) + "  CPBars " + WriteVal(Sel_CurrPeakBars,1.0)
  304.                         + "  DivCode  " + WriteVal(SDiv_Code,1.0));
  305. _TRACE("Bear Reversal #3 - LB_PGroup " + WriteVal(Sel_LastBar_PG,1.0) + "  FB_PGroup " + WriteVal(Sel_FirstBar_PG,1.0));
  306. _TRACE("Bear Reversal #4 - Pk_PGroup " + WriteVal(PriorPeak,1.2) + "  PB_PG " + WriteVal(PriorPeakBars,1.0));
  307. _TRACE("Bear Reversal #5 - xy1: x10=" + WriteVal(x10,1.0) + " y10=" + WriteVal(y10,1.2)
  308.                        + "   x11=" + WriteVal(x11,1.0) + " y11=" + WriteVal(y11,1.2));
  309. _TRACE("Bear Reversal $6 - xy2: x20=" + WriteVal(x20,1.0) + " y20=" + WriteVal(y20,1.2)
  310.                        + "   x21=" + WriteVal(x21,1.0) + " y21=" + WriteVal(y21,1.2));
  311. _TRACE("Bear Reversal - end ================================================ ");
  312. } // end  Diag_Trace
  313. } // end  Sel_TurnDn_OK
  314. //  Add code for troughs
  315. else
  316. {
  317. SDiv_Code    = 10;
  318. }
  319. return Sel_TurnDn_OK;
  320. } //end DetectBearishReversal
  321. //Determine Troughs
  322. function DetectLastLow(Osc_Issue)
  323. {
  324. global LastLow, LastLowBars, TurnUp_OK, Sel_TurnUp_OK;
  325. TurnUp_OK      = False;
  326. Sel_TurnUp_OK  = False;
  327. LastLow        = 0;
  328. LastLowBars    = 0;
  329. Def_Trough1    = 0;
  330. Def_Trough2    = 0;
  331. Def_Trough1    = Osc_Issue > Ref(Osc_Issue,-1) AND Ref(Osc_Issue,-1) < Ref(Osc_Issue,-2) AND Osc_Issue > Ref(Osc_Issue,-2);
  332. Def_Trough2    = Osc_Issue > Ref(Osc_Issue,-1) AND Ref(Osc_Issue,-1) > Ref(Osc_Issue,-2) AND Ref(Osc_Issue,-2) < Ref(Osc_Issue,-3)
  333.   AND Osc_Issue > Ref(Osc_Issue,-3);
  334. TurnUp_OK      = Def_Trough1 OR Def_Trough2;
  335. Sel_TurnUp_OK  = IIf(TradeON==1,LastValue(TurnUp_OK),SelectedValue(TurnUp_OK));
  336. LowBar1        = IIf(Def_Trough1==1,1,0);
  337. LowBar2        = IIf(Def_Trough2==1,1,0);
  338. LowBar         = IIf(LowBar1==1,3,4);
  339. LastLow        = LLV(Osc_Issue,LowBar);
  340. LastLowBars    = LLVBars(Osc_issue,LowBar);
  341. _TRACE("Bull - LB1 " + WriteVal(LowBar1,1.0) + "  LB2 " + WriteVal(LowBar2,1.0) +  "  LB " + WriteVal(LowBar,1.0));
  342.    
  343. if (Diag_Trace==1)
  344. {
  345. _TRACE("DetectLastLow - LastLow " + WriteVal(LastLow,1.2) + " Def Trough1 " + WriteVal(Def_Trough1,1.0)
  346. + " Def Trough2 " + WriteVal(Def_Trough2,1.0) + "  TUp " + WriteVal(TurnUp_OK,1.0));
  347. _TRACE("DetectLastLow - LastLow - Osc " + WriteVal(Osc_Issue,1.2) +  "  Osc -1 " + WriteVal(Ref(Osc_Issue,-1),1.2)
  348.               + "   Ref Osc -2 " + WriteVal(Ref(Osc_Issue,-2)) + "   Ref Osc -3 " + WriteVal(Ref(Osc_Issue,-3)));
  349. }
  350. _TRACE("Bear Code - end of Bear function " + WriteVal(SDiv_Code,1.0));
  351. return   Sel_TurnUp_OK;
  352. }
  353. function DetectBullishReversal(Osc_Issue,Middle)
  354. {
  355. global  LDiv_Code, BT_LDiv_Code, BT_Code, Bull_Diverge;
  356. LDiv_Code = BT_LDiv_Code = 0;
  357. Bull_Diverge = 0;
  358. _TRACE("Program Flow - Enter Detect Bullish Reversal - Bar Index " + WriteVal(BarIndex(),1.0) +
  359.                "  Last Bar  " + WriteVal(LastValue(BarIndex()),1.0));
  360. //Determine Trough for current period
  361. Sel_TurnUp_OK  = DetectLastLow(Osc_Issue);
  362. _TRACE("Bull Code - Bull function Start " + Name() + "  TurnUp " + WriteVal(sel_TurnUp_OK,1.0)+ "  Code= " + WriteVal(LDiv_Code,1.0));
  363. if (Sel_TurnUp_OK ==1 OR Backtest==1)        // or 1==1 may be needed
  364. {
  365. FirstBar_CurrGroup    = BarsSince(Cross(Middle,Osc_Issue))+1;
  366. CurrTrough            = LLV(Osc_Issue,FirstBar_Currgroup);
  367. CurrTroughBars        = LLVBars(Osc_Issue,FirstBar_Currgroup)+0;
  368. Sel_CurrTrough        = IIf(TradeON==1,LastValue(CurrTrough),SelectedValue(CurrTrough));
  369. //Distances computed relative to selected bar
  370. i=0;
  371. _TRACE("Bull Reversal 00 - start of loop  ------ ");
  372. do
  373. {
  374. i++;
  375. LastBar_PriorGroup         = Sel_BarIndex-ValueWhen(Cross(Osc_Issue,Middle),BarIndex(),i);
  376. FirstBar_PriorGroup        = Sel_BarIndex-ValueWhen(Cross(Middle,Osc_Issue),BarIndex(),i+1);
  377. Sel_LastBar_PG             = IIf(TradeON==1,LastValue(LastBar_PriorGroup),SelectedValue(LastBar_PriorGroup));
  378. Sel_FirstBar_PG            = IIf(TradeON==1,LastValue(FirstBar_PriorGroup),SelectedValue(FirstBar_PriorGroup));
  379. //Find Trough using scalars - This may interfere with Backtest operation, but needed
  380. Trough_PriorGroup          = Ref(LLV(Osc_Issue,Sel_FirstBar_PG - Sel_LastBar_PG+1),-Sel_LastBar_PG+1);
  381. TroughBars_PriorGroup      = Ref(LLVBars(Osc_Issue,Sel_FirstBar_PG - Sel_LastBar_PG+1),-Sel_LastBar_PG+1);
  382. Sel_LastBar_PriorGroup     = IIf(TradeON==1,LastValue(TroughBars_PriorGroup),SelectedValue(TroughBars_PriorGroup));
  383. Sel_TroughBars_PriorGroup  = IIf(TradeON==1,LastValue(LastBar_PriorGroup),SelectedValue(LastBar_PriorGroup));
  384. Sel_Trough_PriorGroup      = IIf(TradeON==1,LastValue(Trough_PriorGroup),SelectedValue(Trough_PriorGroup));
  385. Final_Bars                 = Sel_TroughBars_PriorGroup + Sel_LastBar_PriorGroup - 1;
  386. if (Diag_Trace)
  387. {
  388. _TRACE("Bull Reversal - loop 01 - i= " + WriteVal(i,1.0) + " FB_PrGr " + WriteVal(FirstBar_PriorGroup,1.0)
  389.              + " / " + WriteVal(Sel_FirstBar_PG,1.0) + "  LB_PrGr " + WriteVal(LastBar_PriorGroup,1.0)
  390.              + " / " + WriteVal(Sel_LastBar_PG,1.0));
  391. _TRACE("Bull Reversal - loop 02 - Sel_FB_PrGr  " + WriteVal(Sel_FirstBar_PG,1.0) + "   Sel_LB_PrGr " + WriteVal(Sel_LastBar_PG,1.0));
  392. _TRACE("Bull Reversal - loop 03 - Tr_PG " + WriteVal(Trough_PriorGroup,1.2) + " Tr_PGBars "  + WriteVal(TroughBars_PriorGroup,1.0) + " F Bars " + WriteVal(Final_Bars,1.0));
  393. _TRACE("Bull Reversal - loop 04 - While1= " + WriteVal((Middle - SelectedValue(Trough_PriorGroup)),1.2) + "  Compare= " + WriteVal(((Middle - SelectedValue(CurrTrough)) / 3),1.2));
  394. }
  395. } while (((Middle - Sel_Trough_PriorGroup) < (Middle - Sel_CurrTrough) / 3) AND i<10);
  396. PriorTrough          = Trough_PriorGroup;
  397. PriorTroughBars      = Final_Bars;
  398. //Put Divergence codes into Array
  399. //Compute results for display
  400. Sel_LastLow          = IIf(TradeON==1,LastValue(LastLow),SelectedValue(LastLow));
  401. Sel_CurrTrough       = IIf(TradeON==1,LastValue(CurrTrough),SelectedValue(CurrTrough));
  402. Sel_PriorTrough      = IIf(TradeON==1,LastValue(PriorTrough),SelectedValue(PriorTrough));
  403. Sel_LastLowBars      = IIf(TradeON==1,LastValue(LastLowBars),SelectedValue(LastLowBars));
  404. Sel_CurrTroughBars   = IIf(TradeON==1,LastValue(CurrTroughBars),SelectedValue(CurrTroughBars));
  405. Sel_PriorTroughBars  = IIf(TradeON==1,LastValue(PriorTroughBars),SelectedValue(PriorTroughBars));
  406. //Needed for Backtest Arrays
  407. LR1    = CurrTrough < PriorTrough AND LastLow == CurrTrough;
  408. LR2    = CurrTrough > PriorTrough AND LastLow == CurrTrough;
  409. LR3    = Osc_Issue  < Middle AND CurrTrough < PriorTrough AND LastLow > CurrTrough;
  410. LR4    = Osc_Issue  < Middle AND CurrTrough > PriorTrough AND LastLow > CurrTrough;
  411. LR5    = LastLow    > Middle AND LastLow > CurrTrough AND LR3==0 AND LR4==0;
  412. //Needed for display
  413. Sel_LR1    = IIf(TradeON==1,LastValue(LR1),SelectedValue(LR1));
  414. Sel_LR2    = IIf(TradeON==1,LastValue(LR2),SelectedValue(LR2));
  415. Sel_LR3    = IIf(TradeON==1,LastValue(LR3),SelectedValue(LR3));
  416. Sel_LR4    = IIf(TradeON==1,LastValue(LR4),SelectedValue(LR4));
  417. Sel_LR5    = IIf(TradeON==1,LastValue(LR5),SelectedValue(LR5));
  418. //Determine Price Divergence
  419. if (Sel_LR1==1)
  420. {
  421. Bull_Diverge = 0;
  422. LDiv_Code    = 11;
  423. Diverge      = "";
  424. Pattern      = "Lower Low";
  425. }
  426. if (Sel_LR2==1)
  427. {
  428. Curr_LowPrice     = LLV(Low,5);
  429. Prior_LowPrice    = Ref(LLV(Low,6),-(Sel_PriorTroughBars-3));
  430. Sel_CLowPrice     = IIf(TradeON==1,LastValue(Curr_LowPrice),SelectedValue(Curr_LowPrice));
  431. Sel_PLowPrice     = IIf(TradeON==1,LastValue(Prior_LowPrice),SelectedValue(Prior_LowPrice));
  432. Sel_Bull_Diverge  = Sel_CLowPrice <= Sel_PLowPrice;
  433. if (Sel_Bull_Diverge==1)
  434. {
  435. Bull_Diverge = 1;
  436. LDiv_Code    = 13;
  437. Diverge      = "Bullish";
  438. Pattern      = "Higher Low";
  439. }
  440. else
  441. {
  442. Bull_Diverge = 0;
  443. LDiv_Code    = 12;
  444. Diverge      = "";
  445. Pattern      = "Higher Low";
  446. }
  447. }
  448. if (Sel_LR3==1)
  449. {
  450. Curr_LowPrice     = LLV(Low,5);
  451. CT_LowPrice       = Ref(LLV(Low,6),-(Sel_CurrTroughBars-3));
  452. Sel_CLowPrice     = IIf(TradeON==1,LastValue(Curr_LowPrice),SelectedValue(Curr_LowPrice));
  453. Sel_CTroughPrice  = IIf(TradeON==1,LastValue(CT_LowPrice),SelectedValue(CT_LowPrice));
  454. Sel_Bull_Diverge  = Sel_CLowPrice <= Sel_CTroughPrice;
  455. if (Sel_Bull_Diverge==1)
  456. {
  457. Bull_Diverge = 1;
  458. LDiv_Code    = 15;
  459. Diverge      = "Bullish";
  460. Pattern      = "Lower Low";
  461. }
  462. else
  463. {
  464. Bull_Diverge = 0;
  465. LDiv_Code    = 14;
  466. Diverge      = "";
  467. }
  468. }
  469. if (Sel_LR4==1)
  470. {
  471. Curr_LowPrice     = LLV(Low,5);
  472. CT_LowPrice       = Ref(LLV(Low,6),-(Sel_CurrTroughBars-3));
  473. Sel_CLowPrice     = IIf(TradeON==1,LastValue(Curr_LowPrice),SelectedValue(Curr_LowPrice));
  474. Sel_CTroughPrice  = IIf(TradeON==1,LastValue(CT_LowPrice),SelectedValue(CT_LowPrice));
  475. Sel_Bull_Diverge  = Sel_CLowPrice <= Sel_CTroughPrice;
  476. if (Sel_Bull_Diverge==1)
  477. {
  478. Bull_Diverge = 1;
  479. LDiv_Code    = 17;
  480. Diverge      = "Bullish";
  481. Pattern      = "Higher Low";
  482. }
  483. else
  484. {
  485. Bull_Diverge = 0;
  486. LDiv_Code    = 16;
  487. Diverge      = "";
  488. Pattern      = "Higher Low";
  489. }
  490. }
  491. if (Sel_LR5==1)
  492. {
  493. Bull_Diverge = 0;
  494. LDiv_Code    = 18;
  495. Diverge      = "";
  496. }
  497. BT_LDiv_Code = IIf(LR1==1,11,
  498.                IIf(LR2==1 AND Bull_Diverge==0,12,IIf(LR2==1 AND Bull_Diverge==1,13,
  499.                IIf(LR3==1 AND Bull_Diverge==0,14,IIf(LR3==1 AND Bull_Diverge==1,15,
  500.                IIf(LR4==1 AND Bull_Diverge==0,16,IIf(LR4==1 AND Bull_Diverge==1,17,
  501.                IIf(LR5==1 AND LR4==0 AND LR3==0,18,0))))))));
  502. if (Diag_trace)
  503. {
  504. _TRACE("Bull Reversal #00A - BT_Div_Code " + WriteVal(BT_LDiv_Code,1.0));
  505. _TRACE("Bull Reversal #00B - Div_Code " + WriteVal(LDiv_Code,1.0) + " --  LR1 " + WriteVal(LR1,1.0)
  506.              + " LR2 " + WriteVal(LR2,1.0) + " LR3 " + WriteVal(LR3,1.0) + " LR4 " + WriteVal(LR4,1.0));
  507. _TRACE("Bull Reversal #00C - LastLow " +  WriteVal(Sel_LastLow,1.2) + " CurrTrough " +  WriteVal(Sel_CurrTrough,1.2)
  508.                         + " PriorTrough " +  WriteVal(Sel_PriorTrough,1.2) );
  509. }
  510. if (Backtest == 0)
  511. {
  512. //Assign Values to coordinates
  513. y10=Sel_CurrTrough;
  514. y11=Sel_LastLow;
  515. x10=BarCount - 1 - Sel_CurrTroughBars - (LastValue(BarIndex()) - Sel_BarIndex);
  516. x11=BarCount - 1 - Sel_LastLowBars    - (LastValue(BarIndex()) - Sel_BarIndex);
  517. Line1  = LineArray( x10,y10,x11,y11, 0 );
  518. y20=Sel_PriorTrough;
  519. y21=Sel_CurrTrough;
  520. x20=BarCount - 1 - SelectedValue(Final_Bars) - (LastValue(BarIndex())- Sel_BarIndex);
  521. x21=BarCount - 1 - Sel_CurrTroughBars        - (LastValue(BarIndex())- Sel_BarIndex);
  522. Line2 = LineArray( x20, y20, x21, y21, 0 );
  523. //
  524. //Find min value of oscillator in area of interest
  525. Area_MinValue = 0;
  526. Area_MaxValue = 0;
  527. if (Middle==50)
  528. {
  529. Area_MaxValue = 100;
  530. PlotOver2   = IIf(BarIndex() >= Sel_BarIndex  - (x21-x20)-(x11-x10)-1 AND
  531.      BarIndex() <= Sel_BarIndex - (x11-x10),Area_MaxValue,0);
  532. PlotOver1   = IIf(BarIndex() >= Sel_BarIndex - (x11-x10) -1 AND
  533. BarIndex() <= Sel_BarIndex,Area_MaxValue,0);
  534. if (SelectedValue(LDiv_Code)==15)
  535. {
  536. //Limit the blue bar for divergence to 2nd half of area for code 15
  537. PlotDiverge = IIf(BarIndex() >= Sel_BarIndex - (x11-x10) -1
  538.                         AND BarIndex() <= Sel_BarIndex AND Diverge=="Bullish",10,0);
  539. }
  540. if (SelectedValue(LDiv_Code)==13 OR SelectedValue(LDiv_Code)==17)
  541. {
  542. PlotDiverge = IIf(BarIndex() >= Sel_BarIndex - (x21-x20)-(x11-x10) -1
  543.                         AND BarIndex() <= Sel_BarIndex AND Diverge=="Bullish",10,0);
  544. }
  545. }
  546. else
  547. {
  548. Area_MinValue = Min(y10,y20);
  549. PlotOver2 = IIf(BarIndex() >= Sel_BarIndex  - (x21-x20)-(x11-x10) -1 AND
  550.      BarIndex() <= Sel_BarIndex - (x11-x10) -2,Area_MinValue,0);
  551. PlotOver1 = IIf(BarIndex() >= Sel_BarIndex - (x11-x10) -1 AND
  552. BarIndex() <= Sel_BarIndex,Area_MinValue,0);
  553. }
  554. _TRACE("Plot - Bull  #00C - PlotDiverge " + WriteVal(PlotDiverge,1.0));
  555. } // end if backtest
  556. if (Diag_Trace==1)
  557. {
  558. _TRACE("Bull Reversal #0 - Backtest " + WriteVal(Backtest,1.0));
  559. _TRACE("Bull Reversal #1 - DivCode: " + WriteVal(LDiv_Code,1.0) + " LB DivCode " + WriteVal(LDiv_Code[BarCount-1],1.0));
  560. _TRACE("Bull Reversal #2  - Last Low  " + WriteVal(LastLow,1.2));
  561. _TRACE("Bull Reversal #3 - Area_MinValue " + WriteVal(Area_MinValue,1.2));
  562. _TRACE("Bull Reversal #4 - CurrTrough " + WriteVal(Sel_CurrTrough,1.2) + "  LastLow " + WriteVal(Sel_LastLow,1.2));
  563. _TRACE("Bull Reversal #5 - FBar_CT " + WriteVal(SelectedValue(FirstBar_CurrGroup),1.0) + " BCurrTrough " + WriteVal(CurrTroughBars,1.0));
  564. _TRACE("Bull Reversal #6 - CurrTrough " + WriteVal(CurrTrough,1.2) + "  CTBars " + WriteVal(CurrTroughBars,1.0));
  565. _TRACE("Bull Reversal #7 - LB_PrGroup " + WriteVal(LastBar_PriorGroup,1.0) + "  FB_PrGroup " + WriteVal(FirstBar_PriorGroup,1.0));
  566. _TRACE("Bull Reversal #8 - Tr_PrGroup " + WriteVal(Trough_PriorGroup,1.2) + "  TrB_PrG " + WriteVal(TroughBars_PriorGroup,1.0));
  567. _TRACE("Bull Reversal #9 - PrTrough " + WriteVal(PriorTrough,1.2) + "  PrTrBars " + WriteVal(PriorTroughBars,1.0));
  568. _TRACE("Bull Reversal #10 - xy1: x10=" + WriteVal(x10,1.0) + " y10=" + WriteVal(y10,1.2)
  569.                        + "   x11=" + WriteVal(x11,1.0) + " y11=" + WriteVal(y11,1.2));
  570. _TRACE("Bull Reversal #11 - xy2: x20=" + WriteVal(x20,1.0) + " y20=" + WriteVal(y20,1.2)
  571.                        + "   x21=" + WriteVal(x21,1.0) + " y21=" + WriteVal(y21,1.2));
  572. _TRACE("Bull Reversal - end =========================================== ");
  573. } // end Diag_Trace
  574. } // end Sel_TurnUp_OK
  575. else
  576. {
  577. LDiv_Code    = 10;
  578. }
  579. return Sel_TurnUp_OK;
  580. } // end function BullishReversal
  581. function PlotTrendLines(PlotOver1,PlotOver2,BullBear)
  582. {
  583. //Plot Trendlines
  584. _TRACE("Plot - Enter Module ");
  585. Line1Color   = IIf(BullBear=="Bullish",colorBlack,colorBrown);
  586. Line2Color   = IIf(BullBear=="Bullish",colorGreen,colorYellow);
  587. Area1Color   = IIf(BullBear=="Bullish",colorPaleGreen,colorLightYellow);
  588. Area2Color   = IIf(BullBear=="Bullish",colorAqua,colorLightOrange);
  589. if (Trendlines ==1 OR Trendlines ==3)
  590. {
  591. Plot( Line1, "Trend line", Line1Color,styleDots|styleThick|styleNoLabel);
  592. Plot( Line2, "Trend line", Line2Color,styleDots|styleThick|styleNoLabel);
  593. }
  594. if (Trendlines>=2)
  595. {
  596. _TRACE("Plot - PlotDiverge " + WriteVal(PlotDiverge,1.0));
  597. Plot(PlotDiverge,"",colorBlue,styleArea|styleNoLabel);
  598. Plot(Plotover1,"",Area1color,styleArea|styleNoLabel);
  599. Plot(Plotover2,"",Area2color,styleArea|styleNoLabel);
  600. } // end Trendlines
  601. _TRACE("Plot - End Module ");
  602. } // end PlotTrendlines
  603. // ******************************************************************************************* //
  604. //"Div - EndTime " + Now(2);
  605. // START OF CONTROL SECTION
  606. // Complete loop takes 7ms when no divergence is detected and 17 ms with divergence
  607. function DivergeControl(Osc_Issue,Middle)
  608. {
  609. Backtest = Status("action")==5;
  610. //Declare Variable and set up parameters
  611. ParameterSetup(Osc_Issue);
  612. //Process Bearish Reversal and Continuation
  613. RunStatus = Status("action");
  614. StartTime = Now(4);
  615. _TRACE("Timer Start - " + WriteVal(StartTime,1.0));
  616. Sel_TurnDn_OK  = DetectBearishReversal(Osc_Issue,Middle);
  617. _TRACE("Timer End - " + WriteVal(Now(4),1.0) + " Diff " + WriteVal((Now(4) - StartTime),1.4));
  618. //_TRACE("Control Section - DivCode  " + WriteVal(SDiv_Code,1.0) + "  LB DivCode " +  WriteVal(SDiv_Code[BarCount-1],1.0));
  619. Sel_TurnUp_OK = DetectBullishReversal(Osc_Issue,Middle);
  620. if (Backtest == 0 AND (Sel_TurnDn_OK==1 OR Sel_TurnUp_OK==1))
  621. {
  622. Bull_Bear = WriteIf(Sel_TurnDn_OK==1,"Bearish",WriteIf(Sel_TurnUp_OK==1,"Bullish",""));
  623. PlotTrendlines(PlotOver1,PlotOver2,Bull_Bear);
  624. }
  625. _TRACE("Control Section - end ==============================================================");
  626. _TRACE("Control Section - end ==============================================================");
  627. if (Status("action")==1 AND Alerts==1)
  628. {
  629. _TRACE("Alert section - Bull Code " + WriteVal(LDiv_Code,1.0) + "  Bear Code " + WriteVal(SDiv_Code,1.0));
  630. AlertIf(LDiv_Code==11,"Sound D:\Amibroker\Wav Files\Lower Low.wav","",6,12,0 );
  631. AlertIf((LDiv_Code==12 OR LDiv_Code==13 OR LDiv_Code==14) AND Bull_Diverge==0,"Sound D:\Amibroker\Wav Files\Higher Low.wav","",5,12,0 );
  632. AlertIf((LDiv_Code==12 OR LDiv_Code==13 OR LDiv_Code==14) AND Bull_Diverge==1,"Sound D:\Amibroker\Wav Files\Bull Diverge.wav","",6,12,0 );
  633. AlertIf(SDiv_Code==11,"Sound D:\Amibroker\Wav Files\Higher High.wav","",6,12,0 );
  634. AlertIf((SDiv_Code==12 OR SDiv_Code==13 OR SDiv_Code==14) AND Bear_Diverge==0,"Sound D:\Amibroker\Wav Files\Lower High.wav","",7,12,0 );
  635. AlertIf((SDiv_Code==12 OR SDiv_Code==13 OR SDiv_Code==14) AND Bear_Diverge==1,"Sound D:\Amibroker\Wav Files\Bear Diverge.wav","",8,12,0 );
  636. }
  637. return Pattern + " - " + Diverge;
  638. }  // end DivergeControl
  639. Plot(CCI(20),"CCI(20)",colorRed,styleLine);
  640. divergeControl(Issue,Middle);