Criando um Painel Administrativo de Trading em MQL5 (Parte X): Interface baseada em recursos externos
Conteúdo:
Introdução
Tenho certeza de que encontrar um ponto de partida é sempre um desafio. No entanto, depois de criar um primeiro esboço, fica mais fácil partir dele e descobrir novas possibilidades. Muitos designers e desenvolvedores de sucesso começam com esboços simples e aprimoram seus projetos gradualmente, até chegarem a um resultado realmente atraente. Mesmo quando acreditamos ter chegado à versão definitiva de um produto, sempre há espaço para novos aprimoramentos. A evolução é um processo contínuo, e cada nova versão deve trazer algo diferente em relação à anterior.
Nesta série de desenvolvimento, começamos com um programa monolítico do Painel de Administração, composto por várias interfaces. Quando o código ficou extenso demais e difícil de manter, passamos a organizá-lo melhor utilizando a biblioteca padrão do MQL5, herança de classes e arquivos de cabeçalho personalizados. Essa abordagem nos permitiu trabalhar em partes específicas do programa sem interferir nas demais, reduzindo significativamente a possibilidade de erros e facilitando futuras expansões — limitadas apenas pela criatividade do desenvolvedor. Hoje, iniciamos um novo ciclo, começando pelo painel inicial.
Na minha opinião, os símbolos estão entre as formas mais eficientes de comunicação visual, pois são capazes de transmitir informações detalhadas de maneira imediata e ocupando pouquíssimo espaço. Ao longo da história, os símbolos desempenharam um papel fundamental na comunicação humana. Muito antes da invenção da linguagem escrita, as primeiras civilizações já utilizavam pictogramas e glifos para representar ideias, emoções e instruções. Dos antigos hieróglifos egípcios aos atuais emojis, os símbolos continuam sendo uma forma visual universal e concisa de comunicação, capaz de superar barreiras linguísticas.
No mundo digital, essa tradição continua presente. Um bom exemplo é a fonte Wingdings — uma coleção de símbolos incorporados ao texto que permite transmitir significados sem a necessidade de palavras. No desenvolvimento em MQL5, símbolos desse tipo são extremamente úteis, pois possuem boa documentação e são fáceis de implementar. Seu uso pode reduzir significativamente a quantidade de objetos visuais exibidos no gráfico, sem comprometer a clareza e a elegância das informações apresentadas. Um sinal de "Compra", por exemplo, pode ser representado por uma simples seta apontando para cima em vez de um rótulo de texto completo, economizando espaço na tela e recursos de processamento.
Meu foco aqui está no design e no gerenciamento das áreas da interface. Ao incorporar elementos simbólicos, podemos reduzir a poluição visual e melhorar a usabilidade. Os Wingdingssão uma das opções disponíveis, mas também quero destacar o uso de imagens bitmap personalizadas. Essas imagens podem substituir botões grandes sem comprometer sua funcionalidade, oferecendo uma alternativa mais elegante e eficiente para manter a interface limpa e envolvente.
Embora a interface principal do New_Admin_Panel já tenha alcançado os resultados funcionais esperados, seu aspecto visual ainda pode ser aprimorado. Agora que a estrutura fundamental está pronta, chegou o momento de aperfeiçoar e melhorar o design da interface. Na próxima seção, apresentarei uma visão geral dos objetivos desta etapa de desenvolvimento e de como pretendemos avançar nesse processo de evolução.
Visão Geral da Discussão
O objetivo de hoje está concentrado na interface principal, que será reorganizada e redesenhada para criar um painel mais compacto e visualmente eficiente. Começaremos apresentando o design conceitual da nova interface principal e seus componentes. Em seguida, faremos sua implementação em MQL5, integrando novos recursos e compilando a versão aprimorada do Admin Panel. Uma imagem de referência foi incluída abaixo para ajudar a visualizar a direção que seguiremos.
Anteriormente, mencionei o Wingdings como um ótimo exemplo de comunicação por meio de símbolos, oferecendo elementos visuais capazes de transmitir informações de maneira rápida e simples. Embora seja uma excelente referência para ícones minimalistas, não pretendo utilizá-lo diretamente. Em vez disso, estou considerando imagens bitmap personalizadas, desenvolvidas especificamente para combinar melhor com os objetivos estéticos e funcionais da nossa nova interface. Ferramentas como o GIMP, um editor de imagens de código aberto, são excelentes para criar esses elementos gráficos personalizados.
Assim que as imagens personalizadas estiverem prontas, passaremos à programação de suas funcionalidades e à integração com os recursos existentes no programa. Esses elementos visuais nos permitirão substituir botões grandes por ícones mais leves e compactos, ajudando a reduzir a poluição visual sem comprometer nenhuma funcionalidade.
Como parte deste ciclo de desenvolvimento, também desativaremos temporariamente a autenticação do usuário para facilitar os testes e evitar solicitações constantes de login. Embora a segurança não seja estritamente necessária para o painel nesta etapa, ela se torna importante caso a ferramenta seja utilizada em ambientes nos quais acessos não autorizados possam comprometer operações sensíveis. Embora implementações anteriores tenham usado valores fixos no código para a criptografia de chaves, recomenda-se que os desenvolvedores deem esse passo adicional em direção a um gerenciamento de acesso mais seguro, se necessário.
Esta etapa mostrará como trabalhar com recursos visuais personalizados no MQL5, desde a concepção até a implementação. Ao final, nosso objetivo é obter uma interface aprimorada, responsiva e escalável, que não apenas funcione bem, mas também apresente um visual limpo e moderno.

Esboço da nova interface principal minimizada (56px por 400px)
Design Conceitual
Com esse conceito em mente — e como não encontrei nenhuma opção de símbolo satisfatória entre os recursos disponíveis — decidi criar meus próprios elementos, utilizando ferramentas de código aberto para ter maior flexibilidade e liberdade de personalização. Utilizei o Inkscape para criar rapidamente os designs, pois ele é um dos editores de gráficos vetoriais mais completos e eficientes disponíveis. No entanto, o Inkscape apresenta algumas limitações na exportação para determinados formatos de arquivo.
Para contornar essa limitação, utilizei o GIMP para aprimorar as imagens e exportá-las no formato bitmap desejado, adequado para integração com o MQL5. Abaixo, você encontrará o layout conceitual da interface. Depois de analisarmos o design, detalharemos a função de cada botão e, em seguida, passaremos para a etapa de implementação no código.

Layout conceitual da interface AdminHome
Descrição dos botões da interface principal e suas funções
Botão Recolher e Expandir:
Este botão possui dois estados: um para expandir a interface, tornando todos os seus botões visíveis, e outro para recolhê-la, ocultando todos os botões.
Expandir
Recolher
Botão do Painel de Gerenciamento de Operações:
Utilizamos dois ícones de seta para representar visualmente as ações de compra e venda. Dessa forma, o usuário consegue identificar de maneira rápida e intuitiva a finalidade do botão.
Botão do Painel de Gerenciamento de Operações
Botão do Painel de Gerenciamento de Operações Pressionado
Botões do Painel de Comunicação:
Para este botão, criei o símbolo de um envelope para representar a função de comunicação. Por ser um ícone bastante conhecido, o usuário consegue reconhecer rapidamente sua finalidade e compreender sua função de forma intuitiva.
Botão do Painel de Comunicação
Botão do Painel de Comunicação Pressionado
Botão do Painel de Análises:
Este botão utiliza o símbolo de um gráfico para representar a função de análise. Como os gráficos são ferramentas essenciais para a análise de mercado, o ícone permite que o usuário identifique imediatamente a finalidade do botão.
Botão do Painel de Análises
Botão do Painel de Análises Pressionado
Botão para exibir ou ocultar todos os painéis:
Este botão funciona como um atalho prático para expandir ou recolher todos os painéis de uma só vez. Seu design utiliza setas apontando em direções opostas, representando uma visualização expandida ou mais ampla e comunicando visualmente sua função ao usuário.
Botão Exibir/Ocultar Todos
Botão Exibir/Ocultar Todos Pressionado
Dica:
Para que as imagens funcionassem corretamente no MetaTrader 5, precisei exportá-las no formato BMP utilizando o GIMP, especificamente com a configuração de 24 bits. Qualquer outro formato utilizado não foi exibido corretamente no terminal. As imagens apresentadas acima estão no formato PNG apenas para fins de ilustração. Os arquivos BMP utilizados no projeto estão disponíveis na pasta anexada ao final deste artigo.
Implementação do Código
Agora, começaremos a trabalhar com o código MQL5 para transformar em realidade o conceito apresentado acima. Esta etapa representa uma evolução da interface, passando da estrutura anterior para um design mais refinado e criativo, à medida que continuamos aprimorando nosso painel administrativo. Ao final, teremos uma nova interface principal, conforme ilustrado na imagem abaixo.

Migração da antiga interface principal para uma nova interface baseada em recursos externos
Como mencionado anteriormente, estamos desativando temporariamente o recurso de autenticação para evitar interrupções causadas pelas solicitações de login durante os testes. É importante destacar que isso não significa remover completamente a lógica de autenticação. Em vez disso, apenas comentaremos o código correspondente. Lembre-se de que os comentários inseridos no código não são executados; eles servem para facilitar a comunicação entre os desenvolvedores e explicar a lógica do programa em linguagem simples.
Nesta etapa, também demonstraremos como as imagens personalizadas que preparamos serão utilizadas como recursos e exibidas como botões flutuantes na interface principal. Isso representa uma mudança em relação ao uso da classe Dialog na interface do Home Panel. O novo design é mais simples e minimalista.
Agora, vamos analisar a estrutura do nosso programa principal.
1. Visão Geral
Nesta seção, nosso objetivo é transformar um painel administrativo básico em uma interface moderna e flutuante utilizando imagens BMP como botões. A proposta é criar uma interface na qual os botões, exibidos como imagens, possam alternar entre diferentes estados — por exemplo, "expandido" e "recolhido" — proporcionando um design visualmente atraente e interativo. Esses botões ficam posicionados acima de outros elementos do gráfico, como os candlesticks, garantindo uma interação mais fluida com o usuário.
Incluímos módulos externos para autenticação, além dos módulos de comunicação, Telegram, controles de diálogo, gerenciamento de operações e análises, embora a própria lógica de autenticação esteja temporariamente desativada por meio de comentários no código. Essa decisão é temporária, pois essa funcionalidade ainda está em desenvolvimento e, dessa forma, podemos nos concentrar na criação e nos testes da interface de botões flutuantes sem interrupções causadas pelas solicitações de senha. Posteriormente, poderemos reativar o código de autenticação com poucas alterações, permitindo uma transição simples para um sistema totalmente protegido.
//+------------------------------------------------------------------+ //| New_Admin_Panel.mq5| //| Copyright 2024, Clemence Benjamin | //| https://www.mql5.com/en/users/billionaire2024/seller | //+------------------------------------------------------------------+ #property copyright "Copyright 2024, Clemence Benjamin" #property link "https://www.mql5.com/en/users/billionaire2024/seller" #property version "1.00" // Authentication inputs (unused; authentication disabled). input string AuthPassword = "2024"; input string TwoFactorChatID = "YOUR_CHAT_ID"; input string TwoFactorBotToken = "YOUR_BOT_TOKEN"; #include <Authentication.mqh> #include <CommunicationsDialog.mqh> #include <Telegram.mqh> #include <Controls\Dialog.mqh> #include <TradeManagementPanel.mqh> #include <AnalyticsPanel.mqh>
2. Recursos de Arquivo no MQL5
O MQL5 permite incorporar arquivos externos — como imagens e sons — diretamente ao programa por meio de diretivas de recursos. Neste projeto, utilizamos arquivos de imagem BMP como recursos para criar botões personalizados. Ao incorporar esses arquivos de imagem por meio de declarações de recursos, eles passam a fazer parte do arquivo executável, garantindo que estejam sempre disponíveis durante a execução do programa. Essa técnica é fundamental para criar uma interface confiável e portátil, pois garante acesso consistente aos recursos visuais necessários, independentemente do sistema de arquivos externo.
#resource "\\Images\\expand.bmp" #resource "\\Images\\collapse.bmp" #resource "\\Images\\TradeManagementPanelButton.bmp" #resource "\\Images\\TradeManagementPanelButtonPressed.bmp" #resource "\\Images\\CommunicationPanelButton.bmp" #resource "\\Images\\CommunicationPanelButtonPressed.bmp" #resource "\\Images\\AnalyticsPanelButton.bmp" #resource "\\Images\\AnalyticsPanelButtonPressed.bmp" #resource "\\Images\\ShowAllHideAllButton.bmp" #resource "\\Images\\ShowAllHideAllButtonPressed.bmp"
3. Criação da Interface e Projeto dos Botões
A interface é construída utilizando objetos "bitmap label" que exibem imagens BMP. Cada botão da interface é representado por um desses objetos de imagem, e suas posições no gráfico são definidas por coordenadas predeterminadas. Um valor elevado de Z-order é atribuído a esses objetos para garantir que sejam exibidos sobre os demais elementos do gráfico, tornando-os altamente responsivos aos cliques do usuário. Essa configuração garante que os botões flutuantes sejam não apenas visualmente atraentes, mas também robustos e confiáveis.
// Button names string toggleButtonName = "ToggleButton"; string tradeButtonName = "TradeButton"; string commButtonName = "CommButton"; string analyticsButtonName = "AnalyticsButton"; string showAllButtonName = "ShowAllButton"; // Button original positions const int BUTTON_TOGGLE_X = 10; const int BUTTON_TOGGLE_Y = 30; const int BUTTON_TRADE_X = 10; const int BUTTON_TRADE_Y = 100; const int BUTTON_COMM_X = 10; const int BUTTON_COMM_Y = 170; const int BUTTON_ANALYTICS_X = 10; const int BUTTON_ANALYTICS_Y = 240; const int BUTTON_SHOWALL_X = 10; const int BUTTON_SHOWALL_Y = 310;
4. Técnica para Ocultar e Exibir Botões
Funções auxiliares são utilizadas para mover os botões para uma coordenada específica fora da área visível da tela, simulando um efeito de recolhimento. Quando a interface é expandida, outro conjunto de funções auxiliares restaura os botões às suas posições originais na tela. Essa técnica oferece uma forma eficiente e responsiva de gerenciar a visibilidade dos elementos da interface do usuário.
// Off-screen coordinate for hiding buttons const int HIDDEN_X = -50; // Hide a button by moving it off-screen. void HideButton(string buttonName) { ObjectSetInteger(0, buttonName, OBJPROP_XDISTANCE, HIDDEN_X); } // Restore a button to its original position. void ShowButton(string buttonName, int X, int Y) { ObjectSetInteger(0, buttonName, OBJPROP_XDISTANCE, X); ObjectSetInteger(0, buttonName, OBJPROP_YDISTANCE, Y); }
5. Gerenciamento das Interações com os Subpainéis
Cada botão da interface está vinculado a um subpainel, como gerenciamento de operações, comunicação ou análises. Quando um botão é clicado, o subpainel correspondente é criado, caso ainda não exista, ou alternado entre os estados visível e oculto. Essa criação sob demanda reduz o uso de recursos e mantém a interface organizada. Cada subpainel é gerenciado de forma independente, permitindo que o usuário trabalhe com uma seção por vez e, ao mesmo tempo, tenha acesso às demais sempre que necessário.
// Handle the Communications Panel button. void HandleCommunications() { if(g_commPanel != NULL && g_commPanel.IsVisible()) { g_commPanel.Hide(); ChartRedraw(); return; } if(g_commPanel == NULL) { g_commPanel = new CCommunicationDialog(TwoFactorChatID, TwoFactorBotToken); if(!g_commPanel.Create(g_chart_id, "CommPanel", g_subwin, 80, 100, 380, 300)) { delete g_commPanel; g_commPanel = NULL; return; } ObjectSetInteger(0, "CommPanel", OBJPROP_ZORDER, 10); } g_commPanel.Toggle(); ChartRedraw(); } // Handle the Trade Management Panel button. void HandleTradeManagement() { if(g_tradePanel != NULL && g_tradePanel.IsVisible()) { g_tradePanel.Hide(); ChartRedraw(); return; } if(g_tradePanel == NULL) { g_tradePanel = new CTradeManagementPanel(); if(!g_tradePanel.Create(g_chart_id, "TradeManagementPanel", g_subwin, 390, 20, 900, 530)) { delete g_tradePanel; g_tradePanel = NULL; return; } ObjectSetInteger(0, "TradeManagementPanel", OBJPROP_ZORDER, 10); } g_tradePanel.Toggle(); ChartRedraw(); } // Handle the Analytics Panel button. void HandleAnalytics() { if(g_analyticsPanel != NULL && g_analyticsPanel.IsVisible()) { g_analyticsPanel.Hide(); ChartRedraw(); return; } if(g_analyticsPanel == NULL) { g_analyticsPanel = new CAnalyticsPanel(); if(!g_analyticsPanel.CreatePanel(g_chart_id, "AnalyticsPanel", g_subwin, 980, 20, 1480, 480)) { delete g_analyticsPanel; g_analyticsPanel = NULL; return; } ObjectSetInteger(0, "AnalyticsPanel", OBJPROP_ZORDER, 10); } g_analyticsPanel.Toggle(); ChartRedraw(); }
6. Encapsulamento da Lógica de Alternância entre Recolher e Expandir
Para simplificar o gerenciamento da interface do usuário, a lógica de recolhimento e expansão é encapsulada em uma única função. Essa função verifica o estado atual do botão principal de alternância, modifica esse estado e, em seguida, oculta os demais botões ou restaura suas posições. Encapsular essa lógica em uma única função evita redundâncias no código de tratamento de eventos e torna o design geral mais organizado e fácil de manter.
// Toggle collapse/expand of interface buttons. void ToggleInterface() { // Toggle the state of the toggle button. bool currentState = ObjectGetInteger(0, toggleButtonName, OBJPROP_STATE); bool newState = !currentState; ObjectSetInteger(0, toggleButtonName, OBJPROP_STATE, newState); if(newState) UpdateButtonVisibility(false); // Collapse: hide buttons and minimize sub-panels. else UpdateButtonVisibility(true); // Expand: restore button positions. ChartRedraw(); }
7. Inicialização do Programa
Testes detalhados são essenciais para garantir que a interface se comporte conforme o esperado. A função de inicialização configura os botões e garante que eles estejam visíveis desde o início. Durante os testes, é importante verificar se os botões continuam respondendo corretamente, se os subpainéis alternam adequadamente entre os estados visível e oculto e se os botões permanecem sempre acima dos elementos do gráfico graças aos valores elevados de Z-order. Além disso, embora a autenticação esteja atualmente desativada, o código correspondente permanece incluído como comentário, facilitando a reativação das restrições de acesso quando necessário. Aprimoramentos futuros podem incluir a integração de sons ou animações para enriquecer ainda mais a experiência do usuário.
// Expert initialization function int OnInit() { g_chart_id = ChartID(); g_subwin = 0; // For potential future use, authentication can be re-enabled by uncommenting these: // if(!g_authManager.Initialize()) // return INIT_FAILED; // Create main toggle and sub-panel buttons using their original positions. CreateObjectBITMAP_LABEL(toggleButtonName, BUTTON_TOGGLE_X, BUTTON_TOGGLE_Y, "::Images\\expand.bmp", "::Images\\collapse.bmp"); CreateObjectBITMAP_LABEL(tradeButtonName, BUTTON_TRADE_X, BUTTON_TRADE_Y, "::Images\\TradeManagementPanelButtonPressed.bmp", "::Images\\TradeManagementPanelButton.bmp"); CreateObjectBITMAP_LABEL(commButtonName, BUTTON_COMM_X, BUTTON_COMM_Y, "::Images\\CommunicationPanelButtonPressed.bmp", "::Images\\CommunicationPanelButton.bmp"); CreateObjectBITMAP_LABEL(analyticsButtonName, BUTTON_ANALYTICS_X, BUTTON_ANALYTICS_Y, "::Images\\AnalyticsPanelButtonPressed.bmp", "::Images\\AnalyticsPanelButton.bmp"); CreateObjectBITMAP_LABEL(showAllButtonName, BUTTON_SHOWALL_X, BUTTON_SHOWALL_Y, "::Images\\ShowAllHideAllButtonPressed.bmp", "::Images\\ShowAllHideAllButton.bmp"); // Always show the interface initially. UpdateButtonVisibility(true); ChartRedraw(); return INIT_SUCCEEDED; } // Expert deinitialization function void OnDeinit(const int reason) { ObjectDelete(0, toggleButtonName); ObjectDelete(0, tradeButtonName); ObjectDelete(0, commButtonName); ObjectDelete(0, analyticsButtonName); ObjectDelete(0, showAllButtonName); if(g_commPanel != NULL) { g_commPanel.Destroy(reason); delete g_commPanel; g_commPanel = NULL; } if(g_tradePanel != NULL) { g_tradePanel.Destroy(reason); delete g_tradePanel; g_tradePanel = NULL; } if(g_analyticsPanel != NULL) { g_analyticsPanel.Destroy(reason); delete g_analyticsPanel; g_analyticsPanel = NULL; } }
Testes
Como de costume no MetaTrader 5, você pode iniciar o programa simplesmente arrastando-o da lista de Expert Advisors para um gráfico. Para garantir que a compilação e a execução ocorram corretamente, é essencial que todos os módulos externos estejam armazenados em suas respectivas pastas e que todos os recursos necessários — como as imagens — estejam devidamente organizados.
Abaixo, incluí uma imagem que apresenta o resultado da nossa interface redesenhada. A partir dessa visualização, é possível compreender claramente a direção que estamos seguindo e identificar pontos que ainda podem ser aprimorados.

Testando a Interface New_Admin_Home
Dica:
Ao utilizar o novo botão pela primeira vez após adicionar o programa ao gráfico, o primeiro clique inicializa o painel correspondente, mas ele não é exibido imediatamente. O painel se torna visível somente após o segundo clique.
Conclusão
Hoje, exploramos como utilizar recursos externos de maneira eficiente para criar uma interface de usuário poderosa e personalizável no MQL5. Neste projeto, evoluímos de uma interface principal básica para um sistema de painéis flutuantes mais dinâmico e visualmente atraente, preservando as principais funcionalidades e incorporando novos recursos para melhorar a usabilidade e a acessibilidade.
Um dos principais aprendizados deste desenvolvimento é a ampliação da nossa compreensão sobre os recursos oferecidos pelo MQL5, especialmente em relação ao uso de elementos gráficos, como imagens BMP. O design com botões flutuantes oferece acesso centralizado às funcionalidades do painel administrativo e, ao mesmo tempo, mantém o gráfico organizado, preservando uma área maior da tela para a visualização das informações relevantes para o trading.
É importante lembrar que nenhuma solução é realmente perfeita. No entanto, cada nova versão — cada avanço — nos aproxima de uma solução melhor e mais eficiente. As versões anteriores continuam sendo importantes, pois servem como pontos de referência para a inovação e o aprimoramento.
Para facilitar o acompanhamento deste desenvolvimento e evitar problemas, considerei reunir o código-fonte de hoje e os módulos anteriores em um único arquivo ZIP. Dessa forma, todos os arquivos necessários estarão incluídos, especialmente para aqueles que não acompanharam ou não realizaram algumas das configurações anteriores. A ausência de arquivos costuma gerar erros durante a compilação, portanto, essa abordagem ajudará os usuários a iniciar o projeto com mais facilidade.
Um agradecimento especial à MetaQuotes pelo artigo informativo sobre a utilização de recursos no MQL5, que serviu como uma referência valiosa. Implementar essas ideias em um projeto real como este foi uma experiência enriquecedora e bastante proveitosa.
| Nome do Arquivo | Especificações |
|---|---|
| New_Admin_Panel.mq5 | O novo programa principal com uma interface renovada. |
| New_Admin_Panel_BMP images.zip | Esta pasta contém todas as imagens bitmap utilizadas. Adicione essas imagens ao diretório MQL5\Images para garantir que sejam carregadas e exibidas corretamente pela interface. |
| All Modules.zip | Uma pasta contendo todos os arquivos de cabeçalho utilizados na Parte (X). Extraia esses arquivos para o diretório MQL5\Include da sua instalação do MetaTrader para garantir a compilação e o funcionamento corretos. |
Traduzido do Inglês pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/en/articles/17780
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.
Caminhe em novos trilhos: Personalize indicadores no MQL5
Repensando Estratégias Clássicas (Parte 14): Configurações de Alta Probabilidade
Está chegando o novo MetaTrader 5 e MQL5
Introdução à linguagem MQL5 (Parte 16): Criação de EAs com padrões de análise técnica
- 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