English Русский 中文 Español Deutsch 日本語
preview
Otimização Automatizada de Parâmetros para Estratégias de Trading Usando Python e MQL5

Otimização Automatizada de Parâmetros para Estratégias de Trading Usando Python e MQL5

MetaTrader 5Exemplos | 5 novembro 2024, 17:16
516 0
Javier Santiago Gaston De Iriarte Cabrera
Javier Santiago Gaston De Iriarte Cabrera

Por Que a Auto-Otimização é Essencial

Imagine que você tem um robô de trading desenvolvido com muito esforço. Você está ansioso para vê-lo em ação, mas começa sem uma otimização adequada. Resultados iniciais positivos podem enganá-lo ao pensar que está tudo bem, mas logo inconsistências e perdas começam a aparecer.

Um robô não otimizado carece de consistência e pode responder a dados irrelevantes, resultando em lucros e perdas imprevisíveis. Ele pode tomar decisões com base em sinais falsos, não se adaptando às mudanças do mercado, e assumir riscos inesperados, causando perdas significativas. A otimização garante um desempenho e confiabilidade melhores.

Os leitores entenderão a importância da auto-otimização, os diferentes algoritmos utilizados e verão exemplos práticos em scripts Python e Expert Advisor (EA). Eles aprenderão como configurar a auto-otimização, comparar resultados e configurar corretamente a otimização de parâmetros, aumentando a eficiência de suas estratégias de trading.

Algoritmos de auto-otimização para estratégias de trading incluem otimização de parâmetros, algoritmos evolutivos, métodos heurísticos, técnicas baseadas em gradiente, aprendizado de máquina e otimização baseada em simulação. Cada um possui vantagens e desvantagens únicas, adaptadas para diferentes necessidades de trading e condições de mercado.


Técnicas de Otimização de Parâmetros

  1. Otimização por Força Bruta: Testa todas as combinações de parâmetros para obter resultados precisos, mas é intensivo em recursos.
  2. Pesquisa em Grade: Avalia combinações em uma grade para um equilíbrio entre exaustividade e eficiência.
  3. Pesquisa Aleatória: Testa combinações aleatoriamente para resultados mais rápidos, sacrificando um pouco de precisão.

Cada técnica possui suas vantagens, tornando a escolha dependente dos recursos disponíveis, do tempo e da precisão desejada.


Por que e quando devemos usar Python?

Programas em Python são uma excelente ferramenta para testar ideias, criar gráficos rapidamente e confirmar afirmações teóricas com dados históricos de trading. O Python permite que os usuários desenvolvam e ajustem modelos de forma ágil, o que facilita a experimentação com diferentes estratégias e parâmetros. Sua capacidade de gerar gráficos detalhados e visualizações ajuda a interpretar os resultados de forma mais intuitiva. Além disso, a possibilidade de integrar dados históricos permite verificar como as estratégias teriam funcionado em cenários passados, fornecendo uma validação prática para as teorias levantadas. Essa combinação de velocidade, flexibilidade e capacidade analítica torna o Python uma ferramenta inestimável para qualquer trader que busca otimizar suas estratégias e entender melhor os mercados financeiros.


Qual Estratégia Usaremos Neste Artigo e Seu Indicador

A Estratégia de Cruzamento de Médias Móveis (MAs Crossing) é uma técnica de trading baseada na interseção de duas médias móveis para gerar sinais de Compra e Venda. Ela usa duas médias móveis de diferentes períodos, uma curta e uma longa, para identificar mudanças na tendência de preço. Quando a média móvel curta cruza acima da média móvel longa, um sinal de Compra é gerado, indicando uma possível tendência de alta. Por outro lado, quando a média móvel curta cruza abaixo da média longa, um sinal de Venda é gerado, sugerindo uma possível tendência de baixa. Essa estratégia é popular devido à sua simplicidade e eficácia em mercados com tendências claras.

O indicador SMA (Média Móvel Simples) é uma ferramenta que calcula o preço médio de um ativo durante um período específico. Para calcular uma SMA, somam-se os preços de fechamento de um ativo durante o período selecionado e, em seguida, divide-se pelo número de períodos. A SMA suaviza as flutuações de preço e ajuda a identificar a direção geral da tendência. Esse indicador é útil para eliminar ruídos do mercado e fornecer uma visão mais clara da tendência subjacente. No Python, a SMA pode ser facilmente calculada usando bibliotecas como pandas, que oferecem funções para calcular médias móveis de forma eficiente e precisa.


Otimizações de Parâmetros com Python. Estudo de Caso

Temos um script para cada técnica em Python. Já vimos as diferenças de cada abordagem.

A estratégia é a mesma nos três scripts. Se você quiser usar outra estratégia, é isso que deve alterar:

    data = data.copy()  # Create a copy of the original DataFrame
    data['Short_MA'] = data['Close'].rolling(window=short_window).mean()
    data['Long_MA'] = data['Close'].rolling(window=long_window).mean()
    data['Signal'] = 0
    data.loc[data.index[short_window:], 'Signal'] = np.where(
        data['Short_MA'][short_window:] > data['Long_MA'][short_window:], 1, 0)
    data['Position'] = data['Signal'].diff()

Python é muito direto, então não explicarei o código.

Os três scripts estão anexados ao artigo (b forec.py, grid search v2.py e random search v2.py).

Antes de usar esses scripts, é necessário instalar as bibliotecas. Você pode usar o pip para isso:

pip install numpy pandas matplotlib itertools MetaTrader5 random 

Os resultados para cada script mostrarão algo semelhante a isto, com estas entradas:

symbol = "EURUSD"
timeframe = mt5.TIMEFRAME_D1
start = pd.Timestamp("2020-01-01")
end = pd.Timestamp("2021-01-01")

Força Bruta

Força Bruta esquerda

Força Bruta direita

Melhores parâmetros: Curto = 14.0, Longo = 43.0
Melhor desempenho: 10014.176, Risco: 3.7431030827241524e-05

Pesquisa em Grade

Pesquisa em Grade esquerda

Pesquisa em Grade direita

Melhores parâmetros: Curto = 14.0, Longo = 43.0
Melhor desempenho: 10014.176, Risco: 3.7431030827241524e-05

Pesquisa Aleatória

Pesquisa Aleatória esquerda

Pesquisa Aleatória direita

Melhores parâmetros: Curto = 14.0, Longo = 44.0
Melhor desempenho: 10013.697, Risco: 3.725494046576829e-05

Esses scripts não se auto-otimizam, então você deve selecionar cada período para estudar.

Os resultados são bons em todos eles e iguais, mas devemos levar em conta que a estratégia era simples, enquanto outras estratégias podem ter mais parâmetros e intervalos maiores.


Com que frequência devo otimizar uma estratégia?

Otimizar uma estratégia de trading é crucial para manter sua eficácia ao longo do tempo. A frequência e o período de retrocesso para otimização dependem de vários fatores, especialmente da volatilidade do mercado.

Imagine que você está desenvolvendo uma estratégia de trading que opera com um período de 1 dia, ou seja, cada sinal é baseado em dados diários do mercado. A volatilidade desempenha um papel importante aqui: quando o mercado é mais volátil, os movimentos de preço são maiores e mais rápidos, o que pode afetar a eficácia de sua estratégia se ela não se ajustar adequadamente.

Para determinar quando otimizar e qual retrocesso usar, você precisa monitorar a volatilidade do mercado. Uma boa forma de fazer isso é observar o intervalo diário de preços (ALTO - BAIXO) ou o intervalo médio verdadeiro dos ativos com os quais você opera. Abaixo está um guia aproximado baseado na volatilidade.

Baixa volatilidade: Quando o mercado está calmo e os intervalos diários são pequenos, as estratégias tendem a precisar de ajustes menos frequentes. Você pode pensar em otimizar a cada 1-3 meses com um período de retrocesso mais longo para capturar tendências mais estáveis. Um retrocesso de 50-100 dias pode ser adequado.

Volatilidade moderada: Em condições normais de mercado, com movimentos de preço mais regulares, mas não extremamente grandes, considere otimizar a cada 1-2 meses. Um retrocesso de 20-50 dias pode ser suficiente para capturar mudanças significativas na tendência.

Alta volatilidade: Durante períodos de alta volatilidade, como em tempos de crise ou eventos econômicos importantes, os movimentos de preço são grandes e rápidos. Aqui, é crucial otimizar com mais frequência, possivelmente a cada 2-4 semanas, e usar um retrocesso mais curto, como 10-20 dias, para se adaptar rapidamente às mudanças nas condições do mercado.


Exemplo de Auto-Otimização em MQL5

Este código em MQL5 é um robô de trading que implementa uma estratégia de cruzamento de médias móveis (MA). Ele funciona na plataforma MetaTrader 5 e foi projetado para operar no mercado financeiro automaticamente. O bot usa duas MAs simples (SMA) com períodos ajustáveis para gerar sinais de Compra e Venda quando se cruzam.

O principal objetivo do bot é otimizar automaticamente os períodos das MAs para maximizar o benefício líquido, minimizar o rebaixamento ou maximizar o índice de Sharpe, de acordo com a configuração escolhida pelo usuário. Isso é alcançado através de um processo de otimização que testa diferentes combinações de períodos de MA em um período específico de dados históricos.

O bot é estruturado com várias seções-chave:

1. Inicialização e configuração: Define os parâmetros iniciais, como períodos de MA, tamanho de lote, número mágico para identificação de ordens, etc.

2. Otimização: Usa um algoritmo de busca exaustiva para testar todas as combinações possíveis de períodos de MA dentro dos intervalos especificados. A otimização é realizada com base nos critérios selecionados: Benefício líquido ou rebaixamento mínimo.

3. Execução de operações: Monitora continuamente o mercado e abre posições de compra ou venda quando ocorrem cruzamentos de MA de acordo com a estratégia definida. Também gerencia posições abertas, aplicando perdas e níveis de ganhos com base no ATR (Average True Range).

4. Reotimização automática: Em certos períodos de tempo (configurável), o bot reotimiza os parâmetros das MAs para se adaptar às condições de mercado em mudança.

5. Trailing Stop: Implementa diferentes tipos de Trailing Stops (Simples e Expectativa Moral) para garantir lucros e proteger contra perdas.

6. Horários de negociação: Pode ser configurado para não operar em certos dias da semana ou em horários específicos.

7. Finalização e limpeza: O robô realiza a limpeza adequada e o fechamento de todas as operações abertas ao parar.

Em resumo, este robô de trading é uma implementação complexa que combina análise técnica (cruzamento de MAs) com estratégias de gerenciamento de risco (Stops e Trailing Stops) e otimização automatizada de parâmetros. Ele é projetado para operar de forma autônoma e é otimizado para maximizar o desempenho ajustado ao risco em um ambiente de trading automatizado.

Os trailing stops usados no artigo e no código são obtidos do artigo: Trailing stop em trading de Aleksej Poljakov.

 


Código

Para usar outra Técnica de Otimização, você deve alterar esta parte do código:

   for(int fastPeriod = FastMAPeriodStart; fastPeriod <= FastMAPeriodStop; fastPeriod += FastMAPeriodStep)
     {
      for(int slowPeriod = SlowMAPeriodStart; slowPeriod <= SlowMAPeriodStop; slowPeriod += SlowMAPeriodStep)
        {
         double criterionValue = PerformBacktest(fastPeriod, slowPeriod, startBar);

         if(IsNewOptimal(criterionValue, bestCriterionValue, OptimizationCriterion))
           {
            bestCriterionValue = criterionValue;
            bestFastPeriod = fastPeriod;
            bestSlowPeriod = slowPeriod;
           }
        }
     }

Para usar outra Estratégia, você deve alterar esta parte do código (e suas entradas):

double fastMA_curr[];
   double slowMA_curr[];
   double fastMA_prev[];
   double slowMA_prev[];

   ArraySetAsSeries(fastMA_curr, true);
   ArraySetAsSeries(slowMA_curr, true);
   ArraySetAsSeries(fastMA_prev, true);
   ArraySetAsSeries(slowMA_prev, true);

   int fastMA_current = iMA(_Symbol, 0, FastMAPeriod, 0, MODE_SMA, PRICE_CLOSE);
   int fastMA_previous = iMA(_Symbol, 0, FastMAPeriod, 1, MODE_SMA, PRICE_CLOSE);

   int slowMA_current = iMA(_Symbol, 0, SlowMAPeriod, 0, MODE_SMA, PRICE_CLOSE);
   int slowMA_previous = iMA(_Symbol, 0, SlowMAPeriod, 1, MODE_SMA, PRICE_CLOSE);


   CopyBuffer(fastMA_current, 0, 0, 2, fastMA_curr);
   CopyBuffer(slowMA_current, 0, 0, 2, slowMA_curr);
   CopyBuffer(fastMA_previous, 0, 0, 2, fastMA_prev);
   CopyBuffer(slowMA_previous, 0, 0, 2, slowMA_prev);

   double fastMA_previousFF = fastMA_prev[0];
   double slowMA_previousSS = slowMA_prev[0];
   double fastMA_currentFF = fastMA_curr[0];
   double slowMA_currentSS = slowMA_curr[0];

// Check for buy signal (fast MA crosses above slow MA)
   if(fastMA_previousFF < slowMA_previousSS && fastMA_currentFF > slowMA_currentSS)
     {
      // Close any existing sell positions
      if(PositionsTotal() > 0)
        {
         for(int i = PositionsTotal() - 1; i >= 0; i--)
           {
            if(PositionSelectByTicket(i))
              {
               if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
                 {
                  Print("Closing sell position: Ticket ", PositionGetInteger(POSITION_TICKET));
                  ClosePosition(PositionGetInteger(POSITION_TICKET));
                 }
              }
           }
        }

      // Open a buy position
      double openPrice = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
      double atrMultiplier = ATRmultiplier;
      OpenPosition(ORDER_TYPE_BUY, openPrice, atrMultiplier);
     }

// Check for sell signal (fast MA crosses below slow MA)
   else
      if(fastMA_previousFF > slowMA_previousSS && fastMA_currentFF < slowMA_currentSS)
        {
         // Close any existing buy positions
         if(PositionsTotal() > 0)
           {
            for(int i = PositionsTotal() - 1; i >= 0; i--)
              {
               if(PositionSelectByTicket(i))
                 {
                  if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
                    {
                     Print("Closing buy position: Ticket ", PositionGetInteger(POSITION_TICKET));
                     ClosePosition(PositionGetInteger(POSITION_TICKET));
                    }
                 }
              }
           }

         // Open a sell position
         double openPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);
         double atrMultiplier = ATRmultiplier;
         OpenPosition(ORDER_TYPE_SELL, openPrice, atrMultiplier);

        }
   IndicatorRelease(fastMA_current);
   IndicatorRelease(slowMA_current);
   IndicatorRelease(fastMA_previous);
   IndicatorRelease(slowMA_previous);
  }

É importante observar que, se você não liberar os indicadores, a janela do gráfico ficará cheia deles.


Diferença com e sem auto-otimização

Usaremos o mesmo período (de 20-04-2024 a 20-05-2024) para EURUSD e um período de barras de 1 dia.

configurações com otimização

Com Otimização

entradas com otimização

backtest com otimização

gráfico com otimização

Sem auto-otimização

entradas sem auto-otimização

backtest sem parametrização automática

gráfico sem auto-otimização

Claramente, é uma solução melhor auto-otimizar. Nenhuma operação foi realizada sem auto-otimização. A primeira foi auto-otimizada no início, e então teve 40 dias para reotimizar (fora do período).


Conclusão

A auto-otimização é crucial para garantir o desempenho consistente e confiável dos bots de trading nos mercados financeiros em constante mudança. Neste artigo, os leitores obtiveram uma compreensão abrangente do porquê a auto-otimização é essencial, os vários tipos de algoritmos disponíveis para otimizar estratégias de trading e parâmetros, e os benefícios e desvantagens das diferentes técnicas de otimização de parâmetros. A importância do Python como ferramenta para back-testing de estratégias de maneira rápida e eficiente foi destacada, juntamente com um estudo de caso que demonstra a otimização de parâmetros usando uma estratégia de cruzamento de Médias Móveis.

O artigo explorou ainda a necessidade de otimização regular com base na volatilidade do mercado, enfatizando a necessidade de ajustes frequentes para manter a eficácia. Um exemplo de auto-otimização usando MQL5 ilustrou a aplicação prática desses conceitos, mostrando as melhorias significativas de desempenho alcançáveis através da auto-otimização. A comparação entre bots auto-otimizados e não otimizados ressaltou as claras vantagens do primeiro, com bots otimizados demonstrando maior adaptabilidade e eficiência.

Em conclusão, a auto-otimização não só aprimora o desempenho do bot de trading, mas também proporciona aos traders maior confiança e tranquilidade, sabendo que seu bot pode navegar pelas complexidades dos mercados financeiros de forma eficaz. Essa abordagem estratégica para o desenvolvimento e manutenção de bots de trading é indispensável para quem deseja alcançar sucesso consistente e sustentável no trading.


Livros e recursos educacionais

  • "Avanços em Machine Learning Financeiro" de Marcos López de Prado.
  • "Algorithmic Trading and DMA" de Barry Johnson.
  • "Python para Análise de Dados" de Wes McKinney.
  • "Machine Learning para Gestores de Ativos" de Marcos López de Prado.
  • "Quantitative Trading: How To Build Your Own Algorithmic Trading Business" de Ernest P.


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

Arquivos anexados |
b_forec.py (3.64 KB)
grid_search_v2.py (3.64 KB)
Funcionalidades do Assistente MQL5 que você precisa conhecer (Parte 16): Método de componentes principais com autovetores Funcionalidades do Assistente MQL5 que você precisa conhecer (Parte 16): Método de componentes principais com autovetores
Este artigo discute o método de componentes principais, um método de redução da dimensionalidade ao analisar dados, e como ele pode ser implementado usando autovalores e vetores. Como sempre, vamos tentar desenvolver um protótipo da classe de sinais para EA que pode ser usado no Assistente MQL5.
Construindo um Modelo de Restrição de Tendência de Candlestick (Parte 5): Sistema de Notificação (Parte II) Construindo um Modelo de Restrição de Tendência de Candlestick (Parte 5): Sistema de Notificação (Parte II)
Hoje, estamos discutindo uma integração funcional do Telegram para notificações do Indicador MetaTrader 5 usando o poder do MQL5, em parceria com Python e a API do Bot do Telegram. Explicaremos tudo em detalhes para que ninguém perca nenhum ponto. Ao final deste projeto, você terá adquirido conhecimentos valiosos para aplicar em seus projetos.
Construção de um modelo de restrição de tendência de velas (Parte 1): Para EAs e indicadores técnicos Construção de um modelo de restrição de tendência de velas (Parte 1): Para EAs e indicadores técnicos
Este artigo é voltado para desenvolvedores iniciantes e experientes em MQL5. Ele oferece um código que define indicadores para gerar sinais, limitando-os com base nas tendências de timeframes mais altos. Dessa forma, traders podem aprimorar suas estratégias ao incluir uma visão mais ampla do mercado, o que pode resultar em sinais de negociação potencialmente mais confiáveis.
Visualizações de negociações no gráfico (Parte 2): Desenho gráfico de informações Visualizações de negociações no gráfico (Parte 2): Desenho gráfico de informações
Escreveremos do zero um script para facilitar a captura de capturas de tela (print-screens) de negociações, visando a análise de entradas. Em um único gráfico, será conveniente exibir todas as informações necessárias sobre uma negociação específica, com a possibilidade de desenhar diferentes timeframes.