Desenvolvimento de um Kit de Ferramentas para análise de ação de preço (Parte 17): Ferramenta TrendLoom EA
Conteúdo
Introdução
Os métodos de análise de mercado e confirmação de entrada variam entre os analistas de tendência. Muitos traders analisam vários intervalos de tempo, como M1, M5 e M15 ou H1, H4 e W1, para validar suas entradas e aumentar a confiabilidade dos sinais. Em vez de alterar os intervalos de tempo para avaliar a tendência geral, basta pressionar um botão e obter uma atualização em tempo real ou receber atualizações automáticas. Você já viu um gráfico em um período gráfico menor indicando venda, entrou em uma operação e, em seguida, abriu um gráfico em um período gráfico maior apenas para descobrir uma tendência de compra?
O EA TrendLoom foi projetado para evitar esse erro. Ele possui um painel com sete botões que representam vários estilos de trading. Cada botão exibe três timeframes que são analisados em conjunto usando médias móveis para gerar sinais como BUY, SELL ou NEUTRAL. Essa ferramenta robusta fornece atualizações rápidas de confirmação e se atualiza continuamente com sinais relevantes conforme são detectados.
Visão Geral da Estratégia
O EA TrendLoom é estruturado como uma interface gráfica (painel). O painel contém sete botões, cada um correspondente a uma estratégia de trading específica- Foco no Curto Prazo (M1, M5, M15)
- Scalping/Intraday (M5, M15, H1)
- Swing Trading (M15, H1, H4)
- Negociação de tendências (H1, H4, D1)
- Confirmação de Tendência MTF (H1, H4, W1)
- Scalper Curto / Tendência Média (M5, H1, D1)
- Tendência de Longo Prazo (H1, D1, W1)
Vamos analisar como o EA gera um sinal de COMPRA, VENDA ou NEUTRO quando um botão é pressionado.
- Coleta de Dados: Para cada um dos três períodos de tempo (por exemplo, M1, M5 e M15), o EA recupera o preço de fechamento da última vela totalmente concluída.
- Cálculo da SMA: Para cada período, o EA calcula uma Média Móvel Simples (SMA) de 50 períodos. Essa SMA atua como referência para o preço atual.
- Se o preço estiver acima da SMA, considera isso um sinal de alta e atribui um valor de +1.
- Se o preço estiver abaixo da SMA, considera isso um sinal de baixa e atribui um valor de -1.
- Quando o preço é igual à SMA, o sinal é neutro (0).
Combinando os Sinais
- Os três sinais individuais (um de cada período) são somados.
- Determinação do Sinal Final:
- Se a soma for igual ou superior a 2, isso indica um forte impulso de alta. O EA retorna um sinal de "COMPRA".
- Se a soma for -2 ou menos, isso indica forte impulso de baixa. O EA retorna um sinal de "VENDA".
- Caso contrário, os sinais são mistos ou neutros, portanto o EA retorna "NEUTRO".
Vamos revisar o diagrama a seguir para entender melhor o processo.

Fig 1. Fluxograma
Implementação em MQL5
No topo, você notará os comentários de cabeçalho e as definições de propriedades do EA. Essas linhas funcionam como metadados para o EA, especificando seus direitos autorais, versão e vinculando-o à sua origem. A diretiva #property strict é usada para impor regras de compilação mais rigorosas, ajudando a prevenir erros comuns de codificação.
//+------------------------------------------------------------------+ //| TrendLoom EA.mq5 | //| Copyright 2025, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2025, MetaQuotes Ltd." #property link "https://www.mql5.com/en/users/lynnchris" #property version "1.00" #property strict
Em seguida, o código inclui vários arquivos de cabeçalho que fornecem controles de diálogo, botão, rótulo e painel. Também inclui controles de objetos de gráfico para exibir texto no gráfico. Essa inclusão modular permite que o EA utilize classes pré-construídas para a interface do usuário.
Isso inclui bibliotecas de referência de diretivas na pasta include do seu MetaEditor. Arquivos na subpasta Controls oferecem classes integradas para diálogos e botões. Eles também fornecem classes para rótulos e painéis. Esse design simplifica a construção de uma interface interativa sem reescrever código. O arquivo na subpasta ChartObjects (ChartObjectsTxtControls.mqh) permite exibir texto dinâmico no gráfico.
#include <Controls/Dialog.mqh> #include <Controls/Button.mqh> #include <Controls/Label.mqh> #include <Controls/Panel.mqh> #include <ChartObjects/ChartObjectsTxtControls.mqh> // Adjusted include path (singular folder)
Constantes para alinhamento de texto e um valor de cor são então definidos. Essa prática melhora a clareza e a facilidade de manutenção do código.
#ifndef ALIGN_LEFT #define ALIGN_LEFT 0 #endif #ifndef ALIGN_CENTER #define ALIGN_CENTER 1 #endif #ifndef ALIGN_RIGHT #define ALIGN_RIGHT 2 #endif #define clrSilver 0xC0C0C0
O EA declara parâmetros de entrada que ajustam a aparência e a posição do painel e de seus botões. PanelX, PanelY e PanelWidth definem a geometria do painel, enquanto os parâmetros de cor definem o tema visual. As dimensões dos botões são controladas com btnWidth, btnHeight e btnSpacing, e o EA permite personalizar tanto o layout quanto as cores. Essa configuração oferece flexibilidade para adaptar a interface do usuário às suas necessidades.
//---- Input parameters ----------------------------------------------- input int PanelX = 10; input int PanelY = 10; input int PanelWidth = 250; input int btnWidth = 220; input int btnHeight = 30; input int btnSpacing = 5; input color PanelBackgroundColor = clrDimGray; input color PanelHeaderColor = clrBlueViolet; input color ButtonBgColor = clrBlack; input color ButtonTextColor = clrBlueViolet; input color AnalysisTextColor = clrLime;
Arrays armazenam os nomes e textos dos botões, o que torna a atualização ou adição de novos botões rápida e simples. Esse design centraliza todas as informações relacionadas aos botões em um único local, de modo que modificações exigem apenas ajustes mínimos. Também melhora a consistência na interface do usuário e reduz a chance de erros. O método oferece flexibilidade para melhorias futuras e mantém o código limpo e organizado.
//---- Button Names and Texts (7 analysis options) -------------------- string buttonNames[7] = { "btnShortTerm", "btnScalping", "btnSwing", "btnTrend", "btnMTFTrend", "btnShortScalper", "btnLongTerm" }; string buttonTexts[7] = { "Short Term Focus\n(M1, M5, M15)", "Scalping/Intraday\n(M5, M15, H1)", "Swing Trading\n(M15, H1, H4)", "Trend Trading\n(H1, H4, D1)", "MTF Trend Confirm\n(H1, H4, W1)", "Short Scalper/Mid Trend\n(M5, H1, D1)", "Long Term Trend\n(H1, D1, W1)" };
Macros globais definem os nomes para o cabeçalho do painel e o rótulo de análise. Essas macros garantem consistência em todo o código e atuam como uma única fonte para esses identificadores. Ao centralizar esses nomes, atualizações nos componentes do painel tornam-se mais fáceis e reduzem o risco de erros de digitação. Essa abordagem simplifica a manutenção e garante um código consistente e claro.
// Global object names for panel header and analysis label #define PANEL_BG "PanelBG" #define PANEL_HEADER "PanelHeader" #define ANALYSIS_LABEL "AnalysisResult"
O código declara então duas funções auxiliares: GetSMA calcula a média móvel simples e AnalyzeTimeframes realiza análises de mercado em vários períodos de tempo. Essas funções formam a lógica central da análise de mercado.
//--- Helper function declarations double GetSMA(string symbol, ENUM_TIMEFRAMES timeframe, int period, int shift); string AnalyzeTimeframes(ENUM_TIMEFRAMES tf1, ENUM_TIMEFRAMES tf2, ENUM_TIMEFRAMES tf3);
A classe personalizada CTrendLoomPanel herda de CAppDialog. Ela agrupa todos os elementos da interface do usuário, como o rótulo de cabeçalho, painel principal, botões e rótulo de resultado. Esse design cria uma interface modular que é mais fácil de gerenciar e expandir.
Criando o Painel
O método CreateTrendPanel primeiro cria uma janela de diálogo. Em seguida, configura um rótulo de cabeçalho com texto personalizado, cor, tamanho de fonte e estilo de fonte. O alinhamento é definido usando a função ObjectSetInteger.
bool CreateTrendPanel(const long chart, const string name, const int x1, const int y1, const int x2, const int y2) { if(!CAppDialog::Create(chart, name, 0, x1, y1, x2, y2)) { Print("Failed to create TrendLoom dialog."); return false; } if(!m_lblHeader.Create(0, "TrendLoomHeader", 0, 10, 10, x2 - x1 - 20, 30)) { Print("Failed to create header label."); return false; } m_lblHeader.Text("TrendLoom EA"); m_lblHeader.Color(PanelHeaderColor); m_lblHeader.FontSize(14); m_lblHeader.Font("Segoe UI"); Add(m_lblHeader); if(!ObjectSetInteger(0L, m_lblHeader.Name(), OBJPROP_ALIGN, (long)ALIGN_CENTER)) Print("Failed to set header alignment");
O método continua criando o painel principal e calcula dinamicamente suas dimensões. Depois, cria cada botão e os posiciona um após o outro. Por fim, um rótulo de resultados é adicionado abaixo dos botões para exibir a saída da análise.
Manipulação de Eventos
O método OnEvent processa as interações do usuário. Ao clicar em um botão, ele chama AnalyzeTimeframes com os parâmetros de período de tempo apropriados. O resultado da análise é atualizado no painel e um alerta é exibido.
bool OnEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { if(sparam == "btnShortTerm") { string res = AnalyzeTimeframes(PERIOD_M1, PERIOD_M5, PERIOD_M15); string out = "Short Term Focus: " + res; UpdateResults(out); Alert(out); return true; } else if(sparam == "btnScalping") { string res = AnalyzeTimeframes(PERIOD_M5, PERIOD_M15, PERIOD_H1); string out = "Scalping/Intraday: " + res; UpdateResults(out); Alert(out); return true; } // Additional conditions for other buttons return false; }
Atualizando a Interface
O método UpdateResults atualiza o rótulo de resultados com novos dados de análise. Em seguida, ele chama ChartRedraw para que as informações atualizadas apareçam imediatamente.
void UpdateResults(const string &result) { m_lblResults.Text("Analysis Result: " + result); ChartRedraw(); }
Funções Centrais de Análise
Calculando a Média Móvel Simples (MMS)
A função GetSMA calcula a SMA criando um identificador de indicador com a função iMA. Ele copia os valores da SMA do buffer do indicador e, em seguida, libera o identificador para liberar recursos.
double GetSMA(string symbol, ENUM_TIMEFRAMES timeframe, int period, int shift) { int handle = iMA(symbol, timeframe, period, 0, MODE_SMA, PRICE_CLOSE); if(handle == INVALID_HANDLE) { Print("Failed to create iMA handle for timeframe ", timeframe); return 0.0; } double sma[]; if(CopyBuffer(handle, 0, shift, 1, sma) <= 0) { Print("Failed to copy buffer for timeframe ", timeframe); IndicatorRelease(handle); return 0.0; } double result = sma[0]; IndicatorRelease(handle); return result; }
Analisando múltiplos períodos de tempo
A função AnalyzeTimeframes recupera o preço de fechamento e a SMA para três períodos de tempo e atribui um sinal de alta quando o preço ultrapassa a SMA ou um sinal de baixa quando cai abaixo dela. O sistema soma os sinais individuais para produzir uma recomendação final: COMPRAR quando a soma for igual ou superior a 2, VENDER quando for igual ou inferior a -2 e NEUTRO caso contrário. Cada período de tempo é avaliado independentemente para capturar uma visão equilibrada das tendências de mercado, enquanto o parâmetro de deslocamento garante que apenas a última vela concluída seja usada para análise. A combinação de sinais de múltiplos períodos de tempo reduz o impacto do ruído transitório do mercado, e o ajuste do período da SMA refina ainda mais a sensibilidade dos sinais de negociação.
string AnalyzeTimeframes(ENUM_TIMEFRAMES tf1, ENUM_TIMEFRAMES tf2, ENUM_TIMEFRAMES tf3) { int period = 50; int shift = 1; // last completed candle double price1 = iClose(_Symbol, tf1, shift); double sma1 = GetSMA(_Symbol, tf1, period, shift); int signal1 = (price1 > sma1) ? 1 : (price1 < sma1 ? -1 : 0); double price2 = iClose(_Symbol, tf2, shift); double sma2 = GetSMA(_Symbol, tf2, period, shift); int signal2 = (price2 > sma2) ? 1 : (price2 < sma2 ? -1 : 0); double price3 = iClose(_Symbol, tf3, shift); double sma3 = GetSMA(_Symbol, tf3, period, shift); int signal3 = (price3 > sma3) ? 1 : (price3 < sma3 ? -1 : 0); int sum = signal1 + signal2 + signal3; if(sum >= 2) return "BUY"; else if(sum <= -2) return "SELL"; else return "NEUTRAL"; }As funções de ciclo de vida do EA lidam com inicialização, limpeza e processamento de eventos. A função OnInit cria o painel TrendLoom usando os parâmetros de entrada. Se a criação do painel falhar, o EA retorna um erro de inicialização.
int OnInit() { if(!TrendPanel.CreateTrendPanel(0, "TrendLoom Panel", PanelX, PanelY, PanelX + PanelWidth + 20, PanelY + 400)) { Print("Failed to create TrendLoom Panel."); return INIT_FAILED; } return INIT_SUCCEEDED; }
A função OnDeinit realiza a limpeza destruindo o painel quando o EA é removido ou o gráfico é fechado.
void OnDeinit(const int reason) { TrendPanel.Destroy(reason); }
Por fim, a função OnChartEvent encaminha os eventos do gráfico para o manipulador de eventos do painel, garantindo que a interface permaneça responsiva.
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { TrendPanel.ChartEvent(id, lparam, dparam, sparam); }
No seu MetaEditor, os arquivos necessários estão armazenados na pasta include. Para acessar os arquivos especificados conforme mostrado no trecho, consulte as subpastas conforme ilustrado nos diagramas abaixo. Essa organização garante que o compilador encontre os arquivos de controle de diálogo, botão, rótulo e painel na pasta include/Controls e os controles de objetos de gráfico na pasta include/ChartObjects.
#include <Controls/Dialog.mqh> #include <Controls/Button.mqh> #include <Controls/Label.mqh> #include <Controls/Panel.mqh> #include <ChartObjects/ChartObjectsTxtControls.mqh> // Adjusted include path (singular folder)
Etapa 1

Fig 2. Etapa 1
Etapa 2

Fig 3. Etapa 2
Código MQL5
//+------------------------------------------------------------------+ //| TrendLoom EA.mq5 | //| Copyright 2025, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2025, MetaQuotes Ltd." #property link "https://www.mql5.com/en/users/lynnchris" #property version "1.00" #property strict #include <Controls/Dialog.mqh> #include <Controls/Button.mqh> #include <Controls/Label.mqh> #include <Controls/Panel.mqh> #include <ChartObjects/ChartObjectsTxtControls.mqh> // Adjusted include path (singular folder) // Define alignment constants if not already defined #ifndef ALIGN_LEFT #define ALIGN_LEFT 0 #endif #ifndef ALIGN_CENTER #define ALIGN_CENTER 1 #endif #ifndef ALIGN_RIGHT #define ALIGN_RIGHT 2 #endif #define clrSilver 0xC0C0C0 //---- Input parameters ----------------------------------------------- input int PanelX = 10; // Top-left X coordinate of panel input int PanelY = 10; // Top-left Y coordinate of panel input int PanelWidth = 250; // Panel width (for longer text) input int btnWidth = 220; // Button width input int btnHeight = 30; // Button height input int btnSpacing = 5; // Spacing between buttons input color PanelBackgroundColor = clrDimGray; // Panel background color input color PanelHeaderColor = clrBlueViolet; // Panel header text color input color ButtonBgColor = clrBlack; // Button background color input color ButtonTextColor = clrBlueViolet; // Button text color input color AnalysisTextColor = clrLime; // Analysis result text color //---- Button Names and Texts (7 analysis options) -------------------- string buttonNames[7] = { "btnShortTerm", "btnScalping", "btnSwing", "btnTrend", "btnMTFTrend", "btnShortScalper", "btnLongTerm" }; string buttonTexts[7] = { "Short Term Focus\n(M1, M5, M15)", "Scalping/Intraday\n(M5, M15, H1)", "Swing Trading\n(M15, H1, H4)", "Trend Trading\n(H1, H4, D1)", "MTF Trend Confirm\n(H1, H4, W1)", "Short Scalper/Mid Trend\n(M5, H1, D1)", "Long Term Trend\n(H1, D1, W1)" }; // Global object names for panel header and analysis label #define PANEL_BG "PanelBG" #define PANEL_HEADER "PanelHeader" #define ANALYSIS_LABEL "AnalysisResult" //--- Helper function declarations double GetSMA(string symbol, ENUM_TIMEFRAMES timeframe, int period, int shift); string AnalyzeTimeframes(ENUM_TIMEFRAMES tf1, ENUM_TIMEFRAMES tf2, ENUM_TIMEFRAMES tf3); //------------------------------------------------------------------------------ // CTrendLoomPanel class - A modern, modular panel for TrendLoom EA //------------------------------------------------------------------------------ class CTrendLoomPanel : public CAppDialog { private: CLabel m_lblHeader; CPanel m_panelMain; CButton m_btnShortTerm; CButton m_btnScalping; CButton m_btnSwing; CButton m_btnTrend; CButton m_btnMTFTrend; CButton m_btnShortScalper; CButton m_btnLongTerm; CLabel m_lblResults; public: // Create the TrendLoom Panel dialog bool CreateTrendPanel(const long chart, const string name, const int x1, const int y1, const int x2, const int y2) { if(!CAppDialog::Create(chart, name, 0, x1, y1, x2, y2)) { Print("Failed to create TrendLoom dialog."); return false; } // Create header label if(!m_lblHeader.Create(0, "TrendLoomHeader", 0, 10, 10, x2 - x1 - 20, 30)) { Print("Failed to create header label."); return false; } m_lblHeader.Text("TrendLoom EA"); m_lblHeader.Color(PanelHeaderColor); m_lblHeader.FontSize(14); m_lblHeader.Font("Segoe UI"); Add(m_lblHeader); // Set header text alignment to center using ObjectSetInteger if(!ObjectSetInteger(0L, m_lblHeader.Name(), OBJPROP_ALIGN, (long)ALIGN_CENTER)) Print("Failed to set header alignment"); // Create main panel background int panelBottom = 50 + (btnHeight + btnSpacing) * 7 + btnSpacing; if(!m_panelMain.Create(0, "TrendLoomPanel", 0, 10, 50, x2 - x1 - 10, panelBottom)) { Print("Failed to create main panel."); return false; } m_panelMain.Color(PanelBackgroundColor); m_panelMain.BorderType(BORDER_RAISED); m_panelMain.ColorBorder(clrSilver); Add(m_panelMain); // Starting coordinates for buttons int btnX = 20; // relative to dialog int btnY = 60; int buttonWidth = btnWidth; int buttonHeight = btnHeight; // Create each button with a modern look if(!m_btnShortTerm.Create(0, buttonNames[0], 0, btnX, btnY, btnX + buttonWidth, btnY + buttonHeight)) return false; m_btnShortTerm.Text(buttonTexts[0]); m_btnShortTerm.Font("Segoe UI"); m_btnShortTerm.FontSize(12); m_btnShortTerm.Color(ButtonBgColor); Add(m_btnShortTerm); btnY += buttonHeight + btnSpacing; if(!m_btnScalping.Create(0, buttonNames[1], 0, btnX, btnY, btnX + buttonWidth, btnY + buttonHeight)) return false; m_btnScalping.Text(buttonTexts[1]); m_btnScalping.Font("Segoe UI"); m_btnScalping.FontSize(12); m_btnScalping.Color(ButtonBgColor); Add(m_btnScalping); btnY += buttonHeight + btnSpacing; if(!m_btnSwing.Create(0, buttonNames[2], 0, btnX, btnY, btnX + buttonWidth, btnY + buttonHeight)) return false; m_btnSwing.Text(buttonTexts[2]); m_btnSwing.Font("Segoe UI"); m_btnSwing.FontSize(12); m_btnSwing.Color(ButtonBgColor); Add(m_btnSwing); btnY += buttonHeight + btnSpacing; if(!m_btnTrend.Create(0, buttonNames[3], 0, btnX, btnY, btnX + buttonWidth, btnY + buttonHeight)) return false; m_btnTrend.Text(buttonTexts[3]); m_btnTrend.Font("Segoe UI"); m_btnTrend.FontSize(12); m_btnTrend.Color(ButtonBgColor); Add(m_btnTrend); btnY += buttonHeight + btnSpacing; if(!m_btnMTFTrend.Create(0, buttonNames[4], 0, btnX, btnY, btnX + buttonWidth, btnY + buttonHeight)) return false; m_btnMTFTrend.Text(buttonTexts[4]); m_btnMTFTrend.Font("Segoe UI"); m_btnMTFTrend.FontSize(12); m_btnMTFTrend.Color(ButtonBgColor); Add(m_btnMTFTrend); btnY += buttonHeight + btnSpacing; if(!m_btnShortScalper.Create(0, buttonNames[5], 0, btnX, btnY, btnX + buttonWidth, btnY + buttonHeight)) return false; m_btnShortScalper.Text(buttonTexts[5]); m_btnShortScalper.Font("Segoe UI"); m_btnShortScalper.FontSize(12); m_btnShortScalper.Color(ButtonBgColor); Add(m_btnShortScalper); btnY += buttonHeight + btnSpacing; if(!m_btnLongTerm.Create(0, buttonNames[6], 0, btnX, btnY, btnX + buttonWidth, btnY + buttonHeight)) return false; m_btnLongTerm.Text(buttonTexts[6]); m_btnLongTerm.Font("Segoe UI"); m_btnLongTerm.FontSize(12); m_btnLongTerm.Color(ButtonBgColor); Add(m_btnLongTerm); btnY += buttonHeight + btnSpacing; // Create results label below the buttons if(!m_lblResults.Create(0, "TrendResults", 0, btnX, btnY, btnX + buttonWidth, btnY + 30)) return false; m_lblResults.Text("Analysis Result: [Waiting for Input]"); m_lblResults.Font("Segoe UI"); m_lblResults.FontSize(12); m_lblResults.Color(AnalysisTextColor); Add(m_lblResults); // Set results text alignment to left using ObjectSetInteger if(!ObjectSetInteger(0L, m_lblResults.Name(), OBJPROP_ALIGN, (long)ALIGN_LEFT)) Print("Failed to set results alignment"); Show(); return true; } // Process events (button clicks) bool OnEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { if(sparam == "btnShortTerm") { string res = AnalyzeTimeframes(PERIOD_M1, PERIOD_M5, PERIOD_M15); string out = "Short Term Focus: " + res; UpdateResults(out); Alert(out); return true; } else if(sparam == "btnScalping") { string res = AnalyzeTimeframes(PERIOD_M5, PERIOD_M15, PERIOD_H1); string out = "Scalping/Intraday: " + res; UpdateResults(out); Alert(out); return true; } else if(sparam == "btnSwing") { string res = AnalyzeTimeframes(PERIOD_M15, PERIOD_H1, PERIOD_H4); string out = "Swing Trading: " + res; UpdateResults(out); Alert(out); return true; } else if(sparam == "btnTrend") { string res = AnalyzeTimeframes(PERIOD_H1, PERIOD_H4, PERIOD_D1); string out = "Trend Trading: " + res; UpdateResults(out); Alert(out); return true; } else if(sparam == "btnMTFTrend") { string res = AnalyzeTimeframes(PERIOD_H1, PERIOD_H4, PERIOD_W1); string out = "MTF Trend Confirm: " + res; UpdateResults(out); Alert(out); return true; } else if(sparam == "btnShortScalper") { string res = AnalyzeTimeframes(PERIOD_M5, PERIOD_H1, PERIOD_D1); string out = "Short Scalper/Mid Trend: " + res; UpdateResults(out); Alert(out); return true; } else if(sparam == "btnLongTerm") { string res = AnalyzeTimeframes(PERIOD_H1, PERIOD_D1, PERIOD_W1); string out = "Long Term Trend: " + res; UpdateResults(out); Alert(out); return true; } return false; } bool ChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { return OnEvent(id, lparam, dparam, sparam); } // Update the results label and refresh the chart void UpdateResults(const string &result) { m_lblResults.Text("Analysis Result: " + result); ChartRedraw(); } }; // Global instance of the TrendLoom Panel CTrendLoomPanel TrendPanel; //------------------------------------------------------------------------------ // Helper functions (core analysis logic) //------------------------------------------------------------------------------ double GetSMA(string symbol, ENUM_TIMEFRAMES timeframe, int period, int shift) { int handle = iMA(symbol, timeframe, period, 0, MODE_SMA, PRICE_CLOSE); if(handle == INVALID_HANDLE) { Print("Failed to create iMA handle for timeframe ", timeframe); return 0.0; } double sma[]; // dynamic array to store SMA values if(CopyBuffer(handle, 0, shift, 1, sma) <= 0) { Print("Failed to copy buffer for timeframe ", timeframe); IndicatorRelease(handle); return 0.0; } double result = sma[0]; IndicatorRelease(handle); return result; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ string AnalyzeTimeframes(ENUM_TIMEFRAMES tf1, ENUM_TIMEFRAMES tf2, ENUM_TIMEFRAMES tf3) { int period = 50; int shift = 1; // last completed candle double price1 = iClose(_Symbol, tf1, shift); double sma1 = GetSMA(_Symbol, tf1, period, shift); int signal1 = (price1 > sma1) ? 1 : (price1 < sma1 ? -1 : 0); double price2 = iClose(_Symbol, tf2, shift); double sma2 = GetSMA(_Symbol, tf2, period, shift); int signal2 = (price2 > sma2) ? 1 : (price2 < sma2 ? -1 : 0); double price3 = iClose(_Symbol, tf3, shift); double sma3 = GetSMA(_Symbol, tf3, period, shift); int signal3 = (price3 > sma3) ? 1 : (price3 < sma3 ? -1 : 0); int sum = signal1 + signal2 + signal3; if(sum >= 2) return "BUY"; else if(sum <= -2) return "SELL"; else return "NEUTRAL"; } //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { if(!TrendPanel.CreateTrendPanel(0, "TrendLoom Panel", PanelX, PanelY, PanelX + PanelWidth + 20, PanelY + 400)) { Print("Failed to create TrendLoom Panel."); return INIT_FAILED; } return INIT_SUCCEEDED; } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { TrendPanel.Destroy(reason); } //+------------------------------------------------------------------+ //| Chart Event Handler | //+------------------------------------------------------------------+ void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { TrendPanel.ChartEvent(id, lparam, dparam, sparam); } //+------------------------------------------------------------------+
Resultados
É extremamente importante que todo trader teste minuciosamente seus sistemas antes de utilizá-los em operações reais. Os testes envolvem a análise retrospectiva de dados históricos para verificar como o sistema teria se comportado sem arriscar quaisquer fundos. Você também pode usar contas demo em tempo real para observar o desempenho real em tempo real. Esse processo ajuda a ajustar e desenvolver uma ferramenta mais confiável que você possa usar com segurança em uma conta real. Pessoalmente, prefiro dedicar um tempo significativo testando e refinando o EA para obter resultados mais robustos.
Nesta seção, apresento os resultados dos testes do EA em execução no gráfico. Eu o testei no Volatility 75 (1s) e ele produziu resultados excelentes e lucrativos. Todos os botões funcionam conforme esperado e as análises são atualizadas quase instantaneamente quando você pressiona um botão. Vamos revisar o primeiro teste abaixo.

Fig 4. Teste Volatility 75 (1s)
Abaixo está um diagrama que ilustra como o mercado se comportou após a execução de uma operação com base no sinal fornecido. Este diagrama dá continuidade à operação mostrada no GIF acima. Utilizei o período de tempo M1 para oferecer uma visão mais ampla das negociações.

Fig 5. Teste V 75 (1s)
Conclusão
Após criar e testar o EA, posso confirmar com confiança que ele tem um impacto positivo na análise de mercado. Seu processamento rápido de sinais e avaliação da tendência geral produziram resultados poderosos em índices de volatilidade. No entanto, esta ferramenta serve como um auxílio complementar, e não como o provedor final de sinais. Incentivo você a testá-la minuciosamente e ajustar os parâmetros de acordo com suas preferências. Você também pode modificá-la para personalizar a aparência dos botões. Use-a para confirmar sua estratégia geral; tenho observado que ela é eficaz dessa forma.
| Data | Nome da Ferramenta | Descrição | Versão | Atualizações | Notas |
|---|---|---|---|---|---|
| 01/10/24 | Projetor de gráficos | Script para sobrepor a ação de preço do dia anterior com efeito fantasma. | 1.0 | Lançamento Inicial | Ferramenta número 1 |
| 18/11/24 | Comentário Analítico | Ele fornece informações do dia anterior em formato tabular, além de antecipar a direção futura do mercado. | 1.0 | Lançamento Inicial | Ferramenta número 2 |
| 27/11/24 | Mestre em Análise | Atualização regular das métricas de mercado a cada duas horas | 1.01 | Segunda Versão | Ferramenta número 3 |
| 02/12/24 | Previsor Analítico | Atualização regular das métricas de mercado a cada duas horas com integração ao Telegram | 1.1 | Terceira Edição | Ferramenta número 4 |
| 09/12/24 | Navegador de Volatilidade | O EA analisa as condições de mercado utilizando os indicadores Bollinger Bands, RSI e ATR | 1.0 | Lançamento Inicial | Ferramenta número 5 |
| 19/12/24 | Reversão à Média Ceifador de Sinal | Analisa o mercado utilizando estratégia de reversão à média e fornece sinal | 1.0 | Lançamento Inicial | Ferramenta número 6 |
| 9/01/25 | Pulso de sinal | Analisador de múltiplos períodos de tempo | 1.0 | Lançamento Inicial | Ferramenta número 7 |
| 17/01/25 | Quadro de Métricas | Painel com botão para análise | 1.0 | Lançamento Inicial | Ferramenta número 8 |
| 21/01/25 | Fluxo externo | Análises por meio de bibliotecas externas | 1.0 | Lançamento Inicial | Ferramenta número 9 |
| 27/01/25 | VWAP | Preço Médio Ponderado por Volume | 1.3 | Lançamento Inicial | Ferramenta número 10 |
| 02/02/25 | Heikin Ashi | Suavização de tendências e identificação de sinais de reversão | 1.0 | Lançamento Inicial | Ferramenta número 11 |
| 04/02/25 | FibVWAP | Geração de sinais por meio de análise em Python | 1.0 | Lançamento Inicial | Ferramenta número 12 |
| 14/02/25 | DIVERGÊNCIA RSI | Divergências entre ação do Preço e RSI | 1.0 | Lançamento Inicial | Ferramenta número 13 |
| 17/02/25 | Parada e Reversão Parabólicas (PSAR) | Automação da estratégia PSAR | 1.0 | Lançamento Inicial | Ferramenta número 14 |
| 20/02/25 | Quarters Drawer Script | Desenho dos níveis de quartis no gráfico | 1.0 | Lançamento Inicial | Ferramenta número 15 |
| 27/02/25 | Detector de Intrusão | Detectar e alertar quando o preço atingir os níveis de quartis. | 1.0 | Lançamento Inicial | Ferramenta número 16 |
| 27/02/25 | Ferramenta TrendLoom | Painel de análise de múltiplos períodos de tempo | 1.0 | Lançamento Inicial | Ferramenta número 17 |
Traduzido do Inglês pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/en/articles/17329
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
Otimização por Comunidade de Cientistas - Community of Scientist Optimization (CoSO): Teoria
Está chegando o novo MetaTrader 5 e MQL5
Desenvolvimento do Kit de Ferramentas de Análise de Price Action (Parte 16): Introduzindo a Teoria dos Quartis (II) — EA Intrusion Detector
- 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
Uau, fantástico, posso ver que há muito esforço nisso, obrigado por compartilhar sua abordagem e seu código