Merge branch 'master' of git://repo.or.cz/mqlkit
[mqlkit.git] / indicators / jmarket_sentiment.mq4.BACKUP.4229.mq4
blob93dfc94ac324be53e81243dad9a7f890b3a390c6
1 //+------------------------------------------------------------------+\r
2 //|                                            jmarket_sentiment.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 #property indicator_separate_window\r
10 #property indicator_buffers 5\r
11 #property indicator_color1 Red\r
12 #property indicator_color2 OrangeRed\r
13 #property indicator_color3 Gold\r
14 #property indicator_color4 SteelBlue\r
15 #property indicator_color5 Lime\r
16 #property indicator_width1 1\r
17 #property indicator_width2 1\r
18 #property indicator_width3 2\r
19 #property indicator_width4 2\r
20 #property indicator_width5 1\r
21 #property indicator_level1 1.0\r
22 #property indicator_level2 -1.0\r
24 #define DEBUG 0\r
27 #define WEIGHT_MOVE 0\r
28 #define ABS_MOVE    1\r
29 #define ABS_PUSH    2\r
30 #define TRENDLINE_NAME "jnextbar_predict"\r
31 #define INVALID_VOLUME 50\r
33 #define NEUTRAL 0\r
34 #define BULLISH 1\r
35 #define BEARISH 2\r
38 extern int MA_Period = 32;\r
39 extern int MA2_Period = 64;\r
40 extern int Time_Frame_Mins = 0;\r
41 extern int Retracement_Look_Back = 32;\r
42 extern int Mode_Function = ABS_MOVE;\r
43 extern bool Normalize_MA = true;\r
44 extern string _Mode_0 = "Bar to bar weighted hi-lo difference aggregate to volume ratio"; // nakaj stiska\r
45 extern string _Mode_1 = "Bar to bar any tick max difference"; // grid\r
46 extern string _Mode_2 = "Bar to bar tick max difference"; // pletkanje\r
47 extern int Sentiment_Expectation = NEUTRAL;\r
48 extern string _Expectation_0 = "Neutral sentiment";\r
49 extern string _Expectation_1 = "Bullish sentiment";\r
50 extern string _Expectation_2 = "Bearish sentiment";\r
52 //--- buffers\r
53 double ExtMapBuffer1[];\r
54 double ExtMapBuffer2[];\r
55 double ExtMapBuffer3[];\r
56 double ExtMapBuffer4[];\r
57 double ExtMapBuffer5[];\r
58 double ExtMapBuffer6[];\r
62 int time_frame;\r
63 double index_factor = 1.0;\r
64 int hTrendLine = -1;\r
65 int ind_window_handle;\r
66 double prev_best_step;\r
67 datetime prev_calc_time;\r
69 void\r
70 create_trendline()\r
71 {\r
72      ind_window_handle = WindowFind("jmarket_sentiment");\r
73    \r
74      if (hTrendLine == -1 && ind_window_handle > -1) {\r
75      \r
76           hTrendLine = ObjectCreate(\r
77                TRENDLINE_NAME, \r
78                OBJ_TREND, \r
79                ind_window_handle, \r
80                iTime(NULL, time_frame, 0), \r
81                0.0, \r
82                iTime(NULL, time_frame, 0) + Period() * 60, \r
83                0.0);\r
84                \r
85           ObjectSet(TRENDLINE_NAME, OBJPROP_COLOR, indicator_color2);\r
86           ObjectSet(TRENDLINE_NAME, OBJPROP_STYLE, STYLE_SOLID);\r
87           ObjectSet(TRENDLINE_NAME, OBJPROP_WIDTH, indicator_width2);\r
88      }\r
89 }\r
91 void\r
92 remove_trendline()\r
93 {\r
94      ObjectDelete(TRENDLINE_NAME);\r
95 }\r
97 //+------------------------------------------------------------------+\r
98 //| Custom indicator initialization function                         |\r
99 //+------------------------------------------------------------------+\r
100 int init()\r
101   {\r
102    IndicatorBuffers(6);\r
103   \r
104 //---- indicators\r
105    SetIndexStyle(0,DRAW_HISTOGRAM);\r
106    SetIndexBuffer(0,ExtMapBuffer1);\r
107    SetIndexLabel(0,"Movement");\r
108    SetIndexEmptyValue(0, EMPTY_VALUE);\r
109    \r
110    SetIndexStyle(1,DRAW_LINE);\r
111    SetIndexBuffer(1,ExtMapBuffer2);\r
112    SetIndexLabel(1,"Movement Sum");\r
113    SetIndexEmptyValue(1, EMPTY_VALUE);\r
114    \r
115    SetIndexStyle(2,DRAW_LINE);\r
116    SetIndexBuffer(2,ExtMapBuffer3);\r
117    SetIndexLabel(2,"Smoothed "+MA_Period);\r
118    SetIndexEmptyValue(2, EMPTY_VALUE);\r
119    \r
120    SetIndexStyle(3,DRAW_LINE);\r
121    SetIndexBuffer(3,ExtMapBuffer4);\r
122    SetIndexLabel(3,"Trend step");\r
123    SetIndexEmptyValue(3, EMPTY_VALUE);\r
125    SetIndexStyle(4,DRAW_LINE);\r
126    SetIndexBuffer(4,ExtMapBuffer5);\r
127    SetIndexLabel(4,"Smoothed "+MA2_Period);\r
128    SetIndexEmptyValue(4, EMPTY_VALUE);\r
129    \r
130    SetIndexStyle(5,DRAW_LINE);\r
131    SetIndexBuffer(5,ExtMapBuffer6);\r
132    SetIndexLabel(5,"Absolute movement");\r
133    SetIndexEmptyValue(5, EMPTY_VALUE);\r
134    \r
135    if (Time_Frame_Mins == 0)\r
136      time_frame = Period();\r
137    else\r
138      time_frame = Time_Frame_Mins;\r
140    if (time_frame < 1) time_frame = 1;\r
142    index_factor = Period();\r
143    index_factor = index_factor / time_frame;\r
144    \r
145    prev_calc_time = 0;\r
146    prev_best_step = 0;\r
147    \r
148    if (Mode_Function != WEIGHT_MOVE) remove_trendline();\r
149    else create_trendline();   \r
150    \r
151 //----\r
152    return(0);\r
153   }\r
154 //+------------------------------------------------------------------+\r
155 //| Custom indicator deinitialization function                       |\r
156 //+------------------------------------------------------------------+\r
157 int deinit()\r
158   {\r
159 //----\r
160    remove_trendline();\r
161 //----\r
162    return(0);\r
163   }\r
165 double\r
166 get_delta_ratio(\r
167      double &SignalBuffer[],\r
168      int SignalBufferLen)\r
170 if (DEBUG == 1)  Print("Debug get_delta_ratio");\r
172      double delta = 0;\r
173      bool going_up = false;\r
174    \r
175      for (int i = 0; i < SignalBufferLen; i++) {\r
176         if (SignalBuffer[i] == 0 || SignalBuffer[i+1] == 0) continue;\r
177         else if (delta != 0 && going_up != (SignalBuffer[i] > SignalBuffer[i+1]) ) break;\r
178         \r
179         if (delta == 0) going_up = (SignalBuffer[i] > SignalBuffer[i+1]);\r
180         \r
181         delta = ( (delta * i) + (SignalBuffer[i] - SignalBuffer[i+1])) / (i + 1.);\r
182      }\r
183    \r
184      return (delta);\r
187 double\r
188 get_time_ratio(bool last_bar)\r
190 if (DEBUG == 1)  Print("Debug get_time_ratio");\r
192      double time_ratio;\r
193      if (last_bar == false) {\r
194           time_ratio = 1;\r
195      } else {\r
196           double frame_delta = TimeCurrent() - iTime(NULL, time_frame, 0);\r
197           if (frame_delta > 0) time_ratio = time_frame * 60. / frame_delta;\r
198           else time_ratio = 0;\r
199      }\r
200           \r
201      return(time_ratio);\r
204 double\r
205 get_weighted_move(\r
206      double &hi, \r
207      double &low, \r
208      double &close, \r
209      double &prevhi, \r
210      double &prevlow, \r
211      double &prevclose,     \r
212      int ix)\r
213 \r
214 if (DEBUG == 1) Print("Debug get_weighted_move");\r
216      if (hi < prevlow || low > prevhi) return (0); // disconnected bars\r
218       //current weighted high minus previous weighted high\r
219      double hidiff = ((2. * hi + close) / 3.) - ((2. * prevhi + prevclose) / 3.);\r
220      double lowdiff = ((2. * low + close) / 3.) - ((2. * prevlow + prevclose) / 3.);\r
221      double absdiff = hidiff + lowdiff;\r
223      double volume_ratio;\r
224      double vol = iVolume(NULL, time_frame, ix);\r
225      double prevol = iVolume(NULL, time_frame, ix+1);\r
226      \r
227      if (vol < INVALID_VOLUME) {\r
228           volume_ratio = 0;\r
229      } else if (prevol < INVALID_VOLUME) {\r
230           volume_ratio = 1;\r
231      } else {               \r
232           volume_ratio = vol / prevol;\r
233      }\r
235      double time_ratio = get_time_ratio( (ix == 0) );\r
236      \r
237      return (absdiff * time_ratio * volume_ratio);\r
241 double\r
242 get_absolute_diff(\r
243      double &hi, \r
244      double &low, \r
245      double &prevhi, \r
246      double &prevlow, \r
247      int ix)\r
248 \r
249 if (DEBUG == 1) Print("Debug get_absolute_diff");\r
251       //current weighted high minus previous weighted high\r
252      double hidiff = MathAbs(hi - prevhi);\r
253      double lowdiff = MathAbs(low - prevlow);\r
254      double absdiff = hidiff + lowdiff;\r
256      double time_ratio = get_time_ratio(ix);\r
257      \r
258      return (absdiff * time_ratio);\r
261 /* largest price difference between two bars */\r
262 double\r
263 get_absolute_move(\r
264      double hi, \r
265      double low, \r
266      double close, \r
267      double prevhi, \r
268      double prevlow, \r
269      double prevclose)\r
271 if (DEBUG == 1)  Print("Debug get_absolute_move");\r
273      double abs_move = 0.0;\r
274      \r
275      double cur_hlc[3];\r
276      cur_hlc[0] = hi;\r
277      cur_hlc[1] = low;\r
278      cur_hlc[2] = close;\r
279      \r
280      double prev_hlc[3];\r
281      prev_hlc[0] = prevhi;\r
282      prev_hlc[1] = prevlow;\r
283      prev_hlc[2] = prevclose;\r
285      for (int i = 0; i < 3; i++) \r
286           for (int j = 0; j < 3; j++) \r
287                if ( MathAbs(cur_hlc[i] - prev_hlc[j]) > MathAbs(abs_move) )\r
288                     abs_move = cur_hlc[i] - prev_hlc[j];\r
289           \r
290      if ( (hi - low) > abs_move ) {\r
291           if (close > prevclose) abs_move = hi - low; \r
292                else abs_move = low - hi;\r
293      }\r
294      \r
295      return (abs_move);\r
298 void\r
299 get_bar_move(\r
300           int now_bar, \r
301           int ref_bar, \r
302           double &max_move)\r
304 if (DEBUG == 1) Print("Debug get_bar_move");\r
306      for (int ix = now_bar - 1; ix >= ref_bar; ix--) {\r
307           double now_move = get_absolute_move(\r
308                                    iHigh(NULL, time_frame, ix),\r
309                                    iLow(NULL, time_frame, ix),\r
310                                    iClose(NULL, time_frame, ix),\r
311                                    iHigh(NULL, time_frame, now_bar),\r
312                                    iLow(NULL, time_frame, now_bar),\r
313                                    iClose(NULL, time_frame, now_bar) );\r
314                                    \r
315           if ( MathAbs(now_move) > MathAbs(max_move) ) max_move = now_move;\r
316      }\r
319 /* largest price difference since start_bar trend */\r
320 double\r
321 get_max_move(int ref_bar)\r
323      if (DEBUG == 1) Print("Debug get_max_move");\r
325      double max_move = 0;\r
326      bool ref_bull = (ExtMapBuffer1[ref_bar] > 0);\r
327      \r
328      for (int now_bar = ref_bar + 1; \r
329           (ref_bull == (ExtMapBuffer1[now_bar] > 0)) && (now_bar < Bars); \r
330           now_bar++) {\r
332           get_bar_move(now_bar, ref_bar, max_move);\r
333      }\r
335      get_bar_move(now_bar, ref_bar, max_move);\r
337      return (max_move);\r
340 #define MAXLEN 1024\r
342 double bears_array[MAXLEN];\r
343 double bulls_array[MAXLEN];\r
346 /* sorted arrays expected ! */\r
347 double\r
348 calc_pips(\r
349      double &trending[],\r
350      int trending_len,\r
351      double &retracements[],\r
352      int retracements_len\r
353      )\r
355      if (DEBUG == 1) Print("Debug calc_pips");\r
357      double best_ratio = 0;\r
358      double best_step = 0;\r
360      if ( (TimeCurrent() - prev_calc_time) < (time_frame * Period() * 5) ) return(prev_best_step);\r
362      double step_base = 0;\r
363      for (int ix = 1;\r
364           (step_base == 0) && (ix < Bars);\r
365           ix++) \r
366      {\r
367           step_base = ExtMapBuffer6[ix];\r
368      }\r
369      if (step_base == 0) return (prev_best_step);\r
370      \r
371      double interpolation_step = step_base * 0.0312; // 1/16\r
372      \r
373           \r
374      for (int z = 0; z < 64; z++) {\r
375           \r
376           double cur_step = step_base + (z * interpolation_step);\r
377                \r
378           double won_pips = 0;\r
379           double lost_pips = 0;\r
380                     \r
381           for (int j = 0; j < retracements_len; j++) {\r
382                lost_pips += cur_step * MathFloor(retracements[j] / cur_step) / Point;\r
383                if (cur_step >= retracements[j]) lost_pips += 1. * MathMod(retracements[j], cur_step) / Point;\r
384           }\r
385                \r
386           for (j = 0; j < trending_len; j++) {\r
387                won_pips += cur_step * MathFloor(trending[j] / cur_step) / Point;\r
388                if (cur_step >= trending[j]) lost_pips += 1. * MathMod(trending[j], cur_step) / Point;\r
389           }\r
391           if (won_pips == 0) double cur_ratio = 0;\r
392           else if (lost_pips == 0) cur_ratio = won_pips;\r
393           else cur_ratio = won_pips / lost_pips;\r
395           if (cur_ratio > best_ratio) {\r
396                best_step = cur_step;\r
397                best_ratio = cur_ratio;\r
398           }\r
400      }\r
401      \r
402      if (best_step == 0) return (prev_best_step);\r
403      \r
404      prev_best_step = best_step;\r
405      prev_calc_time = TimeCurrent();\r
407      if (DEBUG == 1) Print(\r
408           "Recomended minimal pip step " + best_step + " past " + \r
409           trending_len + " trending blocks, " + retracements_len + " retracements blocks.");\r
410      \r
411      return (best_step);\r
414 int\r
415 gcd(int a, int b)\r
417      if (b == 0) return (a);\r
418      else return ( gcd(b, a % b) );\r
421 //+------------------------------------------------------------------+\r
422 //| Custom indicator iteration function                              |\r
423 //+------------------------------------------------------------------+\r
424 int start()\r
425   {\r
426    int counted_bars = IndicatorCounted();\r
427 //----\r
428    int limit = Bars - counted_bars - 1;\r
429    if (limit < 0) return (0);\r
430    \r
431    for (int i = limit; i >= 0; i--) {\r
432    \r
433      int ix = MathFloor(index_factor * i);\r
434      \r
435      double hi = iHigh(NULL, time_frame, ix);\r
436      double low = iLow(NULL, time_frame, ix);\r
437      double close = iClose(NULL, time_frame, ix);\r
439      double prevhi = iHigh(NULL, time_frame, ix+1);\r
440      double prevlow = iLow(NULL, time_frame, ix+1);\r
441      double prevclose = iClose(NULL, time_frame, ix+1);\r
442      \r
443      if (prevhi == 0 || prevlow == 0 || prevclose == 0) continue;\r
444      if (hi == 0 || low == 0 || close == 0) continue;\r
445      \r
446           switch (Mode_Function) {\r
447           case WEIGHT_MOVE:\r
448                ExtMapBuffer1[i] = get_weighted_move(hi, low, close, prevhi, prevlow, prevclose, ix);\r
449                ExtMapBuffer2[i] = ExtMapBuffer1[i];\r
450                break;\r
451          \r
452           case ABS_MOVE:\r
453                ExtMapBuffer1[i] = get_absolute_move(hi, low, close, prevhi, prevlow, prevclose);\r
454                ExtMapBuffer2[i] = get_max_move(i);\r
455                ExtMapBuffer6[i] = MathAbs(ExtMapBuffer1[i]);\r
456           \r
457                // fixup previous bars\r
458                for (int j = i + 1;\r
459                     ((ExtMapBuffer2[i] > 0) == (ExtMapBuffer2[j] > 0.0)) && (j < Bars);\r
460                     j++)\r
461                     ExtMapBuffer2[j] = ExtMapBuffer2[i];\r
462                break;\r
464           case ABS_PUSH:\r
465                ExtMapBuffer1[i] = get_absolute_diff(hi, low, prevhi, prevlow, i);\r
466                ExtMapBuffer2[i] = ExtMapBuffer1[i];\r
467                break;\r
468           }     \r
470      }\r
471    \r
472      if (Mode_Function == WEIGHT_MOVE) {\r
473 <<<<<<< HEAD
474           double ma_coef = 10.0;\r
475 =======
476      \r
477           if (Normalize_MA) double ma_coef = 10;\r
478           else ma_coef = 1;\r
479           \r
480 >>>>>>> 5675db9edd8b65061d7441f40114a38e07f453b1
481           for (i = limit; i >= 0; i--) \r
482                ExtMapBuffer3[i] = ma_coef * iMAOnArray(ExtMapBuffer1, Bars, MA_Period, 0, MODE_EMA, i);\r
483           for (i = limit; i >= 0; i--) \r
484                ExtMapBuffer5[i] = iMAOnArray(ExtMapBuffer3, Bars, MA2_Period, 0, MODE_EMA, i);\r
485                \r
486      } else { \r
487           for (i = limit; i >= 0; i--) {\r
488                ExtMapBuffer3[i] = iMAOnArray(ExtMapBuffer6, Bars, MA_Period, 0, MODE_EMA, i);\r
489                ExtMapBuffer5[i] = iMAOnArray(ExtMapBuffer1, Bars, MA2_Period, 0, MODE_EMA, i);\r
490           }\r
491      }\r
493      if (Mode_Function == ABS_MOVE) {\r
494    \r
495           switch (Sentiment_Expectation) {\r
496           case NEUTRAL:\r
497                bool going_bull = (ExtMapBuffer2[0] > 0);\r
498                break;\r
499           \r
500           case BULLISH:\r
501                going_bull = true;\r
502                break;\r
503           \r
504           case BEARISH:\r
505                going_bull = false;\r
506                break;\r
507           }\r
508                     \r
509           int bulls_len = 0;\r
510           int bears_len = 0;\r
511           double preval = 0;\r
513           /* get unique movements */\r
514           for (i = 0; i < Retracement_Look_Back; i++) {\r
515                if (ExtMapBuffer2[i] == preval) continue;\r
516                preval = ExtMapBuffer2[i];\r
517                \r
518                if (preval > 0) { \r
519                     bulls_array[bulls_len] = preval;\r
520                     bulls_len++;\r
521                } else if (preval < 0) {\r
522                     bears_array[bears_len] = MathAbs(preval);\r
523                     bears_len++;\r
524                }\r
525           }\r
527           if (going_bull == true)\r
528                double pip_step = calc_pips(bulls_array, bulls_len, bears_array, bears_len);\r
529           else\r
530                pip_step = calc_pips(bears_array, bears_len, bulls_array, bulls_len);\r
531           \r
532           ExtMapBuffer4[0] = pip_step;\r
533           SetLevelValue(0, pip_step);\r
534           SetLevelValue(1, -1.0 * pip_step);\r
535        \r
537    } else {\r
538           double delta_sign = get_delta_ratio(ExtMapBuffer1, Bars);\r
539           double predicted_price = delta_sign;\r
540           predicted_price += ExtMapBuffer1[0];\r
541      \r
542           if (hTrendLine != -1) {\r
543                ObjectSet(TRENDLINE_NAME, OBJPROP_TIME1, iTime(NULL, time_frame, 0) );\r
544                ObjectSet(TRENDLINE_NAME, OBJPROP_TIME2, iTime(NULL, time_frame, 0) + Period() * 60);\r
545                ObjectSet(TRENDLINE_NAME, OBJPROP_PRICE1, ExtMapBuffer2[0]);\r
546                ObjectSet(TRENDLINE_NAME, OBJPROP_PRICE2, predicted_price);\r
547           }\r
548    \r
549    }\r
550     \r
551 //----\r
552    return(0);\r
553   }\r
554 //+------------------------------------------------------------------+