bleh
[mqlkit.git] / indicators / jretracto.mq4
blobbb37aa67c358fc6128a69e864544a16034f07059
1 //+------------------------------------------------------------------+\r
2 //|                                           Retracto.mq4 |\r
3 //|                                   Copyright © 2011, Zarko Asenov |\r
4 //|                                              http://jaltoh.6x.to |\r
5 //+------------------------------------------------------------------+\r
6 #property copyright "Copyright © 2011, Zarko Asenov"\r
7 #property link      "http://jaltoh.6x.to"\r
8 \r
9 \r
10 #property indicator_separate_window\r
11 #property indicator_buffers 5\r
12 #property indicator_color1 Green\r
13 #property indicator_color2 DarkGray\r
14 #property indicator_color3 White\r
15 #property indicator_color4 Blue\r
16 #property indicator_color5 Red\r
18 #define AVERAGE_RETRACEMENT_PIPS        0\r
19 #define AVERAGE_RETRACEMENT_PERCENT     1\r
20 #define MOVEMENT_COUNT                  2\r
21 #define MOVEMENT_COUNT_RATIO            3\r
22 #define STRONGEST_PUSH_PIPS             4\r
23 #define STRONGEST_PUSH_PERCENT          5\r
25 extern double Delta_Coefficient = 0.5;\r
27 extern bool Log_Prices_Spread = false;\r
28 extern bool Display_Price_Persistence = false;\r
29 extern bool Opposite_Retracement_Only = true;\r
30 extern double Minimum_Movement_PIPs = 5.1;\r
31 extern double Recentness_Factor = 0.9;\r
33 extern int Mode_of_Function = STRONGEST_PUSH_PERCENT;\r
35 extern string Mode_of_Function_0 = "Average Retracement Pips";\r
36 extern string Mode_of_Function_1 = "Average Retracement Ratio";\r
37 extern string Mode_of_Function_2 = "Movement Count";\r
38 extern string Mode_of_Function_3 = "Movement Count Ratio";\r
39 extern string Mode_of_Function_4 = "Price Push in Pips";\r
40 extern string Mode_of_Function_5 = "Price Push Ratio";\r
42 extern int Used_Price = PRICE_CLOSE;\r
44 extern int Use_Close_Price = PRICE_CLOSE;\r
45 extern int Use_Median_Price = PRICE_MEDIAN;\r
46 extern int Use_Typical_Price = PRICE_TYPICAL;\r
47 extern int Use_Weighted_Price = PRICE_WEIGHTED;\r
50 //---- buffers\r
51 double Retracement_Range_Buffer[];\r
52 double Range_Delta_Buffer[];\r
53 double Spread_Monitor_Buffer[];\r
54 double Bulls_Buffer[];\r
55 double Bears_Buffer[];\r
58 //--- globals\r
59 #define NO_DIRECTION 0\r
60 #define DIRECTION_UP 1\r
61 #define DIRECTION_DOWN 2\r
63 #define NO_PRICE -1.0\r
67 int Last_Direction = NO_DIRECTION;\r
68 double Last_Direction_Change_Price = NO_PRICE;\r
69 double Last_Tick_Price = NO_PRICE;\r
70 double Average_Range;\r
71 int Ranges_Added;\r
72 double Average_Range_2;\r
73 int Ranges_Added_2;\r
75 datetime Last_Tick_Time;\r
77 double Tick_Overall_Movement;\r
78 double Max_Tick_Bears;\r
79 double Max_Tick_Bulls;\r
80 double Minimum_Bullish_Movement;\r
81 double Minimum_Bearish_Movement;\r
82 int Bullish_Movements;\r
83 int Bearish_Movements;\r
85 int subperiods_ct;\r
87 // Copies\r
88 double _Tick_Overall_Movement;\r
89 double _Max_Tick_Bears;\r
90 double _Max_Tick_Bulls;\r
91 double _Minimum_Bullish_Movement;\r
92 double _Minimum_Bearish_Movement;\r
93 int _Bullish_Movements;\r
94 int _Bearish_Movements;\r
95 int _Last_Direction;\r
96 double _Last_Direction_Change_Price;\r
97 double _Last_Tick_Price;\r
98 double _Average_Range;\r
99 int _Ranges_Added;\r
100 double _Average_Range_2;\r
101 int _Ranges_Added_2;\r
105 // Used for price accounting\r
106 #define PRICE_VALUE           0\r
107 #define TOTAL_TIME_ACTIVE     1\r
108 #define LAST_LEFT_TIME        2\r
109 #define LAST_VISIT_TIME       3\r
110 #define NUM_PROPERTIES        4\r
112 int Tick_Price_Time[][NUM_PROPERTIES];\r
113 double spread = 0.0;\r
114 double stop_level = 0.0;\r
117 void\r
118 reset_counters()\r
120      spread = MarketInfo(Symbol(), MODE_SPREAD);\r
121      stop_level = MarketInfo(Symbol(), MODE_STOPLEVEL);\r
123      RefreshRates();\r
125      Bullish_Movements = 0;\r
126      Bearish_Movements = 0;\r
127      Average_Range = NO_PRICE;\r
128      Ranges_Added = 0;\r
129      Average_Range_2 = NO_PRICE;\r
130      Ranges_Added_2 = 0;\r
132      Last_Direction = NO_DIRECTION;\r
133      Last_Direction_Change_Price = NO_PRICE;\r
135      Tick_Overall_Movement = 0.0;\r
136      Max_Tick_Bulls = 0.0;\r
137      Max_Tick_Bears = 0.0;\r
139      Bullish_Movements = 0;\r
140      Bearish_Movements = 0;\r
141      \r
142      ArrayResize(Tick_Price_Time, 0);\r
145 void\r
146 save_counters()\r
148      _Bullish_Movements = Bullish_Movements;\r
149      _Bearish_Movements = Bearish_Movements;\r
150      _Average_Range = Average_Range;\r
151      _Ranges_Added = Ranges_Added;\r
152      _Average_Range_2 = Average_Range_2;\r
153      _Ranges_Added_2 = Ranges_Added_2;\r
155      _Last_Direction = Last_Direction;\r
156      _Last_Direction_Change_Price = Last_Direction_Change_Price;\r
158      _Tick_Overall_Movement = Tick_Overall_Movement;\r
159      _Max_Tick_Bulls = Max_Tick_Bulls;\r
160      _Max_Tick_Bears = Max_Tick_Bears;\r
162      _Bullish_Movements = Bullish_Movements;\r
163      _Bearish_Movements = Bearish_Movements;\r
166 void\r
167 restore_counters()\r
169      Bullish_Movements = _Bullish_Movements;\r
170      Bearish_Movements = _Bearish_Movements;\r
171      Average_Range = _Average_Range;\r
172      Ranges_Added = _Ranges_Added;\r
173      Average_Range_2 = _Average_Range_2;\r
174      Ranges_Added_2 = _Ranges_Added_2;\r
176      Last_Direction = _Last_Direction;\r
177      Last_Direction_Change_Price = _Last_Direction_Change_Price;\r
179      Tick_Overall_Movement = _Tick_Overall_Movement;\r
180      Max_Tick_Bulls = _Max_Tick_Bulls;\r
181      Max_Tick_Bears = _Max_Tick_Bears;\r
183      Bullish_Movements = _Bullish_Movements;\r
184      Bearish_Movements = _Bearish_Movements;\r
187 int\r
188 get_accounted_price_index(double requested_price)\r
190      if (requested_price < 0.0) return (-1);\r
191      \r
192      int requested_price_int = requested_price / Point;\r
193      int price_ix = 0;\r
194      int price_ct = ArrayRange(Tick_Price_Time, 0);\r
195      \r
196      while (price_ix < price_ct) {\r
197           if (Tick_Price_Time[price_ix][PRICE_VALUE] == requested_price_int) break;\r
198           price_ix++;\r
199      }\r
201      if (price_ix < price_ct) return (price_ix);\r
202      else return (-1);\r
205 int\r
206 add_accounted_price(\r
207      double price_value, \r
208      datetime total_time, \r
209      datetime last_left, \r
210      datetime last_visit)\r
212      int price_value_int = price_value / Point;\r
213      int price_ct = ArrayRange(Tick_Price_Time, 0);\r
214      int price_ix = price_ct;\r
216      price_ct++;\r
217      price_ct = ArrayResize(Tick_Price_Time, price_ct);\r
218      \r
219      if (price_ct < 1 || price_ix < 0) return(-1);\r
221      Tick_Price_Time[price_ix][PRICE_VALUE] = price_value_int;     \r
222      Tick_Price_Time[price_ix][TOTAL_TIME_ACTIVE] = total_time;     \r
223      Tick_Price_Time[price_ix][LAST_LEFT_TIME] = last_left;     \r
224      Tick_Price_Time[price_ix][LAST_VISIT_TIME] = last_visit;\r
225      \r
226      return(price_ix);\r
229 datetime\r
230 retime_accounted_price(int price_ix, datetime last_left)\r
232      int price_ct = ArrayRange(Tick_Price_Time, 0);\r
233      if (price_ix < 0 || price_ix >= price_ct) return (-1);\r
235      datetime last_visit = Tick_Price_Time[price_ix][LAST_VISIT_TIME];\r
236      if (last_visit > last_left) return (-1);\r
237      \r
238      datetime total_time = last_left - last_visit;\r
239      \r
240      Tick_Price_Time[price_ix][TOTAL_TIME_ACTIVE] += total_time;\r
241      Tick_Price_Time[price_ix][LAST_LEFT_TIME] = last_left;\r
242      \r
243      return (total_time);\r
246 datetime\r
247 visit_accounted_price(int price_ix, datetime last_visit)\r
249      int price_ct = ArrayRange(Tick_Price_Time, 0);\r
250      if (price_ix < 0 || price_ix >= price_ct) return (-1);\r
252      Tick_Price_Time[price_ix][LAST_VISIT_TIME] = last_visit;\r
253      Tick_Price_Time[price_ix][LAST_LEFT_TIME] = 0;\r
254      \r
255      return (Tick_Price_Time[price_ix][TOTAL_TIME_ACTIVE]);\r
258 void\r
259 update_price_stats(double current_price, double previous_price)\r
261      int price_ix = 0;\r
262      int price_ct = ArrayRange(Tick_Price_Time, 0);\r
263      datetime current_time = TimeCurrent();\r
265 // Update price just left\r
266      price_ix = get_accounted_price_index(previous_price);\r
267      if (price_ix < 0) add_accounted_price(previous_price, 0, current_time, current_time);\r
268      else retime_accounted_price(price_ix, current_time);\r
270 // Update newly visited price     \r
271      price_ix = get_accounted_price_index(current_price);\r
272      if (price_ix < 0) add_accounted_price(current_price, 0, 0, current_time);\r
273      else visit_accounted_price(price_ix, current_time);\r
276 double\r
277 get_current_change_range(double current_price)\r
279 // Detect movement\r
280      int direction;\r
281      double price_difference;\r
282     \r
283      if (Last_Direction_Change_Price == NO_PRICE) \r
284           Last_Direction_Change_Price = current_price;\r
285     \r
286      price_difference = current_price - Last_Direction_Change_Price;\r
287     \r
288      if (price_difference > Minimum_Bullish_Movement) {\r
289           direction = DIRECTION_UP;\r
290           Bullish_Movements++;\r
291      } else if (price_difference < Minimum_Bearish_Movement) {\r
292           direction = DIRECTION_DOWN;\r
293           Bearish_Movements++;\r
294      } else {\r
295           direction = NO_DIRECTION;\r
296      }\r
297      // update_price_stats(Current_Price, Last_Price);\r
299      // no retracement here nothing to see        \r
300      if (direction == NO_DIRECTION || direction == Last_Direction) \r
301           return (NO_PRICE);\r
302           \r
303      double current_range = (current_price - Last_Direction_Change_Price) / Point;\r
304      Last_Direction = direction;\r
305      Last_Direction_Change_Price = current_price;\r
306           \r
307      return (current_range);\r
310 void\r
311 update_retracement_pct(double current_range, int period_index)\r
313   // Find strongest retracement\r
314   Tick_Overall_Movement = Recentness_Factor * Tick_Overall_Movement + current_range;\r
315   if (Tick_Overall_Movement > Max_Tick_Bulls) \r
316      Max_Tick_Bulls = Tick_Overall_Movement;\r
317   else if (Tick_Overall_Movement < Max_Tick_Bears) \r
318      Max_Tick_Bears = Tick_Overall_Movement;\r
319      \r
320   double Max_Push_Difference = Max_Tick_Bulls + Max_Tick_Bears;\r
321      \r
322   // Calculate bull bear ratio\r
323   if (Max_Push_Difference < 0.0) {\r
324      Bears_Buffer[period_index] = -100.0 * Max_Push_Difference / Max_Tick_Bears;\r
325      Bulls_Buffer[period_index] = 0.0;\r
326      Range_Delta_Buffer[period_index] = Bears_Buffer[period_index];\r
327   } else if (Max_Push_Difference > 0.0) {\r
328      Bulls_Buffer[period_index] = 100.0 * Max_Push_Difference / Max_Tick_Bulls;\r
329      Bears_Buffer[period_index] = 0.0;\r
330      Range_Delta_Buffer[period_index] = Bulls_Buffer[period_index];\r
331   }\r
332   \r
335 void\r
336 update_retracement_pips(double current_range, int period_index)\r
338    // Find strongest retracement\r
339    Tick_Overall_Movement = Recentness_Factor * Tick_Overall_Movement + current_range;\r
340    if (Tick_Overall_Movement > Max_Tick_Bulls) Max_Tick_Bulls = Tick_Overall_Movement;\r
341    else if (Tick_Overall_Movement < Max_Tick_Bears) Max_Tick_Bears = Tick_Overall_Movement;\r
342      \r
343    double Max_Push_Difference = Max_Tick_Bulls + Max_Tick_Bears;\r
344      \r
345    // Calculate bull bear push ratio\r
346    Bears_Buffer[period_index] = Max_Tick_Bears;\r
347    Bulls_Buffer[period_index] = Max_Tick_Bulls;\r
350 #define MAX_HISTORY 256\r
352 double Bulls_Buffer_History[MAX_HISTORY];\r
353 double Bears_Buffer_History[MAX_HISTORY];\r
355 void\r
356 update_movement_count(int period_index)\r
358       Bulls_Buffer[period_index] = Bullish_Movements;\r
359       Bears_Buffer[period_index] = -1.0 * Bearish_Movements;\r
362 void\r
363 update_movement_ratio(int period_index)\r
365   double retracement_ratio;\r
366   \r
367   if (Bullish_Movements > Bearish_Movements) {\r
369      retracement_ratio = 1.0 - (1.0 * Bearish_Movements) / Bullish_Movements;\r
370      retracement_ratio *= 100.0;\r
372      Bulls_Buffer[period_index] = retracement_ratio;\r
373      Bears_Buffer[period_index] = 0.0;\r
374      Range_Delta_Buffer[period_index] = retracement_ratio;\r
376   } else if (Bullish_Movements < Bearish_Movements) {\r
377   \r
378      retracement_ratio = 1.0 - (1.0 * Bullish_Movements) / Bearish_Movements;\r
379      retracement_ratio *= -100.0;\r
381      Bears_Buffer[period_index] = retracement_ratio;\r
382      Bulls_Buffer[period_index] = 0.0;\r
383      Range_Delta_Buffer[period_index] = retracement_ratio;\r
385   } else {\r
387      Bears_Buffer[period_index] = 0.0;\r
388      Bulls_Buffer[period_index] = 0.0;\r
389      Range_Delta_Buffer[period_index] = 0.0;\r
391   }\r
392   \r
395 double\r
396 get_period_average_range(double current_range)\r
398      // Calculate weighted average movement range\r
399      if (Average_Range == NO_PRICE || Ranges_Added == 0)\r
400           Average_Range = current_range;\r
401      else\r
402           Average_Range = (Average_Range * Ranges_Added + current_range) / (Ranges_Added + 1);\r
404      Ranges_Added++;\r
406      return (Average_Range);\r
409 double\r
410 get_period_average_range_2(double current_range)\r
412      // Calculate weighted average movement range\r
413      if (Average_Range_2 == NO_PRICE || Ranges_Added_2 == 0)\r
414           Average_Range_2 = current_range;\r
415      else\r
416           Average_Range_2 = (Average_Range_2 * Ranges_Added_2 + current_range) / (Ranges_Added_2 + 1);\r
418      Ranges_Added_2++;\r
420      return (Average_Range_2);\r
423 bool\r
424 get_candle_bullish(int period_index)\r
426      return (Open[period_index] < Close[period_index]);\r
429 void\r
430 update_average_range_pips(double current_range, int period_index)\r
432      // Calculate average range\r
433      if (Opposite_Retracement_Only == true && current_range > 0.0)\r
434          Average_Range = get_period_average_range(current_range);         \r
435      else if (Opposite_Retracement_Only == true && current_range < 0.0)\r
436          Average_Range_2 = get_period_average_range_2(MathAbs(current_range));\r
437      else if (Opposite_Retracement_Only == false)\r
438          Average_Range = get_period_average_range(MathAbs(current_range));\r
440      // Update graph\r
441      if (Opposite_Retracement_Only == true && get_candle_bullish(period_index) == true) {\r
442           Retracement_Range_Buffer[period_index] = Average_Range_2;\r
443           Range_Delta_Buffer[period_index] = Average_Range_2;\r
444      } else if (Opposite_Retracement_Only == true && get_candle_bullish(period_index) == false) {\r
445           Retracement_Range_Buffer[period_index] = Average_Range;\r
446           Range_Delta_Buffer[period_index] = Average_Range;\r
447      } else if (Opposite_Retracement_Only == false) {\r
448           Retracement_Range_Buffer[period_index] = Average_Range;\r
449           Range_Delta_Buffer[period_index] = Average_Range;\r
450      }\r
453 void\r
454 update_average_range_ratio(double current_range, int period_index)\r
456      double candle_length = (High[0] - Low[0]) / Point;\r
457      if (candle_length <= 0.0) return;\r
459      update_average_range_pips(current_range, period_index);\r
461      Retracement_Range_Buffer[period_index] = 100.0 * Retracement_Range_Buffer[period_index] / candle_length;\r
462      Range_Delta_Buffer[period_index] = Retracement_Range_Buffer[period_index];\r
465 //+------------------------------------------------------------------+\r
466 //| expert initialization function                                   |\r
467 //+------------------------------------------------------------------+\r
468 int init()\r
469   {\r
470 //----\r
472    IndicatorShortName("JRetracto"); \r
473    \r
474    if (Log_Prices_Spread == true) {\r
475           SetIndexStyle(2, DRAW_HISTOGRAM); \r
476           SetIndexLabel(2, "Spread History"); \r
477           SetIndexBuffer(2, Spread_Monitor_Buffer); \r
478    } else {\r
479           SetIndexStyle(2, DRAW_NONE); \r
480           SetIndexLabel(2, ""); \r
481           SetIndexBuffer(2, NULL); \r
482    }\r
484    switch (Mode_of_Function) {\r
485      case STRONGEST_PUSH_PERCENT:\r
486           SetIndexStyle(0, DRAW_NONE); \r
487           SetIndexStyle(1, DRAW_LINE); \r
489           SetIndexLabel(0, ""); \r
490           SetIndexBuffer(0, NULL); \r
492           SetIndexLabel(1, "Push Delta"); \r
493           SetIndexBuffer(1, Range_Delta_Buffer); \r
495           SetIndexLabel(3, "Bullish Pressure in Percents"); \r
496           SetIndexStyle(3, DRAW_HISTOGRAM); \r
497           SetIndexBuffer(3, Bulls_Buffer); \r
499           SetIndexLabel(4, "Bearish Pressure in Percents"); \r
500           SetIndexStyle(4, DRAW_HISTOGRAM); \r
501           SetIndexBuffer(4, Bears_Buffer); \r
503           SetLevelStyle(STYLE_DASHDOT, 1, DodgerBlue); \r
504           SetLevelStyle(STYLE_DASHDOT, 2, DodgerBlue); \r
505           SetLevelValue(1, 50.0);\r
506           SetLevelValue(2, -50.0);\r
507           break;\r
509      case STRONGEST_PUSH_PIPS:\r
510           SetIndexStyle(0, DRAW_NONE); \r
511           SetIndexStyle(1, DRAW_LINE); \r
513           SetIndexLabel(0, ""); \r
514           SetIndexBuffer(0, NULL); \r
516           SetIndexLabel(1, "Push Delta"); \r
517           SetIndexBuffer(1, Range_Delta_Buffer); \r
519           SetIndexLabel(3, "Bullish Absolute Movement in Pips"); \r
520           SetIndexLabel(4, "Bearish Absolute Movement in Pips"); \r
521           SetIndexStyle(3, DRAW_HISTOGRAM); \r
522           SetIndexBuffer(3, Bulls_Buffer); \r
523           SetIndexStyle(4, DRAW_HISTOGRAM); \r
524           SetIndexBuffer(4, Bears_Buffer); \r
526           SetLevelStyle(STYLE_SOLID, 0, CLR_NONE);\r
527           SetLevelValue(1, 0.0);\r
528           SetLevelStyle(STYLE_SOLID, 0, CLR_NONE);\r
529           SetLevelValue(2, 0.0);\r
530           break;\r
531           \r
532      case MOVEMENT_COUNT:\r
533           SetIndexStyle(0, DRAW_NONE); \r
534           SetIndexLabel(0, ""); \r
535           SetIndexBuffer(0, NULL); \r
537           SetIndexStyle(1, DRAW_NONE); \r
538           SetIndexLabel(1, ""); \r
539           SetIndexBuffer(1, NULL); \r
541           SetIndexLabel(3, "Bullish Retracements Count"); \r
542           SetIndexStyle(3, DRAW_HISTOGRAM); \r
543           SetIndexBuffer(3, Bulls_Buffer); \r
545           SetIndexLabel(4, "Bearish Retracements Count"); \r
546           SetIndexStyle(4, DRAW_HISTOGRAM); \r
547           SetIndexBuffer(4, Bears_Buffer); \r
549           SetLevelStyle(STYLE_SOLID, 0, CLR_NONE);\r
550           SetLevelValue(1, 0.0);\r
551           SetLevelStyle(STYLE_SOLID, 0, CLR_NONE);\r
552           SetLevelValue(2, 0.0);\r
553           break;\r
555      case MOVEMENT_COUNT_RATIO:\r
556           SetIndexStyle(0, DRAW_NONE); \r
557           SetIndexLabel(0, ""); \r
558           SetIndexBuffer(0, NULL); \r
560           SetIndexStyle(1, DRAW_LINE); \r
561           SetIndexLabel(1, "Retracements Ratio Delta"); \r
562           SetIndexBuffer(1, Range_Delta_Buffer); \r
564           SetIndexLabel(3, "Bullish Retracements Ratio"); \r
565           SetIndexStyle(3, DRAW_HISTOGRAM); \r
566           SetIndexBuffer(3, Bulls_Buffer); \r
568           SetIndexLabel(4, "Bearish Retracements Ratio"); \r
569           SetIndexStyle(4, DRAW_HISTOGRAM); \r
570           SetIndexBuffer(4, Bears_Buffer); \r
572           SetLevelStyle(STYLE_DASHDOT, 1, DodgerBlue); \r
573           SetLevelStyle(STYLE_DASHDOT, 2, DodgerBlue); \r
574           SetLevelValue(1, 50.0);\r
575           SetLevelValue(2, -50.0);\r
576           break;\r
577           \r
578      case AVERAGE_RETRACEMENT_PIPS:\r
579           SetIndexStyle(0, DRAW_HISTOGRAM); \r
580           SetIndexLabel(0, "Average Retracement Range in Pips"); \r
581           SetIndexBuffer(0, Retracement_Range_Buffer); \r
583           SetIndexStyle(1, DRAW_LINE); \r
584           SetIndexLabel(1, "Range Delta"); \r
585           SetIndexBuffer(1, Range_Delta_Buffer); \r
587           SetIndexLabel(3, ""); \r
588           SetIndexStyle(3, DRAW_NONE); \r
589           SetIndexBuffer(3, NULL); \r
591           SetIndexLabel(4, ""); \r
592           SetIndexStyle(4, DRAW_NONE); \r
593           SetIndexBuffer(4, NULL); \r
595           SetLevelStyle(STYLE_SOLID, 0, CLR_NONE);\r
596           SetLevelValue(1, 0.0);\r
597           SetLevelStyle(STYLE_SOLID, 0, CLR_NONE);\r
598           SetLevelValue(2, 0.0);\r
599           break;\r
600           \r
601      case AVERAGE_RETRACEMENT_PERCENT:\r
602           SetIndexStyle(0, DRAW_HISTOGRAM); \r
603           SetIndexLabel(0, "Average Retracement Range in Percents"); \r
604           SetIndexBuffer(0, Retracement_Range_Buffer); \r
606           SetIndexStyle(1, DRAW_LINE); \r
607           SetIndexLabel(1, "Range Delta"); \r
608           SetIndexBuffer(1, Range_Delta_Buffer); \r
610           SetIndexLabel(3, ""); \r
611           SetIndexStyle(3, DRAW_NONE); \r
612           SetIndexBuffer(3, NULL); \r
614           SetIndexLabel(4, ""); \r
615           SetIndexStyle(4, DRAW_NONE); \r
616           SetIndexBuffer(4, NULL); \r
618           SetLevelStyle(STYLE_DASHDOT, 1, DodgerBlue); \r
619           SetLevelStyle(STYLE_DASHDOT, 1, DodgerBlue); \r
620           SetLevelValue(1, 50.0);\r
621           SetLevelValue(2, -50.0);\r
622           break;\r
623    }\r
624    \r
625    Minimum_Bullish_Movement = Minimum_Movement_PIPs * Point;\r
626    Minimum_Bearish_Movement = -1.0 * Minimum_Movement_PIPs * Point;\r
627    \r
628    subperiods_ct = Period() * PERIOD_M1;\r
629    \r
630 //----\r
632    reset_counters();\r
634    return(0);\r
635   }\r
637 double\r
638 get_current_price(int price_type)\r
640      switch (price_type) {\r
641           case PRICE_CLOSE:\r
642                return (Close[0]);\r
644           case PRICE_MEDIAN:\r
645                return ((Low[0] + High[0]) / 2.0);\r
647           case PRICE_TYPICAL:\r
648                return ((Low[0] + High[0] + Close[0]) / 3.0);\r
650           case PRICE_WEIGHTED:\r
651                return ((Low[0] + High[0] + Close[0] + Close[0]) / 4.0);\r
652           \r
653           default:\r
654                return (0.0);\r
655      }\r
658 void\r
659 do_your_thang(double range, int period_index)\r
661   switch (Mode_of_Function) {\r
662     case STRONGEST_PUSH_PERCENT:\r
663       if (range == NO_PRICE) return (0);\r
664       else update_retracement_pct(range, period_index);\r
665       break;\r
667     case STRONGEST_PUSH_PIPS:\r
668       if (range == NO_PRICE) return (0);\r
669       else update_retracement_pips(range, period_index);\r
670       break;\r
671       \r
672     case MOVEMENT_COUNT:\r
673       update_movement_count(period_index);\r
674       break;\r
676     case MOVEMENT_COUNT_RATIO:\r
677       update_movement_ratio(period_index);\r
678       break;\r
679       \r
680     case AVERAGE_RETRACEMENT_PIPS:\r
681       if (range == NO_PRICE) return (0);\r
682       else update_average_range_pips(range, period_index);\r
683       break;\r
685     case AVERAGE_RETRACEMENT_PERCENT:\r
686       if (range == NO_PRICE) return (0);\r
687       else update_average_range_ratio(range, period_index);\r
688       break;\r
689   }\r
692  \r
693 //+------------------------------------------------------------------+\r
694 //| expert deinitialization function                                 |\r
695 //+------------------------------------------------------------------+\r
696 int deinit()\r
697   {\r
698 //----\r
699    \r
700 //----\r
701    return(0);\r
702   }\r
704 int start()\r
705   {\r
706   int limit = Bars - IndicatorCounted() - 1;\r
707   if (limit < 0) return (0);\r
708 //----\r
709   \r
710   save_counters();\r
711   \r
712   for (int ix = limit; ix > 0; ix--) {\r
713      if (ix > 5) continue;\r
714      \r
715      reset_counters();\r
717      for (int subix = subperiods_ct * (ix + 1); subix >= ix * subperiods_ct; subix--) {\r
718           double range;\r
719           range = get_current_change_range(Open[subix]);\r
720           do_your_thang(range, ix);\r
721           range = get_current_change_range(Low[subix]);\r
722           do_your_thang(range, ix);\r
723           range = get_current_change_range(High[subix]);\r
724           do_your_thang(range, ix);\r
725           range = get_current_change_range(Close[subix]);\r
726           do_your_thang(range, ix);\r
727      }\r
728      \r
729   }\r
731   ////   Now do current tick   ////\r
732   \r
733   // Chech if price moved\r
734   double current_price = get_current_price(Used_Price);\r
735   if (current_price == Last_Tick_Price) return (0);\r
736   Last_Tick_Price = current_price;\r
737   \r
738   // New period\r
739   if (Time[0] != Last_Tick_Time) reset_counters();\r
740   else restore_counters();  \r
741   Last_Tick_Time = Time[0];\r
743   // Show price spread graph\r
744   if (Log_Prices_Spread == true) Spread_Monitor_Buffer[0] = spread;\r
747   // Check for movement in range\r
748   double current_range = get_current_change_range(current_price);\r
749   do_your_thang(current_range, 0);\r
750   \r
751 //----\r
752    return(0);\r
753   }\r
754 //+------------------------------------------------------------------+\r