Discussão do artigo "Distribuições estatísticas em forma de histogramas sem buffers de indicador e matrizes"
Uma grande ajuda para trabalhar no mercado seria a criação de um indicador na forma de um histograma na janela principal com dados da pilha sobre o número de ordens, mas em dinâmica....
(um exemplo é o indicador #Xaser-info
Sergey, isso é muito interessante e eu gostaria de falar sobre o assunto.
Primeiro, não sei como obter o código da postagem de notícias. Acabei salvando o código e copiando e colando-o do arquivo salvo. Não tenho certeza do que é um arquivo .mht.
De qualquer forma, colei a função DrawHistogram(), mas quando tentei compilá-la, havia variáveis indefinidas, por exemplo, color_R_active. Você poderia me ajudar a defini-las?
Obrigado.
Chuck Stangor
Sergey, isso é muito interessante e eu gostaria de falar sobre o assunto.
Primeiro, não sei como obter o código da postagem de notícias. Acabei salvando o código e copiando e colando-o do arquivo salvo. Não tenho certeza do que é um arquivo .mht.
De qualquer forma, colei a função DrawHistogram(), mas quando tentei compilá-la, havia variáveis indefinidas, por exemplo, color_R_active. Você poderia me ajudar a defini-las?
Obrigado.
Chuck Stangor
Mostrar o código completo.
Mostrar o código completo.
//|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|
//+------------------------------------------------------------------+
// #define MacrosHello "Olá, mundo!"
// #define MacrosYear 2010
//+------------------------------------------------------------------+
//| Importações de DLL|
//+------------------------------------------------------------------+
// #importar "user32.dll"
// int SendMessageA(int hWnd,int Msg,int wParam,int lParam);
// #importar "my_expert.dll"
// int ExpertRecalculate(int wParam,int lParam);
// #import
//+------------------------------------------------------------------+
//| Importações EX5|
//+------------------------------------------------------------------+
// #importar "stdlib.ex5"
// string ErrorDescription(int error_code);
// #import
//+------------------------------------------------------------------+
void DrawHistogram(bool draw, // desenhar um histograma para a esquerda ou para a direita
string h_name, // prefixo exclusivo para o nome do objeto
double price, // preço (parâmetro analisado)
datetime time, // vincular um histograma à barra atual
int span, // capacidade de dígitos do parâmetro analisado
int swin=0) // janela do histograma
{
double y=NormalizeDouble(price,span);
string pfx=DoubleToString(y,span);
// se draw=true, desenha o histograma à direita
if(draw)
{
string name="+ "+h_name+pfx; // nome do objeto: prefixo+preço
ObjectCreate(0,name,OBJ_TREND,swin,time,y); // criar o objeto
ObjectSetInteger(0,name,OBJPROP_COLOR,color_R_active); // definir a cor do objeto
ObjSet; // macro de encurtamento de código
if(StringFind(ObjectGetString(0,name,OBJPROP_TEXT),"*",0)<0)
{// se o preço resultante entrou na amostra pela primeira vez
ObjectSetString(0,name,OBJPROP_TEXT,"*1"); // a frequência de preço é 1
ObjectSetInteger(0,name,OBJPROP_TIME,1,time+hsize); // definir a coordenada de tempo
}
else
{// se o preço resultante entrou na amostra não pela primeira vez
string str=ObjectGetString(0,name,OBJPROP_TEXT); // obter o valor da propriedade
string strint=StringSubstr(str,1); // destacar a substring
long n=StringToInteger(strint); // obter uma frequência para cálculos adicionais
n++; // aumentar o valor em 1
ObjectSetString(0,name,OBJPROP_TEXT,"*"+(string)n); // gravar um novo valor na propriedade
ObjectSetInteger(0,name,OBJPROP_TIME,1,time+hsize*n);//definir a coordenada de tempo
}
}
// se draw=false, escreva o histograma à esquerda
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, // desenhar um histograma para a esquerda ou para a direita
string h_name, // prefixo exclusivo para o nome do objeto
double price, // preço (parâmetro analisado)
datetime time, // vincular um histograma à barra atual
int span, // capacidade de dígitos do parâmetro analisado
int swin=0) // janela do histograma
{
double y=NormalizeDouble(price,span);
string pfx=DoubleToString(y,span);
// se draw=true, desenha o histograma à direita
if(draw)
{
string name="+ "+h_name+pfx; // nome do objeto: prefixo+preço
ObjectCreate(0,name,OBJ_TREND,swin,time,y); // criar o objeto
ObjectSetInteger(0,name,OBJPROP_COLOR,color_R_active); // definir a cor do objeto
ObjSet; // macro de encurtamento de código
if(StringFind(ObjectGetString(0,name,OBJPROP_TEXT),"*",0)<0)
{// se o preço resultante entrou na amostra pela primeira vez
ObjectSetString(0,name,OBJPROP_TEXT,"*1"); // a frequência de preço é 1
ObjectSetInteger(0,name,OBJPROP_TIME,1,time+hsize); // definir a coordenada de tempo
}
else
{// se o preço resultante entrou na amostra não pela primeira vez
string str=ObjectGetString(0,name,OBJPROP_TEXT); // obter o valor da propriedade
string strint=StringSubstr(str,1); // destacar a substring
long n=StringToInteger(strint); // obter uma frequência para cálculos adicionais
n++; // aumentar o valor em 1
ObjectSetString(0,name,OBJPROP_TEXT,"*"+(string)n); // gravar um novo valor na propriedade
ObjectSetInteger(0,name,OBJPROP_TIME,1,time+hsize*n);//definir a coordenada de tempo
}
}
// se draw=false, escreva o histograma à esquerda
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, // desenhar um histograma para a esquerda ou para a direita
string h_name, // prefixo exclusivo para o nome do objeto
double price, // preço (parâmetro analisado)
datetime time, // vincular um histograma à barra atual
int span, // capacidade de dígitos do parâmetro analisado
int swin=0) // janela do histograma
{
double y=NormalizeDouble(price,span);
string pfx=DoubleToString(y,span);
// se draw=true, desenha o histograma à direita
if(draw)
{
string name="+ "+h_name+pfx; // nome do objeto: prefixo+preço
ObjectCreate(0,name,OBJ_TREND,swin,time,y); // criar o objeto
ObjectSetInteger(0,name,OBJPROP_COLOR,color_R_active); // definir a cor do objeto
ObjSet; // macro de encurtamento de código
if(StringFind(ObjectGetString(0,name,OBJPROP_TEXT),"*",0)<0)
{// se o preço resultante entrou na amostra pela primeira vez
ObjectSetString(0,name,OBJPROP_TEXT,"*1"); // a frequência de preço é 1
ObjectSetInteger(0,name,OBJPROP_TIME,1,time+hsize); // definir a coordenada de tempo
}
else
{// se o preço resultante entrou na amostra não pela primeira vez
string str=ObjectGetString(0,name,OBJPROP_TEXT); // obter o valor da propriedade
string strint=StringSubstr(str,1); // destacar a substring
long n=StringToInteger(strint); // obter uma frequência para cálculos adicionais
n++; // aumentar o valor em 1
ObjectSetString(0,name,OBJPROP_TEXT,"*"+(string)n); // gravar um novo valor na propriedade
ObjectSetInteger(0,name,OBJPROP_TIME,1,time+hsize*n);//definir a coordenada de tempo
}
}
// se draw=false, escreva o histograma à esquerda
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();
}
Sr. Sergey,
Estou tentando plotar o volume de compra e venda de tick em vez de bid e ask para ter um volume no preço como indicador, é possível? você tem algum código com volume de compra/venda de tick que possa postar?
Muito obrigado!
Exemplo de dados que quero plotar, ele plota um histograma horizontal do volume de ticks de compra/venda em uma janela separada:
#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 //--- buffers de indicadores double ExtBuyBuffer[]; double ExtSellBuffer[]; int OnInit() { //--- mapeamento de buffers de 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_calculated para a próxima chamada return(rates_total); }
- Aplicativos de negociação gratuitos
- 8 000+ sinais para cópia
- Notícias econômicas para análise dos mercados financeiros
Você concorda com a política do site e com os termos de uso
Novo artigo Distribuições estatísticas em forma de histogramas sem buffers de indicador e matrizes foi publicado:
O artigo considera a possibilidade de criar histogramas, distribuições estatísticas das características do mercado usando memória gráfica, ou seja, sem o uso de buffers de indicador e matrizes. Aqui você tem à sua disposição não só exemplos detalhados de como construir esses histogramas, mas também pode conhecer a funcionalidade "oculta" dos objetos gráficos da linguagem MQL5.
Neste artigo, vamos nos concentrar nos histogramas verticais de séries de variação: os valores de preço das características estudadas estarão localizados no eixo vertical em ordem crescente, enquanto a frequência, no eixo horizontal (Fig. 1). Os dados de preços, que entram ao terminal, são agrupados e alocados na barra atual e podem ser exibidos com respeito ao eixo da esquerda, direita ou em ambos os lados simultaneamente.
Fig. 1. Gráfico de colunas vertical de distribuição de preços Bid e Ask.
Autor: Sergey Pavlov