Discussion of article "Statistical distributions in the form of histograms without indicator buffers and arrays"

 

New article Statistical distributions in the form of histograms without indicator buffers and arrays has been published:

The article discusses the possibility of plotting statistical distribution histograms of market conditions with the help of the graphical memory meaning no indicator buffers and arrays are applied. Sample histograms are described in details and the "hidden" functionality of MQL5 graphical objects is shown.

In this article, we will focus on the vertical histograms of the variation series: price values of the analyzed parameters are to be located on the vertical axis in ascending order, while frequency is to be located on the horizontal axis (Fig. 1). Incoming price data are distributed and grouped on the current bar and can be displayed relative to its axis from the left, right or both sides simultaneously.

Fig. 1. Vertical histogram of Bid and Ask prices distribution 

Fig. 1. Vertical histogram of Bid and Ask prices distribution

Author: Sergey Pavlov

 

Sergey, this is very interesting and I'd like to talk about it.

First, I don't know how to get the code from the news post.  I ended up saving the code and copy-pasting it from the saved file. I'm not sure what an .mht file is.

Anyway I pasted the  DrawHistogram() function but when I tried to compile it there were undefined variables. e.g color_R_active.  Can you help me define those.

Thank you.

Chuck Stangor 

 
cstangor:

Sergey, this is very interesting and I'd like to talk about it.

First, I don't know how to get the code from the news post.  I ended up saving the code and copy-pasting it from the saved file. I'm not sure what an .mht file is.

Anyway I pasted the  DrawHistogram() function but when I tried to compile it there were undefined variables. e.g color_R_active.  Can you help me define those.

Thank you.

Chuck Stangor 

Show the full code.

 
Sergey Pavlov:

Show the full code.

//+------------------------------------------------------------------+
//|                                               draw_histogram.mqh |
//|                        Copyright 2016, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
//+------------------------------------------------------------------+
//| defines                                                          |
//+------------------------------------------------------------------+
// #define MacrosHello   "Hello, world!"
// #define MacrosYear    2010
//+------------------------------------------------------------------+
//| DLL imports                                                      |
//+------------------------------------------------------------------+
// #import "user32.dll"
//   int      SendMessageA(int hWnd,int Msg,int wParam,int lParam);
// #import "my_expert.dll"
//   int      ExpertRecalculate(int wParam,int lParam);
// #import
//+------------------------------------------------------------------+
//| EX5 imports                                                      |
//+------------------------------------------------------------------+
// #import "stdlib.ex5"
//   string ErrorDescription(int error_code);
// #import
//+------------------------------------------------------------------+

void DrawHistogram(bool draw,     // draw a histogram to the left or to the right
                   string h_name, // unique prefix for the object name
                   double price,  // price (analyzed parameter)
                   datetime time, // bind a histogram to the current bar
                   int span,      // analyzed parameter digit capacity
                   int swin=0)    // histogram window
  {
   double y=NormalizeDouble(price,span);
   string pfx=DoubleToString(y,span);
// if draw=true, draw the histogram to the right
   if(draw)
     {
      string name="+ "+h_name+pfx;                   // object name: prefix+price
      ObjectCreate(0,name,OBJ_TREND,swin,time,y);    // create the object
      ObjectSetInteger(0,name,OBJPROP_COLOR,color_R_active); // set the object color
      ObjSet;                                                // code shortening macro
      if(StringFind(ObjectGetString(0,name,OBJPROP_TEXT),"*",0)<0)
        {// if the resulting price entered the sample for the first time
         ObjectSetString(0,name,OBJPROP_TEXT,"*1");          // the price freuqency is 1
         ObjectSetInteger(0,name,OBJPROP_TIME,1,time+hsize); // define the time coordinate
        }
      else
        {// if the resulting price entered the sample not for the first time
         string str=ObjectGetString(0,name,OBJPROP_TEXT);    // get the property value
         string strint=StringSubstr(str,1);                  // highlight the substring
         long n=StringToInteger(strint);                     // get a frequency for further calculations
         n++;                                                // increase the value by 1
         ObjectSetString(0,name,OBJPROP_TEXT,"*"+(string)n); // write a new value to the property
         ObjectSetInteger(0,name,OBJPROP_TIME,1,time+hsize*n);//define the time coordinate
        }
     }
// if draw=false, write the histogram to the left
   if(!draw)
     {
      string name="- "+h_name+pfx;
      ObjectCreate(0,name,OBJ_TREND,swin,time,y);
      ObjectSetInteger(0,name,OBJPROP_COLOR,color_L_active);
      ObjSet;
      if(StringFind(ObjectGetString(0,name,OBJPROP_TEXT),"*",0)<0)
        {
         ObjectSetString(0,name,OBJPROP_TEXT,"*1");
         ObjectSetInteger(0,name,OBJPROP_TIME,1,time-hsize);
        }
      else
        {
         string str=ObjectGetString(0,name,OBJPROP_TEXT);
         string strint=StringSubstr(str,1);
         long n=StringToInteger(strint);
         n++;
         ObjectSetString(0,name,OBJPROP_TEXT,"*"+(string)n);
         ObjectSetInteger(0,name,OBJPROP_TIME,1,time-hsize*n);
        }
     }
  ChartRedraw();
}
 
//+------------------------------------------------------------------+
//|                                               draw_histogram.mqh |
//|                        Copyright 2016, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
//--- Макросы
#define  R        43    // значения префикса (+) для гистограмм справа
#define  L        45    // значения префикса (-) для гистограмм слева
#define  WIDTH    2     // толщина линий
#define  ObjSet1  ObjectSetInteger(0,name,OBJPROP_WIDTH,WIDTH)
#define  ObjSet2  ObjectSetDouble(0,name,OBJPROP_PRICE,0,y)
#define  ObjSet3  ObjectSetInteger(0,name,OBJPROP_TIME,0,time)
#define  ObjSet4  ObjectSetDouble(0,name,OBJPROP_PRICE,1,y)
#define  ObjSet5  ObjectSetInteger(0,name,OBJPROP_BACK,true)
#define  ObjSet   ObjSet1;ObjSet2;ObjSet3;ObjSet4;ObjSet5
//---
int      hsize=10;                     // масштаб гистограммы
color    color_R_active=clrRed;        // цвет активных линий справа
color    color_R_passive=clrLightCoral;// цвет пассивных линий справа
color    color_L_active=clrBlue;       // цвет активных линий слева
color    color_L_passive=clrSkyBlue;   // цвет пассивных линий слева

void DrawHistogram(bool draw,     // draw a histogram to the left or to the right
                   string h_name, // unique prefix for the object name
                   double price,  // price (analyzed parameter)
                   datetime time, // bind a histogram to the current bar
                   int span,      // analyzed parameter digit capacity
                   int swin=0)    // histogram window
  {
   double y=NormalizeDouble(price,span);
   string pfx=DoubleToString(y,span);
// if draw=true, draw the histogram to the right
   if(draw)
     {
      string name="+ "+h_name+pfx;                   // object name: prefix+price
      ObjectCreate(0,name,OBJ_TREND,swin,time,y);    // create the object
      ObjectSetInteger(0,name,OBJPROP_COLOR,color_R_active); // set the object color
      ObjSet;                                                // code shortening macro
      if(StringFind(ObjectGetString(0,name,OBJPROP_TEXT),"*",0)<0)
        {// if the resulting price entered the sample for the first time
         ObjectSetString(0,name,OBJPROP_TEXT,"*1");          // the price freuqency is 1
         ObjectSetInteger(0,name,OBJPROP_TIME,1,time+hsize); // define the time coordinate
        }
      else
        {// if the resulting price entered the sample not for the first time
         string str=ObjectGetString(0,name,OBJPROP_TEXT);    // get the property value
         string strint=StringSubstr(str,1);                  // highlight the substring
         long n=StringToInteger(strint);                     // get a frequency for further calculations
         n++;                                                // increase the value by 1
         ObjectSetString(0,name,OBJPROP_TEXT,"*"+(string)n); // write a new value to the property
         ObjectSetInteger(0,name,OBJPROP_TIME,1,time+hsize*n);//define the time coordinate
        }
     }
// if draw=false, write the histogram to the left
   if(!draw)
     {
      string name="- "+h_name+pfx;
      ObjectCreate(0,name,OBJ_TREND,swin,time,y);
      ObjectSetInteger(0,name,OBJPROP_COLOR,color_L_active);
      ObjSet;
      if(StringFind(ObjectGetString(0,name,OBJPROP_TEXT),"*",0)<0)
        {
         ObjectSetString(0,name,OBJPROP_TEXT,"*1");
         ObjectSetInteger(0,name,OBJPROP_TIME,1,time-hsize);
        }
      else
        {
         string str=ObjectGetString(0,name,OBJPROP_TEXT);
         string strint=StringSubstr(str,1);
         long n=StringToInteger(strint);
         n++;
         ObjectSetString(0,name,OBJPROP_TEXT,"*"+(string)n);
         ObjectSetInteger(0,name,OBJPROP_TIME,1,time-hsize*n);
        }
     }
  ChartRedraw();
}
 
Sergey Pavlov:
//+------------------------------------------------------------------+
//|                                               draw_histogram.mqh |
//|                        Copyright 2016, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
//--- Макросы
#define  R        43    // значения префикса (+) для гистограмм справа
#define  L        45    // значения префикса (-) для гистограмм слева
#define  WIDTH    2     // толщина линий
#define  ObjSet1  ObjectSetInteger(0,name,OBJPROP_WIDTH,WIDTH)
#define  ObjSet2  ObjectSetDouble(0,name,OBJPROP_PRICE,0,y)
#define  ObjSet3  ObjectSetInteger(0,name,OBJPROP_TIME,0,time)
#define  ObjSet4  ObjectSetDouble(0,name,OBJPROP_PRICE,1,y)
#define  ObjSet5  ObjectSetInteger(0,name,OBJPROP_BACK,true)
#define  ObjSet   ObjSet1;ObjSet2;ObjSet3;ObjSet4;ObjSet5
//---
int      hsize=10;                     // масштаб гистограммы
color    color_R_active=clrRed;        // цвет активных линий справа
color    color_R_passive=clrLightCoral;// цвет пассивных линий справа
color    color_L_active=clrBlue;       // цвет активных линий слева
color    color_L_passive=clrSkyBlue;   // цвет пассивных линий слева

void DrawHistogram(bool draw,     // draw a histogram to the left or to the right
                   string h_name, // unique prefix for the object name
                   double price,  // price (analyzed parameter)
                   datetime time, // bind a histogram to the current bar
                   int span,      // analyzed parameter digit capacity
                   int swin=0)    // histogram window
  {
   double y=NormalizeDouble(price,span);
   string pfx=DoubleToString(y,span);
// if draw=true, draw the histogram to the right
   if(draw)
     {
      string name="+ "+h_name+pfx;                   // object name: prefix+price
      ObjectCreate(0,name,OBJ_TREND,swin,time,y);    // create the object
      ObjectSetInteger(0,name,OBJPROP_COLOR,color_R_active); // set the object color
      ObjSet;                                                // code shortening macro
      if(StringFind(ObjectGetString(0,name,OBJPROP_TEXT),"*",0)<0)
        {// if the resulting price entered the sample for the first time
         ObjectSetString(0,name,OBJPROP_TEXT,"*1");          // the price freuqency is 1
         ObjectSetInteger(0,name,OBJPROP_TIME,1,time+hsize); // define the time coordinate
        }
      else
        {// if the resulting price entered the sample not for the first time
         string str=ObjectGetString(0,name,OBJPROP_TEXT);    // get the property value
         string strint=StringSubstr(str,1);                  // highlight the substring
         long n=StringToInteger(strint);                     // get a frequency for further calculations
         n++;                                                // increase the value by 1
         ObjectSetString(0,name,OBJPROP_TEXT,"*"+(string)n); // write a new value to the property
         ObjectSetInteger(0,name,OBJPROP_TIME,1,time+hsize*n);//define the time coordinate
        }
     }
// if draw=false, write the histogram to the left
   if(!draw)
     {
      string name="- "+h_name+pfx;
      ObjectCreate(0,name,OBJ_TREND,swin,time,y);
      ObjectSetInteger(0,name,OBJPROP_COLOR,color_L_active);
      ObjSet;
      if(StringFind(ObjectGetString(0,name,OBJPROP_TEXT),"*",0)<0)
        {
         ObjectSetString(0,name,OBJPROP_TEXT,"*1");
         ObjectSetInteger(0,name,OBJPROP_TIME,1,time-hsize);
        }
      else
        {
         string str=ObjectGetString(0,name,OBJPROP_TEXT);
         string strint=StringSubstr(str,1);
         long n=StringToInteger(strint);
         n++;
         ObjectSetString(0,name,OBJPROP_TEXT,"*"+(string)n);
         ObjectSetInteger(0,name,OBJPROP_TIME,1,time-hsize*n);
        }
     }
  ChartRedraw();
}
Thank you !
 

mr Sergey,

I´m trying plot tick buy and sell volume instead bid and ask to have a volume at price like indicator, is it possible ? do you have some code with tick buy/sell volume that can post ?

thank´s very much !


Example of data that I want to plot, it plots a horizontal histogram of buy/sell tick volume in separate window I want to plot a vertical histogram in main chart window :

#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots   2
//
#property indicator_label1  "SELL Tick"
#property indicator_type1   DRAW_HISTOGRAM
#property indicator_color1  clrTomato
#property indicator_style1  STYLE_SOLID
//
#property indicator_label2  "BUY Tick"
#property indicator_type2   DRAW_HISTOGRAM
#property indicator_color2  clrSpringGreen
#property indicator_style2  STYLE_SOLID
#property indicator_width2  5

//--- indicator buffers
double         ExtBuyBuffer[];
double         ExtSellBuffer[];

int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,ExtBuyBuffer,INDICATOR_DATA);
   SetIndexBuffer(1,ExtSellBuffer,INDICATOR_DATA);
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0);
   PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,0);
//---
   return(INIT_SUCCEEDED);
  }



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[])
  {

static int ticks=0;
//---
   if(ticks==0)
     {
      ArrayInitialize(ExtSellBuffer,0);
      ArrayInitialize(ExtBuyBuffer,0);
     }
//---
   MqlTick last_tick;
   if(SymbolInfoTick(Symbol(),last_tick) && last_tick.flags == 56)
     {
         ExtBuyBuffer[ticks]+=NormalizeDouble(last_tick.volume,2); 
         int shift=rates_total-1-ticks;
         ticks++;
         ExtBuyBuffer[rates_total-1]=last_tick.volume;
         PlotIndexSetInteger(0,PLOT_SHIFT,shift);
     }
   if(SymbolInfoTick(Symbol(),last_tick) && last_tick.flags == 88)
     {
         ExtSellBuffer[ticks]+=NormalizeDouble(last_tick.volume,2); 
         int shift=rates_total-1-ticks;
         ticks++;
         ExtSellBuffer[rates_total-1]=last_tick.volume;
         PlotIndexSetInteger(1,PLOT_SHIFT,shift);
     }

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

   return(rates_total);
 }

Reason: