English Русский Español
preview
Desenvolvendo um EA multimoeda (Parte 27): Componente para exibição de texto multilinha

Desenvolvendo um EA multimoeda (Parte 27): Componente para exibição de texto multilinha

MetaTrader 5Exemplos |
197 0
Yuriy Bykov
Yuriy Bykov

Conteúdo


Introdução

Na parte anterior, criamos uma versão básica de um EA informador auxiliar, que exibe informações sobre os tamanhos médios das velas em pontos e os comprimentos das séries de velas consecutivas na mesma direção. Isso não está diretamente relacionado ao nosso projeto principal, a saber, um sistema de otimização automática e inicialização de EAs multimoeda que implementam diversas estratégias simples. No entanto, o desenvolvimento posterior do próprio EA informador, por enquanto, continuará no âmbito desta série, pois durante o trabalho já começamos a experimentar e a treinar a implementação de diversos componentes que, posteriormente, esperamos integrar com sucesso ao projeto principal.

Passamos para uma estrutura mais otimizada de organização do código, que abre a possibilidade de paralelizar o trabalho em várias direções de desenvolvimento da biblioteca Adwizard. Uma dessas direções é a criação de uma interface visual para o gerenciamento do funcionamento dos EAs finais. O projeto do EA informador, analisado também neste artigo, nos ajudará a explorar mais a fundo diferentes abordagens para a implementação de interfaces sem complexidade excessiva. Ao estudar suas vantagens e desvantagens, poderemos escolher a mais adequada e desenvolver o projeto principal de forma direcionada.

Da última vez, escrevemos a implementação da parte de cálculo, para a qual não foram impostas exigências rígidas de eficiência. Para a exibição dos resultados dos cálculos, utilizamos dois dos métodos mais simples disponíveis "de fábrica". O primeiro é o uso da função padrão Comment(), que exibe o texto transmitido diretamente no gráfico. O segundo é o uso de outra função padrão, Print(), para exibir texto no diário dos EAs. Isso é bastante conveniente para tarefas simples.

No entanto, esses métodos apresentam uma série de limitações. O principal problema do primeiro é a ausência de controle sobre o tamanho, o estilo e a cor da fonte, bem como a impossibilidade de rolar o texto quando há um grande volume de informações. Isso gera inconvenientes, especialmente ao exibir dados multilinha ou estruturados. O segundo método apresenta os mesmos problemas, com exceção da rolagem, além do inconveniente adicional de alimentar constantemente os registros no diário.  

Por isso, no âmbito deste artigo, criaremos nosso próprio componente, uma janela de diálogo em tela cheia, capaz de exibir texto multilinha com configurações flexíveis de fonte e suporte a rolagem. Essa ferramenta tornará a visualização das informações mais conveniente e clara. Após o refinamento do uso desse componente, ele provavelmente passará a integrar a biblioteca Adwizard, como um meio de exibição de diversas informações sobre o funcionamento de EAs multimoeda.


Traçamos o caminho

Vamos listar os requisitos que gostaríamos de implementar:

  • Exibição de texto multilinha: ao componente é passado um texto totalmente formatado na forma de uma variável string, na qual podem aparecer caracteres de quebra de linha. Cada parte separada por caracteres de quebra de linha será exibida no gráfico em uma nova linha.

  • Rolagem de texto: se todo o texto não couber dentro da área disponível para exibição, será possível realizar rolagem vertical e horizontal, com a roda do mouse e com a tecla Shift pressionada no caso da rolagem horizontal. Por enquanto, não implementaremos a exibição de barras de rolagem, talvez as adicionemos posteriormente.

  • Alteração do tamanho da fonte: com a tecla Ctrl e a roda do mouse, será possível diminuir ou aumentar o tamanho da fonte utilizada para exibir o texto. 

  • Suporte à alteração dos parâmetros da fonte, isto é, estilo, cor do texto e cor de fundo. A alteração desses parâmetros, por enquanto, será realizada apenas de forma programática. No futuro, pode-se adicionar uma interface para modificar esses parâmetros com o programa em execução.

  • Adaptação automática à alteração do tamanho do gráfico: se o usuário realizar quaisquer ações que levem à mudança do tamanho da janela do gráfico no qual o EA que utiliza este componente está em execução, o tamanho da área de exibição do texto também será alterado, continuando a ocupar toda a área disponível para exibição.

  • Minimização: possibilidade de minimizar e maximizar a área de exibição.

É possível que, durante a implementação, ajustemos adicionalmente alguns requisitos, mas, em geral, a lista acima é totalmente suficiente.


Classe CConsoleDialog

Vamos criar uma nova classe, chamando-a de CConsoleDialog. Faremos dela uma herdeira da classe existente da biblioteca padrão CAppDialog, pois nessa classe pai já existe uma quantidade considerável do que planejamos implementar. Por exemplo, a exibição da janela com botões de minimizar, maximizar e fechar o aplicativo do EA já está pronta. Resta-nos cuidar do conteúdo interno da área cliente da janela, é justamente ali que o texto será exibido.

Para a exibição do texto, utilizaremos um objeto da classe CCanvas para desenhar o texto, enquanto o suporte à rolagem e à alteração do tamanho da fonte será implementado por meio do processamento de eventos do gráfico.

É assim que ficará a descrição da nova classe:

//+------------------------------------------------------------------+
//| Fullscreen dialog window class                                   |
//| to display multi-line text                                       |
//+------------------------------------------------------------------+
class CConsoleDialog : public CAppDialog {
protected:
   CCanvas           m_canvas;         // Canvas object for displaying text

   string            m_lines[];        // Array of text lines
   string            m_text;           // Text to display in the dialog window

   int               m_startRow;       // Initial line of visible text
   int               m_startCol;       // Starting column (symbol) of visible text

   int               m_totalRows;      // Total number of text lines
   int               m_totalCols;      // Total number of symbols in the longest line of text

   int               m_visibleRows;    // Maximum number of visible lines
   int               m_visibleCols;    // Maximum number of visible symbols in a line

   string            m_fontName;          // Text font name
   int               m_fontSize;          // Font size
   uint              m_fontColor;         // Font color

   int               m_fontSymbolWidth;   //  Width of one symbol in pixels
   int               m_fontSymbolHeight;  // Text line height in pixels

   uint              m_backgroundColor;   // Background color

   bool              m_mouseWheel;        // Previous state of mouse scroll event tracking

   bool              CreateCanvas();      // Create a canvas
   void              UpdateCanvas();      // Output text on canvas
   void              UpdateCanvasFont();  // Change the canvas font

public:
                     CConsoleDialog();       // Constructor
                    ~CConsoleDialog(void);   // Destructor

   // Methods for creating a dialog window
   bool              Create(string name);
   virtual bool      Create(const long chart, const string name, const int subwin,
                            const int x1, const int y1, const int x2, const int y2);
   // Event handling
   virtual void      ChartEvent(const int id, const long &lparam,
                                const double &dparam, const string &sparam);

   virtual void      Minimize();             // Minimize the dialog window
   virtual void      Maximize();             // Maximize the dialog window

   virtual void      Text(string text);      // Set the new text

   virtual void      FontName(string p_fontName);  // Set the font name
   virtual bool      FontSize(int p_fontSize);     // Set the font size
   virtual void      FontColor(uint p_fontColor);  // Set the font color

   // Set the background color
   virtual void      BackgroundColor(uint p_backgroundColor);
};

De todos os métodos públicos listados, por enquanto utilizaremos principalmente o método de definição de novo texto Text() e a primeira variante do método Create(), que permite criar a janela de diálogo informando apenas o seu nome. Esse mesmo nome será usado como legenda no título da janela. 


Construtor e destrutor

Ao criar um objeto da classe CConsoleDialog, o construtor inicializa a fonte padrão, isto é, uma fonte monoespaçada "Consolas" com tamanho 13, com a cor do texto definida como preta e com uma leve transparência. Essa fonte foi escolhida para permitir a exibição de dados tabulares em forma de texto, de modo que eles realmente se pareçam com tabelas, com colunas alinhadas de maneira uniforme. Caso a fonte não seja monoespaçada, não será possível obter tabelas alinhadas corretamente.

O tamanho da fonte de 13 pixels, por um lado, é pequeno o suficiente para exibir um grande volume de texto e, por outro, ainda não é tão pequeno a ponto de se tornar ilegível. Considerando a possibilidade planejada de alterar facilmente o tamanho, a escolha de um valor inicial específico não desempenha um papel fundamental. A cor de fundo é definida como transparente, portanto, através do canvas veremos a cor cinza padrão de fundo utilizada na classe CDialog.

Para a exibição correta, o método de definição do tamanho da fonte FontSize() é chamado imediatamente, pois ele determina os parâmetros básicos para o desenho do texto no canvas. Por sua vez, o destrutor é responsável pela remoção correta do recurso do canvas e pela restauração da configuração original de tratamento dos eventos de rolagem da roda do mouse no gráfico.

//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+
CConsoleDialog::CConsoleDialog() :
   m_fontName("Consolas"),
   m_fontSize(13),
   m_fontColor(ColorToARGB(clrBlack, 240)),
   m_backgroundColor(ColorToARGB(clrBlack, 0)) {
   FontSize(m_fontSize);
}

//+------------------------------------------------------------------+
//| Destructor                                                       |
//+------------------------------------------------------------------+
CConsoleDialog::~CConsoleDialog() {
// Delete the canvas
   m_canvas.Destroy();

// Return the previous mouse scroll event handling settings
   ChartSetInteger(m_chart_id, CHART_EVENT_MOUSE_WHEEL, (long)m_mouseWheel);
}


Criação da janela de diálogo

Para a criação da janela, existem duas variantes do método Create(). A primeira aceita apenas o nome da janela e define automaticamente a posição e o tamanho da janela para ocupar praticamente toda a área do gráfico, com uma pequena margem superior. Esse método calcula as dimensões do gráfico e chama a segunda variante do Create() com coordenadas específicas.

O segundo método permite criar a janela de diálogo com parâmetros definidos, isto é, o número do gráfico, o nome, o número da subjanela e as coordenadas. Nesse método, primeiro é chamada a implementação da classe pai para criar a janela, em seguida são definidos os tamanhos para o estado minimizado, o canvas é criado, o rastreamento dos eventos de rolagem do mouse é ativado e as posições da área visível do texto são inicializadas, para que a exibição comece desde o início.

//+------------------------------------------------------------------+
//| Method to create a dialog window by name only                    |
//+------------------------------------------------------------------+
bool CConsoleDialog::Create(string name) {
// Set the corner position and window size
   int x1 = 0;
   int y1 = DIALOG_VERTICAL_MARGIN;
   int y2 = (int) ChartGetInteger(0, CHART_HEIGHT_IN_PIXELS, 0);
   int x2 = (int) ChartGetInteger(0, CHART_WIDTH_IN_PIXELS, 0);

// Call the method for creating according to the given dimensions
   return Create(0, name, 0, x1, y1, x2, y2);
}

//+------------------------------------------------------------------+
//| Dialog window creation method                                    |
//+------------------------------------------------------------------+
bool CConsoleDialog::Create(const long chart, const string name, const int subwin, const int x1, const int y1, const int x2, const int y2) {
// Call the parent method to create the dialog
   if(!CAppDialog::Create(chart, name, subwin, x1, y1, x2, y2)) {
      return false;
   }

// Set the size of the minimized dialog window
   m_min_rect.SetBound(0, DIALOG_VERTICAL_MARGIN,
                       250, DIALOG_VERTICAL_MARGIN + CONTROLS_DIALOG_MINIMIZE_HEIGHT);

// Create a canvas
   if(!CreateCanvas()) {
      return false;
   }

// Save the previous mouse scroll event handling settings
   m_mouseWheel = ChartGetInteger(0, CHART_EVENT_MOUSE_WHEEL);

// Set up tracking mouse scroll events
   ChartSetInteger(chart, CHART_EVENT_MOUSE_WHEEL, 1);

// Set the initial text position in the window
   m_startRow = 0;
   m_startCol = 0;

   return true;
}

O valor da margem superior em relação à borda da janela do gráfico é definido pela constante DIALOG_VERTICAL_MARGIN. A presença dessa margem permite visualizar, na parte superior do gráfico, o nome do símbolo e o timeframe, bem como o nome do EA em execução. Ao clicar no nome do EA, é possível acessar rapidamente seus parâmetros. Se a janela de diálogo começasse a partir do topo absoluto do gráfico, essa possibilidade não existiria. Ainda assim, caso ela se mostre desnecessária, basta definir o valor da constante mencionada como 0, e então a janela de diálogo realmente passará a ocupar toda a área disponível do gráfico.


Processamento de eventos

O método ChartEvent() é responsável pelo processamento de diversos eventos do gráfico. Principalmente, trataremos os eventos de rolagem da roda do mouse (CHARTEVENT_MOUSE_WHEEL). Se a janela não estiver minimizada, ocorre a verificação das teclas pressionadas: com a tecla Shift pressionada, é realizada a rolagem horizontal do texto, caso ele exceda o intervalo visível em largura; sem teclas adicionais, ocorre a rolagem vertical quando há excesso em altura; e com a tecla Ctrl pressionada, é possível alterar o tamanho da fonte, escalonando o texto. No caso de alteração do tamanho do gráfico, o método adapta automaticamente as dimensões da janela, expandindo-a para toda a área disponível quando necessário. Todos os demais eventos são tratados na classe base CAppDialog.

//+------------------------------------------------------------------+
//| Event handling                                                   |
//+------------------------------------------------------------------+
void CConsoleDialog::ChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) {
// Handle the mouse wheel scroll event
   if(id == CHARTEVENT_MOUSE_WHEEL) {
      // If the dialog window is minimized, then we do not handle this event
      if(m_minimized) {
         return;
      }

      // Parse the state of the buttons and the mouse wheel for this event 
      int flg_keys = (int)(lparam >> 32);       // Flag of the states of the Ctrl, Shift keys and mouse buttons
      int delta    = (int)dparam;               // total value of the wheel scroll, 
                                                // triggered when +120 or -120 is reached

      // If the SHIFT key is pressed,
      if((flg_keys & 0x0004) != 0) {
         // If the number of symbols in the string is greater than the number of visible
         // symbols in the dialog, then we perform a horizontal shift
         if(m_totalCols > m_visibleCols) {
            // For one scroll event we will move by 2 symbols (120 / 60 = 2)
            delta /= 60;

            // If the new start position is within the allowed range,
            if(m_startCol - delta >= 0
                  && m_startCol - delta <= m_totalCols - m_visibleCols + 2) {
               // Save the new starting position
               m_startCol -= delta;

               // Update the canvas
               UpdateCanvas();
            }
         }
      } else if (flg_keys == 0) {
         // Otherwise, if the number of lines of text is greater than the number of visible
         // lines in the dialog, then we perform a vertical shift
         if(m_totalRows > m_visibleRows) {
            // For each scroll event we will move by 1 line (120 / 120 = 1)
            delta /= 120;

            // If the new start position is within the allowed range,
            if(m_startRow - delta >= 0
                  && m_startRow - delta <= m_totalRows - m_visibleRows + 1) {
               // Save the new starting position
               m_startRow -= delta;

               // Update the canvas
               UpdateCanvas();
            }
         }
      } else if((flg_keys & 0x0008) != 0) {
         // Otherwise, if the CTRL key is pressed, we try to set a new font size
         if(FontSize(m_fontSize + delta / 120)) {
            // Update the canvas
            UpdateCanvas();
         }
      }

      return;
   }

// Handle chart changing event
   if(id == CHARTEVENT_CHART_CHANGE) {
      // If the display size changed
      if(m_chart.HeightInPixels(m_subwin) != Height() + DIALOG_VERTICAL_MARGIN
            || m_chart.WidthInPixels() != Width()) {
         // Set new size for the dialog window
         m_norm_rect.SetBound(0, DIALOG_VERTICAL_MARGIN, m_chart.WidthInPixels(), m_chart.HeightInPixels(m_subwin));

         // If the dialog window is not minimized,
         if(!m_minimized) {
            // maximize it to fill the chart area with new dimensions 
            Maximize();
         }
         return;
      }
   }

// Handle other events in the parent class
   CAppDialog::ChartEvent(id, lparam, dparam, sparam);
}

Como neste diálogo não utilizamos componentes que sejam herdeiros da classe CWndObj, não podemos recorrer aos macros padrão para criar a função OnEvent(), na qual ocorre a vinculação dos eventos dos componentes do diálogo com suas funções manipuladoras. O componente CCanvas que utilizamos nos obriga a usar exclusivamente o manipulador geral de eventos do gráfico ChartEvent().


Minimização

Ao minimizar a janela pelo método Minimize(), o canvas é destruído, liberando os recursos utilizados. Em seguida, é chamada a implementação base para alterar o estado da janela. De forma semelhante, ao maximizar pelo método Maximize(), primeiro é chamado o método da classe pai, que expande a janela, após o que o canvas é criado e a exibição do texto é atualizada, garantindo a renderização correta considerando os novos tamanhos da área cliente.

//+------------------------------------------------------------------+
//| Minimize the dialog window                                       |
//+------------------------------------------------------------------+
void CConsoleDialog::Minimize() {
// Delete the canvas
   m_canvas.Destroy();

// Call the parent Minimize method
   CAppDialog::Minimize();
}

//+------------------------------------------------------------------+
//| Maximize the dialog window                                       |
//+------------------------------------------------------------------+
void CConsoleDialog::Maximize() {
// Call the parent Maximize method
   CAppDialog::Maximize();

// Create a canvas
   CreateCanvas();

// Display text on the canvas
   UpdateCanvas();
}

É possível que, no futuro, seja mais conveniente escrever uma classe de encapsulamento para o canvas, transformando-o em um herdeiro da classe CWndObj. Mas, por enquanto, essa abordagem também é plenamente suficiente.


Trabalho com texto

Para definir ou alterar o texto exibido, utiliza-se o método Text(). Ele verifica se o novo texto é diferente do atual. Em caso afirmativo, a string original é dividida em um array de strings pelo caractere de quebra de linha '\n'. Em seguida, é armazenada a quantidade de linhas e determinada a maior extensão da linha mais longa. Esses dados são necessários para a organização correta da rolagem e da exibição. Depois disso, é chamada a atualização do canvas para exibir o novo texto.

//+------------------------------------------------------------------+
//| Set a text                                                       |
//+------------------------------------------------------------------+
void CConsoleDialog::Text(string text) {
// If the text changes,
   if(text != m_text) {
      // Save the new text
      m_text = text;

      // Divide the text into lines
      StringSplit(m_text, '\n', m_lines);

      // Remember the number of lines
      m_totalRows = ArraySize(m_lines);

      // Define the maximum length of lines
      m_totalCols = 0;
      FOREACH(m_lines) {
         m_totalCols = MathMax(m_totalCols, StringLen(m_lines[i]));
      }

      // Display text on the canvas
      UpdateCanvas();
   }
}


Configuração de fonte e cor

O método FontName() permite definir o nome da fonte utilizada para a exibição do texto e atualiza as configurações do canvas de acordo.

A alteração do tamanho da fonte é implementada no método FontSize(), que recebe um novo valor e verifica se ele está dentro de limites razoáveis, de 8 a 72. Em caso de alteração bem-sucedida, a posição de rolagem é redefinida para o início do texto, e os parâmetros da fonte do canvas são atualizados conforme o novo tamanho. Além disso, para o novo tamanho são calculados e armazenados os valores de largura e altura de um único caractere, necessários para o cálculo correto da parte visível do texto.

O método FontColor() permite definir a cor da fonte.

//+------------------------------------------------------------------+
//| Set the font name                                                |
//+------------------------------------------------------------------+
void CConsoleDialog::FontName(string p_fontName) {
// Save the new font name
   m_fontName = p_fontName;

// Update the canvas font
   UpdateCanvasFont();
}

//+------------------------------------------------------------------+
//| Set the font size                                                |
//+------------------------------------------------------------------+
bool CConsoleDialog::FontSize(int p_fontSize) {
// If the size is within reasonable limits,
   if (p_fontSize >= 8 && p_fontSize <= 72) {
      // Save the new font size
      m_fontSize = p_fontSize;

      // Reset the starting row and column
      m_startRow = 0;
      m_startCol = 0;

      // Update the canvas font
      UpdateCanvasFont();

      return true;
   }

   return false;
}

//+------------------------------------------------------------------+
//| Set the font color                                               |
//+------------------------------------------------------------------+
void CConsoleDialog::FontColor(uint p_fontColor) {
   m_fontColor = p_fontColor;
}


Trabalho com canvas

A criação do canvas é responsabilidade do método CreateCanvas(), que inicializa o objeto CCanvas com os tamanhos da área cliente da janela de diálogo e define o formato de cor com canal alfa. Em caso de criação bem-sucedida do canvas, a fonte e os parâmetros dos caracteres são definidos imediatamente. O método UpdateCanvas() é responsável pela renderização direta do texto no canvas: ele limpa o fundo e, em seguida, exibe as linhas visíveis, levando em conta as posições atuais de rolagem por linhas e por caracteres. Para cada linha visível, o início da string é truncado quando necessário, e o texto é exibido com pequenos recuos em relação às bordas. Após a conclusão da renderização, é chamada a atualização do canvas para que as alterações se tornem visíveis ao usuário.

Por fim, o método UpdateCanvasFont() atualiza os parâmetros da fonte no canvas, calcula as dimensões de um único caractere com base na letra "M" e determina quantas linhas e quantos caracteres podem ser acomodados nos tamanhos atuais da janela, o que é necessário para a organização da rolagem.

//+------------------------------------------------------------------+
//| Create a canvas                                                  |
//+------------------------------------------------------------------+
bool CConsoleDialog::CreateCanvas() {
// Get the dimensions of the dialog window client area
   int height = ClientAreaHeight();
   int width = ClientAreaWidth();

// If the size is non-zero
   if(height > 0 && width > 0) {
      // If an error occurred while creating the canvas, then exit
      if(!m_canvas.CreateBitmapLabel("display",
                                     ClientAreaLeft(),
                                     ClientAreaTop(),
                                     ClientAreaWidth(),
                                     ClientAreaHeight(),
                                     COLOR_FORMAT_ARGB_NORMALIZE)) {
         PrintFormat(__FUNCTION__" | ERROR: Creating canvas %d", GetLastError());
         return false;
      }

      UpdateCanvasFont();
   }

   return true;
}

//+------------------------------------------------------------------+
//| Display text on canvas                                           |
//+------------------------------------------------------------------+
void CConsoleDialog::UpdateCanvas() {
// Erase the canvas with the background color
   m_canvas.Erase(m_backgroundColor);

// For each line that falls within the visible range
   for (int i = m_startRow; i < MathMin(m_totalRows, m_startRow + m_visibleRows); i++) {
      // Take the next line of text
      string line = m_lines[i];

      // If it should be shown not from the first symbol, then
      if (m_startCol > 0) {
         // Cut out the initial symbols
         line = StringSubstr(line, m_startCol);
      }

      // Display the string on the canvas
      m_canvas.TextOut(5, 5 + (i - m_startRow) * m_fontSymbolHeight, line, m_fontColor, TA_LEFT | TA_TOP);
   }

// Call the method to draw the canvas on the screen
   m_canvas.Update(true);
}

//+------------------------------------------------------------------+
//| Change the canvas font                                           |
//+------------------------------------------------------------------+
void CConsoleDialog::UpdateCanvasFont() {
// Set font parameters for text output on canvas
   m_canvas.FontSet(m_fontName, m_fontSize);

// Set new sizes of one symbol
   m_canvas.TextSize("M", m_fontSymbolWidth, m_fontSymbolHeight);

// Determine the number of visible lines and symbols per line (columns)
   m_visibleRows = ClientAreaHeight() / m_fontSymbolHeight;
   m_visibleCols = ClientAreaWidth() / m_fontSymbolWidth;
}

Vamos salvar o código obtido no arquivo ConsoleDialog.mqh na pasta do projeto e verificar quais alterações precisam ser feitas no arquivo do EA informador para conectar o componente desenvolvido.


Conectamos o componente

Para exibir texto no gráfico utilizando o novo componente, abrimos o arquivo do EA informador. Antes de tudo, conectamos o arquivo de biblioteca criado:

#include "ConsoleDialog.mqh"

Em seguida, criamos um objeto global do diálogo:

CConsoleDialog *dialog;

No método Init(), antes do início dos cálculos e da exibição, adicionamos os comandos de criação e inicialização do diálogo:

//+------------------------------------------------------------------+
//| Initialize the EA                                                |
//+------------------------------------------------------------------+
int OnInit(void) {
// ...

// Create and launch a dialog to display the results
   dialog = new CConsoleDialog();
   dialog.Create("Symbols Informer");
   dialog.Run();

// Perform a forced recalculation
   Calculate(true);

// Show the results
   Show();

   return(INIT_SUCCEEDED);
}

E, por fim, na função Show() substituímos a chamada da função Comment() pela definição do texto com os resultados para o nosso diálogo:

//+------------------------------------------------------------------+
//| Show results                                                     |
//+------------------------------------------------------------------+
void Show() {
// Get the results as text
   string text = TextComment();

// Show it on the chart in the dialog window
   dialog.Text(text);
}

Salvamos as alterações realizadas no arquivo SymbolsInformer.mq5 na pasta do projeto.


Teste

Executamos o EA informador com os parâmetros padrão. Como agora tanto a rolagem quanto a alteração do tamanho do texto funcionam, é possível escolher com tranquilidade o tamanho mais confortável e a área visível desejada dos resultados.

Se nos interessarem, por exemplo, apenas os dados sobre o tamanho médio das velas para EURUSD M30, podemos configurar essa exibição aumentando o tamanho da fonte:

Se, por outro lado, quisermos ver imediatamente todos os valores para GBPUSD e EURGBP, podemos reduzir novamente o tamanho da fonte e rolar o texto para baixo:

O componente desenvolvido pode ser facilmente adaptado para uso em EAs já prontos, nos quais não é utilizada uma interface gráfica, e todas as informações são exibidas no gráfico na forma de texto.

Por exemplo, em um artigo recente, Arbitragem Forex: sistema de negociação matricial para retorno ao valor justo com limitação de risco, o autor apresenta justamente um exemplo desse tipo de EA:

Ao introduzir pequenas alterações em seu código-fonte, descritas na seção sobre a conexão do componente, obtemos o seguinte resultado:

Dessa forma, a percepção das informações torna-se muito mais conveniente e agradável.


Conclusão

Assim, aprimoramos um pouco a primeira versão do EA informador auxiliar, que exibe informações sobre os tamanhos médios das velas em pontos e os comprimentos das séries de velas consecutivas na mesma direção. Paralelamente, desenvolvemos um componente que pode ser útil em muitos outros EAs.

No entanto, por enquanto, tanto a parte de cálculo quanto a exibição dos resultados ficam a cargo de um único EA. Na próxima vez, tentaremos separar essas duas partes para garantir maior flexibilidade. Esse mesmo enfoque planejamos aplicar posteriormente também ao EA multimoeda de negociação.

Obrigado pela atenção e até a próxima!


Aviso importante

Todos os resultados apresentados neste artigo e em todos os artigos anteriores deste ciclo baseiam-se exclusivamente em dados de testes em histórico e não constituem garantia de qualquer tipo de rentabilidade futura. O trabalho realizado no âmbito deste projeto tem caráter de pesquisa. Todos os resultados publicados podem ser utilizados livremente por qualquer interessado, por sua própria conta e risco.


Conteúdo do arquivo compactado

#
Nome Versão Descrição Últimas alterações
  SymbolsInformer   Pasta de trabalho do projeto  
1 SymbolsInformer.mq5 1.01
EA para exibir informações sobre os comprimentos de séries de velas consecutivas na mesma direção
Parte 27
2 CConsoleDialog.mqh 1.00   Parte 27
3 AbbyCross.mq5 Exemplo de arquivo de EA de terceiros com a classe CConsoleDialog conectada
  SymbolsInformer/Include/Adwizard/Utils
  Utilitários auxiliares e macros para redução de código  
4 Macros.mqh
1.07 Macros úteis para operações com arrays
Parte 26
5 NewBarEvent.mqh  1.00 Classe para detecção de novo candle para um símbolo específico Parte 8
Além disso, o código-fonte também está disponível nos repositórios públicos SymbolsInformer e Adwizard.

Traduzido do russo pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/ru/articles/17883

Arquivos anexados |
MQL5.zip (19 KB)
Mineração de dados dos balanços dos bancos centrais e obtenção de um panorama da liquidez global Mineração de dados dos balanços dos bancos centrais e obtenção de um panorama da liquidez global
A mineração de dados dos balanços dos bancos centrais permite obter um panorama da liquidez global do mercado Forex e das principais moedas. Nós unificamos dados do Fed, do BCE, do BOJ e do PBoC em um índice composto e aplicamos aprendizado de máquina para identificar padrões ocultos. Essa abordagem transforma um fluxo bruto de dados em sinais reais de trading, conectando a análise fundamentalista e a análise técnica.
Indicador do modelo CAPM no mercado Forex Indicador do modelo CAPM no mercado Forex
Adaptação do modelo clássico CAPM para o mercado cambial Forex em MQL5. O indicador calcula a rentabilidade esperada e o prêmio de risco com base na volatilidade histórica. Os indicadores aumentam nos picos e nas depressões, refletindo os princípios fundamentais de precificação. Aplicação prática para estratégias contra a tendência e de seguimento de tendência, levando em conta a dinâmica da relação entre risco e rentabilidade em tempo real. Inclui o aparato matemático e a implementação técnica.
Mineração de dados da CFTC em Python e modelo de IA com base neles Mineração de dados da CFTC em Python e modelo de IA com base neles
Vamos tentar minerar dados da CFTC, carregar os relatórios COT e TFF via Python, conectar isso às cotações do MetaTrader 5 e a um modelo de IA e obter previsões. O que são os relatórios COT no mercado Forex? Como usar os relatórios COT e TFF para previsão?
Redes neurais em trading: Extração eficiente de características para classificação precisa (Construção de objetos) Redes neurais em trading: Extração eficiente de características para classificação precisa (Construção de objetos)
Mantis é uma ferramenta universal para análise profunda de séries temporais, escalável de forma flexível para quaisquer cenários financeiros. Saiba como a combinação de patching, convoluções locais e atenção cruzada permite obter uma interpretação de alta precisão dos padrões de mercado.