
Implementação do EA Deus: Negociação automatizada com RSI e médias móveis em MQL5
Introdução
O artigo aborda os principais componentes do EA Deus, incluindo sua lógica de negociação, configurações de parâmetros e o código MQL5 necessário para sua implementação. O objetivo é fornecer a você o conhecimento e as ferramentas necessárias para desenvolver e aprimorar seu algoritmo de negociação. Ao usar o EA Deus, você poderá explorar o mundo da negociação automatizada e descobrir novas oportunidades para o seu trading.
Vamos analisar a funcionalidade do EA Deus, uma metodologia automatizada de negociação desenvolvida com MQL5. Durante a discussão, o foco principal será a forma como o EA Deus utiliza médias móveis e o Índice de Força Relativa (RSI) para tomar decisões de negociação. Ao analisar esses indicadores, o EA identifica os melhores pontos de entrada e saída no mercado, visando maximizar a lucratividade das operações e minimizar o risco.
Desenvolvido para a plataforma MetaTrader 5, o EA Deus é um sistema de negociação automatizado que gera sinais de compra e venda com base nas médias móveis e no Índice de Força Relativa (RSI). Ao identificar tendências de mercado e detectar condições de sobrecompra ou sobrevenda, ele busca aprimorar as decisões de negociação. Além disso, o EA inclui ferramentas de gerenciamento de risco, como stop-loss, take-profit e trailing stops.
Visão geral do EA Deus
O EA Deus utiliza o Índice de Força Relativa (RSI) e médias móveis para automatizar as decisões de negociação. Seu objetivo é aumentar a eficiência das negociações e gerenciar riscos de maneira eficaz, utilizando esses indicadores para fornecer recomendações precisas de compra e venda.
Abaixo estão os principais elementos do EA Deus:
- Indicadores técnicos:
- Relative Strength Index (RSI) - este oscilador de momentum mede a velocidade e a magnitude das movimentações dos preços. Ele ajuda a determinar quando o mercado está sobrecomprado ou sobrevendido e a reagir rapidamente às movimentações de preço. No nosso caso, o EA usará um RSI de curto prazo com período de 7 dias e valores-limite de 35 para sobrecompra e 15 para sobrevenda.
- Moving Averages (MA) - a média móvel suaviza os dados de preços para identificar tendências ao longo de um determinado período. No EA Deus, utilizaremos uma média móvel simples (SMA) de 25 períodos para filtrar sinais de negociação e definir a direção geral do mercado.
- Sinal de compra: Quando o preço está acima da média móvel e o RSI indica uma condição de sobrevenda (abaixo de 15), sugerindo um possível movimento ascendente no preço, uma ordem de compra é colocada.
- Sinal de venda: Se o preço estiver abaixo da média móvel e o RSI indicar uma condição de sobrecompra (acima de 35), o que sugere uma possível tendência de queda, uma ordem de venda é colocada.
3. Gerenciamento de risco:
- Stop-loss e take-profit: No nosso EA, incluímos parâmetros ajustáveis para os níveis de stop-loss e take-profit, definidos em 50 pontos cada, para ajudar a gerenciar riscos e garantir a realização de lucros.
- Trailing-stop: Utilizamos um trailing-stop de 25 pontos para ajustar dinamicamente os níveis de stop-loss à medida que o preço se move a favor da posição, buscando proteger os lucros enquanto permite que a operação permaneça aberta enquanto o mercado seguir na direção desejada.
4. Gerenciamento de ordens:
- Gerenciamento de posições: Apenas uma posição pode estar aberta ao mesmo tempo; todas as posições existentes são fechadas antes de abrir uma nova, com base nos sinais de negociação.
O EA Deus possui funções de inicialização, processamento de ticks, abertura e fechamento de posições, além da configuração do trailing-stop. Ele é implementado na linguagem de script MQL5, utilizada no MetaTrader 5. A programação deve seguir as diretrizes de gerenciamento de risco e garantir o processamento eficiente dos sinais de negociação.
O EA Deus ajuda a automatizar os processos de negociação, reduzir o impacto emocional na tomada de decisões e melhorar os resultados operacionais por meio dessas funções. O artigo fornece uma base para compreender os conceitos e funcionalidades do EA Deus.
Implementação em MQL5
Primeiro, precisamos abrir posições de negociação. As posições são abertas por meio da inclusão de um arquivo específico para essa finalidade.
#include <Trade\Trade.mqh>
CTrade trade;
Aqui, utilizamos um arquivo para incluir a biblioteca de negociação. Isso permite que o EA Deus tenha acesso às funções de operações de mercado. Nesta etapa, também definimos a classe CTrade, que oferece um alto nível de abstração para a execução de atividades de negociação. O EA pode utilizar a classe CTrade incluída para gerenciar transações. No EA, esse objeto será utilizado para executar diversas tarefas de negociação, incluindo a abertura, modificação e fechamento de posições.
Nesta seção, analisaremos os principais parâmetros de entrada do EA Deus. O EA Deus é um algoritmo de negociação avançado que utiliza indicadores de média móvel e RSI para identificar oportunidades de negociação. Ajustando esses parâmetros, os traders podem configurar o EA para se comportar da maneira que melhor se adapte à sua estratégia de negociação e ao seu nível de tolerância ao risco.
Os parâmetros de entrada são os seguintes:
input double Lots = 0.1; // Lot size input double StopLoss = 50; // Stop loss in points input double TakeProfit = 50; // Take profit in points input double TrailingStop = 25; // Trailing stop in points
- Lots (volume de negociação)
input double Lots = 0.1; // Lot size
O tamanho de cada operação é determinado pelo parâmetro Lots. Neste caso, o EA está configurado para negociar 0,1 lote por operação. Os traders podem gerenciar o nível de risco ajustando o tamanho do lote. Um lote menor reduz tanto os riscos potenciais quanto os lucros, enquanto um lote maior aumenta não apenas os possíveis ganhos, mas também os riscos. Para equilibrar risco e retorno, é essencial escolher o tamanho de lote adequado.
2. StopLoss (stop-loss em pontos)
input double StopLoss = 50; // Stop loss in points
O prejuízo máximo permitido por operação é definido pelo parâmetro StopLoss, que, neste caso, está configurado para 50 pontos. Para evitar perdas excessivas, a posição será fechada automaticamente caso o mercado se mova contra a operação além desse limite. Isso protege a conta de negociação contra grandes perdas.
3. TakeProfit (take-profit em pontos)
input double TakeProfit = 50; // Take profit in points
O alvo de lucro para cada operação é definido pelo parâmetro TakeProfit, configurado para 50 pontos. Para garantir a obtenção de lucros, a posição será fechada automaticamente quando o mercado se mover favoravelmente até o nível especificado. Isso ajuda a proteger os ganhos antes que as condições do mercado mudem, melhorando a rentabilidade da estratégia.
4. TrailingStop (gatilho do trailing-stop)
input double TrailingStop = 25; // Trailing stop in points
Utilizamos um stop-loss dinâmico por meio do parâmetro TrailingStop, que ajusta sua posição conforme o mercado se move a favor da operação. Quando o preço avança na direção da negociação, o trailing-stop, inicialmente definido a 25 pontos da entrada, será ajustado para garantir a fixação dos lucros. Essa funcionalidade permite que os traders capturem ganhos em grandes oscilações do mercado enquanto protegem seus lucros.
Parâmetros do indicador RSI:
input int RSI_Period = 7; // RSI period input double RSI_Overbought = 35.0; // RSI overbought level input double RSI_Oversold = 15.0; // RSI oversold level
5. RSI_Period (período de cálculo do RSI)
input int RSI_Period = 7; // RSI period
O número de períodos usados para calcular o Índice de Força Relativa (RSI) é determinado pelo parâmetro RSI_Period. No nosso caso, ele é definido como 7. O RSI é um oscilador de momentum que mede a velocidade e a magnitude das variações de preço. Um RSI de curto período, como 7, é mais sensível às oscilações recentes do preço, tornando-se útil para identificar rapidamente condições de sobrecompra ou sobrevenda.
6. RSI_Overbought (nível de sobrecompra do RSI)
input double RSI_Overbought = 35.0;
O limite para identificar uma condição de sobrecompra é definido pelo parâmetro RSI_Overbought, configurado para 35,0. Normalmente, o nível de sobrecompra é 70, mas nesta abordagem, o valor de 35,0 representa uma postura de venda mais agressiva. O EA executará uma venda quando o RSI ultrapassar esse valor, indicando uma alta probabilidade de reversão do mercado para queda.
7. RSI_Oversold (nível de sobrevenda do RSI)
input double RSI_Oversold = 15.0; // RSI oversold level
O limite para indicar uma condição de sobrevenda é definido pelo parâmetro RSI_Oversold, configurado para 15,0. Embora essa abordagem utilize um nível mais conservador para sinalizar uma possível compra, um nível típico de sobrevenda pode ser 30. O EA executará uma compra quando o RSI cair abaixo desse valor, pois isso é interpretado como uma possível reversão do mercado para alta.
Parâmetros da Média Móvel
input int MA_Period = 25; // Moving Average period input ENUM_MA_METHOD MA_Method = MODE_SMA; // Moving Average method input ENUM_APPLIED_PRICE MA_Price = PRICE_CLOSE; // Applied price for MA
8. MA_Period (período da média móvel)
input int MA_Period = 25; // Moving Average period
O período de cálculo da média móvel (MA) é determinado pelo parâmetro MA_Period, que está definido como 25. A média móvel suaviza os dados de preço para identificar tendências. A janela de 25 períodos proporciona uma visão abrangente das tendências de mercado, pois não apenas reduz o ruído de curto prazo, mas também reage a mudanças significativas no preço.
9. MA_Method (método da média móvel)
Moving Average period input ENUM_MA_METHOD MA_Method = MODE_SMA; // Moving Average method
O tipo de média móvel utilizada, neste caso, a média móvel simples (SMA), é definido pelo parâmetro MA_Method. A SMA é um indicador de tendência básico que calcula a média dos preços de fechamento ao longo de um determinado período. Para ajustar a sensibilidade, podem ser usados métodos alternativos, como a média móvel exponencial (EMA), mas a SMA continua sendo um indicador confiável e estável de tendência.
10. MA_Price (preço aplicado à média móvel)
input ENUM_APPLIED_PRICE MA_Price = PRICE_CLOSE; // Applied price for MA
O tipo de preço usado para calcular a média móvel é especificado pelo parâmetro MA_Price, que está configurado como PRICE_CLOSE. Isso significa que a média móvel é calculada com base nos preços de fechamento, frequentemente utilizados por representarem o fechamento da sessão de negociação. Essa escolha garante que a média móvel forneça informações confiáveis sobre a tendência geral do mercado.
O comportamento de negociação e o gerenciamento de risco do EA Deus são amplamente determinados por seus parâmetros de entrada. Os traders podem ajustar o EA para que ele se adeque melhor às suas metas individuais de negociação e às condições atuais do mercado, modificando parâmetros como volume de negociação, ferramentas de gerenciamento de risco, duração dos indicadores e níveis de limite. Para aproveitar ao máximo o EA Deus na negociação automatizada, é essencial compreender e ajustar esses parâmetros adequadamente.
Vamos analisar as novas variáveis do nosso EA, baseadas nos indicadores de média móvel e RSI. Compreendendo esses fatores, podemos entender como o EA processa a execução das operações e analisa os dados do mercado.
//--- Variables double rsiValue; // RSI value double maValue; // Moving Average value double Ask; double Bid; double Close; // Initializing Close array with two elements
Valor do RSI:
double rsiValue; // RSI value
O valor atual do Índice de Força Relativa (RSI) é armazenado na variável rsiValue. Sendo um oscilador de momentum, o RSI ajuda a identificar quando o mercado está sobrecomprado ou sobrevendido, calculando a velocidade e a dispersão das variações de preço.
Para determinar o valor do RSI, são utilizados o tipo de preço e o período de RSI especificado. O EA Deus calcula o RSI com base nos parâmetros definidos pelo usuário e nos dados de preço mais recentes.
Quando o valor do RSI cai abaixo do nível RSI_Oversold, o EA interpreta isso como um sinal de compra. Isso indica que o mercado pode estar sobrevendido e que há possibilidade de uma reversão para alta.
Por outro lado, se o valor do RSI ultrapassar o nível RSI_Overbought de baixo para cima, isso é um sinal de venda. Isso significa que o mercado está sobrecomprado e pode ocorrer um recuo nos preços.
Valor da Média Móvel:
double maValue; // Moving Average value
O valor atual da média móvel é armazenado na variável maValue. Ao suavizar os dados de preço ao longo de um determinado período, o indicador facilita a identificação da tendência.
A média móvel é calculada utilizando o método escolhido, o tipo de preço e o período especificado. No nosso EA, a média móvel é calculada com base no preço de fechamento do período definido.
Tendência: A tendência do mercado é confirmada pelo valor da média móvel. Quando o preço está acima da média móvel, o EA considera que o mercado está em tendência de alta. Quando o preço está abaixo da média móvel, o EA interpreta que o mercado está em tendência de baixa.
Sinal de entrada: A formação dos sinais de negociação depende da relação entre os valores do RSI e da média móvel. Por exemplo, se o preço de fechamento anterior estava acima do valor da média móvel e o RSI estiver abaixo do nível RSI_Oversold, o sinal de compra é considerado confirmado. Os valores do RSI e da média móvel são combinados no EA Deus, permitindo que ele tome decisões de negociação fundamentadas.
double Ask;
O preço ask atual do ativo é armazenado na variável ask. Esse é o preço pelo qual os traders podem comprar o ativo. Ele define o preço de entrada para ordens de compra dentro da função OpenPosition. O preço ask representa o valor máximo disponível no momento para a compra de um ativo. O monitoramento preciso desse preço garante que as ordens de compra sejam executadas no momento certo.
double Bid;
O preço bid atual do ativo é armazenado na variável bid. Esse é o preço pelo qual os traders podem vender o ativo. Ele define o preço de entrada para ordens de venda dentro da função OpenPosition. O melhor preço possível para vender um ativo no momento é refletido no preço bid.
double Close[];
O preço de fechamento do ativo em um determinado período é armazenado no array Close. Neste EA, ele foi expandido para armazenar valores para uso atual. O array é utilizado para gerar sinais de negociação e analisar o movimento dos preços. Para decidir se um sinal de compra ou venda deve ser ativado, o valor é comparado com os preços de fechamento do período anterior (Close[1]) e do período mais recente (Close[0]). Essa comparação nos ajudará a determinar se o preço está subindo ou caindo.
void ApplyTrailingStop();
Essa função será útil para a implementação do mecanismo de trailing-stop. Se o preço atual do mercado se mover na direção do stop-loss da posição, a função percorrerá todas as posições abertas e ajustará o stop-loss. A função garante que o stop-loss permaneça na posição mais vantajosa, mesmo se o preço do mercado se mover contra a operação.
void OpenPosition(CTrade trade, int orderType);
Dependendo do tipo de ordem, esse método é projetado para abrir novas posições de negociação. A função define os níveis de take-profit, stop-loss e o preço de entrada com base no tipo de ordem. A execução da operação é realizada utilizando os parâmetros calculados por meio do objeto CTrade. Isso ajudará o EA a gerar sinais que podem ser cruciais para o início da negociação.
void ClosePositions(int orderType);
Com essa função, as posições de negociação de um determinado tipo de ordem são fechadas. A função percorre todas as posições abertas e fecha aquelas que correspondem ao tipo de ordem especificado. Isso ajudará a eliminar posições que não estão mais alinhadas com a estratégia de negociação ou com as condições atuais do mercado, melhorando, assim, o gerenciamento da negociação.
//--- Function prototypes void ApplyTrailingStop(); void OpenPosition(CTrade trade, int orderType);
Em seguida, combinamos esses protótipos de funções para permitir que o EA gerencie as posições de forma eficiente. O método OpenPosition inicia negociações com base nas condições do mercado, a função ClosePositions monitora e encerra operações conforme necessário, e a função ApplyTrailingStop aprimora o gerenciamento das operações ajustando os níveis de stop-loss. Todas essas funções, em conjunto, permitem que o EA reaja rapidamente às mudanças do mercado e execute operações de maneira eficiente.
Agora, vamos para a função OnInit. O EA Deus utiliza a função OnInit para iniciar a negociação. Ele foi projetado para realizar operações com base nos indicadores de média móvel e RSI.
//+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { Print("Deus EA initialized successfully."); return(INIT_SUCCEEDED); }
Ao iniciar o terminal ou carregar o EA no gráfico, a função OnInit é chamada uma única vez. Durante essa etapa, ocorre a inicialização das variáveis, a configuração dos handles dos indicadores e a execução de quaisquer outras operações de configuração que exijam essa função. Em seguida, desmembramos essa função em partes da seguinte forma:
Print("Deus EA initialized successfully.");
O objetivo desta linha de código é exibir uma mensagem no log do EA, confirmando a conclusão bem-sucedida da inicialização. O registro de logs é um dos componentes mais importantes de qualquer EA. Dessa forma, podemos garantir que o EA foi carregado e inicializado corretamente, sem problemas. Isso também é útil para depuração e para verificar se o EA está pronto para processar dados de mercado e executar operações.
return(INIT_SUCCEEDED); }
A instrução return (INIT_SUCCEEDED); notifica a plataforma MetaTrader sobre a conclusão do processo de inicialização. O EA deve retornar INIT_SUCCEEDED para prosseguir para as próximas etapas, como a função OnTick, onde a lógica principal de negociação é executada. Caso a inicialização falhe por qualquer motivo, a função pode retornar INIT_FAILED, interrompendo a execução do EA e prevenindo possíveis falhas durante a operação.
Agora, vamos analisar a função OnDeinit. Ela desempenha um papel crucial na manutenção da confiabilidade e integridade do EA. Vamos discutir sua função. Quando o EA é recompilado, ele é removido do gráfico. Essa ação ativa a função OnDeinit, permitindo que ela execute tarefas de limpeza, garantindo que os recursos sejam liberados corretamente e que todas as etapas finais sejam concluídas.
//+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { Print("Deus EA deinitialized. Reason: ", reason); }
O motivo da desinicialização é determinado pelo parâmetro reason da função OnDeinit. Esse parâmetro pode ser útil para depuração e para entender as razões pelas quais o EA foi desinicializado. Para registrar essa informação, utilizamos a função Print no EA Deus.
void OnDeinit(const int reason) { Print("Deus EA deinitialized. Reason: ", reason); }
Esses registros simples no log permitem identificar claramente se o EA foi removido manualmente, recompilado ou se a desinicialização ocorreu devido ao encerramento do terminal. Essas informações podem ser valiosas durante as fases de desenvolvimento e teste.
Embora o motivo da desinicialização seja o único aspecto registrado na implementação atual da função OnDeinit, essa função pode ser expandida para incluir qualquer procedimento de limpeza necessário. Por exemplo, pode ser necessário fechar todos os recursos abertos, liberar handles de arquivos ou salvar o estado atual do EA. A limpeza correta evita vazamentos de recursos e garante que o EA seja reinicializado de maneira limpa. Isso é essencial em operações de negociação em tempo real, onde a confiabilidade e a estabilidade são fundamentais. Um bom gerenciamento desse processo evita que problemas de desempenho causados por execuções anteriores afetem o novo início do EA.
Agora passamos para a função OnTick, que é fundamental para o processo de tomada de decisões do EA em tempo real. Essa função é chamada a cada novo tick de preço, permitindo que o EA avalie as condições do mercado e execute operações de acordo com a estratégia previamente definida. Abaixo estão os principais componentes da função OnTick, juntamente com a explicação de como ela integra os elementos da estratégia do EA Deus:
- Obtenção de informações de mercado:
Na primeira execução, a função OnTick coleta o máximo possível de dados de mercado.
Ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); Bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); ArrayResize(Close, 2); Close[0] = iClose(_Symbol, _Period, 0); Close[1] = iClose(_Symbol, _Period, 1);
O código armazena os preços de fechamento mais recentes e obtém os preços ask e bid. Para garantir que haja espaço suficiente no array Close para armazenar o último preço de fechamento, utiliza-se ArrayResize.
- Cálculo dos indicadores técnicos:
A média móvel e o Índice de Força Relativa (RSI) são calculados com base em seus respectivos algoritmos.
//--- Calculate RSI value rsiValue = iRSI(_Symbol, _Period, RSI_Period, PRICE_CLOSE, 0); if (rsiValue == WRONG_VALUE) { Print("Error calculating RSI"); return; } //--- Calculate Moving Average value maValue = iMA(_Symbol, _Period, MA_Period, 0, MA_Method, MA_Price, 0); if (maValue == WRONG_VALUE) { Print("Error calculating Moving Average"); return; }
Enquanto o valor da média móvel ajuda a identificar a direção da tendência, o valor do RSI indica as condições de sobrecompra ou sobrevenda. Antes de prosseguir com a verificação, é essencial garantir que os valores estejam corretos.
- Geração de sinais de negociação: Após calcular os indicadores, a função busca por sinais de compra e venda:
//--- Check for Buy Signal if(rsiValue < RSI_Oversold && Close[1] > maValue) { if(PositionsTotal() == 0) { ClosePositions(ORDER_TYPE_SELL); OpenPosition(ORDER_TYPE_BUY); } } //--- Check for Sell Signal if(rsiValue > RSI_Overbought && Close[1] < maValue) { if(PositionsTotal() == 0) { ClosePositions(ORDER_TYPE_BUY); OpenPosition(ORDER_TYPE_SELL); } }
Um sinal de compra ocorre quando o preço de fechamento atual está acima da média móvel e o RSI está abaixo do nível de sobrevenda. Isso indica uma possível reversão para alta.
Um sinal de venda ocorre quando o preço de fechamento está abaixo da média móvel e o RSI está acima do nível de sobrecompra. Isso indica uma possível reversão para baixa.
- Aplicação do trailing-stop: Para minimizar perdas e proteger lucros, a função OnTick inclui a lógica de aplicação do trailing-stop.
//--- Apply trailing stop if specified if (TrailingStop > 0) { ApplyTrailingStop(); }
Se o parâmetro de trailing-stop estiver ativado, esta seção garante que o mecanismo de trailing-stop seja utilizado. Para garantir os ganhos, a função ApplyTrailingStop ajusta o nível de stop-loss conforme o preço se move na direção desejada.
- Abertura e fechamento de posições: A função OpenPosition tenta abrir uma posição após definir o preço de entrada, os níveis de stop-loss e take-profit. Fechamento de posição: A função ClosePositions percorre todas as posições abertas e fecha aquelas que atendem ao tipo de ordem especificado.
Isso explica como o EA Deus se adapta dinamicamente às condições do mercado utilizando a função OnTick. Essa função combina os indicadores RSI e MA para gerar sinais de negociação e utilizar stops móveis para proteger os lucros. Com essa estratégia, o EA garante a preservação dos ganhos e responde rapidamente às mudanças do mercado. A seguir, é apresentado o código completo da função OnTick:
//+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { Ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); Bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); ArrayResize(Close, 2); Close[0] = iClose(_Symbol, _Period, 0); Close[1] = iClose(_Symbol, _Period, 1); //--- Calculate RSI value rsiValue = iRSI(_Symbol, _Period, RSI_Period, PRICE_CLOSE, 0); if (rsiValue == WRONG_VALUE) { Print("Error calculating RSI"); return; } //--- Calculate Moving Average value maValue = iMA(_Symbol, _Period, MA_Period, 0, MA_Method, MA_Price, 0); if (maValue == WRONG_VALUE) { Print("Error calculating Moving Average"); return; } //--- Check for Buy Signal if(rsiValue < RSI_Oversold && Close[1] > maValue) { if(PositionsTotal() == 0) { ClosePositions(ORDER_TYPE_SELL); OpenPosition(ORDER_TYPE_BUY); } } //--- Check for Sell Signal if(rsiValue > RSI_Overbought && Close[1] < maValue) { if(PositionsTotal() == 0) { ClosePositions(ORDER_TYPE_BUY); OpenPosition(ORDER_TYPE_SELL); } } //--- Apply trailing stop if specified if (TrailingStop > 0) { ApplyTrailingStop(); }
Concluímos a explicação da função OnTick. Agora, vamos analisar as funções auxiliares do nosso EA. Para que o EA Deus possa executar operações com base nos sinais do RSI e da média móvel, a função de abertura de posição é essencial. Ela garante a colocação precisa de ordens de compra e venda, levando em consideração fatores de gerenciamento de risco.
void OpenPosition(int orderType)
O tipo de ordem executada é determinado por um único parâmetro: o tipo de ordem aceito pela função OpenPosition. Para ordens de compra e venda, esse parâmetro pode ser ORDER_TYPE_BUY ou ORDER_TYPE_SELL, respectivamente. O tipo de ordem define o preço utilizado dentro da função.
double price = (orderType == ORDER_TYPE_BUY) ? Ask : Bid;
A função usa o preço Ask para ordens de compra e o preço Bid para ordens de venda.
Para controle de risco e garantia de lucros, os níveis de stop-loss (SL) e take-profit (TP) são estabelecidos:
double sl = (orderType == ORDER_TYPE_BUY) ? price - StopLoss * _Point : price + StopLoss * _Point; double tp = (orderType == ORDER_TYPE_BUY) ? price + TakeProfit * _Point : price - TakeProfit * _Point;
Para ordens de compra, o take-profit é definido acima do preço da ordem, enquanto o stop-loss é colocado abaixo. Para ordens de venda, o take-profit e o stop-loss são posicionados abaixo e acima do preço da ordem, respectivamente. A função PositionOpen da classe CTrade é utilizada para abrir uma posição real:
bool result = trade.PositionOpen(_Symbol, orderType, Lots, price, sl, tp, "Deus EA");
Esse método requer vários parâmetros:
- {Symbol} – O ativo negociado, como EURUSD.
- {orderType} – O tipo de ordem (compra ou venda).
- "Lots" – O tamanho do lote da ordem.
- {price} – O preço da ordem (bid ou ask).
- {sl} – O nível de stop-loss calculado.
- {tp} – O nível de take-profit definido.
- "Deus EA" – O identificador da ordem.
Após a tentativa de abertura da posição, a função verifica o resultado e, se necessário, registra uma mensagem.
if(result) { Print("Order opened successfully. Type: ", orderType, ", Price: ", price); } else { Print("Failed to open order. Error code: ", GetLastError()); } }
Se a ordem for aberta com sucesso, um aviso de confirmação é exibido. Caso contrário, a função GetLastError é usada para obter o código do erro, que pode ser analisado para solucionar o problema.
O código completo da função de abertura de posições é apresentado a seguir:
//+------------------------------------------------------------------+ //| Function to open a position | //+------------------------------------------------------------------+ void OpenPosition(int orderType) { double price = (orderType == ORDER_TYPE_BUY) ? Ask : Bid; double sl = (orderType == ORDER_TYPE_BUY) ? price - StopLoss * _Point : price + StopLoss * _Point; double tp = (orderType == ORDER_TYPE_BUY) ? price + TakeProfit * _Point : price - TakeProfit * _Point; bool result = trade.PositionOpen(_Symbol, orderType, Lots, price, sl, tp, "Deus EA"); if(result) { Print("Order opened successfully. Type: ", orderType, ", Price: ", price); } else { Print("Failed to open order. Error code: ", GetLastError()); } } )
Agora que cobrimos uma das funções auxiliares, vamos analisar outra – a função de fechamento de posições. A função ClosePositions do EA Deus é fundamental para garantir que as posições indesejadas sejam encerradas conforme os parâmetros da estratégia de negociação. Quando determinadas condições são atendidas, essa função gerencia o fechamento de posições específicas (compra ou venda). Vamos examinar como essa função opera e sua importância na estratégia geral.
void OpenPosition(int orderType)
O tipo de posição a ser fechada é indicado pelo argumento orderType, aceito pela função ClosePositions. Os valores possíveis desse parâmetro são ORDER_TYPE_SELL ou ORDER_TYPE_BUY. A função percorre todas as posições abertas naquele momento e fecha as que correspondem ao critério definido.
for(int i = PositionsTotal() - 1; i >= 0; i--) { if(PositionSelectByIndex(i)) { if(PositionGetInteger(POSITION_TYPE) == orderType) { if(!trade.PositionClose(ticket) { Print("Failed to close position. Error code: ", GetLastError()); } } } }
O laço percorre as posições de trás para frente, começando pela mais recente. Como o fechamento de uma posição reduz o número total de operações abertas, um laço convencional pode ser comprometido, exigindo uma iteração reversa. Para selecionar a posição pelo índice especificado {i}, utiliza-se a função PositionSelectByIndex(i).
A função verifica se a posição selecionada corresponde ao {orderType} especificado dentro do laço.
if(PositionGetInteger(POSITION_TYPE) == orderType)
Se {orderType} não for igual ao tipo da posição, ela não deve ser fechada. Caso contrário, a função tenta encerrar a posição se os tipos coincidirem.
if(!trade.PositionClose(ticket) { Print("Failed to close position. Error code: ", GetLastError()); } } } }
A posição é fechada ao tentar identificá-la pelo número do ticket {trade.PositionClose(ticket)}. Se a posição não puder ser fechada, uma mensagem de erro é exibida com o código do erro, obtido através da função GetLastError(). Isso ajuda a determinar o motivo da falha no fechamento da posição e facilita a correção de problemas.
O EA Deus pode garantir a realização de lucros ao encerrar posições lucrativas quando atingirem um determinado nível de rentabilidade. Isso é feito fechando posições selecionadas sob determinadas condições.
O código completo da função de fechamento de posições está apresentado a seguir:
//+------------------------------------------------------------------+ //| Function to close positions | //+------------------------------------------------------------------+ void ClosePositions(int orderType) { for(int i = PositionsTotal() - 1; i >= 0; i--) { if(PositionSelectByIndex(i)) { if(PositionGetInteger(POSITION_TYPE) == orderType) { if(!trade.PositionClose(ticket) { Print("Failed to close position. Error code: ", GetLastError()); } } } }
Agora, passamos para a última função auxiliar — a aplicação do trailing-stop. Essa função permite reduzir perdas ao encerrar operações deficitárias e evitar a retenção simultânea de posições compradas e vendidas, bem como evitar estratégias de hedge. O trailing-stop ajusta dinamicamente os níveis de stop-loss à medida que o preço do mercado se move a favor da posição aberta. O método ApplyTrailingStop no EA Deus assegura a aplicação eficiente desse mecanismo. O trailing-stop limita as perdas potenciais e fixa os lucros ao acompanhar as oscilações do mercado. Vamos analisar seu funcionamento.
void ApplyTrailingStop()
Como essa função se aplica a todas as posições abertas no ativo atual, o método ApplyTrailingStop não exige parâmetros. Assim como ClosePositions, essa função começa percorrendo todas as posições abertas:
for (int i = PositionsTotal() - 1; i >= 0; i--) { if (PositionSelectByIndex(i) && PositionGetSymbol() == _Symbol)
O laço percorre as posições de trás para frente, iniciando pela mais recente.
{PositionSelectByIndex(i)}: A função seleciona a posição com índice {i}. Em seguida, verifica se a posição corresponde ao ativo em negociação usando {PositionGetSymbol() == _Symbol}.
A função usa a distância do trailing-stop e o preço atual do mercado para determinar o novo nível de stop-loss:
double price = (PositionGetInteger(POSITION_TYPE) == ORDER_TYPE_BUY) ? Bid : Ask; double sl = (PositionGetInteger(POSITION_TYPE) == ORDER_TYPE_BUY) ? price - TrailingStop * _Point : price + TrailingStop * _Point;
Para posições de compra, o trailing-stop é ajustado para um nível abaixo do preço Bid. Para posições de venda, o trailing-stop é ajustado para um nível acima do preço Ask. Depois de determinar um nível adequado de stop-loss, a função utiliza PositionModify para aplicá-lo:
if (PositionGetInteger(POSITION_TYPE) == ORDER_TYPE_BUY && PositionGetDouble(POSITION_SL) < sl) { if (!trade.PositionModify(PositionGetInteger(POSITION_TICKET), sl, PositionGetDouble(POSITION_TP))) { Print("Failed to modify position. Error code: ", GetLastError()); } } else if (PositionGetInteger(POSITION_TYPE) == ORDER_TYPE_SELL && PositionGetDouble(POSITION_SL) > sl) { if (!trade.PositionModify(PositionGetInteger(POSITION_TICKET), sl, PositionGetDouble(POSITION_TP))) { Print("Failed to modify position. Error code: ", GetLastError()); } } }
O stop-loss da posição só é modificado se o novo nível {sI} for superior ao existente. Caso o novo nível de stop-loss seja inferior ao atual, o stop-loss é atualizado para as posições de venda.
Se a modificação da posição falhar, uma mensagem será exibida com o código do erro. Isso facilita a depuração e permite identificar o motivo pelo qual o trailing-stop não foi aplicado.
O código completo da função de aplicação do trailing-stop é apresentado a seguir:
//+------------------------------------------------------------------+ //| Function to apply trailing stop | //+------------------------------------------------------------------+ void ApplyTrailingStop() { for (int i = PositionsTotal() - 1; i >= 0; i--) { if (PositionSelectByIndex(i) && PositionGetSymbol() == _Symbol) { double price = (PositionGetInteger(POSITION_TYPE) == ORDER_TYPE_BUY) ? Bid : Ask; double sl = (PositionGetInteger(POSITION_TYPE) == ORDER_TYPE_BUY) ? price - TrailingStop * _Point : price + TrailingStop * _Point; if (PositionGetInteger(POSITION_TYPE) == ORDER_TYPE_BUY && PositionGetDouble(POSITION_SL) < sl) { if (!trade.PositionModify(PositionGetInteger(POSITION_TICKET), sl, PositionGetDouble(POSITION_TP))) { Print("Failed to modify position. Error code: ", GetLastError()); } } else if (PositionGetInteger(POSITION_TYPE) == ORDER_TYPE_SELL && PositionGetDouble(POSITION_SL) > sl) { if (!trade.PositionModify(PositionGetInteger(POSITION_TICKET), sl, PositionGetDouble(POSITION_TP))) { Print("Failed to modify position. Error code: ", GetLastError()); } } }
O código completo do artigo está apresentado a seguir:
//+------------------------------------------------------------------+ //| Deus EA | //| Copyright 2024, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #include <Trade\Trade.mqh> CTrade trade; //--- Input parameters input double Lots = 0.1; // Lot size input double StopLoss = 50; // Stop loss in points input double TakeProfit = 50; // Take profit in points input double TrailingStop = 25; // Trailing stop in points //--- RSI parameters input int RSI_Period = 7; // RSI period input double RSI_Overbought = 35.0; // RSI overbought level input double RSI_Oversold = 15.0; // RSI oversold level //--- Moving Average parameters input int MA_Period = 25; // Moving Average period input ENUM_MA_METHOD MA_Method = MODE_SMA; // Moving Average method input ENUM_APPLIED_PRICE MA_Price = PRICE_CLOSE; // Applied price for MA //--- Variables double rsiValue; // RSI value double maValue; // Moving Average value double Ask; double Bid; double Close[2]; // Initializing Close array with two elements //--- Function prototypes void ApplyTrailingStop(); void OpenPosition(CTrade &trade, int orderType); // Pass CTrade by reference void ClosePositions(int orderType); // pass orderType directly //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { Print("Deus EA initialized successfully."); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { Print("Deus EA deinitialized. Reason: ", reason); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- Update current prices Ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); Bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); ArrayResize(Close, 2); Close[0] = iClose(_Symbol, Period(), 0); Close[1] = iClose(_Symbol, Period(), 1); //--- Calculate RSI value rsiValue = iRSI(_Symbol, _Period, RSI_Period, PRICE_CLOSE, 0); if (rsiValue == WRONG_VALUE) { Print("Error calculating RSI"); return; //--- Calculate Moving Average value maValue = iMA(_Symbol, _Period, MA_Period, 0, MA_Method, MA_Price, 0); if (maValue == WRONG_VALUE) { Print("Error calculating Moving Average"); return; } //--- Check for Buy Signal if(rsiValue < RSI_Oversold && Close[1] > maValue) { if(PositionsTotal() == 0) { ClosePositions(ORDER_TYPE_SELL); OpenPosition(ORDER_TYPE_BUY); } } //--- Check for Sell Signal if(rsiValue > RSI_Overbought && Close[1] < maValue) { if(PositionsTotal() == 0) { ClosePositions(ORDER_TYPE_BUY); OpenPosition(ORDER_TYPE_SELL); } } //--- Apply trailing stop if specified if(TrailingStop > 0) { ApplyTrailingStop(); } } //+------------------------------------------------------------------+ //| Function to open a position | //+------------------------------------------------------------------+ void OpenPosition(int orderType) { //--- Determine price stop loss, and take profit levels double price = (orderType == ORDER_TYPE_BUY) ? Ask : Bid; double sl = (orderType == ORDER_TYPE_BUY) ? price - StopLoss * _Point : price + StopLoss * _Point; double tp = (orderType == ORDER_TYPE_BUY) ? price + TakeProfit * _Point : price - TakeProfit * _Point; bool result = trade.PositionOpen(_Symbol, orderType, Lots, price, sl, tp, "Deus EA"); if(result) { Print("Order opened successfully. Type: ", orderType, ", Price: ", price); } else { Print("Failed to open order. Error code: ", GetLastError()); } } //+------------------------------------------------------------------+ //| Function to close positions | //+------------------------------------------------------------------+ void ClosePositions(int orderType) { for(int i = PositionsTotal() - 1; i >= 0; i--) { if(PositionSelectByIndex(i)) { //--- Check if the positions type matches the order type to be closed if(PositionGetInteger(POSITION_TYPE) == orderType) { ulong ticket = PositionGetInteger(POSITION_TICKET); if(!trade.PositionClose(ticket) { Print("Failed to close position. Error code: ", GetLastError()); } } } } } //+------------------------------------------------------------------+ //| Function to apply trailing stop | //+------------------------------------------------------------------+ void ApplyTrailingStop() { for (int i = PositionsTotal() - 1; i >= 0; i--) { if (PositionSelectByIndex(i) && PositionGetSymbol() == _Symbol) { double price = (PositionGetInteger(POSITION_TYPE) == ORDER_TYPE_BUY) ? Bid : Ask; double sl = (PositionGetInteger(POSITION_TYPE) == ORDER_TYPE_BUY) ? price - TrailingStop * _Point : price + TrailingStop * _Point; //--- Trailing stop logic for buy positions if (PositionGetInteger(POSITION_TYPE) == ORDER_TYPE_BUY && PositionGetDouble(POSITION_SL) < sl) { if (!trade.PositionModify(PositionGetInteger(POSITION_TICKET), sl, PositionGetDouble(POSITION_TP))) { Print("Failed to modify position. Error code: ", GetLastError()); } } //--- Trailing stop logic for sell positions else if (PositionGetInteger(POSITION_TYPE) == ORDER_TYPE_SELL && PositionGetDouble(POSITION_SL) > sl) { if (!trade.PositionModify(PositionGetInteger(POSITION_TICKET), sl, PositionGetDouble(POSITION_TP))) { Print("Failed to modify position. Error code: ", GetLastError()); } } } }
Parabéns! Implementamos o EA Deus para automatizar operações de negociação.
Aqui estão os resultados dos testes:
Relatório:
O teste foi realizado no par USDJPY no período de 10/07/2024 a 06/08/2024 no timeframe H1. Os parâmetros utilizados foram os mesmos que analisamos durante a implementação.
Esse tipo de estratégia funciona melhor para os pares de moedas EURUSD e USDJPY, mas apenas se um alto percentual de operações vencedoras não for um requisito essencial. Abaixo, estão os parâmetros de teste do EA:
Considerações finais
O EA Deus utiliza médias móveis e o Índice de Força Relativa (RSI) para gerar sinais de negociação, combinando indicadores técnicos para gerenciar e aproveitar oportunidades de mercado. Este artigo detalhou a lógica de negociação, o controle de riscos e o código MQL5 que compõe o EA, permitindo que ele automatize decisões de negociação, aumentando a consistência e reduzindo o impacto emocional.
O gráfico demonstra que valores reduzidos dos parâmetros de otimização não apenas minimizam riscos, mas também aumentam as perdas. Por isso, testes rigorosos e ajustes são essenciais antes da implementação do EA em operações reais. Isso garantirá sua eficiência em diferentes condições de mercado e sua adequação aos objetivos específicos da estratégia de negociação.
Para manter a eficácia do EA Deus e de outros sistemas automatizados, são necessários monitoramento contínuo e ajustes regulares. Este artigo forneceu as informações e ferramentas fundamentais para a implementação e otimização eficaz do EA Deus. Caso necessite de recursos adicionais, você pode obtê-los através da plataforma MQL5.
Traduzido do Inglês pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/en/articles/15431
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.





- 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
Você poderia explicar por que está usando 15 e 35 como valores-limite para o RSI?
Isso realmente não faz sentido para mim, parece um truque para fazer seu backtest funcionar para o único mês que você está mostrando...
Ele dá erro de compilação.
Concordo e tentei adicionar colchetes extras, mas continuo recebendo o erro de compilação
Concordo que, se você usar 15 como nível de sobrevenda, o nível de sobrecompra deverá ser 85 e não 35