Construindo um Modelo de Restrição de Tendência de Candlestick (Parte 8): Desenvolvimento do Expert Advisor (II)
Conteúdo
Introdução
No nosso artigo anterior, exploramos a criação de um Expert Advisor (EA) utilizando o indicador Trend Constraint V1.09, complementado pelo script Trend Constraint R-R executado manualmente para posicionar retângulos de risco e recompensa. Embora essa configuração proporcionasse sinais de negociação perspicazes e melhorasse a visualização, ela exigia intervenção manual que poderia ser otimizada. Com a natureza acelerada dos ambientes de negociação, torna-se evidente a necessidade de uma solução mais eficiente. Muitos traders buscam sistemas integrados que funcionem de forma autônoma, reduzindo a necessidade de supervisão constante e execução manual.
Este artigo dá o próximo passo em nossa série, orientando você no desenvolvimento de um Expert Advisor (EA) independente que não apenas incorpora as capacidades de análise de tendência do Trend Constraint V1.09, mas também integra funcionalidades de risco-recompensa diretamente no EA. Nosso objetivo é capacitar os traders com uma solução tudo-em-um utilizando MQL5 na plataforma MetaTrader 5, oferecendo maior automação e operação contínua para acompanhar as exigências do mercado.
Para atingir isso, revisitaremos as etapas fundamentais abordadas na Parte 1, Parte 2 e Parte 3, aproveitando a lógica necessária para que o EA execute suas tarefas de negociação. Agora, combinaremos todas essas partes e suas lógicas para escrever o Expert Advisor.
Abaixo está um resumo das condições que geravam sinais no indicador conforme implementado em MQL5:
Condição de Compra (Long):
Condição de Venda (Short):
- O candlestick do dia deve ser de alta.
- Em um período de tempo inferior dentro de um candlestick D1 de alta, precisamos de uma confluência de sinais. Especificamente, o indicador interno, como o Índice de Força Relativa (RSI), deve indicar uma condição de sobrevenda, e a média móvel rápida deve cruzar acima da média móvel lenta.
- O candlestick do dia deve ser de baixa.
- Em um período de tempo inferior dentro de um candlestick D1 de baixa, precisamos de uma confluência de sinais. Especificamente, o indicador interno, como o Índice de Força Relativa (RSI), deve indicar uma condição de sobrecompra, e a média móvel rápida deve cruzar abaixo da média móvel lenta.
Criando o Expert Advisor:
Utilizamos o aplicativo MetaEditor para escrever nosso Programa Expert em MQL5. O mais importante é manter em mente a base. Abaixo está a estrutura resumida do nosso EA.
Resumo da arquitetura da maioria dos programas de EA:
- Inicialização (OnInit): Configurar os indicadores e variáveis necessárias.
- Loop Principal (OnTick): Processar os ticks recebidos para avaliar as condições do mercado e tomar decisões de negociação.
- Gerenciamento de Trades (OnTrade): Lidar com eventos relacionados a negociações.
- Teste (OnTester e funções relacionadas): Fornecer estrutura para otimizar e avaliar o desempenho do EA no Strategy Tester.
- Interação com o Usuário (OnChartEvent): Opcional, mas permite a interação com o EA através de eventos no gráfico.
Acredito que o rascunho do Diagrama de Blocos abaixo ajudará a esclarecer nosso objetivo, tornando-o mais fácil de entender.

Um diagrama de blocos simples das partes do EA e como elas se interligam
Essa estrutura garante que nosso EA esteja bem organizado e capaz de lidar de forma eficaz com as diversas tarefas necessárias para implementar nossa estratégia de negociação. Dividirei o processo de desenvolvimento em subseções, mas desenvolvedores mais avançados podem pular as etapas (i) e (ii) e seguir diretamente para a subseção (iii).(i) Iniciando o EA padrão (modelo) no MetaEditor.
(iii) Escrevendo a lógica do Expert em Restrição de Tendência no Modelo preparado.
(i) Iniciando o modelo de EA
No MetaEditor, pressione Ctrl + N para abrir um novo arquivo e escolha "Expert Advisor (Template)" conforme mostrado na imagem abaixo:

Inicie um novo Expert Advisor (Modelo)
Observe que os detalhes do autor e os links já estão disponíveis ao iniciar um novo projeto devido a projetos anteriores no meu computador. Você pode personalizá-los conforme necessário.
(ii) Personalizando o Modelo
A intenção por trás desta escrita não é apenas demonstrar minha habilidade de programação, mas também impactar aqueles que estão começando a entender o processo, para que possam aplicar as habilidades adquiridas no futuro. Neste ponto, estamos olhando para o modelo, que pode não parecer significativo para um iniciante. Antes de começarmos a codificar no esqueleto do modelo, irei extrair e explicar brevemente as funções mais importantes necessárias. Em seguida, prosseguiremos preenchendo os detalhes, escrevendo o código do EA para atender às nossas necessidades. Essa abordagem é crucial, pois permitirá que você inicie outros projetos próprios, diferentes do que estamos focando agora, sem dificuldade.
O esqueleto fornece a base sobre a qual mais tarde construiremos a lógica para nosso EA.
Aqui está o modelo gerado a partir do MetaEditor:
//+------------------------------------------------------------------+ //| Trend Constraint Expert.mq5 | //| Copyright 2024, Clemence Benjamin | //| https://www.mql5.com/en/users/billionaire2024/seller | //+------------------------------------------------------------------+ #property copyright "Copyright 2024, Clemence Benjamin" #property link "https://www.mql5.com/en/users/billionaire2024/seller" #property version "1.00" //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- } //+------------------------------------------------------------------+ //| Trade function | //+------------------------------------------------------------------+ void OnTrade() { //--- } //+------------------------------------------------------------------+ //| Tester function | //+------------------------------------------------------------------+ double OnTester() { //--- double ret=0.0; //--- //--- return(ret); } //+------------------------------------------------------------------+ //| TesterInit function | //+------------------------------------------------------------------+ void OnTesterInit() { //--- } //+------------------------------------------------------------------+ //| TesterPass function | //+------------------------------------------------------------------+ void OnTesterPass() { //--- } //+------------------------------------------------------------------+ //| TesterDeinit function | //+------------------------------------------------------------------+ void OnTesterDeinit() { //--- } //+------------------------------------------------------------------+ //| ChartEvent function | //+------------------------------------------------------------------+ void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { //--- } //+------------------------------------------------------------------+
A partir do modelo, vamos discutir as funções-chave essenciais para nossos Expert Advisors:
- Função OnInit(): Esta função é executada uma vez quando o EA é inicializado, configurando indicadores, variáveis ou recursos necessários para a operação. Uma inicialização adequada garante que todos os recursos necessários estejam prontos antes que o EA comece a processar os dados do mercado. Para o seu "Expert Advisor de Restrição de Tendência", o indicador RSI e outras variáveis cruciais normalmente seriam inicializados aqui.
- Função OnDeinit(): Esta função é chamada quando o EA é desinicializado, como quando é removido de um gráfico ou quando o terminal é encerrado. Ela é usada para limpar recursos, como liberar identificadores de indicadores ou fechar arquivos, a fim de evitar vazamentos de memória ou outros problemas.
- Função OnTick(): Esta função principal é acionada toda vez que um novo tick (atualização de preço) é recebido para o símbolo ao qual o EA está anexado. No seu "Expert Advisor de Restrição de Tendência", ela incluiria a lógica para verificar as condições de mercado, como a tendência no D1 e os níveis do RSI, e tomar decisões de negociação, como abrir ou fechar posições.
- Função OnTrade(): Chamada quando ocorre um evento de negociação, como a colocação, modificação ou fechamento de uma ordem, esta função é vital para monitorar o status das operações e reagir a mudanças. Por exemplo, você poderia usá-la para rastrear quando uma operação é aberta e ajustar o comportamento do EA de acordo.
- Função OnTester(): Esta função é usada durante o teste de estratégia para retornar um valor double, servindo como critério personalizado para otimização. Ela permite definir uma métrica personalizada, como o fator de lucro ou o drawdown, para avaliar o desempenho do EA durante testes no Strategy Tester.
- Funções OnTesterInit(), OnTesterPass() e OnTesterDeinit(): Estas funções são especificamente para testes e otimizações de estratégia, gerenciando o início, as passagens e o término dos testes no Strategy Tester. Elas oferecem maior controle sobre o processo de teste, inicializando recursos, coletando dados e realizando a limpeza após os testes.
- Função OnChartEvent(): Esta função lida com eventos no gráfico, como cliques do mouse ou pressionamentos de tecla, permitindo a interação com o EA enquanto ele está em execução. Se o seu EA incluir interação do usuário, como alteração de parâmetros ou acionamento de ações por meio de eventos no gráfico, esta função será essencial.
Com a compreensão dessas funções, podemos ver como estruturar a lógica dentro delas. No entanto, as funções fornecidas pelo modelo podem não ser suficientes para a complexidade do EA que estamos desenvolvendo. Funções adicionais podem ser necessárias, e precisaremos justificar e explicar sua inclusão para atender aos requisitos específicos do nosso "Expert Advisor de Restrição de Tendência".
Funções adicionais não incluídas no modelo de Expert Advisor, mas necessárias para o nosso projeto:- Funções de Indicador (por exemplo, iRSI): Utilizadas para calcular indicadores como o RSI, que são integrais à sua estratégia de negociação.
- Funções de Negociação (classe CTrade): Utilizadas para gerenciar ordens e posições, como colocar ordens de compra/venda, definir stop loss e modificar posições.
//+------------------------------------------------------------------+ //| Trend Constraint Expert Advisor.mq5| //| Copyright 2024, Clemence Benjamin| //| https://www.mql5.com/en/users/billionaire2024/seller| //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { // Initialization code here rsi_handle = iRSI(_Symbol, PERIOD_CURRENT, RSI_Period, PRICE_CLOSE); if (rsi_handle == INVALID_HANDLE) { Print("Failed to create RSI indicator handle"); return(INIT_FAILED); } // Any other initialization tasks return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { // Cleanup code here IndicatorRelease(rsi_handle); // Release RSI indicator handle // Any other deinitialization tasks } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { // Main trading logic goes here // Determine market conditions (e.g., daily trend, RSI levels) // Check for trade conditions and execute orders if necessary // Implement trailing stop logic if necessary } //+------------------------------------------------------------------+ //| Trade event function | //+------------------------------------------------------------------+ void OnTrade() { // Handle trade events (e.g., order placement, modification, closure) } //+------------------------------------------------------------------+ //| Tester function | //+------------------------------------------------------------------+ double OnTester() { double ret = 0.0; // Custom optimization criteria (if any) go here return(ret); } //+------------------------------------------------------------------+ //| TesterInit function | //+------------------------------------------------------------------+ void OnTesterInit() { // Initialization for testing (if needed) } //+------------------------------------------------------------------+ //| TesterPass function | //+------------------------------------------------------------------+ void OnTesterPass() { // Actions after each optimization pass (if needed) } //+------------------------------------------------------------------+ //| TesterDeinit function | //+------------------------------------------------------------------+ void OnTesterDeinit() { // Cleanup after testing (if needed) } //+------------------------------------------------------------------+ //| Chart event function | //+------------------------------------------------------------------+ void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { // Handle chart events (e.g., mouse clicks, key presses) here } //+------------------------------------------------------------------+
(iii) Escrevendo lógica de especialista em restrição de tendência.
Agora, podemos prosseguir escrevendo a lógica para cada função que constitui nosso Expert Advisor. Vamos construir nosso programa passo a passo:
Incluir a Biblioteca de Negociação
Começamos incluindo a biblioteca de negociações, o que é necessário porque a classe CTrade dentro desta biblioteca fornece as funções necessárias para executar operações de negociação, como abrir, modificar e fechar posições. Ao incluir esta biblioteca, permitimos que o EA interaja com o mercado e gerencie negociações programaticamente.
#include <Trade\Trade.mqh> // Include the trade libraryDefinindo os Parâmetros de Entrada:
Em seguida, definimos os parâmetros de entrada, que os usuários podem ajustar para corresponder às suas preferências de negociação. Esses parâmetros incluem o período do RSI, níveis de sobrecompra e sobrevenda, tamanho do lote, stop loss, take profit e trailing stop. Ao escrever essas linhas de entrada, garantimos que o EA possa ser customizado para diferentes condições de mercado. O programa usará esses valores para tomar decisões sobre quando entrar e sair de negociações.
// Input parameters 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 double Lots = 0.1; // Lot size input double StopLoss = 100; // Stop Loss in points input double TakeProfit = 200; // Take Profit in points input double TrailingStop = 50; // Trailing Stop in pointsDeclarando Variáveis Globais:
Em seguida, declaramos variáveis globais, como RSI_value e RSI_handle, que armazenarão respectivamente o valor do RSI e o identificador, bem como uma instância da classe CTrade. Ao declarar essas variáveis, garantimos que o EA possa manter o estado entre diferentes funções, permitindo que o programa acesse e modifique esses valores conforme necessário durante sua execução.
// Global variables double rsi_value; int rsi_handle; CTrade trade; // Declare an instance of the CTrade classInicializando o Expert Advisor:
Na função OnInit, criamos o identificador do indicador RSI usando a função iRSI. Esta etapa é crucial porque o programa requer este identificador para buscar os valores do RSI a cada tick. Se o identificador não puder ser criado, programamos para que o EA retorne INIT_FAILED, impedindo que ele funcione sem este componente crítico. Isso garante que o programa só será executado quando estiver totalmente equipado para analisar os dados do mercado.
int OnInit() { // Create an RSI indicator handle rsi_handle = iRSI(_Symbol, PERIOD_CURRENT, RSI_Period, PRICE_CLOSE); if (rsi_handle == INVALID_HANDLE) { Print("Failed to create RSI indicator handle"); return(INIT_FAILED); } return(INIT_SUCCEEDED); }Desinicializando o Expert Advisor:
Para gerenciar recursos de forma eficaz, implementamos a função OnDeinit para liberar o identificador do indicador RSI quando o EA é removido do gráfico. Ao escrever esse código de limpeza, evitamos vazamentos de memória e garantimos que os recursos sejam liberados adequadamente. O programa executará essa limpeza automaticamente quando for desinicializado, mantendo um desempenho ideal.
void OnDeinit(const int reason) { // Release the RSI indicator handle IndicatorRelease(rsi_handle); }Implementando a Lógica Central de Negociação:
A lógica central de negociação reside na função OnTick, que projetamos para ser executada a cada novo tick do mercado. Primeiro, escrevemos o código para determinar a tendência diária atual, comparando os preços de abertura e fechamento do candle diário. Essa análise permite que o programa identifique se o mercado está em alta ou em baixa, o que é vital para tomar decisões de negociação informadas.
void OnTick() { // Determine current daily trend (bullish or bearish) double daily_open = iOpen(_Symbol, PERIOD_D1, 0); double daily_close = iClose(_Symbol, PERIOD_D1, 0); bool is_bullish = daily_close > daily_open; bool is_bearish = daily_close < daily_open;Recuperando Valores do RSI:
Em seguida, recuperamos o valor do RSI usando a função CopyBuffer e o identificador do RSI que foi criado anteriormente. Ao fazer isso, garantimos que o programa possa avaliar se o mercado está em uma condição de sobrecompra ou sobrevenda. O programa usará este valor do RSI em seu processo de tomada de decisão, determinando se atende às condições para entrar em uma operação.
// Get the RSI value for the current bar double rsi_values[]; if (CopyBuffer(rsi_handle, 0, 0, 1, rsi_values) <= 0) { Print("Failed to get RSI value"); return; } rsi_value = rsi_values[0];Fechando Posições em Mudança de Tendência:
Também incluímos lógica para fechar quaisquer posições abertas se a tendência do mercado mudar. Por exemplo, se a tendência mudar de alta para baixa, o EA fechará quaisquer posições de compra abertas, e vice-versa. Ao escrever essa salvaguarda, garantimos que o programa mantenha o alinhamento com o sentimento atual do mercado, o que é crucial para minimizar o risco.
// Close open positions if the trend changes for (int i = PositionsTotal() - 1; i >= 0; i--) { if (PositionSelect(PositionGetSymbol(i))) // Corrected usage { int position_type = PositionGetInteger(POSITION_TYPE); ulong ticket = PositionGetInteger(POSITION_TICKET); // Get the position ticket if ((position_type == POSITION_TYPE_BUY && is_bearish) || (position_type == POSITION_TYPE_SELL && is_bullish)) { trade.PositionClose(ticket); // Use the ulong variable directly } } }Verificando Condições de Compra e Venda:
Para as condições de compra e venda, escrevemos a lógica para verificar uma tendência de alta combinada com um RSI em sobrevenda para ordens de compra, e uma tendência de baixa combinada com um RSI em sobrecompra para ordens de venda. Ao programar essas condições, garantimos que o EA só entre em operações quando ambos os indicadores de tendência e momento estiverem em concordância. O programa monitorará essas condições e executará operações de acordo, garantindo uma abordagem disciplinada à negociação.
// Check for buy condition (bullish trend + RSI oversold) if (is_bullish && rsi_value < RSI_Oversold) { // No open positions? Place a buy order if (PositionsTotal() == 0) { double price = SymbolInfoDouble(_Symbol, SYMBOL_ASK); double sl = price - StopLoss * _Point; double tp = price + TakeProfit * _Point; // Open a buy order trade.Buy(Lots, _Symbol, price, sl, tp, "TrendConstraintExpert Buy"); } } // Check for sell condition (bearish trend + RSI overbought) if (is_bearish && rsi_value > RSI_Overbought) { // No open positions? Place a sell order if (PositionsTotal() == 0) { double price = SymbolInfoDouble(_Symbol, SYMBOL_BID); double sl = price + StopLoss * _Point; double tp = price - TakeProfit * _Point; // Open a sell order trade.Sell(Lots, _Symbol, price, sl, tp, "TrendConstraintExpert Sell"); } }Implementando um Mecanismo de Trailing Stop:
Por fim, implementamos um mecanismo de trailing stop para proteger os lucros à medida que o mercado se move a favor de uma posição aberta. Ao escrever esta lógica de trailing stop, garantimos que o EA ajuste dinamicamente o stop loss para preservar os lucros enquanto permite que a operação continue enquanto o mercado permanecer favorável. O programa gerenciará automaticamente o trailing stop, garantindo que ele responda aos movimentos do mercado para maximizar ganhos e minimizar perdas.
// Apply trailing stop for (int i = PositionsTotal() - 1; i >= 0; i--) { if (PositionSelect(PositionGetSymbol(i))) // Corrected usage { double price = PositionGetDouble(POSITION_PRICE_OPEN); double stopLoss = PositionGetDouble(POSITION_SL); double current_price; if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) { current_price = SymbolInfoDouble(_Symbol, SYMBOL_BID); if (current_price - price > TrailingStop * _Point) { if (stopLoss < current_price - TrailingStop * _Point) { trade.PositionModify(PositionGetInteger(POSITION_TICKET), current_price - TrailingStop * _Point, PositionGetDouble(POSITION_TP)); } } } else if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL) { current_price = SymbolInfoDouble(_Symbol, SYMBOL_ASK); if (price - current_price > TrailingStop * _Point) { if (stopLoss > current_price + TrailingStop * _Point || stopLoss == 0) { trade.PositionModify(PositionGetInteger(POSITION_TICKET), current_price + TrailingStop * _Point, PositionGetDouble(POSITION_TP)); } } } } } }
Nosso programa final com cabeçalho e outras propriedades:
//+------------------------------------------------------------------+ //| Trend Constraint Expert.mq5 | //| Copyright 2024, Clemence Benjamin | //| https://www.mql5.com/en/users/billionaire2024/seller | //+------------------------------------------------------------------+ #property copyright "Copyright 2024, Clemence Benjamin" #property link "https://www.mql5.com/en/users/billionaire2024/seller" #property version "1.00" #property description "A System that seeks to Long D1 Bullish sentiment and short D1 Bearish sentiment" #property strict #include <Trade\Trade.mqh> // Include the trade library // Input parameters 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 double Lots = 0.1; // Lot size input double StopLoss = 100; // Stop Loss in points input double TakeProfit = 200; // Take Profit in points input double TrailingStop = 50; // Trailing Stop in points // Global variables double rsi_value; int rsi_handle; CTrade trade; // Declare an instance of the CTrade class //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { // Create an RSI indicator handle rsi_handle = iRSI(_Symbol, PERIOD_CURRENT, RSI_Period, PRICE_CLOSE); if (rsi_handle == INVALID_HANDLE) { Print("Failed to create RSI indicator handle"); return(INIT_FAILED); } return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { // Release the RSI indicator handle IndicatorRelease(rsi_handle); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { // Determine current daily trend (bullish or bearish) double daily_open = iOpen(_Symbol, PERIOD_D1, 0); double daily_close = iClose(_Symbol, PERIOD_D1, 0); bool is_bullish = daily_close > daily_open; bool is_bearish = daily_close < daily_open; // Get the RSI value for the current bar double rsi_values[]; if (CopyBuffer(rsi_handle, 0, 0, 1, rsi_values) <= 0) { Print("Failed to get RSI value"); return; } rsi_value = rsi_values[0]; // Close open positions if the trend changes for (int i = PositionsTotal() - 1; i >= 0; i--) { if (PositionSelect(PositionGetSymbol(i))) // Corrected usage { int position_type = PositionGetInteger(POSITION_TYPE); ulong ticket = PositionGetInteger(POSITION_TICKET); // Get the position ticket if ((position_type == POSITION_TYPE_BUY && is_bearish) || (position_type == POSITION_TYPE_SELL && is_bullish)) { trade.PositionClose(ticket); // Use the ulong variable directly } } } // Check for buy condition (bullish trend + RSI oversold) if (is_bullish && rsi_value < RSI_Oversold) { // No open positions? Place a buy order if (PositionsTotal() == 0) { double price = SymbolInfoDouble(_Symbol, SYMBOL_ASK); double sl = price - StopLoss * _Point; double tp = price + TakeProfit * _Point; // Open a buy order trade.Buy(Lots, _Symbol, price, sl, tp, "TrendConstraintExpert Buy"); } } // Check for sell condition (bearish trend + RSI overbought) if (is_bearish && rsi_value > RSI_Overbought) { // No open positions? Place a sell order if (PositionsTotal() == 0) { double price = SymbolInfoDouble(_Symbol, SYMBOL_BID); double sl = price + StopLoss * _Point; double tp = price - TakeProfit * _Point; // Open a sell order trade.Sell(Lots, _Symbol, price, sl, tp, "TrendConstraintExpert Sell"); } } // Apply trailing stop for (int i = PositionsTotal() - 1; i >= 0; i--) { if (PositionSelect(PositionGetSymbol(i))) // Corrected usage { double price = PositionGetDouble(POSITION_PRICE_OPEN); double stopLoss = PositionGetDouble(POSITION_SL); double current_price; if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) { current_price = SymbolInfoDouble(_Symbol, SYMBOL_BID); if (current_price - price > TrailingStop * _Point) { if (stopLoss < current_price - TrailingStop * _Point) { trade.PositionModify(PositionGetInteger(POSITION_TICKET), current_price - TrailingStop * _Point, PositionGetDouble(POSITION_TP)); } } } else if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL) { current_price = SymbolInfoDouble(_Symbol, SYMBOL_ASK); if (price - current_price > TrailingStop * _Point) { if (stopLoss > current_price + TrailingStop * _Point || stopLoss == 0) { trade.PositionModify(PositionGetInteger(POSITION_TICKET), current_price + TrailingStop * _Point, PositionGetDouble(POSITION_TP)); } } } } } } //+------------------------------------------------------------------+ //HAPPY DEVELOPING!
Tendo chegado a este estágio, podemos prosseguir para testar nosso programa. Incluí abaixo a minha experiência com os testes.
Testador
Para testar o "Trend Constraint Expert" no Strategy Tester do MetaTrader 5, começaremos configurando um backtest usando dados históricos para avaliar o desempenho do EA. Esse processo nos permitirá simular sua estratégia de negociação sob diversas condições de mercado, ajudando a analisar lucratividade, gestão de risco e eficácia geral. Precisamos selecionar nosso período de tempo desejado (neste caso, período M1), parâmetros de entrada e ambiente de negociação, e observar quão bem o EA segue a lógica de acompanhamento de tendência e as condições do RSI. Este teste é crucial para ajustar o Expert antes de considerar a negociação em conta real. Sou fã do índice Boom 500 e adorei testar o EA nesse ativo maravilhoso.

Configurações do Strategy Tester: Trend Constraint Expert

Desempenho do Trend Constraint no Tester
Resultados do Testador 01/2023-12/2023
Conclusão
Fico feliz que tenhamos chegado à conclusão desta maravilhosa discussão no formato de tutorial. Nosso objetivo era criar um expert advisor (EA) independente que não exigisse a instalação de indicadores específicos. Espero que esta discussão tenha inspirado você a compreender a estrutura do desenvolvimento de EAs e oferecido um ponto de partida sólido. Focamos nos conceitos mais fundamentais para garantir que a base fosse fácil de entender. A capacidade de personalizar o EA inserindo diversos fatores permite experimentar valores para encontrar as configurações mais lucrativas.
Conseguimos desenvolver com sucesso um expert advisor funcional baseado na nossa ideia inicial, e podemos observar a execução de ordens no Tester. No entanto, ainda há espaço significativo para melhorias. O Trend Constraint Expert precisa de mais refinamentos, particularmente nas suas condições de entrada, para melhorar a lucratividade em conformidade com as tendências diárias predominantes. Desta vez, não incluímos um número mágico, e ao testá-lo em uma conta demo real, percebi que o EA estava interferindo em outras ordens já colocadas.
Uma vantagem deste desenvolvimento, em comparação com o anterior que dependia de um indicador instalado, é que agora temos um único arquivo portátil para execução. Isso não significa que nossos esforços anteriores foram em vão; na verdade, aprendemos lições valiosas, e as ferramentas daquele projeto continuam úteis para empreendimentos futuros. Nosso objetivo é continuar refinando o EA para obter os melhores resultados possíveis conforme avançamos em nossa série.
Em seguida, vamos codificar um número mágico, aprimorar nossas técnicas de entrada e aumentar ainda mais nossa criatividade neste desenvolvimento. Feliz Negociação!
| Arquivo | Descrição |
|---|---|
| Trend Constraint Expert.mq5 | Código fonte. |
Traduzido do Inglês pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/en/articles/15322
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.
Do básico ao intermediário: Estruturas (VI)
Aprendendo MQL5 do iniciante ao profissional (Parte VI): Fundamentos da criação de EAs
Simulação de mercado (Parte 18): Iniciando o SQL (I)
Algoritmo de busca orbital atômica — Atomic Orbital Search (AOS): Modificação
- 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