English Русский 中文 Español Deutsch 日本語
preview
Desenvolvimento de um Kit de Ferramentas para Análise da Ação do Preço (Parte 6): Mean Reversion Signal Reaper

Desenvolvimento de um Kit de Ferramentas para Análise da Ação do Preço (Parte 6): Mean Reversion Signal Reaper

MetaTrader 5Sistemas de negociação |
83 3
Christian Benjamin
Christian Benjamin

Introdução

A reversão à média é uma estratégia de negociação intrigante que muitos traders experientes utilizam para otimizar suas percepções de mercado. Esse conceito gira em torno da ideia de que os preços dos ativos tendem a retornar às suas médias históricas, criando oportunidades para operações com timing estratégico. No entanto, analisar manualmente os movimentos de preço pode ser demorado e sujeito a falhas de observação. É aí que a automação pode melhorar significativamente a experiência de negociação.

Neste artigo, desenvolveremos um Expert Advisor em MQL5 projetado para identificar oportunidades de negociação fundamentadas nos princípios da reversão à média. Utilizando uma Média Móvel Exponencial (EMA) de 50 períodos e o Índice de Força Relativa (RSI), geraremos sinais de entrada precisos que nos permitirão aproveitar as flutuações do mercado. Para tornar o processo de negociação ainda mais intuitivo, nosso EA exibirá sinais de compra e venda como setas visuais diretamente no gráfico, juntamente com um resumo informativo detalhando os sinais.

Se você deseja simplificar sua negociação e aproveitar o poder da automação, junte-se a nós enquanto exploramos como criar um Expert Advisor em MQL5 que capture a essência da reversão à média. Vamos mergulhar nos detalhes e analisar o índice.



O que é Reversão à Média?

A reversão à média é um conceito financeiro que postula que preços de ativos, retornos ou outras métricas de mercado tendem a retornar à sua média histórica ou “média” com o passar do tempo. Essa média pode ser calculada por diferentes métodos, incluindo o preço médio em um período determinado, uma média móvel ou um retorno de referência padrão.

A teoria baseia-se na crença de que flutuações extremas no mercado são normalmente de curta duração e que os preços eventualmente se estabilizam. Traders e analistas utilizam esse princípio para identificar oportunidades de negociação, especialmente quando os preços se afastam significativamente de suas médias históricas.

Breve História e Origem

A reversão à média é um conceito enraizado na estatística e nas finanças, reconhecido pela primeira vez no início do século XX através dos trabalhos de matemáticos como Francis Galton. Originalmente aplicada ao estudo de fenômenos naturais, como a tendência de características extremas em populações (por exemplo, altura) retornarem à média ao longo das gerações, a reversão à média mais tarde tornou-se um pilar da teoria financeira.
Nos mercados financeiros, essa ideia foi popularizada por economistas como John Maynard Keynes, que observou que os preços dos ativos frequentemente oscilam em torno de seus valores fundamentais. Isso levou ao desenvolvimento de estratégias de negociação que exploram essas tendências. Por exemplo, durante a bolha das ponto-com no final dos anos 1990, muitas ações de tecnologia supervalorizadas eventualmente retornaram aos seus valores fundamentais, demonstrando a reversão à média em ação.

Exemplos Práticos de Reversão à Média

  • Mercado de Ações: Durante a pandemia de COVID-19, muitas ações apresentaram desvios acentuados de suas médias históricas. Por exemplo, ações do setor de viagens caíram drasticamente abaixo de suas médias, mas depois se recuperaram à medida que o mercado se normalizou.
  • Paridades Cambiais: As taxas de câmbio frequentemente retornam às suas médias de longo prazo devido a políticas de bancos centrais e fundamentos econômicos. Por exemplo, o par USD/JPY historicamente oscila dentro de uma faixa previsível ao longo do tempo.
  • Commodities: Os preços do ouro e do petróleo frequentemente demonstram comportamento de reversão à média, retornando a níveis históricos após picos ou quedas extremas devido a eventos geopolíticos.

Definindo Reversão à Média no Contexto de Nosso Expert Advisor (EA)

No contexto deste projeto, reversão à média refere-se à tendência do preço de um ativo retornar ao seu nível médio após mover-se significativamente acima ou abaixo dele. Esse princípio forma a base para os sinais de negociação que serão gerados pelo Expert Advisor (EA).

  • Média (50 EMA): O código utiliza uma Média Móvel Exponencial (EMA) de 50 períodos para representar a média. A EMA se ajusta dinamicamente aos dados de preço recentes, fornecendo uma referência confiável para a tendência atual do mercado. Quando o preço se desvia significativamente da EMA, isso sinaliza uma potencial reversão. 
  • Reversão em Ação: Um sinal de compra é gerado quando o preço está abaixo da EMA de 50 e o RSI está em condição de sobrevenda; o EA prevê um movimento de alta retornando em direção à EMA. Um sinal de venda, por outro lado, ocorre quando o preço está acima da EMA de 50 e o RSI está sobrecomprado; o EA antecipa uma correção de baixa retornando para a média.


Visão Geral da Estratégia

Esta estratégia é construída em torno do conceito de reversão à média, que sugere que os preços tendem a retornar aos seus níveis médios após desvios significativos. Esse comportamento cria oportunidades de negociação quando combinado com indicadores confiáveis como a EMA de 50 períodos e o Índice de Força Relativa (RSI).

  • Como funciona:

A estratégia utiliza dois indicadores principais:

  1. A EMA de 50 períodos atua como referência, representando o preço médio dinâmico ao longo de um período específico. 
  2. O RSI identifica condições de sobrecompra ou sobrevenda.

Quando os preços se desviam excessivamente da EMA de 50 e o RSI confirma condições extremas, a estratégia assume uma provável reversão em direção à média.

Conceito de Reversão à MédiaPrice (Preço) 

Fig 1. Conceito de Reversão à Média

O diagrama acima (Fig 1) ilustra os movimentos de preço em relação à Média Móvel Exponencial (EMA) e destaca os sinais de negociação acionados em níveis extremos do Índice de Força Relativa (RSI).

Um sinal de compra é gerado quando:
O preço está abaixo da EMA de 50, indicando um desvio de baixa.O RSI está abaixo de 30, confirmando um mercado em sobrevenda. Esse cenário sinaliza um possível retorno do preço em direção à média.

Um sinal de venda ocorre quando:
O preço está acima da EMA de 50, indicando um desvio de alta.O RSI está acima de 70, confirmando um mercado sobrecomprado.

  • Indicadores Visuais e Resumo em Texto:
Setas verdes indicam sinais de compra.Setas vermelhas indicam sinais de venda.Um resumo em texto é exibido no canto superior direito do gráfico mostrando o tipo de sinal (Compra/Venda). A estratégia incorpora regras claras de stop loss e take profit:
  1. Stop Loss: Colocado abaixo da mínima recente para operações de compra e acima da máxima recente para operações de venda.
  2. Take Profit: Alvo próximo da EMA de 50, onde se espera a reversão do preço.
  3. Mecanismo de Cooldown. Para evitar sinais redundantes e excesso de operações, um período de cooldown é aplicado. Após um sinal, a estratégia aguarda um número específico de candles antes de considerar novos sinais. Esse recurso ajuda a reduzir ruídos durante condições de mercado voláteis. 

O ATR (Average True Range) é utilizado para estabelecer níveis dinâmicos para definir valores de Take Profit (TP) e Stop Loss (SL).

  • Principais Benefícios da Estratégia

Benefício
Explicação:
Lógica Simples e Eficaz
Combina EMA e RSI para oportunidades confiáveis de reversão à média.
Sinais Visuais 
Setas e resumos em texto tornam os sinais claros e acionáveis.
Integração de Gestão de Risco 
Regras claras de stop loss e take profit protegem as operações e gerenciam o risco. 
Redução de Ruído Períodos de cooldown ajudam a filtrar sinais redundantes em mercados laterais.
Parâmetros Configuráveis Personalize facilmente o período da EMA, níveis de RSI e configurações de cooldown.

  • O código MQL5 para o Expert Advisor (EA).

//+------------------------------------------------------------------+
//|                                        Mean Reversion Reaper.mq5 |
//|                              Copyright 2024, Christian Benjamin. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Christian Benjamin"
#property link      "https://www.mql5.com"
#property version   "1.00"

#property strict
#property indicator_chart_window

//--- Input Parameters
input int EMA_Period = 50;                     // EMA Period
input int RSI_Period = 14;                     // RSI Period
input double RSI_Overbought = 70.0;            // RSI Overbought level
input double RSI_Oversold = 30.0;              // RSI Oversold level
input int CooldownBars = 3;                    // Cooldown bars between signals
input double ATR_Multiplier = 2.0;             // ATR Multiplier for TP and SL
input int ATR_Period = 14;                     // ATR Period
input color BuySignalColor = clrGreen;         // Buy signal arrow color
input color SellSignalColor = clrRed;          // Sell signal arrow color
input int ArrowSize = 2;                       // Arrow size
input color TextColor = clrDodgerBlue;         // Color for TP/SL text summary

//--- Global Variables
int EMA_Handle, RSI_Handle, ATR_Handle;
datetime lastSignalTime = 0;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
// Create handles for indicators
   EMA_Handle = iMA(NULL, 0, EMA_Period, 0, MODE_EMA, PRICE_CLOSE);
   RSI_Handle = iRSI(NULL, 0, RSI_Period, PRICE_CLOSE);
   ATR_Handle = iATR(NULL, 0, ATR_Period);

   if(EMA_Handle == INVALID_HANDLE || RSI_Handle == INVALID_HANDLE || ATR_Handle == INVALID_HANDLE)
     {
      Print("Failed to create indicator handles. Error: ", GetLastError());
      return INIT_FAILED;
     }

   Print("Mean Reversion EA initialized.");
   return INIT_SUCCEEDED;
  }

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
// Clear the Signal Summary text object upon deinitialization
   ObjectDelete(0, "SignalSummary");
   Print("Mean Reversion EA deinitialized.");
  }

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
// Avoid repeating signals on cooldown
   if(BarsSinceLastSignal() < CooldownBars)
      return;

   double EMA_Value = GetEMA();
   double RSI_Value = GetRSI();
   double ATR_Value = GetATR();

   if(EMA_Value == 0 || RSI_Value == 0 || ATR_Value == 0)
      return;

   double closePrice = iClose(NULL, 0, 0); // Current close price
   double highPrice = iHigh(NULL, 0, 1);   // Previous bar high
   double lowPrice = iLow(NULL, 0, 1);     // Previous bar low

// Check for Buy Signal
   if(closePrice < EMA_Value && RSI_Value <= RSI_Oversold)
     {
      DrawSignalArrow("BuySignal", closePrice, BuySignalColor);
      DisplayTextSummary("BUY", closePrice, lowPrice, ATR_Value);
      UpdateSignalTime();
     }
// Check for Sell Signal
   else
      if(closePrice > EMA_Value && RSI_Value >= RSI_Overbought)
        {
         DrawSignalArrow("SellSignal", closePrice, SellSignalColor);
         DisplayTextSummary("SELL", closePrice, highPrice, ATR_Value);
         UpdateSignalTime();
        }
  }

//+------------------------------------------------------------------+
//| Get EMA Value                                                    |
//+------------------------------------------------------------------+
double GetEMA()
  {
   double emaValues[1];
   if(CopyBuffer(EMA_Handle, 0, 0, 1, emaValues) <= 0)
      return 0;
   return emaValues[0];
  }

//+------------------------------------------------------------------+
//| Get RSI Value                                                    |
//+------------------------------------------------------------------+
double GetRSI()
  {
   double rsiValues[1];
   if(CopyBuffer(RSI_Handle, 0, 0, 1, rsiValues) <= 0)
      return 0;
   return rsiValues[0];
  }

//+------------------------------------------------------------------+
//| Get ATR Value                                                    |
//+------------------------------------------------------------------+
double GetATR()
  {
   double atrValues[1];
   if(CopyBuffer(ATR_Handle, 0, 0, 1, atrValues) <= 0)
      return 0;
   return atrValues[0];
  }

//+------------------------------------------------------------------+
//| Draw signal arrow on the chart                                   |
//+------------------------------------------------------------------+
void DrawSignalArrow(string signalType, double price, color arrowColor)
  {
   string arrowName = signalType + "_" + TimeToString(TimeCurrent(), TIME_MINUTES);
// Delete the existing arrow if it exists
   if(ObjectFind(0, arrowName) != -1)  // If the object exists
     {
      ObjectDelete(0, arrowName); // Delete the existing object
     }
   ObjectCreate(0, arrowName, OBJ_ARROW, 0, TimeCurrent(), price);
   ObjectSetInteger(0, arrowName, OBJPROP_ARROWCODE, (signalType == "BuySignal") ? 233 : 234);
   ObjectSetInteger(0, arrowName, OBJPROP_COLOR, arrowColor);
   ObjectSetInteger(0, arrowName, OBJPROP_WIDTH, ArrowSize);
  }

//+------------------------------------------------------------------+
//| Display TP and SL as text summary                                |
//+------------------------------------------------------------------+
void DisplayTextSummary(string signalType, double price, double refPrice, double ATR)
  {
   string objectName = "SignalSummary"; // Unique object name for the summary

// Delete the existing summary if it exists
   if(ObjectFind(0, objectName) != -1)  // If the object exists
     {
      ObjectDelete(0, objectName); // Delete the existing object
     }

   double SL = (signalType == "BUY") ? refPrice - (ATR * ATR_Multiplier) : refPrice + (ATR * ATR_Multiplier);
   double TP = (signalType == "BUY") ? price + (ATR * ATR_Multiplier) : price - (ATR * ATR_Multiplier);

   string summary = signalType + " Signal\n" +
                    "Price: " + DoubleToString(price, 5) + "\n" +
                    "TP: " + DoubleToString(TP, 5) + "\n" +
                    "SL: " + DoubleToString(SL, 5);

   ObjectCreate(0, objectName, OBJ_LABEL, 0, 0, 0);
   ObjectSetString(0, objectName, OBJPROP_TEXT, summary);
   ObjectSetInteger(0, objectName, OBJPROP_COLOR, TextColor);
   ObjectSetInteger(0, objectName, OBJPROP_FONTSIZE, 10); // Adjust font size if needed

// Position the label at the left upper corner
   ObjectSetInteger(0, objectName, OBJPROP_CORNER, CORNER_LEFT_UPPER);
   ObjectSetInteger(0, objectName, OBJPROP_XDISTANCE, 10); // 10 pixels from the left
   ObjectSetInteger(0, objectName, OBJPROP_YDISTANCE, 10); // 10 pixels from the top
  }

//+------------------------------------------------------------------+
//| Update signal time to prevent frequent signals                   |
//+------------------------------------------------------------------+
void UpdateSignalTime()
  {
   lastSignalTime = iTime(NULL, 0, 0);
  }

//+------------------------------------------------------------------+
//| Calculate bars since the last signal                             |
//+------------------------------------------------------------------+
int BarsSinceLastSignal()
  {
   datetime currentBarTime = iTime(NULL, 0, 0);
   if(lastSignalTime == 0)
      return INT_MAX; // If no signal has been generated return a large number.
   return (int)((currentBarTime - lastSignalTime) / PeriodSeconds());
  }
//+------------------------------------------------------------------+


Análise do código

Informações do Cabeçalho

O cabeçalho fornece metadados básicos sobre o Expert Advisor (EA), incluindo seu nome, autor e versão. Essas informações são úteis para identificar o EA e garantir a atribuição adequada. As diretivas #property especificam metadados, como direitos autorais, link do autor e versão, que são exibidos quando o EA é utilizado. Além disso, a diretiva #property indicator_chart_window indica que este EA opera na janela principal do gráfico, e não em uma subjanela separada.
//+------------------------------------------------------------------+
//| Mean Reversion Reaper.mq5                                        |
//| Author: Christian Benjamin                                       |
//| Website: https://www.mql5.com                                    |
//+------------------------------------------------------------------+
#property copyright "Christian Benjamin"
#property link      "https://www.mql5.com"
#property version   "1.00"

// Indicator operates in the main chart window
#property indicator_chart_window

Parâmetros de Entrada

Os parâmetros de entrada permitem que os usuários personalizem o comportamento do EA sem modificar o código. Esses parâmetros incluem configurações essenciais, como períodos da EMA, RSI e ATR, bem como limites para níveis de sobrecompra e sobrevenda do RSI. Um período de cooldown pode ser definido para evitar a geração frequente de sinais, ajudando a reduzir o ruído de mercado e garantindo clareza. Os usuários também podem definir elementos visuais, como cores e tamanhos das setas de compra e venda, além da cor do texto do resumo exibido no gráfico. Ao ajustar esses parâmetros, os traders podem adaptar o EA à sua estratégia ou às condições de mercado.

input int EMA_Period = 50;                     // EMA Period
input int RSI_Period = 14;                     // RSI Period
input double RSI_Overbought = 75.0;            // RSI Overbought level
input double RSI_Oversold = 25.0;              // RSI Oversold level
input int CooldownBars = 3;                    // Cooldown bars between signals
input double ATR_Multiplier = 2.0;             // ATR Multiplier for TP and SL
input int ATR_Period = 14;                     // ATR Period
input color BuySignalColor = clrGreen;         // Buy signal arrow color
input color SellSignalColor = clrRed;          // Sell signal arrow color
input int ArrowSize = 2;                       // Arrow size
input color TextColor = clrDodgerBlue;         // Color for TP/SL text summary

Variáveis Globais

A seção de variáveis globais define variáveis críticas de acompanhamento de estado e referências para os indicadores usados pelo EA. Os handles para os indicadores EMA, RSI e ATR são declarados aqui, juntamente com lastSignalTime, que armazena o timestamp do sinal mais recente. Essas variáveis garantem que o EA possa acessar os dados dos indicadores de forma eficiente e aplicar lógicas como o período de cooldown entre sinais.

int EMA_Handle, RSI_Handle, ATR_Handle;        // Handles for EMA, RSI, and ATR
datetime lastSignalTime = 0;                   // Tracks last signal time
Inicialização (OnInit)

A função OnInit é executada quando o EA é carregado em um gráfico. Sua função principal é inicializar os handles dos indicadores usando funções como iMA para EMA, iRSI para RSI e iATR para ATR. Esses handles são essenciais para recuperar valores dos indicadores durante a execução. A função também realiza verificações de erro para garantir que todos os handles sejam criados com sucesso. Se algum handle falhar, uma mensagem de erro é registrada, e o EA para de funcionar. Uma inicialização bem-sucedida gera uma mensagem de confirmação no diário, indicando que o EA está pronto para operar.

int OnInit()
{
    EMA_Handle = iMA(NULL, 0, EMA_Period, 0, MODE_EMA, PRICE_CLOSE);
    RSI_Handle = iRSI(NULL, 0, RSI_Period, PRICE_CLOSE);
    ATR_Handle = iATR(NULL, 0, ATR_Period);

    if (EMA_Handle == INVALID_HANDLE || RSI_Handle == INVALID_HANDLE || ATR_Handle == INVALID_HANDLE) {
        Print("Failed to create indicator handles. Error: ", GetLastError());
        return INIT_FAILED; // Stops EA if initialization fails
    }

    Print("Mean Reversion EA initialized.");
    return INIT_SUCCEEDED;
}

Limpeza (OnDeinit)

A função OnDeinit é chamada automaticamente quando o EA é removido do gráfico ou reinicializado. Sua principal responsabilidade é limpar objetos do gráfico criados durante a execução do EA. Especificamente, ela exclui o rótulo "SignalSummary" para garantir que o gráfico permaneça organizado. Essa função também registra uma mensagem confirmando a desinicialização do EA, proporcionando clareza sobre seu processo de encerramento.

void OnDeinit(const int reason)
{
    ObjectDelete(0, "SignalSummary"); // Remove any signal summary text
    Print("Mean Reversion EA deinitialized.");
}

Processamento de Sinais (OnTick)

A função OnTick serve como o núcleo do EA, processando cada novo tick do mercado. Ela começa verificando se o período de cooldown foi concluído desde o último sinal. Caso contrário, a função é encerrada antecipadamente para evitar sinais redundantes. Em seguida, ela obtém os valores mais recentes dos indicadores EMA, RSI e ATR utilizando seus handles correspondentes. Com esses valores, o EA avalia as condições para sinais de compra ou venda.

Um sinal de compra é acionado quando o preço está abaixo da EMA e o RSI está em território de sobrevenda. Por outro lado, um sinal de venda ocorre quando o preço está acima da EMA e o RSI está sobrecomprado. Para cada sinal, a função desenha uma seta no gráfico e exibe um resumo em texto com o preço, os níveis de stop-loss (SL) e take-profit (TP). O timestamp do sinal é atualizado para aplicar o mecanismo de cooldown.

void OnTick()
{
    if (BarsSinceLastSignal() < CooldownBars) return; // Skip if cooldown is active

    double EMA_Value = GetEMA();   // Fetch EMA value
    double RSI_Value = GetRSI();   // Fetch RSI value
    double ATR_Value = GetATR();   // Fetch ATR value

    double closePrice = iClose(NULL, 0, 0); // Current bar's close price

    if (closePrice < EMA_Value && RSI_Value <= RSI_Oversold) {
        // Buy Signal
        DrawSignalArrow("BuySignal", closePrice, BuySignalColor);
        DisplayTextSummary("BUY", closePrice, iLow(NULL, 0, 1), ATR_Value);
        UpdateSignalTime(); // Update last signal time
    } else if (closePrice > EMA_Value && RSI_Value >= RSI_Overbought) {
        // Sell Signal
        DrawSignalArrow("SellSignal", closePrice, SellSignalColor);
        DisplayTextSummary("SELL", closePrice, iHigh(NULL, 0, 1), ATR_Value);
        UpdateSignalTime(); // Update last signal time
    }
}

Funções Utilitárias
  • Obter Valores dos Indicadores

Funções utilitárias como GetEMA, GetRSI e GetATR são projetadas para buscar os valores mais recentes de seus respectivos indicadores. Essas funções utilizam o método CopyBuffer para extrair dados dos handles dos indicadores. Se a obtenção de dados falhar por qualquer motivo, as funções retornam zero, sinalizando que o EA deve ignorar o processamento naquele tick. Essas funções são leves e modulares, mantendo o código limpo e de fácil manutenção.

double GetEMA()
{
    double emaValues[1];
    if (CopyBuffer(EMA_Handle, 0, 0, 1, emaValues) <= 0)
        return 0;
    return emaValues[0];
}

double GetRSI()
{
    double rsiValues[1];
    if (CopyBuffer(RSI_Handle, 0, 0, 1, rsiValues) <= 0)
        return 0;
    return rsiValues[0];
}

double GetATR()
{
    double atrValues[1];
    if (CopyBuffer(ATR_Handle, 0, 0, 1, atrValues) <= 0)
        return 0;
    return atrValues[0];
}
  • Desenhar Seta de Sinal

A função DrawSignalArrow adiciona um indicativo visual ao gráfico, sinalizando compra ou venda. Ela gera dinamicamente um nome único para cada seta usando o tipo de sinal e o horário atual, garantindo que não haja sobreposição com objetos existentes. Se uma seta com o mesmo nome já existir, ela é excluída antes da criação de uma nova. As propriedades da seta, como cor, tamanho e tipo, são determinadas pelos parâmetros definidos pelo usuário, permitindo uma representação visual clara e personalizável.

void DrawSignalArrow(string signalType, double price, color arrowColor)
{
    string arrowName = signalType + "_" + TimeToString(TimeCurrent(), TIME_MINUTES);
    if (ObjectFind(0, arrowName) != -1) ObjectDelete(0, arrowName);

    ObjectCreate(0, arrowName, OBJ_ARROW, 0, TimeCurrent(), price);
    ObjectSetInteger(0, arrowName, OBJPROP_ARROWCODE, (signalType == "BuySignal") ? 233 : 234);
    ObjectSetInteger(0, arrowName, OBJPROP_COLOR, arrowColor);
    ObjectSetInteger(0, arrowName, OBJPROP_WIDTH, ArrowSize);
}
  • Exibir Resumo de TP/SL

A função DisplayTextSummary fornece um resumo conciso do sinal, incluindo preço, stop-loss e take-profit. Essas informações são exibidas como um rótulo no gráfico, posicionado no canto superior esquerdo. A função calcula os níveis de TP e SL com base no ATR e no seu multiplicador, oferecendo níveis dinâmicos que se adaptam à volatilidade do mercado. Se um rótulo de resumo já existir, ele é excluído antes da criação de um novo. Isso garante que apenas as informações mais recentes sejam exibidas, reduzindo a desordem e melhorando a legibilidade.

void DisplayTextSummary(string signalType, double price, double refPrice, double ATR)
{
    string objectName = "SignalSummary";
    if (ObjectFind(0, objectName) != -1) ObjectDelete(0, objectName);

    double SL = (signalType == "BUY") ? refPrice - (ATR * ATR_Multiplier) : refPrice + (ATR * ATR_Multiplier);
    double TP = (signalType == "BUY") ? price + (ATR * ATR_Multiplier) : price - (ATR * ATR_Multiplier);

    string summary = signalType + " Signal\n" +
                     "Price: " + DoubleToString(price, 5) + "\n" +
                     "TP: " + DoubleToString(TP, 5) + "\n" +
                     "SL: " + DoubleToString(SL, 5);

    ObjectCreate(0, objectName, OBJ_LABEL, 0, 0, 0);
    ObjectSetString(0, objectName, OBJPROP_TEXT, summary);
    ObjectSetInteger(0, objectName, OBJPROP_COLOR, TextColor);
    ObjectSetInteger(0, objectName, OBJPROP_CORNER, CORNER_LEFT_UPPER);
    ObjectSetInteger(0, objectName, OBJPROP_XDISTANCE, 10);
    ObjectSetInteger(0, objectName, OBJPROP_YDISTANCE, 10);
}
  • Gerenciamento de Cooldown
O EA aplica um período de cooldown entre os sinais para evitar excesso de operações durante condições voláteis de mercado. A função UpdateSignalTime atualiza a variável lastSignalTime com o timestamp do sinal mais recente, enquanto a função BarsSinceLastSignal calcula o número de candles decorridos desde o último sinal. Se nenhum sinal tiver sido gerado ainda, um valor alto é retornado para garantir a operação normal. Esse mecanismo garante que os sinais sejam espaçados adequadamente, oferecendo aos traders percepções mais claras e confiáveis.
void UpdateSignalTime()
{
    lastSignalTime = iTime(NULL, 0, 0); // Store time of the current bar
}

int BarsSinceLastSignal()
{
    datetime currentBarTime = iTime(NULL, 0, 0);
    if (lastSignalTime == 0) return INT_MAX; // No signals generated yet
    return (int)((currentBarTime - lastSignalTime) / PeriodSeconds());
}


Testes e Resultados

Vamos falar sobre backtesting, uma etapa essencial na avaliação do seu Expert Advisor (EA). Basicamente, backtesting envolve executar o EA em dados históricos de mercado para verificar como ele teria se comportado no passado. Esse processo é crucial para determinar se sua estratégia está alinhada com diferentes condições de mercado e para obter insights sobre sua robustez geral.
Aqui estão alguns pontos importantes a serem considerados ao realizar backtesting:
  • Faixa de Dados Históricos: Certifique-se de usar dados que incluam diferentes condições de mercado, como períodos de tendência e de consolidação. Isso ajuda a avaliar a adaptabilidade do seu EA.
  • Métricas-Chave: Concentre-se em medir o desempenho por meio de métricas importantes, incluindo fator de lucro, taxa de acerto, rebaixamento máximo e duração média das operações. Essas métricas oferecerão uma visão mais clara da eficácia da sua estratégia.
  • Otimização: Não hesite em testar diferentes combinações de parâmetros — como período da EMA e níveis do RSI — para descobrir as configurações mais eficazes para determinados instrumentos ou timeframes.
  • Validação Visual: Por fim, sempre verifique se as setas e os sinais gerados pelo EA estão alinhados com a lógica pretendida da sua estratégia. Isso é fundamental para garantir que tudo esteja funcionando conforme projetado.

Ao realizar o backtesting do seu EA considerando esses pontos, você poderá construir uma estratégia de negociação mais confiável e eficaz.

TESTE DE SINAL

Fig 2. Resultado do Teste 1

O diagrama acima exibe os testes realizados em dois timeframes diferentes para o índice Volatility 75 (1s) ao longo de um período de 29 dias. Abaixo, apresentamos em tabela os resultados dos dois testes.

Tabelas de Geração de Sinais e Desempenho

  • Tabela 1

Tipo de Sinal  Timeframe  Total de sinais gerados
Sinais verdadeiros (onde o preço subiu após o sinal)
Precisão do Sinal de Compra (%)
Compra M30 41 33 80.5%
Venda M30 21 15 71.4%

  • Tabela 2

Tipo de Sinal  Timeframe  Total de sinais gerados
Sinais verdadeiros (onde o preço subiu após o sinal)
Precisão do Sinal de Compra (%)
 Compra H1 19 14 73.6% 
 Venda H1  13 61.5% 

Abaixo está uma ilustração dos resultados do teste em tempo real para o Expert Advisor (EA).

Sinal em Tempo Real

Fig 3. Resultado do Teste 2

Vamos também analisar o GIF abaixo.

RESULTADO DO TESTE

Fig 4. Resultado do Teste 3

Referências:


Conclusão

O Expert Advisor (EA) Mean Reversion Reaper oferece um sistema confiável de geração de sinais baseado em princípios de reversão à média, alcançando uma taxa de precisão impressionante de pelo menos 70% para sinais de compra. Seu uso do Average True Range (ATR) para definição dos níveis de stop-loss (SL) e take-profit (TP) permite que o sistema se adapte a diferentes condições de volatilidade do mercado, tornando-o particularmente eficaz em mercados laterais.

No entanto, é importante ter em mente que o EA pode ser menos eficaz durante mercados fortemente direcionais, o que é uma característica típica de estratégias de reversão à média. Para aprimorar sua experiência de negociação, considere ajustar os parâmetros e explorar filtros adicionais para sinais de venda. Como o EA não executa operações automaticamente, seus sinais podem ser especialmente úteis para traders manuais que desejam aproveitar reversões de curto prazo.

Em essência, o Mean Reversion Reaper EA pode ser um aliado poderoso para traders interessados em padrões de reversão de mercado. Ao manter atenção às condições do mercado e estar disposto a ajustar sua estratégia, você pode maximizar o potencial dessa ferramenta em seu arsenal de negociação.

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 A primeira ferramenta do Lynnchris Tools Chest
18/11/24 Comentário Analítico Fornece informações do dia anterior em formato tabular, além de antecipar a direção futura do mercado. 1.0 Lançamento Inicial Segunda ferramenta no Lynnchris Tool Chest
27/11/24 Mestre em Análise Atualização Regular das métricas de mercado a cada duas horas  1.01 Segundo Lançamento Terceira ferramenta no Lynnchris Tool Chest
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 usando os indicadores Bandas de Bollinger, RSI e ATR 1.0 Lançamento Inicial Ferramenta número 5
19/12/24 Mean Reversion Signal Reaper  Analisa o mercado usando a estratégia de reversão à média e fornece sinais.  1.0  Lançamento Inicial  Ferramenta número 6 

Traduzido do Inglês pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/en/articles/16700

Arquivos anexados |
Mean_Reversion.mq5 (16.16 KB)
Últimos Comentários | Ir para discussão (3)
linfo2
linfo2 | 7 jan. 2025 em 03:33
Obrigado, Christian, muito útil como modelo
Roman Shiredchenko
Roman Shiredchenko | 3 set. 2025 em 18:58
Sim.... Obrigado. Material interessante - vou levá-lo para meu trabalho e também procurar variantes da abordagem de negociação no testador de estratégias e em negociações reais......
khanatd
khanatd | 15 out. 2025 em 06:10

Olá, senhor, a versão mql4 está disponível com setas na vela atual?

Obrigado

khan

Gerenciamento de riscos (Parte 2): Implementação do cálculo de lotes na interface gráfica Gerenciamento de riscos (Parte 2): Implementação do cálculo de lotes na interface gráfica
Neste artigo, analisaremos como aprimorar e aplicar de forma mais eficiente os conceitos apresentados no artigo anterior, utilizando as poderosas bibliotecas de elementos gráficos de controle do MQL5. Conduzirei você passo a passo pelo processo de criação de uma interface gráfica totalmente funcional, explicando o plano de projeto subjacente, bem como o propósito e o princípio de funcionamento de cada método empregado. Além disso, ao final do artigo testaremos o painel criado, a fim de confirmar seu correto funcionamento e sua aderência aos objetivos estabelecidos.
Técnicas do MQL5 Wizard que você deve conhecer (Parte 51): Aprendizado por Reforço com SAC Técnicas do MQL5 Wizard que você deve conhecer (Parte 51): Aprendizado por Reforço com SAC
Soft Actor Critic é um algoritmo de Aprendizado por Reforço que utiliza 3 redes neurais. Uma rede ator e 2 redes críticas. Esses modelos de aprendizado de máquina são combinados em uma parceria mestre-escravo onde as redes críticas são modeladas para melhorar a precisão de previsão da rede ator. Ao mesmo tempo em que introduzimos ONNX nesta série, exploramos como essas ideias podem ser colocadas à prova como um sinal personalizado de um Expert Advisor montado pelo wizard.
Do básico ao intermediário: Sobrecarga de operadores (II) Do básico ao intermediário: Sobrecarga de operadores (II)
Este será um artigo que a principio irá parecer bem confuso devido ao que será mostrado nele. Porém tentei deixar as coisas o mais simples e didáticas quanto foi possível ser feito. Espero que você consiga compreender o que estará sendo demonstrando neste artigo. E que isto venha a lhe ser útil em algum momento.
Desenvolvimento de sistemas de trading avançados ICT: Implementação de sinais no indicador Order Blocks Desenvolvimento de sistemas de trading avançados ICT: Implementação de sinais no indicador Order Blocks
Neste artigo você vai aprender como desenvolver um indicador Order Blocks baseado no volume do livro de ofertas (profundidade de mercado) e otimizá-lo usando buffers para melhorar a precisão. Com isso, concluímos a etapa atual do projeto e nos preparamos para as próximas, nas quais será implementada uma classe de gerenciamento de risco e um robô de negociação que utilizará os sinais gerados pelo indicador.