Otimização e ajuste fino do código-fonte para melhorar os resultados do backtesting
Introdução
A obtenção de resultados confiáveis de backtesting na negociação algorítmica depende não apenas de uma lógica de estratégia robusta, mas também da eficiência e da precisão do código de base. A otimização e o ajuste fino do código-fonte são fundamentais para garantir o funcionamento adequado dos EAs, minimizar os custos computacionais e maximizar a precisão da execução. Um código mal otimizado pode distorcer os resultados do backtesting devido a atrasos na execução de ordens, detecção incorreta de sinais ou esgotamento de recursos, problemas que mascaram o verdadeiro potencial da estratégia.
Durante o desenvolvimento da estratégia, adotaremos várias etapas essenciais para garantir que o EA seja robusto do ponto de vista funcional e tecnicamente confiável. Começaremos adicionando funções auxiliares personalizadas e blocos lógicos reutilizáveis para otimizar as operações e eliminar código repetitivo. Em seguida, introduziremos variáveis e constantes bem estruturadas, que melhoram a legibilidade do código e simplificam o ajuste dos parâmetros. Essas alterações fundamentais ajudarão a manter o código manutenível e melhorarão o tempo geral de execução sob cargas elevadas durante o backtesting ou testes multissímbolo.
Outra área importante de aprimoramento é o uso mais eficiente de indicadores técnicos. Em vez de calcular indicadores cegamente a cada tick ou barra, implementaremos uma lógica de atualização mais inteligente para reduzir a carga e a latência. Também vamos experimentar diferentes combinações de indicadores para dar suporte a uma tomada de decisão mais eficiente na lógica do EA. Ao combinar o aprimoramento estrutural do código, funções projetadas com foco em eficiência e otimização de indicadores, podemos melhorar significativamente tanto a qualidade quanto a velocidade do backtesting, aproximando-nos de uma estratégia consistentemente lucrativa e pronta para implantação.
Desenvolvimento da estratégia
O desenvolvimento da nossa estratégia de negociação algorítmica começa com uma abordagem estruturada e metódica para o reconhecimento de padrões e a validação de sinais. A estratégia se baseia em um framework de análise de candles, projetado para identificar cenários de reversão de alta probabilidade. Para posições longas, a lógica detecta sistematicamente três candles de alta consecutivos, seguidos por um ou dois candles corretivos de baixa, culminando em um candle de alta de confirmação no índice 1, a última barra fechada.
Por outro lado, as posições curtas são acionadas pelo padrão inverso: três candles de baixa consecutivos, seguidos por um ou dois candles corretivos de alta, culminando em um candle de baixa de confirmação no índice 1. Essa configuração garante que os sinais sejam confirmados apenas na formação de uma nova barra, alinhando a execução com a ação do preço confirmada, e não com oscilações intrabarra.

Para a implementação prática dessa lógica, a arquitetura da estratégia dará prioridade ao desenvolvimento modular do código e à eficiência computacional. Primeiro, serão implementadas funções auxiliares para abstrair tarefas repetitivas, como a classificação de candles japoneses (identificação de tendência de alta/baixa) e a verificação de sequência (validação sequencial de padrões de candles). Essas funções usarão métodos nativos de acesso a dados de preço em MQL5, incluindo iOpen() e iClose(), minimizando cálculos redundantes por meio do cache de variáveis estáticas.
Em segundo lugar, o modelo de execução orientado a eventos garante que o EA processe sinais apenas na formação de uma nova barra, o que é determinado pela comparação das marcas temporais no índice 1. Essa abordagem reduz a carga computacional desnecessária e evita falsos gatilhos enquanto a barra ainda está se formando.

A etapa final do desenvolvimento será focada na otimização da eficiência e no teste de confiabilidade. Para aumentar a precisão de entrada/saída, serão integrados indicadores técnicos como filtros de volume ou níveis de stop loss ajustados pela volatilidade. Além disso, arrays de buffer históricos serão pré-alocados para armazenar padrões de candles japoneses, reduzindo a sobrecarga de alocação de memória durante a execução. Ao combinar esses elementos, design modular do código, execução orientada a eventos e integração de indicadores da estratégia, o EA alcançará um equilíbrio entre capacidade de resposta e uso eficiente dos recursos.
Código://+------------------------------------------------------------------+ //| Includes | //+------------------------------------------------------------------+ #include <Trade/Trade.mqh> MqlTick CTick, PTick; CTrade trade; enum InLot{ Lot_fixed, Lot_dynamic, }; //+------------------------------------------------------------------+ //| Inputs | //+------------------------------------------------------------------+ input group "--------------General Inputs--------------" input int RSI_Period = 14; input int TakeProfit = 100; // TP in points input ulong MagicNumber = 888888; // EA identifier input int MaxBarsCheck = 8; // Historical bars to analyze input InLot Lot_mode = Lot_fixed; input double In_Lot = 0.01; input bool TrailYourStop = true; input int trailingStop = 50; //input int StopLoss = 234; //+------------------------------------------------------------------+ //| Global Variables | //+------------------------------------------------------------------+ int rsiHandle, macdHanlde; datetime lastBarTime; double pointMultiplier; double StopLoss = 150; bool bullish_pattern_met = false; bool bearish_pattern_met = false; double first_bullish_low = 0.0; double first_bearish_high = 0.0; ENUM_TIMEFRAMES TimeFrame = PERIOD_CURRENT;
A arquitetura do EA integra as principais bibliotecas e estruturas de dados que dão suporte à operação contínua das funções de trading. A inclusão da biblioteca <Trade/Trade.mqh> fornece acesso à classe CTrade, otimizando operações de gestão de ordens, como abertura, modificação e fechamento de posições. Duas estruturas MqlTick, CTick e PTick, são usadas para rastrear dados de preço em tempo real, garantindo a precisão no timing de execução e na análise das condições de mercado. A enumeração (InLot) define o método de cálculo do tamanho da posição do EA, oferecendo os modos fixo (Lot_fixed) e dinâmico (Lot_dynamic), sendo este último reservado para possíveis cálculos de lote ajustados ao risco em ciclos futuros.
A configuração do usuário é feita por meio de uma interface de entrada dedicada, permitindo ajustar parâmetros sem alterar o código principal. Entre as configurações críticas estão RSI_Period (padrão: 14), que controla o indicador cuja sensibilidade usaremos posteriormente no desenvolvimento, bem como os valores TakeProfit e trailingStop (em pontos) para definir os níveis de risco e lucro. O parâmetro MagicNumber garante a identificação correta das operações, enquanto MaxBarsCheck define a profundidade dos dados históricos para a análise de padrões. A flexibilidade na gestão do tamanho da posição é obtida por meio de Lot_mode e In_Lot, e as funções de trailing stop (TrailYourStop, trailingStop) automatizam a proteção do lucro à medida que as operações evoluem favoravelmente.
Internamente, as variáveis globais gerenciam fluxos de execução complexos. Os handles dos indicadores (rsiHandle, macdHandle) armazenam instâncias dos indicadores e as referenciam durante a execução, enquanto lastBarTime simplifica a sincronização temporal ao registrar a marca temporal do último candle analisado. Flags booleanas (bullish_pattern_met, bearish_pattern_met) e marcadores de níveis de oscilação (first_bullish_low, first_bearish_high) acompanham dinamicamente as condições de mercado, e TimeFrame indica a periodicidade de funcionamento do EA, definindo por padrão o timeframe do gráfico ativo para facilitar o uso imediato.
//+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit(){ // Create RSI and MACD indicator handles rsiHandle = iRSI(_Symbol, TimeFrame, RSI_Period, PRICE_CLOSE); macdHanlde = iMACD(_Symbol, TimeFrame, 12, 26, 9, PRICE_CLOSE); return(INIT_SUCCEEDED); }
A função OnInit() inicializa corretamente os indicadores RSI e MACD, atribuindo as configurações adequadas para seus períodos e tipos de preço. Esses indicadores são mantidos na memória para uso futuro na otimização dos sinais de trading. Uma configuração bem-sucedida retorna INIT_SUCCEEDED, confirmando que o EA está pronto para operar.
void OnTick(){ if(!NewBarTrigger()) return; ThreeBar(); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Detects new bar formation | //+------------------------------------------------------------------+ bool NewBarTrigger(){ datetime currentTime = iTime(_Symbol, PERIOD_CURRENT, 0); if(currentTime != lastBarTime){ lastBarTime = currentTime; return true; } return false; } double getHigh(int index) { return iHigh(_Symbol, _Period, index); } double getLow(int index) { return iLow(_Symbol, _Period, index); } //+------------------------------------------------------------------+ //| Execute trade with risk parameters | //+------------------------------------------------------------------+ void ExecuteTrade(ENUM_ORDER_TYPE tradeType) { double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT); double price = (tradeType == ORDER_TYPE_BUY) ? SymbolInfoDouble(_Symbol, SYMBOL_ASK) : SymbolInfoDouble(_Symbol, SYMBOL_BID); // Convert StopLoss and TakeProfit from pips to actual price distances double sl_distance = StopLoss * point; double tp_distance = TakeProfit * point; double sl = (tradeType == ORDER_TYPE_BUY) ? price - sl_distance : price + sl_distance; double tp = (tradeType == ORDER_TYPE_BUY) ? price + tp_distance : price - tp_distance; trade.PositionOpen(_Symbol, tradeType, In_Lot, price, sl, tp, NULL); }
A função OnTick() atua como o pulso do nosso EA, sendo acionada a cada tick recebido. Para evitar processamento redundante e cálculos desnecessários, primeiro, verifica-se se há um novo candle por meio de NewBarTrigger(). Se uma nova barra tiver sido formada, chamamos então a função ThreeBar(), que contém nossa lógica de trading e o rotina de detecção de padrões.
A função NewBarTrigger() é responsável por detectar o início de um novo candle. Isso é feito comparando o horário atual de abertura do candle com o valor salvo anteriormente (lastBarTime). Quando uma nova marca temporal é detectada, ela atualiza lastBarTime e retorna true, permitindo que OnTick() continue a execução. Isso garante que as decisões de trading sejam tomadas apenas uma vez por barra, o que é essencial para nossa estratégia, baseada em confirmações de fechamento da barra. As funções auxiliares getHigh() e getLow() são funções utilitárias simples que retornam a máxima e a mínima de um determinado índice de barra no gráfico atual.
A função ExecuteTrade() gerencia a abertura de operações com os parâmetros de risco correspondentes. Primeiro, ela obtém o preço de mercado atual de acordo com o tipo de operação (compra ou venda) e, em seguida, calcula o stop loss e o take profit em unidades reais de preço, convertendo os valores de pips/pontos definidos pelo usuário usando o valor Point do símbolo. Depois, esses níveis calculados são passados para o método PositionOpen() da classe CTrade, garantindo que cada operação seja executada com controle de risco preciso e consistente.
//+------------------------------------------------------------------+ //| Candle pattern detection Function | //+------------------------------------------------------------------+ void ThreeBar() { // Settings string symbol = Symbol(); // Current symbol ENUM_TIMEFRAMES timeframe = PERIOD_M5; // Timeframe (e.g., 1-hour) // Pattern detection variables int min_bullish_count = 3; int min_bearish_count = 3; int check_candles = 6; // Check the last 6 candles for patterns bool bullish_pattern = false; bool bearish_pattern = false; static bool bullish_pattern_detected = false; static bool bearish_pattern_detected = false; // Loop through recent candles to search for patterns for (int i = check_candles; i >= min_bullish_count; i--) { // Reset pattern flags for each loop iteration bullish_pattern = false; bearish_pattern = false; // 1. Check for Bullish Trend Pattern int bullish_count = 0; int bearish_count = 0; // Count initial bullish candles for (int j = i; j >= i - min_bullish_count + 1; j--) { if (iClose(symbol, timeframe, j) > iOpen(symbol, timeframe, j)){ bullish_count++; first_bullish_low = getLow(5); } else break; } // Check for 1 or 2 bearish candles followed by a bullish candle if (bullish_count >= min_bullish_count) { for (int j = i - bullish_count; j >= i - bullish_count - 1; j--) { if (iClose(symbol, timeframe, j) < iOpen(symbol, timeframe, j)) bearish_count++; else break; } if ((bearish_count == 1 || bearish_count == 2) && iClose(symbol, timeframe, i - bullish_count - bearish_count) > iOpen(symbol, timeframe, i - bullish_count - bearish_count)) { bullish_pattern = true; } } // 2. Check for Bearish Trend Pattern int bearish_candles_count = 0; int bullish_candles_count = 0; // Count initial bearish candles for (int j = i; j >= i - min_bearish_count + 1; j--) { if (iClose(symbol, timeframe, j) < iOpen(symbol, timeframe, j)){ bearish_candles_count++; first_bearish_high = getHigh(5); } else break; } // Check for 1 or 2 bullish candles followed by a bearish candle if (bearish_candles_count >= min_bearish_count) { for (int j = i - bearish_candles_count; j >= i - bearish_candles_count - 1; j--) { if (iClose(symbol, timeframe, j) > iOpen(symbol, timeframe, j)) bullish_candles_count++; else break; } if ((bullish_candles_count == 1 || bullish_candles_count == 2) && iClose(symbol, timeframe, i - bearish_candles_count - bullish_candles_count) < iOpen(symbol, timeframe, i - bearish_candles_count - bullish_candles_count)) { bearish_pattern = true; } } // Print result and call functions only once for each pattern if (bullish_pattern && !bullish_pattern_detected) { Print("Bullish pattern conditions are met"); ExecuteTrade(ORDER_TYPE_BUY); // Call to buyer function bullish_pattern_detected = true; } else if (!bullish_pattern) { bullish_pattern_detected = false; // Reset when conditions no longer met } if (bearish_pattern && !bearish_pattern_detected) { Print("Bearish pattern conditions are met"); ExecuteTrade(ORDER_TYPE_SELL); // Call to seller function bearish_pattern_detected = true; } else if (!bearish_pattern) { bearish_pattern_detected = false; // Reset when conditions no longer met } } }
A função ThreeBar() é a principal lógica de detecção de padrões do nosso EA. Ela analisa formações recentes de candles no timeframe M5, ou em qualquer outro timeframe que você carregar no EA, para detectar possíveis setups de reversão de tendência de alta ou de baixa. A lógica começa com a varredura dos últimos seis candles para identificar padrões em que uma série de pelo menos três candles consecutivos de alta ou de baixa é seguida por um recuo curto (um ou dois candles opostos) e, em seguida, por um candle de confirmação na direção original da tendência. Quando essa estrutura é detectada, isso indica a presença de um padrão válido.
Durante cada ciclo de varredura, pontos-chave de preço, como a mínima da oscilação de alta ou a máxima da oscilação de baixa, são registrados para possível uso futuro, por exemplo, em quebras de estrutura ou filtros de trading.

Atualmente, o EA abre duas posições quando há um candle de baixa após um candle de alta e abre mais uma operação após o fechamento do candle, mas abre uma única posição quando há dois candles de baixa seguidos por um candle de alta. O mesmo acontece com os sinais de venda. Para resolver esse problema, precisamos adicionar break, que interrompe imediatamente o loop assim que o padrão inicia uma operação. Isso impede que o EA continue percorrendo candles anteriores e encontre o mesmo padrão em outro ponto, especialmente quando a estrutura permite recuos tanto de 1 barra quanto de 2 barras.
// Print result and call functions only once for each pattern if (bullish_pattern && !bullish_pattern_detected) { Print("Bullish pattern conditions are met"); ExecuteTrade(ORDER_TYPE_BUY); bullish_pattern_detected = true; break; // prevent further detection in this run } else if (!bullish_pattern) { bullish_pattern_detected = false; } if (bearish_pattern && !bearish_pattern_detected) { Print("Bearish pattern conditions are met"); ExecuteTrade(ORDER_TYPE_SELL); bearish_pattern_detected = true; break; // prevent further detection in this run } else if (!bearish_pattern) { bearish_pattern_detected = false; }
Inclusão de filtros de indicadores:
// Indicator buffers double rsi_value[1]; // Use array for buffer storage double macd_main[1]; double macd_signal[1]; // Get indicator values - with error checking if (CopyBuffer(rsiHandle, 0, 0, 1, rsi_value) <= 0) { Print("RSI CopyBuffer error: ", GetLastError()); return; } if (CopyBuffer(macdHandle, 0, 0, 1, macd_main) <= 0) { Print("MACD Main Line error: ", GetLastError()); return; } if (CopyBuffer(macdHandle, 1, 0, 1, macd_signal) <= 0) { Print("MACD Signal Line error: ", GetLastError()); return; }
Antes de incluir filtros de indicadores na lógica de trading, precisamos extrair e validar os valores dos indicadores RSI e MACD usando CopyBuffer(). Isso garante que o EA receba as valores mais recentes dos indicadores. No código acima, usamos arrays para armazenar um valor de cada buffer do indicador, e o tratamento de erros é incluído após cada cópia do buffer para identificar possíveis problemas, como falha no acesso ao handle ou ausência de dados.
Se algum buffer não conseguir obter dados, a função encerra a execução antecipadamente e registra o erro correspondente, impedindo que o EA tome decisões de trading com base em entradas de indicadores inválidas ou ausentes.
// Filter + Trade Logic if (bullish_pattern && !bullish_pattern_detected && rsi_value[0] > 50 && macd_main[0] > macd_signal[0]) { Print("Bullish pattern confirmed with RSI(", rsi_value[0], ") and MACD(", macd_main[0], "/", macd_signal[0], ")"); ExecuteTrade(ORDER_TYPE_BUY); bullish_pattern_detected = true; break; } else if (!bullish_pattern) bullish_pattern_detected = false; if (bearish_pattern && !bearish_pattern_detected && rsi_value[0] < 50 && macd_main[0] < macd_signal[0]) { Print("Bearish pattern confirmed with RSI(", rsi_value[0], ") and MACD(", macd_main[0], "/", macd_signal[0], ")"); ExecuteTrade(ORDER_TYPE_SELL); bearish_pattern_detected = true; break; } else if (!bearish_pattern) bearish_pattern_detected = false;
O padrão de candles japoneses de três barras, por si só, costuma apresentar resultados ruins em testes com dados históricos, pois não considera a tendência geral do mercado, o que frequentemente leva a sinais falsos. Para aumentar a eficiência, implementamos a confirmação de tendência incluindo os indicadores RSI e MACD diretamente no bloco de decisão de trading.
Para que um sinal de alta seja válido, agora exigimos que o RSI esteja acima de 50, o que indica momentum de alta, e que a linha principal do MACD esteja acima da linha de sinal, o que indica confirmação da tendência de alta. De forma semelhante, para sinais de baixa, o RSI deve estar abaixo de 50, e a linha principal do MACD deve estar abaixo da linha de sinal. Essa lógica de filtragem aumenta a precisão das operações ao alinhar as entradas à dinâmica mais ampla do mercado.
Ao implementar esses filtros, garantimos que as operações iniciadas pelo padrão de três barras sejam executadas apenas quando houver suporte de indicadores técnicos que reflitam a direção predominante do mercado. Essa abordagem de dupla confirmação reduz a frequência de operações em mercados instáveis ou laterais e aumenta a probabilidade de entrar em operações com momentum.
Em última análise, esse aprimoramento melhora a capacidade de decisão do EA, gerando resultados de backtesting mais consistentes e favoráveis, além de ajudar a evitar oscilações bruscas causadas pela dependência exclusiva da estrutura dos candles japoneses.
Resultados do backtesting no par (XAU/USD)
O backtesting foi avaliado com dados históricos de preço do XAUUSD (ouro/dólar americano) no timeframe de 1 hora durante uma janela de teste de 4 meses (26 de novembro de 2021 a 17 de março de 2022). Os principais parâmetros incluíram:
- Período do RSI: 14
- Gestão de risco: take profit (TP) de 500 pontos, stop loss (SL) de 150 pontos, tamanho de lote fixo
- Configuração da análise: período histórico de 8 barras
Contexto de mercado.
Durante o período de teste, o preço médio do ouro foi de US$ 1.841,59, e os extremos de volatilidade variaram de US$ 1.752,95 (mínima) a US$ 2.070,48 (máxima). Essa trajetória ascendente reflete um forte sentimento de alta, especialmente evidente no início de 2022, quando os preços subiram cerca de 18%, atingindo o pico de março. A tendência de alta pronunciada nesse período está alinhada a fatores macroeconômicos.


Conclusão
Nesta otimização, eliminamos as limitações associadas à dependência exclusiva do padrão de candles japoneses de três barras para entrada em operações, incorporando indicadores técnicos essenciais: RSI e MACD. Começamos garantindo a obtenção confiável de dados usando handles de indicadores e cópia do buffer com verificação de erros. Em seguida, aplicamos esses indicadores como filtros de confirmação na lógica de execução de operações, alinhando as operações à tendência predominante do mercado. Isso melhora significativamente a qualidade das operações e a consistência do backtesting ao filtrar sinais de baixa probabilidade em condições de lateralização ou contra a tendência.
Assim, a combinação de padrões brutos de price action com indicadores baseados em momentum, como RSI e MACD, cria um sistema de trading mais orientado ao contexto. Essa abordagem em múltiplas camadas aumenta a capacidade do EA de distinguir setups de alta qualidade de setups de baixa qualidade. Ao exigir a convergência entre padrões de candles e sinais de tendência mais amplos, o EA se torna mais disciplinado e menos suscetível ao ruído de curto prazo, o que, em última análise, eleva a eficiência e a confiabilidade tanto no backtesting quanto na negociação real.
Aprimoramentos e pesquisas futuras:
| Área | Proposta | Benefício |
|---|---|---|
| Stop loss ou take profit dinâmico | Ajustar SL/TP com base no ATR ou na volatilidade recente | Torna a gestão de risco adaptada às condições de mercado |
| Aprimoramento do filtro de tendência | Incluir médias móveis (por exemplo, EMA 200) para determinar a tendência de longo prazo | Aumenta a precisão direcional das entradas |
| Controle da frequência de operações | Adicionar um tempo de espera entre operações ou limitar o número máximo de operações por dia | Reduz o excesso e o acúmulo de operações |
| Análise multitimeframe | Confirmar tendências do RSI e do MACD em timeframes superiores (por exemplo, H1, H4) | Aumenta a confiabilidade do sinal por meio do alinhamento entre os timeframes |
| Filtragem de notícias | Integrar um calendário econômico ou a identificação dos horários de divulgação de notícias | Evita operações durante eventos importantes |
Traduzido do Inglês pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/en/articles/17702
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.
Algoritmos avançados de execução de ordens em MQL5: TWAP, VWAP e ordens Iceberg
Rede neural na prática: Uma questão de escala
Está chegando o novo MetaTrader 5 e MQL5
Criação de interfaces gráficas dinâmicas em MQL5 por meio de interpolação bicúbica
- 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
Por favor, esclareça-me como CTick e PTick funcionam. Vejo que ambos são declarados junto com Includes, mas nenhum deles é referenciado em outra parte do código. Em outras palavras, o que o CTick rastreia e o que o PTick rastreia?
(Não consigo encontrar nada na documentação do MQ).
The pursuit of reliable back-test results in algorithmic trading hinges not only on robust strategy logic but also on the efficiency and precision of the underlying code. Raw code optimization and tweaking are critical to ensuring that Expert Advisors (EAs) perform as intended, minimizing computational overhead while maximizing execution accuracy. Poorly optimized code can distort back-test outcomes through delayed order execution, incorrect signal detection, or resource exhaustion—issues that mask a strategy’s true potential.
Durante o processo de desenvolvimento da estratégia, tomaremos várias medidas importantes para garantir que o EA seja forte do ponto de vista funcional e sólido do ponto de vista técnico. Começaremos adicionando funções auxiliares personalizadas e blocos lógicos reutilizáveis para simplificar as operações e evitar códigos repetitivos. Em seguida, introduziremos variáveis e constantes bem estruturadas que melhoram a legibilidade do código e simplificam os ajustes de parâmetros. Esses ajustes fundamentais ajudarão na manutenção do código e melhorarão o tempo de execução geral durante cargas pesadas de back-test ou testes com vários símbolos.
Outra grande área de aprimoramento envolve o aproveitamento mais eficiente dos indicadores técnicos. Em vez de calcular cegamente os indicadores em cada tick ou barra, implementaremos uma lógica de atualização mais inteligente para reduzir a carga e o atraso. Também faremos experimentos com diferentes combinações de indicadores para dar suporte a uma melhor tomada de decisão na lógica do EA. Combinando o refinamento do código estrutural, as funções sensíveis ao desempenho e a otimização de indicadores, podemos melhorar drasticamente a qualidade e a velocidade do backtesting, aproximando-nos de uma estratégia consistentemente lucrativa e implementável.
Não quero ofender ninguém, mas devo dizer que este artigo é um fracasso. Aqui acima está a introdução, com muitas afirmações fortes e , todas as quais o autor não conseguiu implementar.
Minha intenção inicial era mostrar os problemas com o código, mas eles são tantos... que vou apontar apenas 2.
Código robusto? Onde é feita a verificação de erros? As entradas são usadas como estão, sem nenhuma verificação, os níveis de estoque não são verificados, a margem não é verificada, a solicitação de negociação não é verificada...
Desempenho? Usando iClose/iOpen candle por candle? Essas funções são as mais lentas para lidar com dados.
Além disso, o getLow(5) parece ser um bug. Não verifiquei mais.
Não vou comentar sobre o algoritmo de negociação em si, apenas observei como o autor convenientemente selecionou um curto período da história em que o EA dá bons resultados.
Esse artigo é muito ruim.
Boa tarde, muito boa essa análise, mas complemento a mesma com a força, se volume!!! apesar dos candlesticks te darem informações o que acaba confirmando é o volume, dessa forma você poderia executar mais trade sem erro!!!
Saudações