Desenvolvimento de ferramentas para análise do movimento de preços (Parte 7): Expert Advisor Signal Pulse
Conteúdo
Introdução
Neste artigo, examinaremos o desenvolvimento do EA Signal Pulse em MQL5. O EA utilizará a combinação dos indicadores Bollinger Bands e Stochastic Oscillator em três timeframes distintos para detectar sinais de compra e venda. O propósito do EA é ajudar os traders a tomar decisões fundamentadas, confirmando sinais em múltiplos timeframes antes de entrar numa operação. Incluímos vários timeframes, as Bandas de Bollinger (BB) e o Oscilador Estocástico para gerar sinais. Nosso objetivo é minimizar sinais falsos que podem causar transtornos aos traders. Ao combinar esses elementos, buscamos aumentar a precisão de nossos sinais de negociação. Abaixo, elaborei uma tabela com a importância de cada componente em nossa ferramenta de geração de sinais.
- Vários timeframes
| Benefício | Descrição |
|---|---|
| Gerenciamento de risco | O uso de vários timeframes permite que o EA analise o mercado sob diferentes pontos de vista, reduzindo o impacto de falsos sinais e melhorando o gerenciamento de risco. |
| Confiança nos sinais | Ao confirmar sinais em vários timeframes, o EA ganha confiança na direção da negociação, reduzindo a probabilidade de entrar em uma operação com um sinal fraco ou falso. |
| Diversificação | A análise de múltiplos timeframes fornece uma visão de mercado mais diversificada, permitindo que o EA se adapte a condições de mercado em mudança e tome decisões de negociação mais fundamentadas. |
- Estocástico
| Benefício | Descrição |
|---|---|
| Condições de sobrecompra/sobrevenda | O Estocástico ajuda a identificar condições de sobrecompra e sobrevenda, indicando possíveis pontos de reversão no mercado. |
| Ferramenta de confirmação | O Estocástico serve como ferramenta de confirmação para as Bandas de Bollinger, garantindo que o EA não entre em uma operação baseado exclusivamente em sinais das Bollinger. |
| Filtragem de sinais falsos | Utilizando o Estocástico, o EA pode filtrar sinais falsos gerados pelas Bandas de Bollinger, especialmente em períodos de alta volatilidade. |
- Bandas de Bollinger
| Benefício | Descrição |
|---|---|
| Indicação de volatilidade | As Bandas de Bollinger mostram o nível de volatilidade do mercado, ajudando o EA a compreender o sentimento do mercado e identificar potenciais oportunidades de negociação. |
| Níveis de suporte/resistência | As Bandas de Bollinger atuam como níveis dinâmicos de suporte e resistência, fornecendo ao EA possíveis pontos de entrada e saída. |
| Confirmação de tendência | A largura das Bandas de Bollinger pode confirmar ou refutar a presença de uma tendência, ajudando o EA a tomar decisões de negociação fundamentadas. |
A interação entre múltiplos timeframes, o Estocástico e as Bandas de Bollinger (BB) aumenta significativamente a eficiência do EA na geração de sinais de negociação confiáveis e no gerenciamento de riscos. Ao analisar sinais em diferentes timeframes, o EA garante que as oportunidades de negociação sejam confirmadas por uma combinação sólida dos indicadores Stochastic e BB. Essa abordagem multidimensional reduz a probabilidade de sinais falsos, já que o EA identifica operações potenciais apenas quando existem evidências convincentes que sustentam a decisão. Como resultado, a combinação desses elementos aumenta a confiabilidade dos sinais gerados e melhora o gerenciamento geral de risco, permitindo que os traders tomem decisões mais fundamentadas.
Estratégia
O script Signal Pulse gera sinais de negociação com base no alinhamento das Bandas de Bollinger e do Oscilador Estocástico em três timeframes (M15, M30 e H1). As condições para cada tipo de sinal são as seguintes:
Sinal de compra
- Condição das Bandas de Bollinger: o preço toca a banda inferior de Bollinger em todos os três timeframes.
- Condição do Oscilador Estocástico: O Oscilador Estocástico indica uma condição de sobrevenda em todos os três timeframes, geralmente abaixo de 20.
- Requisito de confirmação: Para formar um sinal de compra, ambas as condições devem ser atendidas simultaneamente nos timeframes M15, M30 e H1.

Esquema 1. Condições para compra
Sinal de venda
- Condição das Bandas de Bollinger: o preço toca a banda superior de Bollinger em todos os três timeframes.
- Condição do Oscilador Estocástico: O Oscilador Estocástico indica uma condição de sobrecompra em todos os três timeframes, geralmente acima de 80.
- Requisito de confirmação: Para formar um sinal de venda, ambas as condições devem ser atendidas simultaneamente nos timeframes M15, M30 e H1.

Esquema 2. Condições para venda
Vamos visualizar esse processo por meio do diagrama abaixo.

Esquema. 3. Geração de sinal
Código MQL5
//+------------------------------------------------------------------+ //| Signal Pulse EA.mq5 | //| Copyright 2025, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2025, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" // Input parameters input ENUM_TIMEFRAMES Timeframe1 = PERIOD_M15; // M15 timeframe input ENUM_TIMEFRAMES Timeframe2 = PERIOD_M30; // M30 timeframe input ENUM_TIMEFRAMES Timeframe3 = PERIOD_H1; // H1 timeframe input int BB_Period = 20; // Bollinger Bands period input double BB_Deviation = 2.0; // Bollinger Bands deviation input int K_Period = 14; // Stochastic %K period input int D_Period = 3; // Stochastic %D period input int Slowing = 3; // Stochastic slowing input double SignalOffset = 10.0; // Offset in points for signal arrow input int TestBars = 10; // Number of bars after signal to test win condition input double MinArrowDistance = 5.0; // Minimum distance in points between arrows to avoid overlapping // Signal tracking structure struct SignalInfo { datetime time; double price; bool isBuySignal; }; // Arrays to store signal information datetime signalTimes[]; double signalPrices[]; bool signalBuySignals[]; //+------------------------------------------------------------------+ //| Retrieve Bollinger Band Levels | //+------------------------------------------------------------------+ bool GetBollingerBands(ENUM_TIMEFRAMES timeframe, double &upper, double &lower, double &middle) { int handle = iBands(Symbol(), timeframe, BB_Period, 0, BB_Deviation, PRICE_CLOSE); if(handle == INVALID_HANDLE) { Print("Error creating iBands for timeframe: ", timeframe); return false; } double upperBand[], middleBand[], lowerBand[]; if(!CopyBuffer(handle, 1, 0, 1, upperBand) || !CopyBuffer(handle, 0, 0, 1, middleBand) || !CopyBuffer(handle, 2, 0, 1, lowerBand)) { Print("Error copying iBands buffer for timeframe: ", timeframe); IndicatorRelease(handle); return false; } upper = upperBand[0]; middle = middleBand[0]; lower = lowerBand[0]; IndicatorRelease(handle); return true; } //+------------------------------------------------------------------+ //| Retrieve Stochastic Levels | //+------------------------------------------------------------------+ bool GetStochastic(ENUM_TIMEFRAMES timeframe, double &k_value, double &d_value) { int handle = iStochastic(Symbol(), timeframe, K_Period, D_Period, Slowing, MODE_SMA, STO_CLOSECLOSE); if(handle == INVALID_HANDLE) { Print("Error creating iStochastic for timeframe: ", timeframe); return false; } double kBuffer[], dBuffer[]; if(!CopyBuffer(handle, 0, 0, 1, kBuffer) || // %K line !CopyBuffer(handle, 1, 0, 1, dBuffer)) // %D line { Print("Error copying iStochastic buffer for timeframe: ", timeframe); IndicatorRelease(handle); return false; } k_value = kBuffer[0]; d_value = dBuffer[0]; IndicatorRelease(handle); return true; } //+------------------------------------------------------------------+ //| Check and Generate Signal | //+------------------------------------------------------------------+ void CheckAndGenerateSignal() { double upper1, lower1, middle1, close1; double upper2, lower2, middle2, close2; double upper3, lower3, middle3, close3; double k1, d1, k2, d2, k3, d3; if(!GetBollingerBands(Timeframe1, upper1, lower1, middle1) || !GetBollingerBands(Timeframe2, upper2, lower2, middle2) || !GetBollingerBands(Timeframe3, upper3, lower3, middle3)) { Print("Error retrieving Bollinger Bands data."); return; } if(!GetStochastic(Timeframe1, k1, d1) || !GetStochastic(Timeframe2, k2, d2) || !GetStochastic(Timeframe3, k3, d3)) { Print("Error retrieving Stochastic data."); return; } // Retrieve the close prices close1 = iClose(Symbol(), Timeframe1, 0); close2 = iClose(Symbol(), Timeframe2, 0); close3 = iClose(Symbol(), Timeframe3, 0); bool buySignal = (close1 <= lower1 && close2 <= lower2 && close3 <= lower3) && (k1 < 5 && k2 < 5 && k3 < 5); // Oversold condition bool sellSignal = (close1 >= upper1 && close2 >= upper2 && close3 >= upper3) && (k1 > 95 && k2 > 95 && k3 > 95); // Overbought condition // Check if an arrow already exists in the same region before placing a new one if(buySignal && !ArrowExists(close1)) { Print("Buy signal detected on all timeframes with Stochastic confirmation!"); string arrowName = "BuySignal" + IntegerToString(TimeCurrent()); ObjectCreate(0, arrowName, OBJ_ARROW, 0, TimeCurrent(), close1); ObjectSetInteger(0, arrowName, OBJPROP_ARROWCODE, 241); ObjectSetInteger(0, arrowName, OBJPROP_COLOR, clrGreen); ObjectSetInteger(0, arrowName, OBJPROP_WIDTH, 2); // Store signal data ArrayResize(signalTimes, ArraySize(signalTimes) + 1); ArrayResize(signalPrices, ArraySize(signalPrices) + 1); ArrayResize(signalBuySignals, ArraySize(signalBuySignals) + 1); signalTimes[ArraySize(signalTimes) - 1] = TimeCurrent(); signalPrices[ArraySize(signalPrices) - 1] = close1; signalBuySignals[ArraySize(signalBuySignals) - 1] = true; } if(sellSignal && !ArrowExists(close1)) { Print("Sell signal detected on all timeframes with Stochastic confirmation!"); string arrowName = "SellSignal" + IntegerToString(TimeCurrent()); ObjectCreate(0, arrowName, OBJ_ARROW, 0, TimeCurrent(), close1); ObjectSetInteger(0, arrowName, OBJPROP_ARROWCODE, 242); ObjectSetInteger(0, arrowName, OBJPROP_COLOR, clrRed); ObjectSetInteger(0, arrowName, OBJPROP_WIDTH, 2); // Store signal data ArrayResize(signalTimes, ArraySize(signalTimes) + 1); ArrayResize(signalPrices, ArraySize(signalPrices) + 1); ArrayResize(signalBuySignals, ArraySize(signalBuySignals) + 1); signalTimes[ArraySize(signalTimes) - 1] = TimeCurrent(); signalPrices[ArraySize(signalPrices) - 1] = close1; signalBuySignals[ArraySize(signalBuySignals) - 1] = false; } } //+------------------------------------------------------------------+ //| Check if an arrow already exists within the MinArrowDistance | //+------------------------------------------------------------------+ bool ArrowExists(double price) { for(int i = 0; i < ArraySize(signalPrices); i++) { if(MathAbs(signalPrices[i] - price) <= MinArrowDistance) { return true; // Arrow exists in the same price region } } return false; // No arrow exists in the same region } //+------------------------------------------------------------------+ //| OnTick Event | //+------------------------------------------------------------------+ void OnTick() { CheckAndGenerateSignal(); } //+------------------------------------------------------------------+ //| OnDeinit Function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { // Clean up the objects long chart_id = 0; for(int i = ObjectsTotal(chart_id) - 1; i >= 0; i--) { string name = ObjectName(chart_id, i); if(StringFind(name, "Signal") != -1) { ObjectDelete(chart_id, name); } } Print("Multitimeframe Bollinger-Stochastic Analyzer deinitialized."); } //+------------------------------------------------------------------+
Análise do código
Nesta análise do EA Signal Pulse, serão examinados passo a passo os diferentes componentes do EA, os mecanismos do seu funcionamento e a lógica básica do seu sistema. - Título, propriedades e parâmetros de entrada
Logo no início do nosso EA, incluímos o cabeçalho que fornece os metadados necessários. Ele é composto pelo nome do EA, informações de direitos autorais e links de referência. Mas o que realmente importa para nós, como traders, são os parâmetros de entrada. Esses parâmetros configuráveis permitem que você adapte o comportamento do EA ao seu estilo de negociação.
//+------------------------------------------------------------------+ //| Signal Pulse EA.mq5 | //| Copyright 2024, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Christian Benjamin" #property link "https://www.mql5.com/en/users/lynnchris" #property version "1.00" // Input parameters input ENUM_TIMEFRAMES Timeframe1 = PERIOD_M15; // M15 timeframe input ENUM_TIMEFRAMES Timeframe2 = PERIOD_M30; // M30 timeframe input ENUM_TIMEFRAMES Timeframe3 = PERIOD_H1; // H1 timeframe input int BB_Period = 20; // Bollinger Bands period input double BB_Deviation = 2.0; // Bollinger Bands deviation input int K_Period = 14; // Stochastic %K period input int D_Period = 3; // Stochastic %D period input int Slowing = 3; // Stochastic slowing input double SignalOffset = 10.0; // Offset in points for signal arrow input int TestBars = 10; // Number of bars after signal to test win condition input double MinArrowDistance = 5.0; // Minimum distance in points between arrows to avoid overlappingAqui especificamos diferentes timeframes (M15, M30 e H1), o que possibilita analisar a dinâmica de preços em múltiplos períodos. Também definimos os parâmetros das Bandas de Bollinger, como o período e o desvio, além das configurações do Oscilador Estocástico, incluindo os períodos %K e %D. Incluímos ainda configurações visuais para as setas que marcarão os sinais de compra e venda no gráfico, bem como parâmetros destinados a minimizar a desordem visual, evitando a sobreposição das setas.
- Monitoramento de sinais e estruturas
Em seguida, definimos a estrutura SignalInfo, que desempenha um papel importante na organização dos sinais de negociação. Essa estrutura reúne informações sobre o momento em que o sinal ocorreu, o preço naquele instante e se foi um sinal de compra ou de venda. Além disso, configuramos arrays para armazenar dinamicamente essas informações.
// Signal tracking structure struct SignalInfo { datetime time; double price; bool isBuySignal; }; // Arrays to store signal information datetime signalTimes[]; double signalPrices[]; bool signalBuySignals[];Por meio dos arrays signalTimes, signalPrices e signalBuySignals, registramos os sinais de negociação que o EA gera ao longo do tempo, o que facilita significativamente o processamento de múltiplos sinais e ajuda a evitar confusões.
- Funções de busca de indicadores
Agora vamos examinar com mais detalhe as funções que utilizamos para extrair os valores dos indicadores, em especial das Bandas de Bollinger e dos indicadores Estocásticos.
//+------------------------------------------------------------------+ //| Retrieve Bollinger Band Levels | //+------------------------------------------------------------------+ bool GetBollingerBands(ENUM_TIMEFRAMES timeframe, double &upper, double &lower, double &middle) { int handle = iBands(Symbol(), timeframe, BB_Period, 0, BB_Deviation, PRICE_CLOSE); if(handle == INVALID_HANDLE) { Print("Error creating iBands for timeframe: ", timeframe); return false; } double upperBand[], middleBand[], lowerBand[]; if(!CopyBuffer(handle, 1, 0, 1, upperBand) || !CopyBuffer(handle, 0, 0, 1, middleBand) || !CopyBuffer(handle, 2, 0, 1, lowerBand)) { Print("Error copying iBands buffer for timeframe: ", timeframe); IndicatorRelease(handle); return false; } upper = upperBand[0]; middle = middleBand[0]; lower = lowerBand[0]; IndicatorRelease(handle); return true; } //+------------------------------------------------------------------+ //| Retrieve Stochastic Levels | //+------------------------------------------------------------------+ bool GetStochastic(ENUM_TIMEFRAMES timeframe, double &k_value, double &d_value) { int handle = iStochastic(Symbol(), timeframe, K_Period, D_Period, Slowing, MODE_SMA, STO_CLOSECLOSE); if(handle == INVALID_HANDLE) { Print("Error creating iStochastic for timeframe: ", timeframe); return false; } double kBuffer[], dBuffer[]; if(!CopyBuffer(handle, 0, 0, 1, kBuffer) || // %K line !CopyBuffer(handle, 1, 0, 1, dBuffer)) { // %D line Print("Error copying iStochastic buffer for timeframe: ", timeframe); IndicatorRelease(handle); return false; } k_value = kBuffer[0]; d_value = dBuffer[0]; IndicatorRelease(handle); return true; }A primeira função, GetBollingerBands(), extrai os níveis superior, médio e inferior das Bandas de Bollinger para o timeframe especificado. Ela cria um handle para o indicador e verifica se ele foi criado com sucesso. Se tudo estiver correto, copia os valores das bandas para arrays, que posteriormente podemos usar em nossa lógica de negociação. De maneira análoga, a função GetStochastic() extrai os valores de %K e %D do Oscilador Estocástico. Ela utiliza os mesmos procedimentos de verificação de erros e cópia de dados, garantindo que sempre obtenhamos dados precisos para a tomada de decisão.
- Verificação e geração de sinais
Agora passamos à função CheckAndGenerateSignal(), que contém a lógica principal do nosso EA. Essa função chama as funções de indicadores que definimos anteriormente para coletar dados das Bandas de Bollinger e dos indicadores Estocásticos em todos os timeframes especificados. Além disso, ela obtém os preços de fechamento mais recentes desses timeframes.
A função verifica sinais de compra e venda com base nas condições atuais do mercado. Um sinal de compra é acionado quando os preços de fechamento caem abaixo da banda inferior de Bollinger e os valores do Estocástico indicam uma condição de sobrevenda (menor que 5). De forma oposta, os sinais de venda ocorrem quando os preços ultrapassam a banda superior de Bollinger e as leituras do Estocástico excedem 95, indicando uma condição de sobrecompra.
//+------------------------------------------------------------------+ //| Check and Generate Signal | //+------------------------------------------------------------------+ void CheckAndGenerateSignal() { double upper1, lower1, middle1, close1; double upper2, lower2, middle2, close2; double upper3, lower3, middle3, close3; double k1, d1, k2, d2, k3, d3; if(!GetBollingerBands(Timeframe1, upper1, lower1, middle1) || !GetBollingerBands(Timeframe2, upper2, lower2, middle2) || !GetBollingerBands(Timeframe3, upper3, lower3, middle3)) { Print("Error retrieving Bollinger Bands data."); return; } if(!GetStochastic(Timeframe1, k1, d1) || !GetStochastic(Timeframe2, k2, d2) || !GetStochastic(Timeframe3, k3, d3)) { Print("Error retrieving Stochastic data."); return; } // Retrieve the close prices close1 = iClose(Symbol(), Timeframe1, 0); close2 = iClose(Symbol(), Timeframe2, 0); close3 = iClose(Symbol(), Timeframe3, 0); bool buySignal = (close1 <= lower1 && close2 <= lower2 && close3 <= lower3) && (k1 < 5 && k2 < 5 && k3 < 5); // Oversold condition bool sellSignal = (close1 >= upper1 && close2 >= upper2 && close3 >= upper3) && (k1 > 95 && k2 > 95 && k3 > 95); // Overbought condition // Check if an arrow already exists in the same region before placing a new one if(buySignal && !ArrowExists(close1)) { Print("Buy signal detected on all timeframes with Stochastic confirmation!"); string arrowName = "BuySignal" + IntegerToString(TimeCurrent()); ObjectCreate(0, arrowName, OBJ_ARROW, 0, TimeCurrent(), close1); ObjectSetInteger(0, arrowName, OBJPROP_ARROWCODE, 241); ObjectSetInteger(0, arrowName, OBJPROP_COLOR, clrGreen); ObjectSetInteger(0, arrowName, OBJPROP_WIDTH, 2); // Store signal data ArrayResize(signalTimes, ArraySize(signalTimes) + 1); ArrayResize(signalPrices, ArraySize(signalPrices) + 1); ArrayResize(signalBuySignals, ArraySize(signalBuySignals) + 1); signalTimes[ArraySize(signalTimes) - 1] = TimeCurrent(); signalPrices[ArraySize(signalPrices) - 1] = close1; signalBuySignals[ArraySize(signalBuySignals) - 1] = true; } if(sellSignal && !ArrowExists(close1)) { Print("Sell signal detected on all timeframes with Stochastic confirmation!"); string arrowName = "SellSignal" + IntegerToString(TimeCurrent()); ObjectCreate(0, arrowName, OBJ_ARROW, 0, TimeCurrent(), close1); ObjectSetInteger(0, arrowName, OBJPROP_ARROWCODE, 242); ObjectSetInteger(0, arrowName, OBJPROP_COLOR, clrRed); ObjectSetInteger(0, arrowName, OBJPROP_WIDTH, 2); // Store signal data ArrayResize(signalTimes, ArraySize(signalTimes) + 1); ArrayResize(signalPrices, ArraySize(signalPrices) + 1); ArrayResize(signalBuySignals, ArraySize(signalBuySignals) + 1); signalTimes[ArraySize(signalTimes) - 1] = TimeCurrent(); signalPrices[ArraySize(signalPrices) - 1] = close1; signalBuySignals[ArraySize(signalBuySignals) - 1] = false; } }
Além disso, antes de desenhar uma seta para marcar o sinal no gráfico, a função verifica se não há sobreposição com uma seta existente, por meio da chamada da função ArrowExists(). Se tudo estiver correto, ela cria a seta correspondente e salva as informações do sinal nos arrays que definimos anteriormente.
- Verificação da existência de setas
A função ArrowExists() permite manter o gráfico limpo e organizado, verificando se existe alguma seta próxima ao preço do novo sinal. Isso evita a sobreposição de múltiplas setas, o que poderia causar confusão. Ao comparar o novo preço do sinal com os preços armazenados no array signalPrices, determinamos se já existe uma seta suficientemente próxima para que a criação de uma nova seja desnecessária.
//+------------------------------------------------------------------+ //| Check if an arrow already exists within the MinArrowDistance | //+------------------------------------------------------------------+ bool ArrowExists(double price) { for(int i = 0; i < ArraySize(signalPrices); i++) { if(MathAbs(signalPrices[i] - price) <= MinArrowDistance) { return true; // Arrow exists in the same price region } } return false; // No arrow exists in the same region }
- Funções OnTick e OnDeinit
Por fim, temos as funções OnTick() e OnDeinit(). A função OnTick() é chamada toda vez que chega um novo tick do mercado, garantindo que o nosso EA permaneça responsivo e atualizado. Ela chama a função CheckAndGenerateSignal() para reavaliar possíveis sinais de negociação com base nos dados mais recentes.
Já a função OnDeinit() é chamada quando o EA é removido do gráfico ou quando o terminal é fechado. Sua tarefa é limpar todos os objetos gráficos criados pelo EA, especialmente as setas que indicam sinais de compra e venda, mantendo assim o gráfico organizado.
//+------------------------------------------------------------------+ //| OnTick Event | //+------------------------------------------------------------------+ void OnTick() { CheckAndGenerateSignal(); } //+------------------------------------------------------------------+ //| OnDeinit Function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { // Clean up the objects long chart_id = 0; for(int i = ObjectsTotal(chart_id) - 1; i >= 0; i--) { string name = ObjectName(chart_id, i); if(StringFind(name, "Signal") != -1) { ObjectDelete(chart_id, name); } } Print("Multitimeframe Bollinger-Stochastic Analyzer deinitialized."); }
Além disso, no EA Signal Pulse ajustamos os níveis de limite do Oscilador Estocástico para garantir a geração apenas dos sinais mais confiáveis. Essas modificações têm como objetivo confirmar que o mercado se encontra em condições extremas — ou seja, em sobrevenda para sinais de compra, ou em sobrecompra para sinais de venda — antes de executar qualquer ação.
- Condição de sobrevenda: sinal de compra
bool buySignal = (close1 <= lower1 && close2 <= lower2 && close3 <= lower3) && (k1 < 5 && k2 < 5 && k3 < 5); // Oversold condition
Para um sinal de compra, o preço deve estar no nível ou abaixo da banda inferior de Bollinger em todos os três timeframes (M15, M30, H1), o que indica uma forte pressão de baixa. Além disso, o valor de %K do Oscilador Estocástico deve ser menor que 5 em todos os três timeframes. Esse valor representa uma condição de sobrevenda extrema, na qual o mercado tem alta probabilidade de reverter para cima. O limite mais rigoroso de < 5 garante que o EA considere apenas sinais em que a probabilidade de reversão seja suficientemente alta.
- Condição de sobrecompra: sinal de venda
bool sellSignal = (close1 >= upper1 && close2 >= upper2 && close3 >= upper3) && (k1 > 95 && k2 > 95 && k3 > 95); // Overbought condition
Para um sinal de venda, o preço deve estar no nível ou acima da banda superior de Bollinger em todos os três timeframes, o que indica um forte impulso de alta que pode se reverter em breve. O valor de %K do Oscilador Estocástico deve exceder 95 em todos os timeframes, sinalizando uma condição de sobrecompra extrema, na qual o mercado provavelmente se tornará baixista. Essa condição rigorosa garante que o EA evite sinais falsos de venda durante movimentos de preço moderados ou períodos de consolidação.
Testes e resultados
- Testes em dados históricos
1. Carregamento dos dados históricos
Para iniciar o teste em histórico, é necessário carregar dados históricos de alta qualidade, preferencialmente no nível de ticks, para o instrumento e timeframes escolhidos. Esses dados servirão como base para a avaliação do desempenho do EA. É fundamental garantir a precisão e a confiabilidade das informações, pois qualquer inconsistência pode levar a conclusões incorretas sobre o funcionamento do EA.
Após o carregamento dos dados, é hora de configurar o testador de estratégias no MetaTrader, definindo os parâmetros necessários. Eles incluem:2. Configuração dos parâmetros de teste
- Símbolo – selecionar o par de moedas ou ativo para negociação.
- Período – utilizar os mesmos timeframes definidos nas configurações do EA (por exemplo, M15, M30, H1).
- Spread – definir um spread realista ou fixo, a fim de simular custos de negociação e garantir que os resultados reflitam condições reais de mercado.
- Otimização – testar os parâmetros de entrada (por exemplo, o período das Bandas de Bollinger e os limites do Estocástico) para alcançar o melhor desempenho possível.
3. Avaliação dos resultadosApós a configuração dos parâmetros de teste, chega o momento de analisar os resultados obtidos:
- Lucratividade: avaliar o lucro líquido do EA e o fator de lucro para determinar sua rentabilidade geral.
- Risco: avaliar o rebaixamento máximo (drawdown) para estimar a resistência do EA ao risco.
- Taxa de operações lucrativas e frequência de operações: analisar o número de operações bem-sucedidas e a frequência com que elas ocorrem, a fim de compreender a eficiência do EA em diferentes condições de mercado.
Vamos observar os resultados dos testes apresentados a seguir.

Fig. 4. Resultado do teste 1

Esquema. 5. Resultado do teste 2
Os gráficos acima ilustram o teste de desempenho do EA. Na animação GIF, podemos observar o registro de cada sinal detectado. Você pode continuar os testes ajustando os parâmetros de entrada, os timeframes e os níveis do Estocástico até alcançar resultados que atendam às suas exigências.
Conclusão
Neste artigo, desenvolvemos o EA Signal Pulse, que combina as Bandas de Bollinger e o Oscilador Estocástico para gerar sinais de negociação nos timeframes M15, M30 e H1. O sistema identifica condições de sobrecompra/sobrevenda apenas quando há coincidência entre múltiplos timeframes, o que aumenta a probabilidade de sucesso. É fundamental realizar testes detalhados em diferentes condições de mercado. Melhorias futuras podem incluir a adição de filtros de direção de tendência, aprimoramento do gerenciamento de risco e refinamento da lógica de sinais para diferentes tipos de mercado. Incentivamos os traders a utilizarem o Signal Pulse junto de suas próprias estratégias e metodologias, adotando uma abordagem abrangente para a negociação.
| Data | Nome da ferramenta | Descrição | Versão | Atualizações | Observações |
|---|---|---|---|---|---|
| 01/10/24 | Chart Projector | Script que sobrepõe o efeito “fantasma” ao movimento do preço do dia anterior. | 1.0 | Versão inicial | Primeira ferramenta do Lynnchris Tools Chest |
| 18/11/24 | Analytical Comment | Fornece informações do dia anterior em formato de tabela e também prevê a direção futura do mercado. | 1.0 | Versão inicial | Segunda ferramenta do Lynnchris Tools Chest |
| 27/11/24 | Analytics Master | Atualiza regularmente os indicadores de mercado a cada duas horas. | 1.01 | Segunda versão | Terceira ferramenta do Lynnchris Tools Chest |
| 02/12/24 | Analytics Forecaster | Atualiza regularmente os indicadores de mercado a cada duas horas, com integração ao Telegram. | 1.1 | Terceira versão | Ferramenta número 4 |
| 09/12/24 | Volatility Navigator | EA que analisa as condições de mercado usando Bandas de Bollinger, RSI e ATR. | 1.0 | Versão inicial | Ferramenta número 5 |
| 19/12/24 | Mean Reversion Signal Reaper | Analisa o mercado e gera sinais utilizando a estratégia de retorno à média | 1.0 | Versão inicial | Ferramenta número 6 |
| 09/01/2025 | Signal Pulse | Analisa múltiplos timeframes. | 1.0 | Versão inicial | Ferramenta número 7 |
Traduzido do Inglês pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/en/articles/16861
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.
Modelos ocultos de Markov para previsão de volatilidade com consideração de tendência
MQL5 Trading Toolkit (Parte 5): Expansão da biblioteca EX5 para gerenciamento do histórico com funções do último ordem pendente executada
Integrando MQL5 com pacotes de processamento de dados (Parte 4): Manipulação de Big Data
Recursos do Assistente MQL5 que você precisa conhecer (Parte 52): Oscilador Accelerator
- 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