Desenvolvimento de um Kit de Ferramentas para Análise da Ação do Preço (Parte 6): Mean Reversion Signal Reaper
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.
- Introdução
- O que é Reversão à Média?
- Visão Geral da Estratégia
- Análise do código
- Testes e Resultados
- Conclusão
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:
- 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.
- 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.
Price (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:
- Stop Loss: Colocado abaixo da mínima recente para operações de compra e acima da máxima recente para operações de venda.
- Take Profit: Alvo próximo da EMA de 50, onde se espera a reversão do preço.
- 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 timeInicializaçã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
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.

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 | 8 | 61.5% |
Abaixo está uma ilustração dos resultados do teste em tempo real para o Expert Advisor (EA).

Fig 3. Resultado do Teste 2
Vamos também analisar o GIF abaixo.

Fig 4. Resultado do Teste 3
Referências:
- De Bondt, Werner F. M., e Richard Thaler. "Does the stock market overreact?" The Journal of Finance, 1985.
- Pindyck, Robert S. "The dynamics of commodity spot and futures markets: A primer." The Energy Journal, 2001.
- Wilder, J. Welles Jr. "New Concepts in Technical Trading Systems." Trend Research, 1978.
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
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.
Gerenciamento de riscos (Parte 2): Implementação do cálculo de lotes na interface gráfica
Técnicas do MQL5 Wizard que você deve conhecer (Parte 51): Aprendizado por Reforço com SAC
Do básico ao intermediário: Sobrecarga de operadores (II)
Desenvolvimento de sistemas de trading avançados ICT: Implementação de sinais no indicador Order Blocks
- 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
Olá, senhor, a versão mql4 está disponível com setas na vela atual?
Obrigado
khan