Desenvolvendo um EA multimoeda (Parte 27): Componente para exibição de texto multilinha
Conteúdo
- Introdução
- Traçamos o caminho
- Classe CConsoleDialog
- Construtor e destrutor
- Criação da janela de diálogo
- Processamento de eventos
- Minimização
- Trabalho com texto
- Configuração de fonte e cor
- Trabalho com canvas
- Conectamos o componente
- Teste
- Conclusão
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 |
Traduzido do russo pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/ru/articles/17883
Aviso: Todos os direitos sobre esses materiais pertencem à MetaQuotes Ltd. É proibida a reimpressão total ou parcial.
Esse artigo foi escrito por um usuário do site e reflete seu ponto de vista pessoal. A MetaQuotes Ltd. não se responsabiliza pela precisão das informações apresentadas nem pelas possíveis consequências decorrentes do uso das soluções, estratégias ou recomendações descritas.
Mineração de dados dos balanços dos bancos centrais e obtenção de um panorama da liquidez global
Indicador do modelo CAPM no mercado Forex
Mineração de dados da CFTC em Python e modelo de IA com base neles
Redes neurais em trading: Extração eficiente de características para classificação precisa (Construção de objetos)
- 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