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
9 #property indicator_separate_window
\r
10 #property indicator_buffers 4
\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_width1 1
\r
16 #property indicator_width2 1
\r
17 #property indicator_width3 2
\r
18 #property indicator_width4 2
\r
19 #property indicator_level1 1.0
\r
20 #property indicator_level2 -1.0
\r
25 #define WEIGHT_MOVE 0
\r
28 #define TRENDLINE_NAME "jnextbar_predict"
\r
29 #define INVALID_VOLUME 50
\r
36 extern int MA_Period = 32;
\r
37 extern int Time_Frame_Mins = 0;
\r
38 extern int Retracement_Look_Back = 32;
\r
39 extern int Mode_Function = ABS_MOVE;
\r
40 extern string _Mode_0 = "Bar to bar weighted hi-lo difference aggregate to volume ratio"; // nakaj stiska
\r
41 extern string _Mode_1 = "Bar to bar any tick max difference"; // grid
\r
42 extern string _Mode_2 = "Bar to bar tick max difference"; // pletkanje
\r
43 extern int Sentiment_Expectation = NEUTRAL;
\r
44 extern string _Expectation_0 = "Neutral sentiment";
\r
45 extern string _Expectation_1 = "Bullish sentiment";
\r
46 extern string _Expectation_2 = "Bearish sentiment";
\r
49 double ExtMapBuffer1[];
\r
50 double ExtMapBuffer2[];
\r
51 double ExtMapBuffer3[];
\r
52 double ExtMapBuffer4[];
\r
53 double ExtMapBuffer5[];
\r
58 double index_factor = 1.0;
\r
59 int hTrendLine = -1;
\r
60 int ind_window_handle;
\r
61 double prev_best_step;
\r
62 datetime prev_calc_time;
\r
67 ind_window_handle = WindowFind("jmarket_sentiment");
\r
69 if (hTrendLine == -1 && ind_window_handle > -1) {
\r
71 hTrendLine = ObjectCreate(
\r
75 iTime(NULL, time_frame, 0),
\r
77 iTime(NULL, time_frame, 0) + Period() * 60,
\r
80 ObjectSet(TRENDLINE_NAME, OBJPROP_COLOR, indicator_color2);
\r
81 ObjectSet(TRENDLINE_NAME, OBJPROP_STYLE, STYLE_SOLID);
\r
82 ObjectSet(TRENDLINE_NAME, OBJPROP_WIDTH, indicator_width2);
\r
89 ObjectDelete(TRENDLINE_NAME);
\r
92 //+------------------------------------------------------------------+
\r
93 //| Custom indicator initialization function |
\r
94 //+------------------------------------------------------------------+
\r
97 IndicatorBuffers(5);
\r
100 SetIndexStyle(0,DRAW_HISTOGRAM);
\r
101 SetIndexBuffer(0,ExtMapBuffer1);
\r
102 SetIndexLabel(0,"Movement");
\r
103 SetIndexEmptyValue(0, EMPTY_VALUE);
\r
105 SetIndexStyle(1,DRAW_LINE);
\r
106 SetIndexBuffer(1,ExtMapBuffer2);
\r
107 SetIndexLabel(1,"Movement Sum");
\r
108 SetIndexEmptyValue(1, EMPTY_VALUE);
\r
110 SetIndexStyle(2,DRAW_LINE);
\r
111 SetIndexBuffer(2,ExtMapBuffer3);
\r
112 SetIndexLabel(2,"Smoothed "+MA_Period);
\r
113 SetIndexEmptyValue(2, EMPTY_VALUE);
\r
115 SetIndexStyle(3,DRAW_LINE);
\r
116 SetIndexBuffer(3,ExtMapBuffer4);
\r
117 SetIndexLabel(3,"Trend step");
\r
118 SetIndexEmptyValue(3, EMPTY_VALUE);
\r
120 SetIndexStyle(4,DRAW_LINE);
\r
121 SetIndexBuffer(4,ExtMapBuffer5);
\r
122 SetIndexLabel(4,"Absolute movement");
\r
123 SetIndexEmptyValue(4, EMPTY_VALUE);
\r
125 if (Time_Frame_Mins == 0)
\r
126 time_frame = Period();
\r
128 time_frame = Time_Frame_Mins;
\r
130 if (time_frame < 1) time_frame = 1;
\r
132 index_factor = Period();
\r
133 index_factor = index_factor / time_frame;
\r
135 prev_calc_time = 0;
\r
136 prev_best_step = 0;
\r
138 if (Mode_Function == ABS_MOVE) remove_trendline();
\r
139 else create_trendline();
\r
144 //+------------------------------------------------------------------+
\r
145 //| Custom indicator deinitialization function |
\r
146 //+------------------------------------------------------------------+
\r
150 remove_trendline();
\r
157 double &SignalBuffer[],
\r
158 int SignalBufferLen)
\r
160 if (DEBUG == 1) Print("Debug get_delta_ratio");
\r
162 double delta = 0.0;
\r
163 bool going_up = false;
\r
165 for (int i = 0; i < SignalBufferLen; i++) {
\r
166 if (SignalBuffer[i] == 0. || SignalBuffer[i+1] == 0.) continue;
\r
167 else if (delta != 0. && going_up != (SignalBuffer[i] > SignalBuffer[i+1]) ) break;
\r
169 if (delta == 0.) going_up = (SignalBuffer[i] > SignalBuffer[i+1]);
\r
171 delta = (delta * i + (SignalBuffer[i] - SignalBuffer[i+1])) / (i + 1.);
\r
178 get_time_ratio(bool last_bar)
\r
180 if (DEBUG == 1) Print("Debug get_time_ratio");
\r
183 if (last_bar == false) {
\r
186 double frame_delta = TimeCurrent() - iTime(NULL, time_frame, 0);
\r
187 if (frame_delta > 0) time_ratio = time_frame * 60. / frame_delta;
\r
188 else time_ratio = 0;
\r
191 return(time_ratio);
\r
201 double &prevclose,
\r
204 if (DEBUG == 1) Print("Debug get_weighted_move");
\r
206 if (hi < prevlow || low > prevhi) return (0); // disconnected bars
\r
208 //current weighted high minus previous weighted high
\r
209 double hidiff = ((2. * hi + close) / 3.) - ((2. * prevhi + prevclose) / 3.);
\r
210 double lowdiff = ((2. * low + close) / 3.) - ((2. * prevlow + prevclose) / 3.);
\r
211 double absdiff = hidiff + lowdiff;
\r
213 double volume_ratio;
\r
214 double vol = iVolume(NULL, time_frame, ix);
\r
215 double prevol = iVolume(NULL, time_frame, ix+1);
\r
217 if (vol < INVALID_VOLUME) {
\r
219 } else if (prevol < INVALID_VOLUME) {
\r
222 volume_ratio = vol / prevol;
\r
225 double time_ratio = get_time_ratio( (ix == 0) );
\r
227 return (absdiff * time_ratio * volume_ratio);
\r
239 if (DEBUG == 1) Print("Debug get_absolute_diff");
\r
241 //current weighted high minus previous weighted high
\r
242 double hidiff = MathAbs(hi - prevhi);
\r
243 double lowdiff = MathAbs(low - prevlow);
\r
244 double absdiff = hidiff + lowdiff;
\r
246 double time_ratio = get_time_ratio(ix);
\r
248 return (absdiff * time_ratio);
\r
251 /* largest price difference between two bars */
\r
261 if (DEBUG == 1) Print("Debug get_absolute_move");
\r
263 double abs_move = 0.0;
\r
268 cur_hlc[2] = close;
\r
270 double prev_hlc[3];
\r
271 prev_hlc[0] = prevhi;
\r
272 prev_hlc[1] = prevlow;
\r
273 prev_hlc[2] = prevclose;
\r
275 for (int i = 0; i < 3; i++)
\r
276 for (int j = 0; j < 3; j++)
\r
277 if ( MathAbs(cur_hlc[i] - prev_hlc[j]) > MathAbs(abs_move) )
\r
278 abs_move = cur_hlc[i] - prev_hlc[j];
\r
280 if ( (hi - low) > abs_move ) {
\r
281 if (close > prevclose) abs_move = hi - low;
\r
282 else abs_move = low - hi;
\r
294 if (DEBUG == 1) Print("Debug get_bar_move");
\r
296 for (int ix = now_bar - 1; ix >= ref_bar; ix--) {
\r
297 double now_move = get_absolute_move(
\r
298 iHigh(NULL, time_frame, ix),
\r
299 iLow(NULL, time_frame, ix),
\r
300 iClose(NULL, time_frame, ix),
\r
301 iHigh(NULL, time_frame, now_bar),
\r
302 iLow(NULL, time_frame, now_bar),
\r
303 iClose(NULL, time_frame, now_bar) );
\r
305 if ( MathAbs(now_move) > MathAbs(max_move) ) max_move = now_move;
\r
309 /* largest price difference since start_bar trend */
\r
311 get_max_move(int ref_bar)
\r
313 if (DEBUG == 1) Print("Debug get_max_move");
\r
315 double max_move = 0;
\r
316 bool ref_bull = (ExtMapBuffer1[ref_bar] > 0);
\r
318 for (int now_bar = ref_bar + 1;
\r
319 (ref_bull == (ExtMapBuffer1[now_bar] > 0)) && (now_bar < Bars);
\r
322 get_bar_move(now_bar, ref_bar, max_move);
\r
325 get_bar_move(now_bar, ref_bar, max_move);
\r
330 #define MAXLEN 1024
\r
332 double bears_array[MAXLEN];
\r
333 double bulls_array[MAXLEN];
\r
336 /* sorted arrays expected ! */
\r
339 double &trending[],
\r
341 double &retracements[],
\r
342 int retracements_len
\r
345 if (DEBUG == 1) Print("Debug calc_pips");
\r
347 double best_ratio = 0;
\r
348 double best_step = 0;
\r
350 if ( (TimeCurrent() - prev_calc_time) < (time_frame * Period() * 5) ) return(prev_best_step);
\r
352 double step_base = 0;
\r
354 (step_base == 0) && (ix < Bars);
\r
357 step_base = ExtMapBuffer5[ix];
\r
359 if (step_base == 0) return (prev_best_step);
\r
361 double interpolation_step = step_base * 0.0312; // 1/16
\r
364 for (int z = 0; z < 64; z++) {
\r
366 double cur_step = step_base + (z * interpolation_step);
\r
368 double won_pips = 0;
\r
369 double lost_pips = 0;
\r
371 for (int j = 0; j < retracements_len; j++) {
\r
372 lost_pips += cur_step * MathFloor(retracements[j] / cur_step) / Point;
\r
373 if (cur_step >= retracements[j]) lost_pips += 1. * MathMod(retracements[j], cur_step) / Point;
\r
376 for (j = 0; j < trending_len; j++) {
\r
377 won_pips += cur_step * MathFloor(trending[j] / cur_step) / Point;
\r
378 if (cur_step >= trending[j]) lost_pips += 1. * MathMod(trending[j], cur_step) / Point;
\r
381 if (won_pips == 0) double cur_ratio = 0;
\r
382 else if (lost_pips == 0) cur_ratio = won_pips;
\r
383 else cur_ratio = won_pips / lost_pips;
\r
385 if (cur_ratio > best_ratio) {
\r
386 best_step = cur_step;
\r
387 best_ratio = cur_ratio;
\r
392 if (best_step == 0) return (prev_best_step);
\r
394 prev_best_step = best_step;
\r
395 prev_calc_time = TimeCurrent();
\r
397 if (DEBUG == 1) Print(
\r
398 "Recomended minimal pip step " + best_step + " past " +
\r
399 trending_len + " trending blocks, " + retracements_len + " retracements blocks.");
\r
401 return (best_step);
\r
407 if (b == 0) return (a);
\r
408 else return ( gcd(b, a % b) );
\r
411 //+------------------------------------------------------------------+
\r
412 //| Custom indicator iteration function |
\r
413 //+------------------------------------------------------------------+
\r
416 int counted_bars = IndicatorCounted();
\r
418 int limit = Bars - counted_bars - 1;
\r
419 if (limit < 0) return (0);
\r
421 for (int i = limit; i >= 0; i--) {
\r
423 int ix = MathFloor(index_factor * i);
\r
425 double hi = iHigh(NULL, time_frame, ix);
\r
426 double low = iLow(NULL, time_frame, ix);
\r
427 double close = iClose(NULL, time_frame, ix);
\r
429 double prevhi = iHigh(NULL, time_frame, ix+1);
\r
430 double prevlow = iLow(NULL, time_frame, ix+1);
\r
431 double prevclose = iClose(NULL, time_frame, ix+1);
\r
433 if (prevhi == 0 || prevlow == 0 || prevclose == 0) continue;
\r
434 if (hi == 0 || low == 0 || close == 0) continue;
\r
436 switch (Mode_Function) {
\r
438 ExtMapBuffer1[i] = get_weighted_move(hi, low, close, prevhi, prevlow, prevclose, ix);
\r
439 ExtMapBuffer2[i] = ExtMapBuffer1[i];
\r
443 ExtMapBuffer1[i] = get_absolute_move(hi, low, close, prevhi, prevlow, prevclose);
\r
444 ExtMapBuffer2[i] = get_max_move(i);
\r
445 ExtMapBuffer5[i] = MathAbs(ExtMapBuffer1[i]);
\r
447 // fixup previous bars
\r
448 for (int j = i + 1;
\r
449 ((ExtMapBuffer2[i] > 0) == (ExtMapBuffer2[j] > 0.0)) && (j < Bars);
\r
451 ExtMapBuffer2[j] = ExtMapBuffer2[i];
\r
455 ExtMapBuffer1[i] = get_absolute_diff(hi, low, prevhi, prevlow, i);
\r
456 ExtMapBuffer2[i] = ExtMapBuffer1[i];
\r
462 if (Mode_Function == WEIGHT_MOVE) {
\r
463 double ma_coef = 1;
\r
464 for (i = limit; i >= 0; i--)
\r
465 ExtMapBuffer3[i] = ma_coef * iMAOnArray(ExtMapBuffer1, Bars, MA_Period, 0, MODE_EMA, i);
\r
468 for (i = limit; i >= 0; i--)
\r
469 ExtMapBuffer3[i] = ma_coef * iMAOnArray(ExtMapBuffer5, Bars, MA_Period, 0, MODE_EMA, i);
\r
472 if (Mode_Function == ABS_MOVE) {
\r
474 switch (Sentiment_Expectation) {
\r
476 bool going_bull = (ExtMapBuffer2[0] > 0);
\r
484 going_bull = false;
\r
492 /* get unique movements */
\r
493 for (i = 0; i < Retracement_Look_Back; i++) {
\r
494 if (ExtMapBuffer2[i] == preval) continue;
\r
495 preval = ExtMapBuffer2[i];
\r
498 bulls_array[bulls_len] = preval;
\r
500 } else if (preval < 0) {
\r
501 bears_array[bears_len] = MathAbs(preval);
\r
506 if (going_bull == true)
\r
507 double pip_step = calc_pips(bulls_array, bulls_len, bears_array, bears_len);
\r
509 pip_step = calc_pips(bears_array, bears_len, bulls_array, bulls_len);
\r
511 ExtMapBuffer4[0] = pip_step;
\r
512 SetLevelValue(0, pip_step);
\r
513 SetLevelValue(1, -1.0 * pip_step);
\r
517 double delta_sign = get_delta_ratio(ExtMapBuffer1, Bars);
\r
518 double predicted_price = delta_sign;
\r
519 predicted_price += ExtMapBuffer1[0];
\r
521 if (hTrendLine != -1) {
\r
522 ObjectSet(TRENDLINE_NAME, OBJPROP_TIME1, iTime(NULL, time_frame, 0) );
\r
523 ObjectSet(TRENDLINE_NAME, OBJPROP_TIME2, iTime(NULL, time_frame, 0) + Period() * 60);
\r
524 ObjectSet(TRENDLINE_NAME, OBJPROP_PRICE1, ExtMapBuffer2[0]);
\r
525 ObjectSet(TRENDLINE_NAME, OBJPROP_PRICE2, predicted_price);
\r
533 //+------------------------------------------------------------------+