Otimização separada de uma estratégia em condições de tendência e lateralizada

Alexander Fedosov | 14 fevereiro, 2019

Conteúdo


Introdução

Ao desenvolver estratégias de negociação, a primeira tarefa é definir as condições de entrada no mercado, o método de monitoramento da posição e o ponto de saída. Vários métodos matemáticos, estatísticos e outros métodos analíticos são aplicados para isso. Eles são freqüentemente reforçados com sistemas autônomos prontos para avaliar as características do mercado na forma de indicadores. Uma das principais questões ao desenvolver qualquer estratégia de negociação é a falta de versatilidade. Um sistema de negociação não é capaz de funcionar em todas as condições de mercado possíveis com eficiência igual. Portanto, os traders geralmente selecionam condições para detectar certas condições de mercado (potencialmente lucrativas) ao desenvolver os Expert Advisors. 

Além disso, cada sistema de negociação tem suas desvantagens. As estratégias seguidoras de tendência falham durante movimentos de lateralização prolongados, enquanto as baseada em lateralização fornecem entradas falsas durante movimentos direcionais fortes. Para reduzir o efeito de sinais falsos e melhorar a lucratividade, os sistemas são flexíveis, o que significa que eles têm um conjunto específico de configurações ou dados de entrada, o que se justifica porque o comportamento do mercado está em constante alteração.

Com o tempo, qualquer sistema de negociação se torna menos eficiente e, portanto, há uma necessidade de adaptar seus parâmetros a novas condições. O Testador de Estratégia integrado a plataforma MetaTrader 5 destina-se a resolver este problema. Esta ferramenta ajuda a analisar o desempenho de qualquer EA de negociação no histórico e define as configurações ideais para seu uso posterior como base na negociação real.


Conceito de otimização separada

Neste artigo, nós vamos considerar a aplicação do Testador de Estratégia em um sentido mais amplo. Obviamente, a maioria dos sistemas de negociação negocia em duas direções (compra e venda sob certas condições). A Fig. 1 mostra um exemplo simples de uma estratégia de negociação em ação. Sua ideia é simples — comprar a um preço em baixa e vender em alta.


Fig.1. Estratégia seguidora de tendência em ação

Geralmente, um conjunto de configurações são usados para determinar a tendência de alta e a tendência de baixa em tal sistema, e as condições de entrada são espelhadas. Mas o ponto é que as especificidades do mercado em alta e baixa podem ser muito diferentes em muitas características, como velocidade e duração. Nesse sentido, eu proponho considerar um sistema que determina entradas no mercado de maneira separada para as tendências de alta e de baixa.

Para conseguir isso, nós precisaremos de dois conjuntos de parâmetros que definem as condições de entrada e saída do mercado. Neste ponto, nós chegamos ao conceito de "otimização separada".

A otimização separada significa definir os parâmetros ideais do sistema de negociação usando o Testador de Estratégia para as tendências de alta e baixa separadamente.

Para testar a otimização separada, eu decidi escolher dois sistemas de negociação: os seguidores de tendência e os baseados em lateralização. Na estratégia seguidora de tendência, nós otimizaremos a tendência de alta e baixa separadamente, enquanto na lateralizada, nós avaliaremos a otimização separada da negociação em um canal. 


Selecionando uma estratégia de negociação seguidora de tendência

Eu vou usar o indicador Centro de Gravidade de J. F. Ehlers representado por um histograma colorido do OSMA (CenterOfGravityOSMA) para testar uma otimização separada. Seu sinal é confirmado pelo indicador que calcula a Velocidade Média (Average Speed) do preço.

Parâmetro Descrição
Indicador aplicado CenterOfGravityOSMA
Indicador aplicado Average Speed
Tempo gráfico H1
Condições de compra O histograma do Center of Gravity mostra crescimento (o valor do indicador é menor que zero) e o valor do Average Speed está acima do limiar (pré-configurado nos parâmetros)
Condições de venda O histograma do Center of Gravity mostra queda (o valor do indicador é maior que zero) e o valor do Average Speed está acima do limiar (pré-configurado nos parâmetros)
Condições de saída Take Profit/Stop Loss

A estratégia é apresentada visualmente na Fig. 2. Como pode ser visto na tabela acima, a estratégia de negociação tem condições claramente definidas para entrar comprado ou vendido no mercado. Como essa é uma estratégia seguidora de tendência, as condições de compra correspondem a uma tendência de alta, enquanto as condições de venda correspondem a uma tendência de baixa. 

Fig. 2. Condições de entrada para a estratégia seguidora de tendência

Ao implementar a estratégia no MetaEditor, nós devemos definir as condições de trabalho do EA de modo que ele possa ser usado somente durante uma tendência de alta, somente durante uma tendência de baixa ou em ambos os casos. 

Nós devemos também levar em conta o seguinte:

  • Capacidade de gerenciar os modos de teste para tendências de alta e baixa, bem como para ambos os casos.
  • Para uma otimização separada, é necessário usar o EA separadamente para uma tendência de alta, uma tendência de baixa e uma operação conjunta;
  • A tendência de alta e de baixa devem apresentar seus próprios parâmetros separados. Isso é necessário para usá-los na operação conjunta;

Para cumprir essas condições de desenvolvimento do EA, digite o seguinte código:

//+------------------------------------------------------------------+
//| Enumeração dos modos de operação                                 |
//+------------------------------------------------------------------+
enum Trend_type
  {
   UPTREND = 1,            //Tendência de alta       
   DOWNTREND,              //Tendência de baixa
   BOTH                    //Ambas as tendências
  };

O conjunto de entrada é o seguinte:

//+------------------------------------------------------------------+
//| Parâmetros de entrada do EA                                      |
//+------------------------------------------------------------------+
input string               Inp_EaComment="Trend Strategy";              //Comentário do EA
input double               Inp_Lot=0.01;                                //Lote
input MarginMode           Inp_MMode=LOT;                               //MM

input Trend_type           Inp_Trend_type=3;                            //Tipo da tendência
//--- Parâmetros da tendência de alta
input string               Inp_Str_label1="===Uptrend parameters===";   //Rótulo
input int                  Inp_MagicNum1=1111;                          //Magic number
input int                  Inp_StopLoss1=40;                            //Stop Loss(pontos)
input int                  Inp_TakeProfit1=60;                          //Take Profit(pontos)

//--- Parâmetros do indicador CenterOfGravityOSMA
input uint                 Period_1=9;                                  //Período médio
input uint                 SmoothPeriod1_1=3;                           //Período de suavização 1
input ENUM_MA_METHOD       MA_Method_1_1=MODE_SMA;                      //Método da média 1
input uint                 SmoothPeriod2_1=3;                           //Período de suavização 2
input ENUM_MA_METHOD       MA_Method_2_1=MODE_SMA;                      //Método da média 2
input Applied_price_       AppliedPrice1=PRICE_OPEN_;                   //Preço aplicado

//--- Parâmetros do indicador Average Speed
input int                  Inp_Bars1=1;                                 //Dias
input ENUM_APPLIED_PRICE   Price1=PRICE_CLOSE;                          //Preço aplicado
input double               Trend_lev1=2;                                //Nível de tendência

//--- Parâmetros da tendência de baixa
input string               Inp_Str_label2="===Downtrend parameters==="; //Rótulo
input int                  Inp_MagicNum2=2222;                          //Magic number
input int                  Inp_StopLoss2=40;                            //Stop Loss(pontos)
input int                  Inp_TakeProfit2=60;                          //Take Profit(pontos)

//--- Parâmetros do indicador CenterOfGravityOSMA
input uint                 Period_2=9;                                  //Período médio
input uint                 SmoothPeriod1_2=3;                           //Período de suavização 1
input ENUM_MA_METHOD       MA_Method_1_2=MODE_SMA;                      //Método da média 1
input uint                 SmoothPeriod2_2=3;                           //Período de suavização 2
input ENUM_MA_METHOD       MA_Method_2_2=MODE_SMA;                      //Método da média 2
input Applied_price_       AppliedPrice2=PRICE_OPEN_;                   //Preço aplicado

//--- Parâmetros do indicador Average Speed
input int                  Inp_Bars2=1;                                 //Dias
input ENUM_APPLIED_PRICE   Price2=PRICE_CLOSE;                          //Preço aplicado
input double               Trend_lev2=2;                                //Nível de tendência

Como podemos ver no código, a variável Inp_Trend_type é responsável por selecionar o modo de operação do EA, enquanto os parâmetros de entrada para os modos Uptrend e Downtrend são separados para os 'Parâmetros de Tendência de alta' e 'Parâmetros de Tendência de baixa', respectivamente. Ao escolher o modo Both, as entradas de ambas as seções são usadas, enquanto o código de implementação da lógica principal é fornecido na listagem a seguir:

//+------------------------------------------------------------------+
//| Função tick do Expert                                            |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- Obtém os dados para o cálculo

   if(!GetIndValue())
      return;

   if(Inp_Trend_type==1 && !Trade.IsOpenedByMagic(Inp_MagicNum1))
     {
      //--- Abre a ordem se houver um sinal de compra
      if(BuySignal())
         Trade.BuyPositionOpen(Symbol(),Inp_Lot,Inp_StopLoss1,Inp_TakeProfit1,Inp_MagicNum1,Inp_EaComment);
     }
   else if(Inp_Trend_type==2 && !Trade.IsOpenedByMagic(Inp_MagicNum2))
     {
      //--- Abre a ordem se houver um sinal de venda
      if(SellSignal())
         Trade.SellPositionOpen(Symbol(),Inp_Lot,Inp_StopLoss2,Inp_TakeProfit2,Inp_MagicNum2,Inp_EaComment);
     }
   else if(Inp_Trend_type==3)
     {
      //--- Abre a ordem se houver um sinal de compra
      if(BuySignal() && !Trade.IsOpenedByMagic(Inp_MagicNum1))
         Trade.BuyPositionOpen(Symbol(),Inp_Lot,Inp_StopLoss1,Inp_TakeProfit1,Inp_MagicNum1,Inp_EaComment);
      //--- Abre a ordem se houver um sinal de venda
      if(SellSignal() && !Trade.IsOpenedByMagic(Inp_MagicNum2))
         Trade.SellPositionOpen(Symbol(),Inp_Lot,Inp_StopLoss2,Inp_TakeProfit2,Inp_MagicNum2,Inp_EaComment);
     }
  }
//+------------------------------------------------------------------+
//| Condições de compra                                              |
//+------------------------------------------------------------------+
bool BuySignal()
  {
   return(avr_speed1[0]>Trend_lev1 && cog1[1]<cog1[0] &&(cog1[1]<0 && cog1[0]<0))?true:false;
  }
//+------------------------------------------------------------------+
//| Condições de venda                                               |
//+------------------------------------------------------------------+
bool SellSignal()
  {
   return(avr_speed2[0]>Trend_lev2 && cog2[1]>cog2[0] &&(cog2[1]>0 && cog2[0]>0))?true:false;
  }
//+------------------------------------------------------------------+
//| Obtém os valores do indicador atual                              |
//+------------------------------------------------------------------+
bool GetIndValue()
  {
   return(CopyBuffer(InpInd_Handle1,0,0,2,cog1)<=0 ||
          CopyBuffer(InpInd_Handle2,0,0,2,cog2)<=0 ||
          CopyBuffer(InpInd_Handle3,0,0,2,avr_speed1)<=0 ||
          CopyBuffer(InpInd_Handle4,0,0,2,avr_speed2)<=0
          )?false:true;
  }
//+------------------------------------------------------------------+

As regras de negociação são simples para os modos Uptrend e Downtrend: comprar durante uma tendência de alta e vender durante uma tendência de baixa, ou seja, seguir a tendência. No modo Both, esses sistemas trabalham juntos e independentemente uns do outro com seus parâmetros de entrada exclusivos - Uptrend+Downtrend.


Testando a estratégia de negociação

Para testar e separar a otimização de uma estratégia selecionada, seria razoável selecionar períodos de tendência de alta claros para o modo Uptrend e períodos de tendência de baixa para o Downtrend. Portanto, eu decidi selecionar os seguintes períodos de tempo exibidos na Fig. 3.

Fig. 3. Períodos de tempo selecionados para o teste

Então, vamos resumir as configurações do teste.

  • Intervalo: Para o modo Uptrend: 10.04.2017 — 01.02.2018. Para o modo Downtrend: 08.05.2014 — 13.03.2015.
  • Símbolo: EURUSD.
  • Modo de negociação: Sem delay. Estas não são estratégias de negociação de alta frequência, portanto o efeito dos delays seria pequeno.
  • Teste: М1 OHLC. O pré-teste em ticks reais exibe resultados quase similares. 
  • Depósito inicial: 1000 USD.
  • Alavancagem: 1:500.
  • Servidor: MetaQuotes-Demo.
  • Cotações: 5-digit.

Os objetivos de teste e otimização são os parâmetros dos indicadores usados na estratégia, bem como os valores de take profit e stop loss.

Os resultados da otimização para uma tendência de alta são os seguintes:


Fig. 4. Resultados do teste e otimização na tendência de alta

Os resultados da otimização para uma tendência de baixa são os seguintes:


Fig. 5. Resultados do teste e otimização na tendência de baixa

Depois de definir os melhores parâmetros usando a otimização nos intervalos de tempo favoráveis para os modos selecionados, é hora de testar esses parâmetros em um intervalo misto com tendências ascendentes e descendentes. Isso nos permitirá testar a versatilidade da estratégia de negociação. 

Eu decidi escolher o seguinte intervalo de tempo, o que é bastante adequado para as ordens mencionadas acima.

Fig. 6. Período de tempo selecionado para testes mistos

Como nós podemos ver na Fig. 6, este intervalo de tempo apresenta tendências ascendentes e descendentes com reversões e movimentos lateralizados. Agora nós vamos ver como o EA se comportará em um período desconhecido do histórico.


Fig. 7. Os resultados do teste da estratégia seguidora de tendência otimizada no intervalo desfavorável


Considerando os resultados dos testes dessas estratégias seguidoras de tendência, nós podemos fazer as seguintes observações:

  • A estratégia demonstrou um resultado positivo em um intervalo desfavorável.
  • O percentual de negócios comprados bem-sucedidos se mostrou de alta qualidade do que o percentual de vendidos.
  • Além disso, os parâmetros como Lucratividade e Retorno Esperado mostraram que a estratégia geralmente demonstrou uma dinâmica positiva nesse intervalo de teste. 

Seleção de uma estratégia baseada em lateralização

Para realizar uma otimização separada em um mercado lateralizado, eu selecionei a Faixa Percentual de Williams para determinar o estado de sobrecompra/sobrevenda. Essa ferramenta deve ser usada como o principal indicador para buscar entradas. O indicador seguidor de tendência ADX será usado como confirmação de ausência de tendência.

Parâmetro Descrição
Indicador aplicado Williams Percent Range
Indicador aplicado ADX
Tempo gráfico H1
Condições de compra O indicador WPR está na zona de sobrevenda (abaixo de -80) e o valor do ADX está abaixo do limiar.
Condições de venda O indicador WPR está na zona de sobrecompra (acima de -20) e o valor de ADX está abaixo do limiar.
Condições de saída   Take Profit/Stop Loss

A Fig. 8 fornece um exemplo visual de entrada no mercado de acordo com essa estratégia.

Fig. 8. Condições de entrada de acordo com a estratégia lateralizada

Com base na estratégia escolhida, a otimização separada será executada por tipos de operação: nos modos Compra e Venda.

//+------------------------------------------------------------------+
//| Enumeração dos modos de operação                                 |
//+------------------------------------------------------------------+
enum Trend_type
  {
   UPTREND = 1,            //Compra       
   DOWNTREND,              //Venda
   BOTH                    //Ambos 
  };

Desta forma, é possível determinar como a estratégia escolhida se comporta em condições lateralizadas. O código do EA é fornecido abaixo:

//+------------------------------------------------------------------+
//| Função tick do Expert                                            |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- Obtém os dados para o cálculo

   if(!GetIndValue())
      return;

   if(Inp_Trend_type==1 && !Trade.IsOpenedByMagic(Inp_MagicNum1))
     {
      //--- Abre a ordem se houver um sinal de compra
      if(BuySignal())
         Trade.BuyPositionOpen(Symbol(),Inp_Lot,Inp_StopLoss1,Inp_TakeProfit1,Inp_MagicNum1,Inp_EaComment);
     }
   else if(Inp_Trend_type==2 && !Trade.IsOpenedByMagic(Inp_MagicNum2))
     {
      //--- Abre a ordem se houver um sinal de venda
      if(SellSignal())
         Trade.SellPositionOpen(Symbol(),Inp_Lot,Inp_StopLoss2,Inp_TakeProfit2,Inp_MagicNum2,Inp_EaComment);
     }
   else if(Inp_Trend_type==3)
     {
      //--- Abre a ordem se houver um sinal de compra
      if(BuySignal() && !Trade.IsOpenedByMagic(Inp_MagicNum1))
         Trade.BuyPositionOpen(Symbol(),Inp_Lot,Inp_StopLoss1,Inp_TakeProfit1,Inp_MagicNum1,Inp_EaComment);
      //--- Abre a ordem se houver um sinal de venda
      if(SellSignal() && !Trade.IsOpenedByMagic(Inp_MagicNum2))
         Trade.SellPositionOpen(Symbol(),Inp_Lot,Inp_StopLoss2,Inp_TakeProfit2,Inp_MagicNum2,Inp_EaComment);
     }
  }
//+------------------------------------------------------------------+
//| Condições de compra                                              |
//+------------------------------------------------------------------+
bool BuySignal()
  {
   return(wpr1[0]<-80 && adx1[0]<Inp_FlatLevel1)?true:false;
  }
//+------------------------------------------------------------------+
//| Condições de venda                                               |
//+------------------------------------------------------------------+
bool SellSignal()
  {
   return(wpr2[0]>=-20 && adx2[0]<Inp_FlatLevel2)?true:false;
  }
//+------------------------------------------------------------------+
//| Obtém os valores atuais do indicador                             |
//+------------------------------------------------------------------+
bool GetIndValue()
  {
   return(CopyBuffer(InpInd_Handle1,0,0,2,wpr1)<=0  ||
          CopyBuffer(InpInd_Handle2,0,0,2,wpr2)<=0 || 
          CopyBuffer(InpInd_Handle3,0,0,2,adx1)<=0  ||
          CopyBuffer(InpInd_Handle4,0,0,2,adx2)<=0
          )?false:true;
  }
//+------------------------------------------------------------------+


Testando a estratégia baseada em lateralização

Semelhante ao teste da estratégia seguidora de tendência, nós devemos primeiro selecionar um segmento do histórico para treinamento e otimização da estratégia selecionada, baseada em lateralização. A figura abaixo mostra o intervalo do teste:

Fig. 9. Intervalo de teste selecionado para a estratégia lateralizada

As condições gerais do teste são as seguintes:

Os parâmetros take profit e stop loss serão usados nos testes e na otimização. Resultados de otimização separados no modo de Compra são exibidos na tabela abaixo.


Fig. 10. Resultados da otimização da estratégia baseada em lateralização no modo de Compra

Resultados da otimização separada no Modo de Venda são o seguinte:


Fig. 11. Resultados da otimização da estratégia baseada em lateralização no modo de Venda

Depois de definir os melhores parâmetros para os dois modos usando a otimização separada, é hora de verificar a estratégia em um intervalo desfavorável e descobrir como ela se comporta em novas condições. Como um experimento, nós escolheremos um intervalo do mercado em tendência que já foi escolhido para testar a estratégia seguidora de tendência (a apresentada na Fig. 6). Nós o usamos para um teste misto da estratégia seguidora de tendência no modo Both (Uptrend+ Downtrend).

O resultado é o seguinte:


Fig. 12. Resultados do teste da estratégia baseada em lateralização otimizada no intervalo desfavorável

Considerando que a estratégia é baseada em lateralização, enquanto o intervalo de teste apresenta movimentos de tendência prolongados, ela obteve bons resultados e se mostrou lucrativa. 


Combinando as estratégias

Nós consideramos as estratégias baseadas em tendência e baseadas em lateralização como exemplos para a otimização separada. Ambas as estratégias foram divididas em dois componentes, treinadas em mercados favoráveis e otimizadas. Além disso, a sua viabilidade foi testada em um intervalo de mercado desconhecido, e os resultados foram bastante promissores. Agora, vamos verificar a estratégia combinando as duas estratégias descritas acima em um intervalo de tempo mais amplo. Mas primeiro, nós devemos combinar as duas estratégias em uma. 

Imediatamente após a implementação da estratégia no código, os parâmetros otimizados dos dois modos seguidores de tendência e os dois modos das estratégias baseadas em lateralização foram definidos:

//+------------------------------------------------------------------+
//| Parâmetros de entrada do EA                                      |
//+------------------------------------------------------------------+
input string               Inp_EaComment="Universe Strategy";           //Comentário do EA
input double               Inp_Lot=0.01;                                //Lote
input MarginMode           Inp_MMode=LOT;                               //MM

//--- Parâmetros da tendência de alta
input string               Inp_Str_label1="===Uptrend parameters===";   //Label
input int                  Inp_MagicNum1=1111;                          //Magic number
input int                  Inp_StopLoss1=50;                            //Stop Loss(points)
input int                  Inp_TakeProfit1=55;                          //Take Profit(points)

//--- Parâmetros do indicador CenterOfGravityOSMA
input uint                 Period_1=9;                                  //Período médio
input uint                 SmoothPeriod1_1=3;                           //Período de suavização 1
input ENUM_MA_METHOD       MA_Method_1_1=MODE_SMA;                      //Método da média 1
input uint                 SmoothPeriod2_1=3;                           //Período de suavização 2
input ENUM_MA_METHOD       MA_Method_2_1=MODE_SMA;                      //Método da média 2
input Applied_price_       AppliedPrice1=PRICE_TRENDFOLLOW1_;           //Preço aplicado

//--- Parâmetros do indicador Average Speed
input int                  Inp_Bars1=1;                                 //Dias
input ENUM_APPLIED_PRICE   Price1=PRICE_LOW;                            //Preço aplicado
input double               Trend_lev1=1.6;                              //Nível de tendência

//--- Parâmetros da tendência de baixa
input string               Inp_Str_label2="===Downtrend parameters==="; //Label
input int                  Inp_MagicNum2=2222;                          //Magic number
input int                  Inp_StopLoss2=40;                            //Stop Loss(pontos)
input int                  Inp_TakeProfit2=70;                          //Take Profit(pontos)

//--- Parâmetros do indicador CenterOfGravityOSMA
input uint                 Period_2=15;                                 //Período da média
input uint                 SmoothPeriod1_2=3;                           //Período de suavização 1
input ENUM_MA_METHOD       MA_Method_1_2=MODE_SMA;                      //Método da média 1
input uint                 SmoothPeriod2_2=3;                           //Período de suavização 2
input ENUM_MA_METHOD       MA_Method_2_2=MODE_SMA;                      //Método da média 2
input Applied_price_       AppliedPrice2=PRICE_HIGH_;                   //Preço aplicado

//--- Parâmetros do indicador Average Speed
input int                  Inp_Bars2=1;                                 //Dias
input ENUM_APPLIED_PRICE   Price2=PRICE_WEIGHTED;                       //Preço aplicado
input double               Trend_lev2=1.0;                              //Nível da tendência


//--- Parâmetros de compra
input string               Inp_Str_label3="===Buy parameters===";       //Rótulo
input int                  Inp_MagicNum3=3333;                          //Magic number
input int                  Inp_StopLoss3=40;                            //Stop Loss(pontos)
input int                  Inp_TakeProfit3=60;                          //Take Profit(pontos)

//--- Parâmetros do indicaodor WPR
input int                  Inp_WPRPeriod1=11;                           //Período WPR
//--- Parâmetros do indicador ADX
input int                  Inp_ADXPeriod1=13;                           //Período ADX
input int                  Inp_FlatLevel1=25;                           //Nível de lateralização do ADX

//--- Parâmetros de Venda
input string               Inp_Str_label4="===Sell parameters===";      //Rótulo
input int                  Inp_MagicNum4=4444;                          //Magic number
input int                  Inp_StopLoss4=30;                            //Stop Loss(pontos)
input int                  Inp_TakeProfit4=30;                          //Take Profit(pontos)

//--- Parâmetros do indicaodor WPR
input int                  Inp_WPRPeriod2=7;                            //Período WPR
//--- Parâmetros do indicador ADX
input int                  Inp_ADXPeriod2=15;                           //Período ADX
input int                  Inp_FlatLevel2=40;                           //Nível de lateralização do ADX

Além disso, a opção de definir os modos foi removida, uma vez que o EA combinado não está sujeito a treinamento ou otimização. A estratégia em si é implementada da seguinte forma:

//+------------------------------------------------------------------+
//| Função tick do Expert                                            |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- Obtém os dados para o cálculo

   if(!GetIndValue())
      return;

//--- Abre ordem se houver um sinal de compra (estratégia seguidora de tendência)
   if(BuySignal_1() && !Trade.IsOpenedByMagic(Inp_MagicNum1))
      Trade.BuyPositionOpen(Symbol(),Inp_Lot,Inp_StopLoss1,Inp_TakeProfit1,Inp_MagicNum1,Inp_EaComment);
//--- Abre ordem se houver um sinal de venda (estratégia seguidora de tendência)
   if(SellSignal_1() && !Trade.IsOpenedByMagic(Inp_MagicNum2))
      Trade.SellPositionOpen(Symbol(),Inp_Lot,Inp_StopLoss2,Inp_TakeProfit2,Inp_MagicNum2,Inp_EaComment);

//--- Abre ordem se houver um sinal de compra (estratégia baseada em lateralização)
   if(BuySignal_2() && !Trade.IsOpenedByMagic(Inp_MagicNum3))
      Trade.BuyPositionOpen(Symbol(),Inp_Lot,Inp_StopLoss3,Inp_TakeProfit3,Inp_MagicNum3,Inp_EaComment);
//--- Abre ordem se houver um sinal de venda (estratégia baseada em lateralização)
   if(SellSignal_2() && !Trade.IsOpenedByMagic(Inp_MagicNum4))
      Trade.SellPositionOpen(Symbol(),Inp_Lot,Inp_StopLoss4,Inp_TakeProfit4,Inp_MagicNum4,Inp_EaComment);
  }
//+------------------------------------------------------------------+
//| Condições de compra (estratégia seguidora de tendência)          |
//+------------------------------------------------------------------+
bool BuySignal_1()
  {
   return(avr_speed1[0]>Trend_lev1 && cog1[1]<cog1[0] &&(cog1[1]<0 && cog1[0]<0))?true:false;
  }
//+------------------------------------------------------------------+
//| Condições de venda (estratégia seguidora de tendência)           |
//+------------------------------------------------------------------+
bool SellSignal_1()
  {
   return(avr_speed2[0]>Trend_lev2 && cog2[1]>cog2[0] &&(cog2[1]>0 && cog2[0]>0))?true:false;
  }
//+------------------------------------------------------------------+
//| Condições de compra (estratégia baseada em lateralização)        |
//+------------------------------------------------------------------+
bool BuySignal_2()
  {
   return(wpr1[0]<-80 && adx1[0]<Inp_FlatLevel1)?true:false;
  }
//+------------------------------------------------------------------+
//| Condições de venda (estratégia baseada em lateralização)         |
//+------------------------------------------------------------------+
bool SellSignal_2()
  {
   return(wpr2[0]>=-20 && adx2[0]<Inp_FlatLevel2)?true:false;
  }
//+------------------------------------------------------------------+
//| Obtém os valores do indicador atual                              |
//+------------------------------------------------------------------+
bool GetIndValue()
  {
   return(CopyBuffer(InpInd_Handle1,0,0,2,cog1)<=0       ||
          CopyBuffer(InpInd_Handle2,0,0,2,cog2)<=0       ||
          CopyBuffer(InpInd_Handle3,0,0,2,avr_speed1)<=0 ||
          CopyBuffer(InpInd_Handle4,0,0,2,avr_speed2)<=0 ||
          CopyBuffer(InpInd_Handle5,0,0,2,wpr1)<=0       ||
          CopyBuffer(InpInd_Handle6,0,0,2,wpr2)<=0       ||
          CopyBuffer(InpInd_Handle7,0,0,2,adx1)<=0       ||
          CopyBuffer(InpInd_Handle8,0,0,2,adx2)<=0
          )?false:true;
  }
//+------------------------------------------------------------------+

Todos os quatro modos das duas estratégias trabalham de forma independente um do outro, tendo seus próprios conjuntos de parâmetros estabelecidos após o treinamento e não se interceptam de forma alguma. Para o teste, eu decidi usar um intervalo mais amplo — nos últimos três anos. A lista completa das condições de teste é a seguinte:

  • Intervalo: 01.01.2015 — 30.11.2018.
  • Símbolo: EURUSD.
  • Modo de negociação: Sem delay. Estas não são estratégias de negociação de alta frequência, portanto o efeito dos delays seria pequeno.
  • Teste: М1 OHLC. O pré-teste em ticks reais exibe resultados quase similares. 
  • Depósito inicial: 1000 USD.
  • Alavancagem: 1:500.
  • Servidor: MetaQuotes-Demo.
  • Cotações: 5-digit.

Os resultados do teste são os seguintes:


Fig. 13. Resultados do teste da estratégia combinada

Nenhuma nova otimização dos parâmetros foi realizada. Os parâmetros foram configurados com os mesmos valores ótimos definidos durante a otimização separada nos intervalos favoráveis. Considerando que as quatro estratégias independentes trabalharam em condições desfavoráveis comuns, o resultado é positivo.


Resumo

Depois de comparar os resultados dos testes das duas estratégias em tendência de alta, tendência de baixa e condições lateralizadas, nós podemos tirar as seguintes conclusões:

Considerando que eu selecionei sistemas de negociação aleatórios para testá-los e melhorá-los através da otimização separada, e a verificação final foi realizada no intervalo do histórico mais desfavorável, o resultado deste estudo é positivo. Os resultados mostram que o método de otimização separado é bastante eficiente e merece ser usado no desenvolvimento e configuração de sistemas de negociação.


Conclusão

O arquivo anexado contém todos os arquivos listados, localizados nas pastas apropriadas. Para uma operação correta, você deve salvar a pasta MQL5 na pasta raiz do terminal

Programas usados ​​no artigo:

#
 Nome
Tipo
Descrição
1
TrendStrategy.mq5 EA
 EA baseado na estratégia seguidora de tendência.
2
FlatStrategy.mq5 EA  EA baseado na estratégia baseada em lateralização.
3 UniverseStrategy.mql5  EA   EA baseado na estratégia combinada.
4 Trade.mqh Biblioteca  Classe das funções de negociação.
5
average_speed.mq5 Indicador  Indicador da velocidade média do preço usado na estratégia seguidora de tendência.
6 centerofgravityosma.mq5 Indicador  Indicador Centro de gravidade de Ehlers usado na estratégia seguidora de tendência.