ms-candle-index

Author: mosaic.system.fx@gmail.com
Miscellaneous
Implements a curve of type %1
0 Views
0 Downloads
0 Favorites
ms-candle-index
ÿþ//+------------------------------------------------------------------+

//|                                                  ms-candle-index |

//|                                       mosaic.system.fx@gmail.com |

//|                               https://www.mql5.com/ru/code/24222 |

//+------------------------------------------------------------------+

/*

=48:0B>@ >?@545;O5B 8=45:A =0?@02;5=8O 10@0 ?> F5=0< 8 -0</@07@K20< 2 =8E.

/2;O5BAO ;>38G5A:8< ?@>4>;65=85< 8=48:0B>@0 ms-Candle https://www.mql5.com/ru/code/23561.



!@02=5=85 F5= Open 8 Close >G5=L G0AB> =5 405B ?@028;L=>9 >F5=:8 =0?@02;5=8O A25G8. 

0 =8E <>6=> >?8@0BLAO, 5A;8 B5;> A25G8 1>;LH5 2/3 5Q @07<5@0, 2 4@C38E A;CG0OE =C65= 

8=>9 ?>4E>4 2 >F5=:5.  8=48:0B>@5 @50;87>20= M<?8@8G5A:89 02B>@A:89 ?>4E>4 : MB>9 7040G5.



 ?@>F5AA5 @0AG5B0 8=48:0B>@0 2K?>;=O5BAO >F5=:0 =5:>B>@KE AB0B8AB8G5A:8E E0@0:B5@8AB8: 

@O40 :>B8@>2>:. E @57C;LB0BK >?8A0=K AB@C:BC@>9 TCandlesStats. KG8A;ONBAO 3@0=8G=K5 

@07<5@K <8=8<0;L=>9 8 <0:A8<0;L=>9 A25G8, 0 B0:65 >@85=B8@>2>G=K9 @07<5@ "A@54=59" 8;8 

"=>@<0;L=>9" A25G8. F5=:0 ?@>2>48BAO :0: ?> 2KA>B5 A25G8, B0: 8 ?> 2KA>B5 5Q B5;0.

 57C;LB0BK @0AG5B0 2K2>4OBAO 2 ;>3 B5@<8=0;0.  0AG5B 2K?>;=O5BAO =0 D8:A8@>20==>< @07<5@5 

>:=0 40==KE 8 ?>2B>@O5BAO ?@8  ?@>E>645=88 =5 <5=55 1/3 >B 53> @07<5@0.

-B> >15A?5G8205B 0:BC0;L=>ABL @57C;LB0B>2 =0 <><5=B @0AG5B0.



F5=:0 @07@K20 2 :>B8@>2:0E (1>;LH>9 3M?) 8A?>;L7C5B @07<5@ <0:A8<0;L=>9 A25G8 87 AB0B8AB8G5A:>9 >F5=:8. 

>;55 25@=K< 1K;> 1K 8A?>;L7>20BL :0=0; 45280F88 F5=K, 8 2KE>4 F5=K Open 70 53> ?@545;K.

4=0:> :>@@5:B=>5 >?@545;5=85 MB>3> :0=0;0 7=0G8B5;L=> 1>;55 A;>6=0O 7040G0.



@8 @0AG5B5 8=48:0B>@0 4;O :064>3> 10@0 @0AAG8BK205BAO AB@C:BC@0 TCandleInfo. 

!<KA; ?>;59 2 =59 ?>=OB5= ?> :><<5=B0@8O<.  0AG5B @50;87>20= 2 2845 <0:@>A>2.



 >:=5 8=48:0B>@0 ?>:07K205BAO 8=D>@<0F8O > A8;5 =0?@02;5=88 10@>2 - 8=45:A5 =0?@02;5=8O.

>;>68B5;L=K9 ?>:070B5;L C:07K205B =0 42865=85 F5=K 225@E, >B@8F0B5;L=K9 - 2=87. 

>:070B5;L 157@07<5@=K9, =>@<0;87>20==K9 >B=>A8B5;L=> AB0B >F5=:8 <0:A8<0;L=>3> @07<5@0 A25G8. 

:;NG5=85 4>?>;=8B5;L=>9 =>@<0;870F88 (?0@0<5B@ CI additional normalization = true) ?>72>;O5B

?@825AB8 7=0G5=8O 8=45:A0 : 8=B5@20;C -1..1. '5< 1>;LH5, 8=45:A B5< O@G5 2K@065=> 42865=85 F5=K. 

=0G5=8O ?> <>4C;N 1>;LH85 1(0.6321 2 @568<5 4>?.=>@<0;870F88) 3>2>@OB > A8;L=>< 8<?C;LA5 2 42865=88

F5=K. 



87C0;L=> :064K9 10@ >?8AK205BAO 42C<O A>AB>O=8O<8 AB>;1F0 38AB>3@0<<K:

1. > 7=0:C 8=45:A0 A25G8 - 2=5H=89 F25B (:@0A=K9/75;5=K9)

2. > >B=>A8B5;L=><C A> 7=0G5=85< =0 ?@54K4CI5< 10@5 87<5=5=8N 8=45:A0 157 CG5B0 7=0:0 B5:CI53> 

10@0 (A25B;>-75;5=K9/A25B;> :@0A=K9).



"0: 4;O A25G8 225@E (8=45:A 2 "+" 7>=5) AB>;15F 1C45B 75;Q=K<. A;8 ?@8 MB>< >B=>A8B5;L=K9 

8=45:A @0AB5B, B> 2=CB@5==89 AB>;15F 1C45B @0A:@0H5= 2 A25B;>-75;5=K9 F25B, 5A;8 ?0405B - A25B;>-:@0A=K9.

;O A25G8 2=87 ?@8=F8? 0=0;>38G5=. A;8 >B=>A8B5;L=>5 87<5=5=85 8=45:A0 @02=> 0, B> 2=CB@5==89 AB>;15F

=5 @8AC5BAO 8 F25B 8=45:A0 AB0=>28BAO ?>;=K< - 75;5=K9 8;8 :@0A=K9.



=0G5=85 8=45:A0 A25G8 <>6=> A3;048BL =51>;LH8< =01>@>< MA.

2B>@ 8A?>;L7>20==>9 181;8>B5:8 - Nikolay Kositsin, >@838=0;L=0O 25@A8O 4>ABC?=0 ?> AAK;:5

https://www.mql5.com/ru/articles/180. ;O 8A?>;L7>20=8O 2 MQL4 2 =55 1K;8 2=5A5=K 2 87<5=5=8O.

7<5=5==CN 181;8>B5:C SmoothAlgorithms45.mqh A;54C5B ?>;>68BL 2 ?0?:C Include B5@<8=0;0.

 01>B05B 2 MT4 8 2 MT5.

5;B0O ;8=8O - MB>  >B 7=0G5=8O CI, A8=OO - MA >B 87<5=5=8O CI (1 ?@>872>4=>9).



 G5< >B;8G85 >B 8=48:0B>@0 ms-Candle? 0:>9 2 =53> 70;>65= A<KA;?

 >?@545;Q==KE A8BC0F8OE, 2 >?@545;5==K9 <><5=B  "C2845BL" GB> =0?@02;5=85 42865=8O C65

=0G0;> 87<5=OBLAO, => =5 B>;L:> D0:B 53> A<5=K. 



;O 8A?>;L7>20=8O 2 MT5 A<5=8B5 @0AH8@5=85 =0 mq5.



7<5=5=8O 2 25@A8OE:



1.00  0;3>@8B< >F5=:8 =0?@02;5=89 22545=0 =>@<0;870F8O, @0AH8@5=0 AB@C:BC@0 TCandleInfo.

1.01 >102;5= 2E>4=>9 ?0@0<5B@ 4;O A:@KB8O 38AB>3@0<<K

1.02 >?>;=8B5;L=0O =>@<0;870F8O 2K?>;=O5BAO ?> :204@0BC :>MDD8F85=B>2 =0?@02;5=8O, GB> ?>72>;O5B 

     1>;55 ?;>B=> 70?>;=OBL 8=B5@20; -1..1 =5 B5@OO ?@>?>@F88 CI : AB0B >F5=:5 >:=0 :>B8@>2>:.

     >102;5=K C@>2=8. E >F5=:C ?@54;030N >1AC48BL.

1.03 B:>@@5:B8@>20=> >?8A0=85. 7<5=5=K C@>2=8, 2 :064>< @568<5 (=>@<0;870F8O 2:;/2K:;) A2>8. 

     >38G5A:8 A>>B25BAB2CNB 4@C3 4@C3C. >102;5=0 ?@>AB0O 8=D> ?0=5;L.

*/



#property copyright "mosaic.system.fx@gmail.com"

#property link      "https://www.mql5.com/ru/code/24222"

#property version   "1.03"

#property description "Candle index"

#property description "https://www.mql5.com/ru/code/24222"

#property strict

#property indicator_separate_window

#property indicator_buffers 7

#property indicator_plots   7



//--- plot CI

#property indicator_label1  "cI"

#property indicator_type1   DRAW_LINE

#property indicator_color1  clrGray

#property indicator_style1  STYLE_SOLID

#property indicator_width1  1

//--- plot dnDir

#property indicator_label2  "dn"

#property indicator_type2   DRAW_HISTOGRAM

#property indicator_color2  clrRed

#property indicator_style2  STYLE_SOLID

#property indicator_width2  6

//--- plot upDir

#property indicator_label3  "up"

#property indicator_type3   DRAW_HISTOGRAM

#property indicator_color3  clrGreen

#property indicator_style3  STYLE_SOLID

#property indicator_width3  6

//--- plot dnDir may be

#property indicator_label4  "dnm"

#property indicator_type4   DRAW_HISTOGRAM

#property indicator_color4  clrCoral

#property indicator_style4  STYLE_SOLID

#property indicator_width4  2

//--- plot upDir may be

#property indicator_label5  "upm"

#property indicator_type5   DRAW_HISTOGRAM

#property indicator_color5  clrYellowGreen

#property indicator_style5  STYLE_SOLID

#property indicator_width5  2

//--- plot MACI

#property indicator_label6  "MAcI"

#property indicator_type6   DRAW_LINE

#property indicator_color6  clrYellow

#property indicator_style6  STYLE_SOLID

#property indicator_width6  2

//--- plot MA diff CI

#property indicator_label7  "MAdcI"

#property indicator_type7   DRAW_LINE

#property indicator_color7  clrBlue

#property indicator_style7  STYLE_SOLID

#property indicator_width7  2





#property indicator_levelcolor clrGray

#property indicator_levelstyle STYLE_DOT

//---

#include <SmoothAlgorithms45.mqh>



//---Input parameters

input bool inpAddExpNorm=true;             // --CI additional normalization

input Smooth_Method inpMAMethod=MODE_JJMA; // --MA Method

input int inpAvgPeriod=9;                  // MA Period

input int inpMAPhase=15;                   // MA Phase

input bool inpShowHistog=true;             // --Show histogramm?

input bool inpShowPanel=true;              // --Show info panel?



//--- indicator buffers

double         CIB[];

double         DNB[];

double         DNMB[];

double         UPB[];

double         UPMB[];

double         MACIB[];

double         MADCIB[];



//--- MA class

CXMA XMA,XMAD;



//---Koeff of "normal" candle

#define Candle_Normal_K 0.6

//---Size of the data window to calculate some statistics 

#define Window_Len 1440

const int Window_Len_1_3=Window_Len/3;

#define Rates_Total_Min 48 // Minimal count of rates to calc indicator

//---Levels const

#define levExpNr1 0.6321 // =1. without additional normalization

//---Graph object mask

string obj_mask;



//+------------------------------------------------------------------+

//| Calculate some statistics of candles                             |

//+------------------------------------------------------------------+

struct TCandlesStats {

  int       window_len; // calculated on window len

  datetime  window_start; // time of start window

  double    height_low; // size of small candle

  double    height_mid; // size of middle ("normal")candle

  double    height_big; // size of big candle

  double    body_low;   // size of small body candle

  double    body_mid;   // size of middle body candle

  double    body_big;   // size of big body candle

};

TCandlesStats CS;



struct TCandleInfo {

  char      dir;        // candle up>0 or dn<0. Maybe 0!

  double    dir_index;  // direction index

  bool      zero;       // Candle has zero size Hi=Lo 

  bool      normal;     // "normal" candle, body size > 0.6 body heigth

  char      body_dir;   // body dir: 1 - up, -1 - down, 0 - body zero

  double    body;       // body size

  double    height;     // size of candle



  double    shadow_up;  // up shadow of candle

  double    shadow_dn;  // dn shadow of candle

  

  double    k_up,k_dn;  // koeff of up/dn direction of candle

  double    k_body_h;   // koeff of body size to heigth of candle

  double    k_shadow_h; // koeff of both shadow to heigth of candle

  

  char      gap_dir;    // gap direction: 1 - up, -1 - down, 0 - gap zero

  char      gap_move;   // price direction after gap: 1 - up, -1 - down

  bool      gap_big;    // gap is big

  double    gap_size;   // gap size

  

  double    op,hi,lo,cl,cl1; // prices, cl1 - prev close

};

TCandleInfo CI;



//+------------------------------------------------------------------+

//| Custom indicator initialization function                         |

//+------------------------------------------------------------------+

int OnInit()

  {

//--- indicator buffers mapping

   SetIndexBuffer(0,CIB);

   SetIndexBuffer(1,DNB);

   SetIndexBuffer(2,UPB);

   SetIndexBuffer(3,DNMB);

   SetIndexBuffer(4,UPMB);

   SetIndexBuffer(5,MACIB);

   SetIndexBuffer(6,MADCIB);



#ifdef __MQL5__

   if(inpShowHistog) {

     PlotIndexSetInteger(1,PLOT_DRAW_TYPE,DRAW_HISTOGRAM);

     PlotIndexSetInteger(2,PLOT_DRAW_TYPE,DRAW_HISTOGRAM);

     PlotIndexSetInteger(3,PLOT_DRAW_TYPE,DRAW_HISTOGRAM);

     PlotIndexSetInteger(4,PLOT_DRAW_TYPE,DRAW_HISTOGRAM);

   } else {

     PlotIndexSetInteger(1,PLOT_DRAW_TYPE,DRAW_NONE);

     PlotIndexSetInteger(2,PLOT_DRAW_TYPE,DRAW_NONE);

     PlotIndexSetInteger(3,PLOT_DRAW_TYPE,DRAW_NONE);

     PlotIndexSetInteger(4,PLOT_DRAW_TYPE,DRAW_NONE);

   }

#else

   if(inpShowHistog) {

     SetIndexStyle(1,DRAW_HISTOGRAM);

     SetIndexStyle(2,DRAW_HISTOGRAM);

     SetIndexStyle(3,DRAW_HISTOGRAM);

     SetIndexStyle(4,DRAW_HISTOGRAM);

   } else {

     SetIndexStyle(1,DRAW_NONE);

     SetIndexStyle(2,DRAW_NONE);

     SetIndexStyle(3,DRAW_NONE);

     SetIndexStyle(4,DRAW_NONE);

   }

#endif    

 

   ArraySetAsSeries(CIB,true);

   ArraySetAsSeries(DNB,true);

   ArraySetAsSeries(DNMB,true);

   ArraySetAsSeries(UPB,true);

   ArraySetAsSeries(UPMB,true);

   ArraySetAsSeries(MACIB,true);

   ArraySetAsSeries(MADCIB,true);

   //---

   XMA.XMALengthCheck("inpAvgPeriod", inpAvgPeriod);

   XMA.XMAPhaseCheck("inpPhase", inpMAPhase, inpMAMethod);

   XMAD.XMALengthCheck("inpAvgPeriod", inpAvgPeriod);

   XMAD.XMAPhaseCheck("inpPhase", inpMAPhase, inpMAMethod);

   ZeroMemory(CS);

   ZeroMemory(CI);

   //---

   if(inpAddExpNorm) {

     const double Levels[]={-0.9270,-0.6321,-0.2212,-0.1358,0,0.1358,0.2212,0.6321,0.9270};

     SetIndicatorLevels(Levels);

   } else {

     const double Levels[]={-1.618,-1,-0.618,-0.5,-0.382,0,0.382,0.5,0.618,1,1.618};

     SetIndicatorLevels(Levels);

   }

   //---

   obj_mask=EnumToString(((ENUM_TIMEFRAMES)_Period));

   StringReplace(obj_mask,"PERIOD_","");

   obj_mask="CI_"+_Symbol+"_"+obj_mask;

//---

   return(INIT_SUCCEEDED);

}

//---

void OnDeinit(const int reason)

{

  ObjectsDeleteAll(0,obj_mask);

}

//---

void SetIndicatorLevels(const double &aLev[])

{

  int count_lev=ArraySize(aLev);

  if(count_lev<=0) return; // empty aLev

  IndicatorSetInteger(INDICATOR_LEVELS,count_lev);

  for(int i=0;i<count_lev;i++) {

    IndicatorSetDouble(INDICATOR_LEVELVALUE,i,aLev[i]);

  }

}

//+------------------------------------------------------------------+

//| Macro for calc direction -1,0,1                                  |

//+------------------------------------------------------------------+

#define MathDirDI(v,delta) (((v)>=delta)?1:(((v)<=-delta)?-1:0))



//+------------------------------------------------------------------+

//| Macro for calc Candle info                                       |

//+------------------------------------------------------------------+

#define defCandleFill(open,high,low,close,i, info) \

{ \

  ZeroMemory(info); \

  info.op=open[i]; \

  info.hi=high[i]; \

  info.lo=low[i]; \

  info.cl=close[i]; \

  info.cl1=close[i+1]; \

}



#define defCandleInfoNr(height_big,height_low, addnorm, info) \

{ \

  info.body=info.cl-info.op; \

  info.body_dir=MathDirDI(info.body,FLT_EPSILON); \

  info.body=info.body*info.body_dir; \

  \

  info.height=info.hi-info.lo; \

  info.zero=(info.height<=FLT_EPSILON); \

  info.normal=false; \

  \

  info.gap_size=info.op-info.cl1; \

  info.gap_dir=info.gap_move=MathDirDI(info.gap_size,FLT_EPSILON); \

  info.gap_size=info.gap_size*info.gap_dir; \

  \

  info.gap_big=info.gap_size>height_big; \

  \

  info.k_up=info.k_dn=0.; \

  if(info.gap_dir!=0) { \

    if(info.cl<info.cl1 && info.gap_dir>0) info.gap_move=-1; \

    else if(info.cl>info.cl1 && info.gap_dir<0) info.gap_move=1; \

    if(!info.gap_big) { \

      \ // If the gap is small, remember it for further calculation of the direction

      info.k_up=(info.gap_dir>0)?info.gap_size:0.; \

      info.k_dn=(info.gap_dir<0)?info.gap_size:0.; \

    } \

  } \

  \

  if(info.zero) { \

    info.k_body_h=info.k_shadow_h=info.shadow_up=info.shadow_dn=0; \

  } else { \

    info.k_body_h=info.body/info.height; \

    info.k_shadow_h=1.-info.k_body_h; \

    info.normal=(info.k_body_h>=Candle_Normal_K) && (info.height>height_low); \

    if(info.body_dir>0) { \

      \ // Candle dir up

      info.shadow_up=info.hi-info.cl; \

      info.shadow_dn=info.op-info.lo; \

      info.k_up=(info.k_up+info.shadow_dn+info.body)/height_big; \

      info.k_dn=(info.k_dn+info.shadow_up)/height_big; \ 

    } else if(info.body_dir<0) { \

      \ // Candle dir down

      info.shadow_up=info.hi-info.op; \

      info.shadow_dn=info.cl-info.lo; \

      info.k_up=(info.k_up+info.shadow_dn)/height_big; \ 

      info.k_dn=(info.k_dn+info.shadow_up+info.body)/height_big; \

    } else { \

      \ // Candle body zero

      info.shadow_up=info.hi-info.cl; \

      info.shadow_dn=info.op-info.lo; \

      info.k_up=(info.k_up+info.shadow_dn)/height_big; \

      info.k_dn=(info.k_dn+info.shadow_up)/height_big; \

    } \

  } \

  if(addnorm) { \

    info.k_up=1.-MathExp(-(info.k_up*info.k_up)); \

    info.k_dn=1.-MathExp(-(info.k_dn*info.k_dn)); \

  } \

  info.dir_index=info.k_up-info.k_dn; \

  info.dir=MathDirDI(info.dir_index,FLT_EPSILON); \

  if(info.dir==0) { \

    info.dir=info.body_dir; \

    info.dir_index=info.dir*((info.dir>0)?info.k_up:(info.dir<0)?info.k_dn:0); \

  } \

  if(info.dir==0) { \

    info.dir=info.gap_dir; \

    info.dir_index=info.dir*((info.dir>0)?info.k_up:(info.dir<0)?info.k_dn:0); \

  } \

}



//+------------------------------------------------------------------+

//|  Macro for calc Percentil on sorted array                        |

//+------------------------------------------------------------------+

static double _percPos_; // temp var

#define MathPercentil(arr,period,perc) \

(\

  ((period<2 || perc<=0.))\

    ?\

    (arr[0])\

    :\

    (\

      (perc>=1.0)\

      ?\

      (arr[period-1])\

      :\

      (\

        arr[(int)(_percPos_=(perc*(period-1)))]*(1.-(_percPos_-int(_percPos_)))\

        +arr[(int)(_percPos_)+1]*(_percPos_-int(_percPos_))\

      )\

    )\

)



bool GetSomeStats( 

               int shift,

               int window_len,

               const datetime &time[],

               const double &open[],

               const double &high[],

               const double &low[],

               const double &close[],

               const long &tick_volume[],

               const long &volume[],

               const int &spread[],

               

               TCandlesStats &cs

               )

{

   //---input data arrays must be set flag "series" to true

   static double dACH[],dACB[]; // only 1 mem alloc for arrays

   static int window_len_max;

   if(shift<0) shift=0;

   window_len_max=ArraySize(close);

   //---shift is right border of Arr, calc left_border on window_len input

   if(shift+window_len>window_len_max) window_len=window_len_max-shift;

   ZeroMemory(cs);   // cs=0

   if(window_len<Rates_Total_Min) return(false);

   //---start calc

   cs.window_start=time[shift];

   //---Memory alloc to arrays

   if(ArrayResize(dACH,window_len,window_len)!=window_len) return(false);

   if(ArrayResize(dACB,window_len,window_len)!=window_len) return(false);

   //---fill arrays

   cs.window_len=window_len;

   for(int j=cs.window_len-1,i=shift+cs.window_len-1;i>=shift;i--,j--) {

     dACH[j]=high[i]-low[i];

     dACB[j]=MathAbs(open[i]-close[i]);

   }

   ArraySort(dACH);

   ArraySort(dACB);

   // body

   cs.body_low=NormalizeDouble(MathPercentil(dACB,cs.window_len,0.1),_Digits);

   window_len=(int)_percPos_; // use window_len to calc index of median value beetwen low and big

   cs.body_big=NormalizeDouble(MathPercentil(dACB,cs.window_len,0.9),_Digits);

   window_len+=int((_percPos_-window_len)*Candle_Normal_K); 

   cs.body_mid=NormalizeDouble(dACB[window_len],_Digits);

   // height

   cs.height_low=NormalizeDouble(MathPercentil(dACH,cs.window_len,0.1),_Digits);

   window_len=(int)_percPos_; // use window_len to calc index of median value beetwen low and big

   cs.height_big=NormalizeDouble(MathPercentil(dACH,cs.window_len,0.9),_Digits);

   window_len+=int((_percPos_-window_len)*Candle_Normal_K);

   cs.height_mid=NormalizeDouble(dACH[window_len],_Digits);

   return(true);

}



//+------------------------------------------------------------------+

//| Custom indicator iteration function                              |

//+------------------------------------------------------------------+

int OnCalculate(const int rates_total,

                const int prev_calculated,

                const datetime &time[],

                const double &open[],

                const double &high[],

                const double &low[],

                const double &close[],

                const long &tick_volume[],

                const long &volume[],

                const int &spread[])

  {

//---

   if(rates_total<Rates_Total_Min) {

     Print("Not enough rates for calc.");

     return(0);

   }

//--- start calculation

   ArraySetAsSeries(time,true);

   ArraySetAsSeries(open,true);

   ArraySetAsSeries(high,true);

   ArraySetAsSeries(low,true);

   ArraySetAsSeries(close,true);

   //---

   static int to_calc; // shift start to calc

   static int end_corr_data; // max shift on corrected calculated values of CI in array CIB

   static int end_corr_data_ma; // max shift on corrected calculated MA values in array MACIB,MADCIB



   //--- Macros for compact code calc

   #define defNeedRecalcStat(shift,cs) (((time[shift]-cs.window_start)/PeriodSeconds())>Window_Len_1_3)

   #define defCSfromCeiling(cs) { \

     double fake_delta_price=NormalizeDouble(2.*_Point*MathPow(MathLog(PeriodSeconds(_Period)/10.),2.),_Digits); \

     cs.height_big=fake_delta_price*8; cs.height_mid=fake_delta_price*5; cs.height_low=fake_delta_price; \

     }

   #define defCalcStat(shift,cs) if(!GetSomeStats(shift,Window_Len,time,open,high,low,close,tick_volume,volume,spread, cs)) defCSfromCeiling(CS);

  

   //--- set start pos for calc

   if(prev_calculated==0) {

     // full recalc

     end_corr_data=rates_total-2;

     end_corr_data_ma=end_corr_data-XMA.GetStartBars(inpMAMethod,inpAvgPeriod,inpMAPhase);

     to_calc=end_corr_data;

     defCalcStat(rates_total-Window_Len-1,CS);

     MACIB[to_calc+1]=CIB[to_calc+1]=0;

   } else {

     // next calc

     to_calc=rates_total-prev_calculated;

     // check for need calc stats

     if(defNeedRecalcStat(0,CS)) defCalcStat(0,CS);

   }

   //--- additional vars

   static int diff_pd;

   static double pcib;

   static datetime time_open=0;

   static bool IsNewBar=false;

   //--- check new bar

   IsNewBar=(time_open!=time[0]);

   if(IsNewBar) time_open=time[0];



//--- main cycle start

   pcib=(to_calc<end_corr_data)?CIB[to_calc+1]:0; // restore prev dir index

   for(int i=to_calc;i>=0 && !IsStopped();i--) {

     // clear buffers

     UPB[i]=UPMB[i]=DNB[i]=DNMB[i]=MACIB[i]=MADCIB[i]=EMPTY_VALUE;

     // calculate stats on full recalc and after 1/3 of the time since the last calculation

     if(prev_calculated==0 && defNeedRecalcStat(i,CS)) defCalcStat(i,CS);

     // Fill prices to struct CI

     defCandleFill(open,high,low,close,i, CI);

     // Calc candle info and normalized dir (index)

     defCandleInfoNr(CS.height_big,CS.height_low, inpAddExpNorm, CI);

     CIB[i]=CI.dir_index;

     // calc difference of curr and prev dir index

     diff_pd=MathDirDI(CI.dir_index-pcib,FLT_EPSILON);

     // fill it to chance buffers

     if(diff_pd>0) UPMB[i]=CI.dir_index;

     else if(diff_pd<0) DNMB[i]=CI.dir_index;

     // fill dir index to buffers

     if(CI.dir>0) UPB[i]=CI.dir_index;

     else if(CI.dir<0) DNB[i]=CI.dir_index;

     // calc MA on dir index

     MACIB[i]=XMA.XMASeries(end_corr_data,prev_calculated,rates_total,

                                    inpMAMethod,inpMAPhase,inpAvgPeriod,CI.dir_index,i,true);

     MADCIB[i]=XMAD.XMASeries(end_corr_data,prev_calculated,rates_total,

                                    inpMAMethod,inpMAPhase,inpAvgPeriod,CI.dir_index-pcib,i,true);

     // save prev dir index

     pcib=CI.dir_index;

   }

//--- main cycle end   

   //--- Log result on last calc statistic on New Bar

   if(prev_calculated==0 || (IsNewBar && time_open==CS.window_start)) {

     Print("Last Statistic calculated on ",CS.window_start, " with window len=",CS.window_len);

     Print("Candles Height's Low=",CS.height_low," Mid=",CS.height_mid," Big=",CS.height_big);

     Print("Candles Body's Low=",CS.body_low," Mid=",CS.body_mid," Big=",CS.body_big);

   }

   if(inpShowPanel) {

     // time of last tick

     static MqlTick tick;

     bool tick_last_good=SymbolInfoTick(_Symbol,tick) && tick.time>0;

     EasyPanel(CS,CI,IsNewBar,time_open,tick.time);

   }

//--- return value of prev_calculated for next call

   return(rates_total);

  }



//+------------------------------------------------------------------+

//|  Easy info panel                                                 |

//+------------------------------------------------------------------+

#define FontDefault "Tahoma"

string EasyPanel(const TCandlesStats &cs, const TCandleInfo &ci, const bool newbar=false, 

                 const datetime time0=0, const datetime time_last_tick=0)

{

  //---

  static bool IsCreated=false; // flag for creating panel

  const int p_x=137;

  const int p_y=2;

  const int p_w=133;

  const int p_h=113;

  static int p_w1=119;

  //---names for dynamic objects

  static string nm_panel="";

  static string nm_dhb="";

  static string nm_dhm="";

  static string nm_dhl="";

  static string nm_dbb="";

  static string nm_dbm="";

  static string nm_dbl="";

  static string nm_dhc="";

  static string nm_dbc="";

  static string nm_s4="";

  static string nm_s41="";

  static string nm_bar_tm="";

  //---

  static int h_prev=0,b_prev=0; // prev call heigth, body of candle

  static char dir_prev=0;       // dir on prev call

  //---

  const color cb1=clrLightGray;

  const color cb2=clrSnow;

  //---

  const color ct1=clrBlue;

  const color ct2=clrBrown;

  const color cs1=clrRed;

  const color cs2=clrGreen;

  const color cs3=clrMediumOrchid;

  //---

  ResetLastError();

  //---

  long chart_id=ChartID(); // Chart Id

  int win_id=ChartWindowFind(); // Win Id

  //---Some calc dynamic data for draw panel on current candle

  color ch=(ci.height<cs.height_mid)?cs3:(ci.height<cs.height_big)?cs2:cs1;

  color cb=(ci.body<cs.body_mid)?cs3:(ci.body<cs.body_big)?cs2:cs1;

  // Color on candle direction

  color cdir=(ci.dir>0)?indicator_color3:(ci.dir<0)?indicator_color2:cs3;

  int h=int(ci.height/_Point); // current heigth

  int b=int(ci.body/_Point); // current body of candle

  

  //---Draw panel

  if(IsCreated) {

    //---update panel

    if(newbar) {

      // Update stats data on each newbar

      ObjectSetString(chart_id,nm_dhb,OBJPROP_TEXT,string(int(cs.height_big/_Point)));

      ObjectSetString(chart_id,nm_dhm,OBJPROP_TEXT,string(int(cs.height_mid/_Point)));

      ObjectSetString(chart_id,nm_dhl,OBJPROP_TEXT,string(int(cs.height_low/_Point)));

      ObjectSetString(chart_id,nm_dbb,OBJPROP_TEXT,string(int(cs.body_big/_Point)));

      ObjectSetString(chart_id,nm_dbm,OBJPROP_TEXT,string(int(cs.body_mid/_Point)));

      ObjectSetString(chart_id,nm_dbl,OBJPROP_TEXT,string(int(cs.body_low/_Point)));

    }

    //---update data for curr bar

    if(h!=h_prev) {

      h_prev=h;

      ObjectSetString(chart_id,nm_dhc,OBJPROP_TEXT,string(h_prev)); 

      ObjectSetInteger(chart_id,nm_dhc,OBJPROP_COLOR,ch); 

    }

    if(b!=b_prev) {

      b_prev=b;

      ObjectSetString(chart_id,nm_dbc,OBJPROP_TEXT,string(b_prev)); 

      ObjectSetInteger(chart_id,nm_dbc,OBJPROP_COLOR,cb); 

    }

    if(dir_prev!=ci.dir) {

      dir_prev=ci.dir;

      ObjectSetInteger(chart_id,nm_s4,OBJPROP_COLOR,cdir); 

      ObjectSetInteger(chart_id,nm_s41,OBJPROP_COLOR,cdir); 

    }

    // time bar

    ObjectSetInteger(chart_id,nm_bar_tm,OBJPROP_BGCOLOR,cdir);

    char position_in_bar=(char)(100.*((time_last_tick-time0))/PeriodSeconds());  

    if(position_in_bar>=0) {

      ObjectSetInteger(chart_id,nm_bar_tm,OBJPROP_XSIZE,p_w1*position_in_bar/100);

    }

  } else {

    //---create panel

    nm_panel=obj_mask+"pi";

    RectLabelCreate(chart_id,nm_panel,win_id,

                  p_x,p_y,p_w,p_h,cb1,1,CORNER_RIGHT_UPPER);

    //---Title and string names, static objects

    LabelCreate(chart_id,nm_panel+"t_t0",win_id,

                  p_x-14,p_y+5,CORNER_RIGHT_UPPER,"Candles info, pips:",ct1,FontDefault,10);

    LabelCreate(chart_id,nm_panel+"t_t1",win_id,

                  p_x-40,p_y+20,CORNER_RIGHT_UPPER,"heigth's",ct2,FontDefault,8);

    LabelCreate(chart_id,nm_panel+"t_t2",win_id,

                  p_x-85,p_y+20,CORNER_RIGHT_UPPER,"body's",ct2,FontDefault,8);

                  

    LabelCreate(chart_id,nm_panel+"t_s1",win_id,

                  p_x-10,p_y+35,CORNER_RIGHT_UPPER,"Big",cs1);

    LabelCreate(chart_id,nm_panel+"t_s2",win_id,

                  p_x-10,p_y+50,CORNER_RIGHT_UPPER,"Mid",cs2);

    LabelCreate(chart_id,nm_panel+"t_s3",win_id,

                  p_x-10,p_y+65,CORNER_RIGHT_UPPER,"Low",cs3);

    

    //---Objects for update

    nm_bar_tm=nm_panel+"r_bt";

    nm_dhb=nm_panel+"t_dhb";

    nm_dhm=nm_panel+"t_dhm";

    nm_dhl=nm_panel+"t_dhl";

    nm_dbb=nm_panel+"t_dbb";

    nm_dbm=nm_panel+"t_dbm";

    nm_dbl=nm_panel+"t_dbl";

    nm_s4=nm_panel+"t_s4";

    nm_s41=nm_panel+"t_s41";

    //---heigth's

    LabelCreate(chart_id,nm_dhb,win_id,

                  p_x-40,p_y+35,CORNER_RIGHT_UPPER,string(int(cs.height_big/_Point)),cs1);

    LabelCreate(chart_id,nm_dhm,win_id,

                  p_x-40,p_y+50,CORNER_RIGHT_UPPER,string(int(cs.height_mid/_Point)),cs2);

    LabelCreate(chart_id,nm_dhl,win_id,

                  p_x-40,p_y+65,CORNER_RIGHT_UPPER,string(int(cs.height_low/_Point)),cs3);

    //---body's

    LabelCreate(chart_id,nm_dbb,win_id,

                  p_x-85,p_y+35,CORNER_RIGHT_UPPER,string(int(cs.body_big/_Point)),cs1);

    LabelCreate(chart_id,nm_dbm,win_id,

                  p_x-85,p_y+50,CORNER_RIGHT_UPPER,string(int(cs.body_mid/_Point)),cs2);

    LabelCreate(chart_id,nm_dbl,win_id,

                  p_x-85,p_y+65,CORNER_RIGHT_UPPER,string(int(cs.body_low/_Point)),cs3);

    //---Current bar info background

    RectLabelCreate(chart_id,nm_panel+"cb_r1",win_id,

                  p_x-5,p_y+82,p_w-10,25,cb2,1,CORNER_RIGHT_UPPER);

    //---Curr bar time 

    p_w1=p_w-14;

    RectLabelCreate(chart_id,nm_bar_tm,win_id,

                  p_x-7,p_y+82+20,p_w1,3,cdir,1,CORNER_RIGHT_UPPER);

                  

    LabelCreate(chart_id,nm_s4,win_id,

                  p_x-10,p_y+85,CORNER_RIGHT_UPPER,"CUR",cdir);

    LabelCreate(chart_id,nm_s41,win_id,

                  p_x-9,p_y+85,CORNER_RIGHT_UPPER,"CUR",cdir); // as bold

                             

    nm_dhc=nm_panel+"t_dhc";

    nm_dbc=nm_panel+"t_dbc";

    LabelCreate(chart_id,nm_dhc,win_id,

                  p_x-40,p_y+85,CORNER_RIGHT_UPPER,string(int(ci.height/_Point)),ch);

    LabelCreate(chart_id,nm_dbc,win_id,

                  p_x-85,p_y+85,CORNER_RIGHT_UPPER,string(int(ci.body/_Point)),cb);

    //---Ready

    IsCreated=true;

  }

  return(nm_panel);

}



//+------------------------------------------------------------------+ 

//| !>7405B B5:AB>2CN <5B:C                                          | 

//+------------------------------------------------------------------+ 

bool LabelCreate(

                 const long              chart_ID=0,               // ID 3@0D8:0

                 const string            name="label",             // 8<O <5B:8 

                 const int               sub_window=0,             // =><5@ ?>4>:=0

                 const int               x=0,                      // :>>@48=0B0 ?> >A8 X 

                 const int               y=0,                      // :>>@48=0B0 ?> >A8 Y 

                 const ENUM_BASE_CORNER  corner=CORNER_LEFT_UPPER, // C3>; 3@0D8:0 4;O ?@82O7:8 

                 const string            text="name",             // B5:AB 

                 const color             clr=clrRed,               // F25B 

                 const string            font=FontDefault,         // H@8DB 

                 const int               font_size=10,             // @07<5@ H@8DB0 

                 const double            angle=0.0,                // =0:;>= B5:AB0 

                 const ENUM_ANCHOR_POINT anchor=ANCHOR_LEFT_UPPER, // A?>A>1 ?@82O7:8 

                 const bool              back=false,               // =0 704=5< ?;0=5 

                 const bool              selection=false,          // 2K45;8BL 4;O ?5@5<5I5=89 

                 const bool              selectable=false,         // 2K45;O5<K9 4;O ?5@5<5I5=89

                 const bool              hidden=true,              // A:@KB 2 A?8A:5 >1J5:B>2 

                 const long              z_order=0)                // ?@8>@8B5B =0 =060B85 <KHLN 

{ 

//--- A1@>A8< 7=0G5=85 >H81:8 

  ResetLastError(); 

  //--- A>74048< B5:AB>2CN <5B:C 

  if(!ObjectCreate(chart_ID,name,OBJ_LABEL,sub_window,0,0)) {

    Print(__FUNCTION__,": text label not created! Err code= ",GetLastError()); 

    return(false); 

  }

  //--- CAB0=>28< :>>@48=0BK <5B:8 

  ObjectSetInteger(chart_ID,name,OBJPROP_XDISTANCE,x); 

  ObjectSetInteger(chart_ID,name,OBJPROP_YDISTANCE,y); 

  //--- CAB0=>28< C3>; 3@0D8:0, >B=>A8B5;L=> :>B>@>3> 1C4CB >?@545;OBLAO :>>@48=0BK B>G:8 

  ObjectSetInteger(chart_ID,name,OBJPROP_CORNER,corner); 

  //--- CAB0=>28< B5:AB 

  ObjectSetString(chart_ID,name,OBJPROP_TEXT,text); 

  //--- CAB0=>28< H@8DB B5:AB0 

  ObjectSetString(chart_ID,name,OBJPROP_FONT,font); 

  //--- CAB0=>28< @07<5@ H@8DB0 

  ObjectSetInteger(chart_ID,name,OBJPROP_FONTSIZE,font_size); 

  //--- CAB0=>28< C3>; =0:;>=0 B5:AB0 

  ObjectSetDouble(chart_ID,name,OBJPROP_ANGLE,angle); 

  //--- CAB0=>28< A?>A>1 ?@82O7:8 

  ObjectSetInteger(chart_ID,name,OBJPROP_ANCHOR,anchor); 

  //--- CAB0=>28< F25B 

  ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr); 

  //--- >B>1@078< =0 ?5@54=5< (false) 8;8 704=5< (true) ?;0=5 

  ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back); 

  //--- 2:;NG8< (true) 8;8 >B:;NG8< (false) @568< ?5@5<5I5=8O <5B:8 <KHLN 

  ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selectable); 

  ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection); 

  //--- A:@>5< (true) 8;8 >B>1@078< (false) 8<O 3@0D8G5A:>3> >1J5:B0 2 A?8A:5 >1J5:B>2 

  ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden); 

  //--- CAB0=>28< ?@8>@8B5B =0 ?>;CG5=85 A>1KB8O =060B8O <KH8 =0 3@0D8:5 

  ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order); 

  //--- CA?5H=>5 2K?>;=5=85 

  return(true); 

} 



//+------------------------------------------------------------------+ 

//| !>7405B ?@O<>C3>;L=CN <5B:C                                      | 

//+------------------------------------------------------------------+ 

bool RectLabelCreate(

                     const long             chart_ID=0,               // ID 3@0D8:0 

                     const string           name="rect",              // 8<O <5B:8 

                     const int              sub_window=0,             // =><5@ ?>4>:=0 

                     const int              x=0,                      // :>>@48=0B0 ?> >A8 X 

                     const int              y=0,                      // :>>@48=0B0 ?> >A8 Y 

                     const int              width=50,                 // H8@8=0 

                     const int              height=18,                // 2KA>B0 

                     const color            back_clr=C'236,233,216',  // F25B D>=0 

                     const ENUM_BORDER_TYPE border=BORDER_SUNKEN,     // B8? 3@0=8FK 

                     const ENUM_BASE_CORNER corner=CORNER_LEFT_UPPER, // C3>; 3@0D8:0 4;O ?@82O7:8 

                     const color            clr=clrRed,               // F25B ?;>A:>9 3@0=8FK (Flat) 

                     const ENUM_LINE_STYLE  style=STYLE_SOLID,        // AB8;L ?;>A:>9 3@0=8FK 

                     const int              line_width=1,             // B>;I8=0 ?;>A:>9 3@0=8FK 

                     const bool             back=false,               // =0 704=5< ?;0=5 

                     const bool             selection=false,          // 2K45;8BL 4;O ?5@5<5I5=89 

                     const bool             selectable=false,         // 2K45;O5<K9 4;O ?5@5<5I5=89

                     const bool             hidden=true,              // A:@KB 2 A?8A:5 >1J5:B>2 

                     const long             z_order=0)                // ?@8>@8B5B =0 =060B85 <KHLN 

{ 

  //--- A1@>A8< 7=0G5=85 >H81:8 

  ResetLastError(); 

  //--- A>74048< ?@O<>C3>;L=CN <5B:C 

  if(!ObjectCreate(chart_ID,name,OBJ_RECTANGLE_LABEL,sub_window,0,0)) { 

    Print(__FUNCSIG__, ": Rect label not created! Err code=",GetLastError()); 

    return(false); 

  } 

  //--- CAB0=>28< :>>@48=0BK <5B:8 

  ObjectSetInteger(chart_ID,name,OBJPROP_XDISTANCE,x); 

  ObjectSetInteger(chart_ID,name,OBJPROP_YDISTANCE,y); 

  //--- CAB0=>28< @07<5@K <5B:8 

  ObjectSetInteger(chart_ID,name,OBJPROP_XSIZE,width); 

  ObjectSetInteger(chart_ID,name,OBJPROP_YSIZE,height); 

  //--- CAB0=>28< F25B D>=0 

  ObjectSetInteger(chart_ID,name,OBJPROP_BGCOLOR,back_clr); 

  //--- CAB0=>28< B8? 3@0=8FK 

  ObjectSetInteger(chart_ID,name,OBJPROP_BORDER_TYPE,border); 

  //--- CAB0=>28< C3>; 3@0D8:0, >B=>A8B5;L=> :>B>@>3> 1C4CB >?@545;OBLAO :>>@48=0BK B>G:8 

  ObjectSetInteger(chart_ID,name,OBJPROP_CORNER,corner); 

  //--- CAB0=>28< F25B ?;>A:>9 @0<:8 (2 @568<5 Flat) 

  ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr); 

  //--- CAB0=>28< AB8;L ;8=88 ?;>A:>9 @0<:8 

  ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style); 

  //--- CAB0=>28< B>;I8=C ?;>A:>9 3@0=8FK 

  ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,line_width); 

  //--- >B>1@078< =0 ?5@54=5< (false) 8;8 704=5< (true) ?;0=5 

  ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back); 

  //--- 2:;NG8< (true) 8;8 >B:;NG8< (false) @568< ?5@5<5I5=8O <5B:8 <KHLN 

  ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selectable); 

  ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection); 

  //--- A:@>5< (true) 8;8 >B>1@078< (false) 8<O 3@0D8G5A:>3> >1J5:B0 2 A?8A:5 >1J5:B>2 

  ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden); 

  //--- CAB0=>28< ?@8>@8B5B =0 ?>;CG5=85 A>1KB8O =060B8O <KH8 =0 3@0D8:5 

  ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order); 

  //--- CA?5H=>5 2K?>;=5=85 

  return(true); 

} 

Comments

Markdown supported. Formatting help

Markdown Formatting Guide

Element Markdown Syntax
Heading # H1
## H2
### H3
Bold **bold text**
Italic *italicized text*
Link [title](https://www.example.com)
Image ![alt text](image.jpg)
Code `code`
Code Block ```
code block
```
Quote > blockquote
Unordered List - Item 1
- Item 2
Ordered List 1. First item
2. Second item
Horizontal Rule ---