Discussão do artigo "Guia prático MQL5: Desenvolvimento de um Indicador de Símbolos Múltiplos para Análise de Divergência de Preço"

 

Novo artigo Guia prático MQL5: Desenvolvimento de um Indicador de Símbolos Múltiplos para Análise de Divergência de Preço foi publicado:

Neste artigo, vamos considerar o desenvolvimento de um indicador de símbolos múltiplos para análise de divergência de preço dentro de um período de tempo determinado. Os temas centrais já foram discutidas no artigo anterior sobre programação de indicadores de múltiplas moedas: "Guia prático do MQL5: Desenvolvimento de um Indicador de Símbolos Múltiplos em MQL5". Então, desta vez vamos focar apenas nas novas características e funções que foram alteradas drasticamente. Se você é novo em programação de indicadores de múltiplas moedas, primeiro eu recomendo a leitura do artigo anterior.

Timeframe semanal no modo "linha vertical"

Neste artigo vamos considerar as seguintes questões:

  • Alterar propriedades do gráfico.
  • Manusear os eventos CHARTEVENT_OBJECT_DRAG (arrastando um objeto gráfico) e CHARTEVENT_CHART_CHANGE (redimensionar gráfico ou modificar as propriedades de gráfico usando as propriedades da janela de diálogo).
  • Renderizar buffers do Indicador usando mais de uma cor.
  • Definir máximas e mínimas em buffers do indicador dentro da área de visibilidade para definir um gráfico de máxima/mínima (high/low).
  • Inversão de uma série.

Autor: Anatoli Kazharski

 

É apenas um erro de digitação ou deveria ser?

Não importa quantas vezes eu tenha tentado, todas as funções do "Esquadrão de cópia" nunca retornam zero, apenas -1 ou >0.

//+------------------------------------------------------------------+
//| Verifica o número de dados disponíveis para todos os caracteres
//+------------------------------------------------------------------+
bool CheckAvailableData()
  {
   int attempts=100;
   
//---
   for(int s=0; s<SYMBOLS_COUNT; s++)
     {
      //--- Se houver esse caractere
      if(symbol_names[s]!=empty_symbol)
        {
datetime time[];                    // Matriz para verificar o número de barras
   int      total_period_bars   =0;    // Número de barras do período atual
   datetime terminal_first_date =NULL; // Primeira data de dados disponíveis do período atual no terminal
         //--- Obtenha a primeira data dos dados do período atual no terminal
         terminal_first_date=(datetime)SeriesInfoInteger(symbol_names[s],Period(),SERIES_TERMINAL_FIRSTDATE);
         //--- Obter o número de barras disponíveis a partir da data especificada
         total_period_bars=Bars(symbol_names[s],Period(),terminal_first_date,TimeCurrent());
         //--- Verificar a prontidão dessas barras
         for(int i=0; i<attempts; i++)
           {
            //--- Copiar a quantidade especificada de dados
            if(CopyTime(symbol_names[s],Period(),0,total_period_bars,time))
              {
               //--- Se a quantidade necessária for copiada, pare o loop
               if(ArraySize(time)>=total_period_bars)
                  break;
              }
           }
         //--- Se menos dados forem copiados, será necessário fazer outra tentativa.
         if(ArraySize(time)==0 || ArraySize(time)<total_period_bars)
           {
            msg_last=msg_prepare_data;
            ShowCanvasMessage(msg_prepare_data);
            OC_prev_calculated=0;
            return(false);
           }
        }
     }
//--- Se estiver no modo de linha vertical para o ponto inicial da diferença de preço, saia
   if(StartPriceDivergence==VERTICAL_LINE)
      return(true);
   else
     {
      datetime time[];                    // Matriz para verificar o número de barras
      int      total_period_bars   =0;    // Número de barras do período atual
      datetime terminal_first_date =NULL; // Primeira data de dados disponíveis do período atual no terminal
      //--- Obtenha a primeira data dos dados do período atual no terminal
      for(int i=0; i<attempts; i++)
         if((terminal_first_date=(datetime)SeriesInfoInteger(Symbol(),Period(),SERIES_FIRSTDATE))>0)
            break;
      //--- Obter o número de barras disponíveis a partir da data especificada
      for(int i=0; i<attempts; i++)
         if((total_period_bars=(int)SeriesInfoInteger(Symbol(),timeframe_start_point,SERIES_BARS_COUNT))>0)
            break;
      //--- Verificar a prontidão dessas barras
      for(int i=0; i<attempts; i++)
         //--- Copiar a quantidade especificada de dados
         if(CopyTime(Symbol(),timeframe_start_point,
            terminal_first_date+PeriodSeconds(timeframe_start_point),TimeCurrent(),time)>0)
            break;
      //--- Se menos dados forem copiados, será necessário fazer outra tentativa.
      if(ArraySize(time)<=0 || total_period_bars<=0)
        {
         msg_last=msg_prepare_data;
         ShowCanvasMessage(msg_prepare_data);
         OC_prev_calculated=0;
         return(false);
        }
     }
//---
   return(true);
  }
 
Fleder:

É apenas um erro de digitação ou deveria ser?

Não importa quantas vezes eu tenha tentado, todas as funções do "Esquadrão de cópia" nunca retornam zero, somente -1 ou >0.

Em geral, você deve fazer >0. Mas, nesse caso, as verificações subsequentes permitem que você não faça isso.
 
tol64:
Em geral, você deve fazer >0. Mas, nesse caso, as verificações subsequentes permitem que você não faça isso.

Mas essa expressão sempre será verdadeira:

if(CopyTime(symbol_names[s],Period(),0,total_period_bars,time))
 
Fleder:

Mas essa expressão sempre será verdadeira:

Você pode remover o if. Nesse caso, isso não é crítico.
 
tol64:
Você poderia remover o if. Nesse caso, ele não é crítico.
Bem, foi isso que pensei :-)
 

Em geral, o carregamento de dados históricos em um símbolo não acontece da forma como está escrito na ajuda.

Na verdade, é assim que acontece:

Se o programa mql5 solicitar dados de alguma série temporal usando, por exemplo, a função CopyTime

e esses dados não estiverem no terminal (ainda não foram carregados), o terminal fará o download desses dados do servidor, não na quantidade solicitada (no exemplo da ajuda, são 100 barras),

mas tantas barras da série temporal desejada quanto o parâmetro "Max bars in chart" permitir "colocar" na RAM.

É suficiente solicitar apenas uma barra de um período mais alto, por exemplo, PERIOD_W1, pois todo o histórico será baixado do servidor.

 
Fleder:

Em geral, o carregamento de dados históricos em um símbolo não acontece da forma como está escrito na ajuda.

Na verdade, é assim que acontece:

Se o programa mql5 solicitar dados de alguma série temporal usando, por exemplo, a função CopyTime

e esses dados não estiverem no terminal (ainda não foram carregados), o terminal fará o download desses dados do servidor, não na quantidade solicitada (no exemplo da ajuda, são 100 barras),

mas tantas barras da série temporal desejada quanto o parâmetro "Max bars in chart" permitir "colocar" na RAM.

É suficiente solicitar apenas uma barra de um período mais alto, por exemplo, PERIOD_W1, pois todo o histórico será baixado do servidor.

A ajuda pode dizer o que você quiser. Você é livre para fazer o que achar melhor. ;)

O exemplo da ajuda foi discutido em outro artigo: Como preparar cotações do MetaTrader 5 para outros programas >>>.

 
tol64:

O certificado pode dizer o que você quiser que ele diga. Você é livre para fazer o que achar melhor. ;)

O exemplo da ajuda foi discutido em outro artigo: Como preparar cotações do MetaTrader 5 para outros programas >>>.

Foi isso que eu fiz. Acabei de ver o cálculo das "barras não carregadas" restantes do servidor em seu código.

E pensei: o terminal não se importa, ele bombeia o quanto for necessário para formar.

 

No final do seu artigo, você escreveu:"Esse indicador pode ser desenvolvido ilimitadamente para melhor".

Em minha opinião, a contemplação da divergência de preços é de pouca utilidade para o olho humano. Um ser humano não é um robô!

Mas é um tópico interessante para um robô.

Você sugeriu várias opções de renderização:

1. a partir da linha.

2. "dia".

No momento, estou trabalhando em algo semelhante, mas no modo "semana".

 
Fleder:

No final do seu artigo, você escreveu:"Esse indicador pode ser desenvolvido ilimitadamente para melhor".

Em minha opinião, a contemplação da divergência de preços é de pouca utilidade para o olho humano. Um ser humano não é um robô!

Mas é um tópico interessante para um robô.

Você sugeriu várias opções de renderização:

1. a partir da linha.

2. "dia".

No momento, estou trabalhando em algo semelhante, mas no modo "semana".

Não tenho certeza se poderei escrever algo mais em breve, pois estou lidando com outros problemas. Mas, de acordo com esse artigo, o desenvolvimento ainda deveria estar nos cálculos de várias moedas e na visualização desses cálculos na tela.

Sim, o homem não é um robô, mas às vezes é preciso olhar para o objeto de estudo de outra forma para ter uma ideia. ;)