Discusión sobre el artículo "Distribuciones estadísticas en forma de histogramas sin búferes de indicador y matrices"

 

Artículo publicado Distribuciones estadísticas en forma de histogramas sin búferes de indicador y matrices:

En el artículo se estudia la posibilidad de crear los histogramas de las distribuciones estadísticas de las características del mercado usando memoria gráfica, es decir, sin usar búferes de indicador y matrices. Se adjuntan ejemplos detallados de la construcción de este tipoo de histogramas y se muestra la llamada funcionalidad "oculta" de los objetos gráficos del lenguaje MQL5.

En este artículo vamos a detenernos en los histogramas verticales de las series de variación: los valores de precio de las características estadísticas se encontrarán en el eje vertical en orden creciente, y las frecuencias, en el horizontal (Fig. 1). Los datos de precio que llegan al terminal se distribuyen y agrupan en la barra actual y pueden ser representados con respecto a su eje: a la izquierda, a la derecha, o simultáneamente en ambos lados.

Fig. 1  Histograma vertical de distribución de los precios Bid y Ask. 

Fig. 1 Histograma vertical de distribución de los precios Bid y Ask.

Autor: Sergey Pavlov

 
¿No estorba la encuadernación?
 

una gran ayuda para trabajar en el mercado sería la creación de un indicador en forma de histograma en la ventana principal con los datos de la pila sobre el número de órdenes, pero en dinámica....

(un ejemplo es el indicador #Xaser-info

[Eliminado]  
Recordado este modo de visualización en indicadores por VSA. Clara y eficaz
 

Sergey, esto es muy interesante y me gustaria comentarlo.

En primer lugar, no sé cómo obtener el código del post de la noticia. Acabé guardando el código y copiándolo y pegándolo desde el archivo guardado. No estoy seguro de lo que es un archivo .mht.

De todos modos he pegado la función DrawHistogram() pero cuando traté de compilarlo había variables no definidas. por ejemplo color_R_active. ¿Puedes ayudarme a definir esos.

Gracias.

Chuck Stangor

 
cstangor:

Sergey, esto es muy interesante y me gustaria comentarlo.

En primer lugar, no sé cómo obtener el código del post de la noticia. Acabé guardando el código y copiándolo y pegándolo desde el archivo guardado. No estoy seguro de lo que es un archivo .mht.

De todos modos he pegado la función DrawHistogram() pero cuando traté de compilarlo había variables no definidas. por ejemplo color_R_active. ¿Puedes ayudarme a definir esos.

Gracias.

Chuck Stangor

Muestra el código completo.

 
Sergey Pavlov:

Mostrar el código completo.

//+------------------------------------------------------------------+
//|dibujar_histograma.mqh |
//| Copyright 2016, MetaQuotes Software Corp. |
//| https://www.mql5.com
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
//+------------------------------------------------------------------+
//| define|
//+------------------------------------------------------------------+
// #define MacrosHello "¡Hola, mundo!"
// #define MacrosAño 2010
//+------------------------------------------------------------------+
//| Importaciones DLL|
//+------------------------------------------------------------------+
// #importar "user32.dll"
// int SendMessageA(int hWnd,int Msg,int wParam,int lParam);
// #importar "mi_experto.dll"
// int ExpertRecalculate(int wParam,int lParam);
// #importar
//+------------------------------------------------------------------+
//| importaciones EX5|
//+------------------------------------------------------------------+
// #import "stdlib.ex5"
// cadena ErrorDescription(int error_code);
// #importar
//+------------------------------------------------------------------+

void DrawHistogram(bool draw,     // dibujar un histograma a la izquierda o a la derecha
                   string h_name, // prefijo único para el nombre del objeto
                   double price,  // precio (parámetro analizado)
                   datetime time, // vincular un histograma a la barra actual
                   int span,      // parámetro analizado capacidad de dígitos
                   int swin=0)    // ventana de histograma
  {
   double y=NormalizeDouble(price,span);
   string pfx=DoubleToString(y,span);
// si draw=true, dibuja el histograma a la derecha
   if(draw)
     {
      string name="+ "+h_name+pfx;                   // nombre del objeto: prefijo+precio
      ObjectCreate(0,name,OBJ_TREND,swin,time,y);    // crear el objeto
      ObjectSetInteger(0,name,OBJPROP_COLOR,color_R_active); // establecer el color del objeto
      ObjSet;                                                // macro de acortamiento de código
      if(StringFind(ObjectGetString(0,name,OBJPROP_TEXT),"*",0)<0)
        {// si el precio resultante entró en la muestra por primera vez
         ObjectSetString(0,name,OBJPROP_TEXT,"*1");          // la frecuencia del precio es 1
         ObjectSetInteger(0,name,OBJPROP_TIME,1,time+hsize); // definir la coordenada temporal
        }
      else
        {// si el precio resultante no entró en la muestra por primera vez
         string str=ObjectGetString(0,name,OBJPROP_TEXT);    // obtener el valor de la propiedad
         string strint=StringSubstr(str,1);                  // resaltar la subcadena
         long n=StringToInteger(strint);                     // obtener una frecuencia para cálculos posteriores
         n++;                                                // aumenta el valor en 1
         ObjectSetString(0,name,OBJPROP_TEXT,"*"+(string)n); // escribir un nuevo valor en la propiedad
         ObjectSetInteger(0,name,OBJPROP_TIME,1,time+hsize*n);//definir la coordenada horaria
        }
     }
// si draw=false, escribe el histograma a la izquierda
   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();
}
 
//+------------------------------------------------------------------+
//|dibujar_histograma.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,     // dibujar un histograma a la izquierda o a la derecha
                   string h_name, // prefijo único para el nombre del objeto
                   double price,  // precio (parámetro analizado)
                   datetime time, // vincular un histograma a la barra actual
                   int span,      // parámetro analizado capacidad de dígitos
                   int swin=0)    // ventana de histograma
  {
   double y=NormalizeDouble(price,span);
   string pfx=DoubleToString(y,span);
// si draw=true, dibuja el histograma a la derecha
   if(draw)
     {
      string name="+ "+h_name+pfx;                   // nombre del objeto: prefijo+precio
      ObjectCreate(0,name,OBJ_TREND,swin,time,y);    // crear el objeto
      ObjectSetInteger(0,name,OBJPROP_COLOR,color_R_active); // establecer el color del objeto
      ObjSet;                                                // macro de acortamiento de código
      if(StringFind(ObjectGetString(0,name,OBJPROP_TEXT),"*",0)<0)
        {// si el precio resultante entró en la muestra por primera vez
         ObjectSetString(0,name,OBJPROP_TEXT,"*1");          // la frecuencia del precio es 1
         ObjectSetInteger(0,name,OBJPROP_TIME,1,time+hsize); // definir la coordenada temporal
        }
      else
        {// si el precio resultante no entró en la muestra por primera vez
         string str=ObjectGetString(0,name,OBJPROP_TEXT);    // obtener el valor de la propiedad
         string strint=StringSubstr(str,1);                  // resaltar la subcadena
         long n=StringToInteger(strint);                     // obtener una frecuencia para cálculos posteriores
         n++;                                                // aumenta el valor en 1
         ObjectSetString(0,name,OBJPROP_TEXT,"*"+(string)n); // escribir un nuevo valor en la propiedad
         ObjectSetInteger(0,name,OBJPROP_TIME,1,time+hsize*n);//definir la coordenada horaria
        }
     }
// si draw=false, escribe el histograma a la izquierda
   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:
//+------------------------------------------------------------------+
//|dibujar_histograma.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,     // dibujar un histograma a la izquierda o a la derecha
                   string h_name, // prefijo único para el nombre del objeto
                   double price,  // precio (parámetro analizado)
                   datetime time, // vincular un histograma a la barra actual
                   int span,      // parámetro analizado capacidad de dígitos
                   int swin=0)    // ventana de histograma
  {
   double y=NormalizeDouble(price,span);
   string pfx=DoubleToString(y,span);
// si draw=true, dibuja el histograma a la derecha
   if(draw)
     {
      string name="+ "+h_name+pfx;                   // nombre del objeto: prefijo+precio
      ObjectCreate(0,name,OBJ_TREND,swin,time,y);    // crear el objeto
      ObjectSetInteger(0,name,OBJPROP_COLOR,color_R_active); // establecer el color del objeto
      ObjSet;                                                // macro de acortamiento de código
      if(StringFind(ObjectGetString(0,name,OBJPROP_TEXT),"*",0)<0)
        {// si el precio resultante entró en la muestra por primera vez
         ObjectSetString(0,name,OBJPROP_TEXT,"*1");          // la frecuencia del precio es 1
         ObjectSetInteger(0,name,OBJPROP_TIME,1,time+hsize); // definir la coordenada temporal
        }
      else
        {// si el precio resultante no entró en la muestra por primera vez
         string str=ObjectGetString(0,name,OBJPROP_TEXT);    // obtener el valor de la propiedad
         string strint=StringSubstr(str,1);                  // resaltar la subcadena
         long n=StringToInteger(strint);                     // obtener una frecuencia para cálculos posteriores
         n++;                                                // aumenta el valor en 1
         ObjectSetString(0,name,OBJPROP_TEXT,"*"+(string)n); // escribir un nuevo valor en la propiedad
         ObjectSetInteger(0,name,OBJPROP_TIME,1,time+hsize*n);//definir la coordenada horaria
        }
     }
// si draw=false, escribe el histograma a la izquierda
   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();
}
Gracias.
 

Señor Sergey,

Estoy tratando de trazar el volumen de compra y venta de garrapatas en lugar de oferta y demanda para tener un volumen en el precio como indicador, ¿es posible ? ¿tiene algún código con el volumen de compra / venta de garrapatas que puede publicar ?

Muchas gracias.


Ejemplo de los datos que quiero trazar, se traza un histograma horizontal de compra / venta de volumen de garrapatas en una ventana separada Quiero trazar un histograma vertical en la ventana principal del gráfico:

#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

//--- tampones indicadores
double         ExtBuyBuffer[];
double         ExtSellBuffer[];

int OnInit()
  {
//--- asignación de búferes indicadores
   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);
     }

//
//--- valor de retorno de prev_calculado para la siguiente llamada

   return(rates_total);
 }