Guia para testes e otimização de Expert Advisors no MQL5

10 janeiro 2014, 14:24
Samuel Olowoyo
1
2 503

Introdução

Na maioria das vezes, o desenvolvedor escreve um Expert Advisor certificando-se que o Expert Advisor alcança seu objetivo de boa lucratividade, é sempre um processo bastante trabalhoso. Neste artigo, observaremos alguns dos principais passos necessários para teste e otimização de um Expert Advisor, de modo que seremos capazes de obter um objetivo próximo ao desejado ao escrever-se um Expert Advisor.


1. Identificando e corrigindo erros de código

Começaremos este artigo observando alguns erros de código comuns, normalmente encontrados no processo de escrita de código de Expert Advisor. Na maior parte do tempo, iniciantes lidam com problemas na identificação e correção de erros de código quando escrevem seus códigos ou quando modificam um código escrito por outro desenvolvedor. Nesta seção, veremos quão fácil é utilizar o editor MQL5 para identificar e corrigir alguns destes erros.

Você terminou a escrita do código e ele parece funcionar, porque você tem quase certeza que o código é livre de erros. Ou, era um código que foi escrito por outra pessoa e você fez algumas mudanças e aí quando você aciona o botão Compile (ou pressiona F7) é apresentada uma série de erros para você no código, como mostrado na guia Error da janela Toolbox do MetaEditor.

Erros de compilação em um código de Expert Advisor

Figura 1. Erros de compilação em um código de Expert Advisor

Uau! 38 erros e 1 aviso, seu código pode não possuir tantos erros quantos mostrados aqui, tudo o que queremos ver são os diversos tipos de erros que podem aparecer quando compilamos nosso código e como podemos resolvê-los. Vamos descrever o diagrama acima.

  • A seção marcada como 1 mostra a descrição do erro no código. Isto foi o que nos deu a ideia de como o erro se parece.
  • A seção marcada 2 nos mostra em qual arquivo temos o erro. Isto é muito importante se incluímos arquivos que possuem erros. Com isto, seremos capazes de saber qual arquivo temos que checar para encontrar o erro descrito.
  • A seção marcada como 3 nos mostra em qual linha e coluna (na linha) de nosso código o erro está localizado. Isto nos permite saber qual linha em particular verificar para encontrar o erro descrito.
  • A seção marcada como 4 mostra o sumário dos erros e avisos de compilação.

Vamos agora começar a resolver os erros um por um. Vamos rolar até a primeira linha na aba Error para que possamos iniciar do começo.

Identificando e corrigindo erros de código - 1

Figura 2. Identificando e corrigindo erros de código

O primeiro problema é descrito como: "truncation of constant value" (truncagem de valor de constante) e foi descoberto na linha 16 coluna 20, para localizar a linha exata em nosso código, a partir do menu Edit (editar) do MetaEditor, selecione Go to Line (ir para linha) ou pressione CTRL G em seu teclado.

Figura 3. Localizando o número da linha do código com erro

Figura 3. Localizando o número da linha do código com erro

Uma caixa de diálogo será exibida.

Figura 4. Diálogo de localização do número da linha com erro

Figura 4. Diálogo de localização do número da linha com erro

A faixa de números mostrada na caixa de diálogo é o número total de linhas em nosso código. Neste caso, (1-354) mostra que nosso código contém 354 linhas de código.

Digite o número da linha que você deseja verificar na caixa e clique no botão OK. Você será levado diretamente ao número da linha no código. Você verá o cursor do mouse piscando naquela linha em particular.

Figura 5. Cursor mostrando o número da linha com erro

Figura 5. Cursor mostrando o número da linha com erro

O problema aqui é que declaramos Lot como uma variável integer (int) mas a inicializamos com um valor double (0.1). Para corrigir este erro, alteraremos o int para double, salvaremos o arquivo e então clicaremos no botão COMPILE novamente para ver se ele foi corrigido.

Figura 6. Compilando e salvando o código após a correção ter sido feita

Figura 6. Compilando e salvando o código após a correção ter sido feita

Ao compilarmos novamente, o primeiro problema foi resolvido, mas ainda temos mais para resolver, conforme mostrado abaixo:

Mais erros no código para resolver

Figura 7. Mais erros mostrados no código após a compilação

Vamos agora seguir o mesmo procedimento acima e ir para a linha 31. Entretanto, desta vez iremos clicar no erro com o botão direito na aba Errors e selecionar Go to line

Outra maneira de localizar a linha do erro no código

Figura 8. Outra maneira de localizar a linha do erro no código

Ou simplesmente selecionar o erro e apertar o botão Enter no seu teclado. Imediatamente você será levado para o número da linha de código 31.

Você verá o cursor do mouse piscando e também um pequeno botão redondo vermelho (ícone de erro) naquela linha de código em particular 31.

Localizando a linha do erro de código

Figura 9a. Localizando a linha do erro de código

Entretanto, se for uma mensagem de aviso como a primeira na linha 16 que corrigimos anteriormente, será mostrado um botão triangular amarelo (ícone de aviso).

Sinal de aviso

Figura 9b. Localizando a linha do erro de código

É bem óbvio que não temos nenhum problema na linha 31, mas a descrição do erro diz: "'STP' - unexpected token" (token inesperado).

Devemos então checar a linha de código anterior (que é a linha 30) para ver o que pode estar errado. Em um exame detalhado, está faltando o ponto e vírgula após "double ccminb = -95.0000" na linha 30, sendo este o motivo de termos este erro na linha 31. Vamos corrigir agora este erro digitando o ponto e vírgula após -95.0000 e compilar o código novamente.

Agora os erros da linha 31 desapareceram. A próxima é a linha 100, conforme mostrado abaixo:

Mais erros ainda existem no código

Figura 10. Mais erros ainda existem no código

Ei, Olowsam, temos que compilar após cada correção, por que não percorremos todas as linhas ao mesmo tempo e após termos feito todas as correções compilamos o código apenas uma vez, em vez de compilar após cada correção?

Você se perguntou esta questão?

Você pode estar certo de alguma maneira, mas eu não aconselharia isso. Problemas sempre são resolvidos um após o outro - Passo a passo. Qualquer tentativa de amontoar os problemas e resolvê-los de uma vez pode levar a muitas dores de cabeça. Você logo vai entender por quê... apenas seja paciente comigo.

De volta a nosso problema, temos que verificar a linha 100 para o próximo erro. O erro declara: "'if' - expressions are not allowed on a global scope" (expressões 'if' não são permitidas em um escopo global) e eu tenho certeza que a expressão if na linha 100 não está em um escopo global, mas por que estamos tendo este erro? Por favor, vamos à linha 100.

Figura 11.  Localizando o erro no código

Figura 11. Localizando o erro no código

Não encontramos nenhum problema na linha 100 e, porque acabamos de corrigir a linha 31, temos certeza que o problema agora é entre a linha 32 e a linha 99. Então vamos para alinha 99 (temos um comentário, então não pode ser um erro). Vamos também olhar se as declarações (MqlTick, MqlTradeRequest e MqlTradeResult) foram corretamente declaradas e pontuadas.

Agora vamos ver o código para a expressão if antes das linhas de código dessa declaração e ver se a expressão está correta. Em um estudo bem atento, descobrimos que a expressão if possui uma chave de fechamento, mas nenhuma chave de abertura.

Figura 12. Olhando acima do número da linha com erro para identificar o erro

Figura 12. Olhando acima do número da linha com erro para identificar o erro

Adicione a chave de abertura e compile o código novamente.

//--- Do we have enough bars to work with
   int Mybars=Bars(_Symbol,_Period);
   if(Mybars<60) // if total bars is less than 60 bars
    {
      Alert("We have less than 60 bars, EA will now exit!!");
      return;
     }

Uma vez o código esteja compilado, os erros nas linhas 100, 107, 121, 126, 129, etc. foram completamente eliminados e novos apareceram. Vê por que é bom seguir passo a passo?

Mais erros aparecem no código

Figura 13. Mais erros ainda existem no código

A seguir, iremos para a linha 56 com dois erros: "'cciVal1' - parameter conversion is not allowed"(conversão de parâmetro não permitida) e "'cciVal1' - array is required" (array é necessário)

Em uma observação mais atenta na linha 56, cciVal1 deveria ter sido declarado como array. Pode ser possível que nós não tenhamos declarado como array, mas agora tentamos usar como array? Vamos verificar a seção de declaração para confirmar isto, antes que possamos saber o que fazer a seguir.

//--- Other parameters
int maHandle;               // handle for our Moving Average indicator
int cciHandle1,cciHandle2;  // handle for our CCI indicator
double maVal[];             // Dynamic array to hold the values of Moving Average for each bars
double cciVal1,cciVal2[];   // Dynamic array to hold the values of CCI for each bars
double p1_close,p2_close;   // Variable to store the close value of Bar 1 and Bar 2 respectively

Aqui podemos ver que declaramos cciVal1 de maneira errada como um double em vez de um array dinâmico, porque omitimos os colchetes ([]). Vamos adicionar os colchetes (assim como fizemos para cciVal2[]) e então compilamos o código.

//--- Other parameters
int maHandle;               // handle for our Moving Average indicator
int cciHandle1,cciHandle2;  // handle for our CCI indicator
double maVal[];             // Dynamic array to hold the values of Moving Average for each bars
double cciVal1[],cciVal2[]; // Dynamic array to hold the values of CCI for each bars
double p1_close,p2_close;   // Variable to store the close value of Bar 1 and Bar 2 respectively

Erros no código diminuíram consideravelmente

Figura 14. Erros no código diminuíram consideravelmente

O quê?! Muitos erros desapareceram. Apenas corrigimos o erro encontrado na linha 56 e alguns outros erros foram resolvidos automaticamente. Isto é porque o erro encontrado na linha 56 era responsável por aqueles outros erros. Este é o motivo pelo qual é bom seguir um processo passo-a-passo na resolução de erros no seu código.

Agora vamos para o próximo erro reportado na linha 103: "'GetLastError' - undeclared identifier" Aguarde um minuto, GetLastError deve ser uma função… Vá para a linha 103 para ver qual é o problema.

//--- Get the last price quote using the MQL5 MqlTick Structure
   if(!SymbolInfoTick(_Symbol,latest_price))
     {
      Alert("Error getting the latest price quote - error:",GetLastError,"!!");    // line 103
      return;
     }

O problema realmente está na linha 103. GetLastError é uma função, e cada função precisa de um par de parênteses para parâmetros de entrada. Vamos digitar um par vazio de parênteses e então compilar o código. O par vazio de parênteses indica que a função não necessita de argumentos ou parâmetros.

//--- Get the last price quote using the MQL5 MqlTick Structure
   if(!SymbolInfoTick(_Symbol,latest_price))
     {
      Alert("Error getting the latest price quote - error:",GetLastError(),"!!");  // line 103
      return;
     }

A seguir, iremos para a linha 159: "'=' - l-value required" (valor necessário) e um aviso: "expression is not Boolean" (expressão não é booleana). Vamos à linha 159 e ver o que este erro significa.

      else if(PositionGetInteger(POSITION_TYPE) = POSITION_TYPE_SELL) // line 159
       {
            Sell_opened = true; // It is a Sell

Ele pode ser visto aqui, onde atribuímos o valor de POSITION_TYPE_SELL para PositionGetInteger(POSITION_TYPE) na declaração if e isto não é o que gostaríamos de fazer. Queríamos fazer uma comparação em vez disso. Agora alteraremos a expressão para utilizar o operador de igualdade em vez de usar um operador de atribuição. (ou seja, "==" em vez de "="). Faça a correção e compile o código.

      else if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL) // line 159
       {
            Sell_opened = true; // It is a Sell

Bom! Agora vamos a mais um erro. Vamos à linha 292 para ver por que ela diz "'PositionsTotal' - undeclared identifier" (identificador não declarado). Espere um minuto, você lembra que já vimos um erro assim antes? ‘GetlastError’ linha 103. Possivelmente esquecemos de adicionar o par de parênteses para PositionsTotal também, já que é uma função. Vamos à linha 292 para confirmar.

bool CheckTrade(string otyp)
{
   bool marker = false;
   for (int i=1; i<=PositionsTotal;i++)  // line 292
   {

Como suspeitávamos, é porque esquecemos de adicionar o par de parênteses para a função PositionsTotal. Agora adicionamos o par de parênteses (PositionsTotal()) e compilamos o código. Permita-me dizer que é possível obter este erro se utilizarmos uma variável que não declaramos em nenhuma parte do código.

Figura 15. Todos os erros de compilação foram completamente resolvidos

Figura 15. Todos os erros de compilação foram completamente resolvidos

Maravilha! Agora fomos capazes de corrigir todos os erros de compilação. Agora é hora de depurarmos nosso código e ver se há erros em tempo de execução. Aqui, não entraremos em detalhes sobre como depurar nosso código, uma vez que isso já foi explicado neste artigo.

Conforme a sessão de depuração começa, percebemos outro erro:

Figura 16. Erro em tempo de execução observado durante a depuração do código

Figura 16. Erro em tempo de execução observado durante a depuração do código

Clique no botão OK e você será levado à linha de código que gerou o erro.

Identificando a linha de código que fera o erro em tempo de execução

Figura 17. Identificando a linha de código que fera o erro em tempo de execução

O erro é gerado por este código na linha 172, como você pode ver na figura acima. Já que o erro é um erro "Array out of range" (array fora da faixa), isso significa que o valor que pretendemos obter do array está fora da faixa disponível para os valores do array. Então iremos agora à linha onde copiamos os buffers de indicadores para os arrays para ver qual é o problema.

//--- Copy the new values of our indicators to buffers (arrays) using the handle
   if(CopyBuffer(maHandle,0,0,3,maVal)<0)
     {
      Alert("Error copying MA indicator Buffers - error:",GetLastError(),"!!");
      return;
     }
   if(CopyBuffer(cciHandle1,0,0,3,cciVal1)<0 || CopyBuffer(cciHandle2,0,0,3,cciVal2)<0)
     {
      Alert("Error copying CCI indicator buffer - error:",GetLastError());
      return;
     }

Podemos observar a partir das funções CopyBuffer que copiamos apenas três valores (Bar 0, 1 e 2) o que significa que podemos acessar apenas valores de array de maVal[0], maVal[1], e maVal[2] e também cciVal1[0] , cciVal1[1] e cciVal1[2], etc. Mas, em nosso código na linha 172, estávamos tentando obter o valor do array para cciVal1[3]. Este é o motivo de o erro ter sido gerado. Agora, pare o depurador para que possamos consertar o erro:

Figura 18. Pare o depurador para corrigir o erro no código

Figura 18. Pare o depurador para corrigir o erro no código

Para consertar isto, precisamos aumentar o número de registros a serem copiados dos buffers de indicador para 5 para que sejamos capazes de obter valores de array de cciVal1[0], cciVal1[1], cciVal1[2], cciVal1[3], e cciVal1[4] se necessários.

//--- Copy the new values of our indicators to buffers (arrays) using the handle
   if(CopyBuffer(maHandle,0,0,5,maVal)<0)
     {
      Alert("Error copying MA indicator Buffers - error:",GetLastError(),"!!");
      return;
     }
   if(CopyBuffer(cciHandle1,0,0,5,cciVal1)<0 || CopyBuffer(cciHandle2,0,0,5,cciVal2)<0)
     {
      Alert("Error copying CCI indicator buffer - error:",GetLastError());
      return;
     }

Corrija o código como mostrado e então inicie o depurador novamente. Desta vez, não encontramos mais erros, já que percebemos que nosso Expert Advisor está realizando ações de comércio.

Figura 19. Todos os erros corrigidos, Expert Advisor realiza comércio durante a depuração

Figura 19. Todos os erros corrigidos, Expert Advisor realiza comércio durante a depuração

2. Testando o Expert Advisor

Uma vez que nos certificamos que nosso código está livre de erros, é hora de tesar o Expert Advisor para sermos capazes de obter as melhores configurações que nos darão os melhores resultados. Para realizar o teste, usaremos o Strategy Tester, um programa que é criado no terminal MetaTrader. Para rodar o Strategy Tester, vá ao menu View (visualizar) no terminal e selecione Strategy Tester.

Figura 20. Rodando o Strategy Tester

Figura 20. Rodando o Strategy Tester

2,1. Teste preliminar de nosso Expert Advisor

Neste momento, queremos testar o Expert usando os símbolos disponíveis na Janela de Mercado. Com este resultado, seremos capazes de descobrir para quais pares de moeda podemos melhor otimizar nosso Expert. Certifique-se que nossa Janela de Mercado contenha a maioria das moedas para as quais você está direcionando o Expert.

Selecione o Expert na aba Settings (configurações) do Strategy Tester, selecione o período/quadro de tempo que você tem em mente (e é claro que você pode testá-lo em diferentes quadros de tempo) e então selecione 'All Symbols Selected in MARKET Watch' (todos os símbolos selecionados em MARKET Watch) no campo de otimização. Diretamente a seguir está o parâmetro de resultados de otimização, selecione Balance + max Profit Factor.

Figura 34. Teste preliminar do Expert Advisor com todos os símbolos na janela Market Watch

Figura 21. Teste preliminar do Expert Advisor com todos os símbolos na janela Market Watch

1. Selecione o modo de geração de tick - (cada Tick)

2. Selecione o tipo de otimização - (todos os símbolos selecionados no MARKET Watch)

3. Selecione o tipo de resultado esperado da otimização

Você pode obter os detalhes sobre os diversos tipos de otimização a partir da documentação de ajuda do terminal. Não faremos o teste de encaminhamento, então deixe o Forward como No.

Para este teste, os parâmetros/valores principais (destacados em verde) na aba Inputs (entradas) serão usados.

Figura 35. Parâmetros de entrada de teste preliminares

Figura 22. Parâmetros de entrada de teste preliminares

Uma vez que você tenha terminado, mude para a aba Settings (configurações) e clique no botão Start (iniciar). Na conclusão do teste, você verá uma mensagem na aba Journal (diário) similar à seguinte:

Figura 36. Teste preliminar concluído

Figura 23. Teste preliminar concluído

Uma vez que o teste esteja concluído, vá para a aba Optimization Results (resultados da otimização) para ver os resultados.

Figura 37. Resultados da otimização do teste preliminar

Figura 24. Resultados da otimização do teste preliminar

Nosso interesse está no símbolo que nos dá o resultado mais alto com base em nossa configuração – (Balance + max Profit Factor). Para obter isto, vamos ordenar o resultado clicando no título Result (resultado), de maneira que o símbolo com o resultado mais alto esteja listado no topo.

Figura 38. Análise do resultado da otimização preliminar

Figura 25. Análise do resultado da otimização preliminar

A partir do resultado, podemos ver que nosso Expert Advisor pode ser lucrativo para os seguintes símbolos (EURUSD, EURJPY, AUDUSD) no quadro de tempo que selecionamos. Você pode realizar este teste posteriormente para outro quadro de tempo, digamos, 30 minutos e ver o que você possui. Isto deve ser realizado com uma tarefa e por favor compartilhe o resultado para que todos possamos aprender também.

A partir do resultado de nosso teste preliminar, vamos decidir agora para qual(is) símbolo(s) e quadro(s) de tempo vamos otimizar nosso Expert Advisor.

Neste exemplo, otimizaremos nosso Expert Advisor para EURUSD e quadro de tempo de 1 hora. Quais são as coisas que motivaram a escolha que fizemos:

  • Fator de lucro:

O fator de lucro é a razão do lucro total com a perda total para este teste. Quanto maior o fator de lucro, mais rentável sua estratégia de negócio será.

  • % de rebaixamento:

Isto refere-se ao rebaixamento relativo da igualdade ou da maior perda (em percentual) a partir do valor máximo de igualdade. Quanto menor o rebaixamento (em percentual), melhor a estratégia.

  • Fator de recuperação:

Está é a relação do lucro para o rebaixamento máximo. Ela reflete o risco da estratégia de comércio.

Tendo decidido sobre o símbolo e quadro de tempo a ser usado, é agora hora de otimizar nosso Expert Advisor.

2,2. Otimizando o Expert Advisor

A otimização é simplesmente um processo de ajuste fino do desempenho de nosso EA, por meio de testes com diversos fatores (parâmetros) que determinam a eficiência ou lucratividade de nossa estratégia codificada no EA. É um procedimento similar ao teste, mas em vez de testar o EA apenas uma vez, ele será testado muitas vezes, dependendo dos parâmetros selecionados na aba Input (entrada).

Para começar, vamos até a aba Settings e habilitaremos a otimização, e então selecionaremos o tipo de resultado que queremos de nossa otimização.

Figura 39. Configurações de otimização para Expert Advisor

Figura 26. Configurações de otimização para Expert Advisor

1. Selecione o modo de geração de tick - (cada Tick)

2. Selecione o tipo de otimização - (Algoritmo de base genética rápido)

3. Selecione o tipo de Resultado esperado da otimização (selecionamos aqui Saldo+ Fator máximo de lucro)

Você pode obter os detalhes sobre os diversos tipos de otimização a partir da documentação de ajuda do terminal. Não encaminharemos o teste, então deixe Forward como No (não). Definidas as propriedades de otimização, vamos definir os parâmetros a serem usados para a otimização na aba Inputs (entradas).

Figura 40. Parâmetros de entrada de otimização

Figura 27. Parâmetros de entrada de otimização

Uma vez que estamos otimizando, apenas nos concentraremos nas áreas destacadas em amarelo. Antes de tudo, qualquer parâmetro que não desejamos usar na otimização devem ser desmarcados. Em outras palavras, apenas verificaremos os parâmetros que desejamos usar na otimização do EA. Aqui, eu marquei cinco parâmetros, mas você pode decidir verificar apenas um ou dois, dependendo dos parâmetros nos quais a eficácia de nossa estratégia está baseada. Por exemplo, você pode marcar apenas a Média Móvel e períodos CCI, de modo que o resultado da otimização deixará você saber o melhor valor para cada um dos indicadores que dão a seu EA o melhor desempenho. Esta é a essência principal da otimização.

Além disso, o número de parâmetros marcados determinará o número total de testes pelos quais seu EA passará. Você logo verá do que eu estou falando.

Configurando os valores

Início:

Este é o valor de início a ser usado para a variável selecionada para otimização. Vamos usar a variável Stop Loss para explicar como definir os valores. Para o Stop Loss, pedimos ao testador para iniciar com um valor de 30. Este será o valor mínimo que será usado para Stop Loss durante a otimização.

Passo:

Este é o valor incremental para Stop Loss. Se definirmos um incremento de 2; isso significa que, se no primeiro teste, usar 30 para Stop Loss, também usará 32, 36, 34 etc. no segundo... Isso não significa que usará 30, e então, seguido por 32, 34 etc. Não, ele seleciona os valores aleatoriamente, mas sempre será múltiplos de (2) entre o valor de Início e o valor de Parada.

Parada:

Este é o valor máximo ou mais alto que será usado para otimização. Aqui especificamos 38. Isto significa que os valores que serão usados para o teste estarão entre 30 e 38, mas serão valores múltiplos de 2. Ele não usará 40 ou qualquer valor maior.

O número total de testes que serão realizados depende das configurações destas três seções. Em nosso exemplo, o testador combinará um total de 5 possibilidades individuais para Stop Loss, como mostrado na coluna Steps (passos) na aba Inputs (entradas), ele combinará um total de 8 possibilidades para Take Profit, etc. Quando você considera todas as outras variáveis, ele estará realizando centenas ou milhares de possibilidades (testes/aprovações). Se você não deseja esperar horas para otimizar um único EA, certifique-se de não incluir ou marcar muitas variáveis; talvez apenas duas ou três das quais o desempenho de seu EA realmente dependa (mais especialmente, os períodos do indicador, se você utilizá-los em seu próprio código). Além disso, você deve certificar-se que seu valor de passo não resultará na criação de muitas possibilidades (testes). Por exemplo, se usarmos 1 como o valor de parada, então aumentamos o número de tentativas para o Stop Loss para 10. Bem, como dito anteriormente, o tempo total necessário para completar uma sessão de otimização depende do número total de agentes disponíveis que você tem configurado em seu sistema.

Eu acredito que a explicação foi suficiente.

Uma vez que terminamos de configurar as entradas, agora voltamos à aba Settings e clicamos no botão Start (iniciar).

Uma vez que a otimização esteja concluída, podemos ver os detalhes na aba Journal (diário).

Figura 43. Otimização concluída, conforme mostrada na aba Journal

Figura 28. Otimização concluída, conforme mostrada na aba Journal

Para visualizar os resultados à medida que cada teste é concluído ou passado, vamos para a guia Optimization Results . E é sempre bom ordenar a saída pelos resultados, para que possamos facilmente identificar as configurações que nos dão o melhor resultado, com base em nossa configuração de otimização. Clicar no cabeçalho Result (resultado) dentro da aba optimization Results (resultados da otimização) ordenará os resultados em ordem ascendente ou descendente.

Figura 44. Relatório de otimização

Figura 29. Relatório de otimização

Troque para a aba Optimization Graph (gráfico de otimização) para ver como o gráfico se parece.

Figura 45. Gráfico de otimização

Figura 30. Gráfico de otimização

Não entende o que vê? Não se preocupe; os pontos que você vê é um gráfico do número de testes que seu EA passou contra o resultado da otimização, com base no tipo de resultado de otimização que você selecionou. Em nosso caso selecionamos Saldo + Fator de lucro máx.

2,3. Interpretando o resultado

Para interpretar o relatório de otimização com sucesso, vá para a aba Resultados da Otimização. Você descobrirá que não pode ver alguns campos como Profit factor (fator de lucro), Expected Payoff (rendimento esperado), Drawdown % (% de rebaixamento), etc. Para vê-los, clique com o botão direito em qualquer lugar da aba Optimization Results (resultados da otimização) e selecione as informações adicionais que você deseja ver, conforme mostrado abaixo:

Figura 46. Selecionando Drawdown % no resultado da otimização

Figura 31. Selecionando Drawdown % no resultado da otimização

Figura 47. Selecionando Profit Factor no resultado da otimização

Figura 32. Selecionando Profit Factor no resultado da otimização

Tendo adicionado estes registros adicionais, nós agora analisaremos o resultado da otimização para decidir as melhores configurações para nosso Expert Advisor.

Análise do relatório de otimização

Figura 33. Analisando o resultado da otimização

A partir da figura acima, as seções destacadas rotuladas A e B indicam os melhores resultados para nosso Expert Advisor. Agora a escolha que você faz é completamente pessoal, tudo depende do que você está procurando. Entretanto, aqui estamos interessados não apenas nas configurações que geram o lucro mais alto, mas também termos uma % de rebaixamento mais baixa.

Como você pode ver, a seção A (destacada em amarelo) possui o melhor resultado (Balance + max Profit Factor) de 22381,71 com um lucro de 924,10, enquanto a seção B (destacada em verde) possui o segundo melhor resultado de 22159,25 mas com um lucro maior de 936,55. A seção A possuiu um Drawdown% mais baixo de 1,78 enquanto B possui um rebaixamento mais alto, de 1,95.

O Testador de estratégia salva os resultados da otimização na pasta "\Tester\cache". Em seu caso, todos os dados de otimização serão salvos no arquivo cci_ma_ea.EURUSD.H1.0.xml,

O nome do arquivo possui a seguinte forma: ExpertName.SYMBOL.PERIOD.GenerationMode.xml, onde:

  • ExpertName - Nome do Expert Advisor;
  • Symbol - Símbolo;
  • Period - Quadro de tempo (M1,H1,...)
  • GenerationMode - Modo de geração do tick (0-cada tick, 1 - OHLC de um minuto, 2 - apenas preços abertos).

Os arquivos XML podem ser abertos pelo MS Excel.

2,4. Escolhendo o melhor resultado

Para finalmente obter o melhor resultado, precisamos olhar o gráfico de otimização novamente. Volte para o gráfico de otimização. Clique com o botão direito em qualquer lugar do gráfico e selecione 1D Graph (gráfico 1d).

Selecione o gráfico 1-D do gráfico de otimização.

Figura 34. Selecione o gráfico unidimensional (1-D) para a análise do resultado

Com isto, podemos facilmente ver os valores de cada um dos parâmetros de entrada que dão o melhor resultado. Você pode agora começar a escolher cada parâmetro para ser capaz de ver o melhor valor. Clique com o botão direito no gráfico e selecione X-Axis (eixo x) e então selecione o parâmetro que você deseja verificar. Ele se parecerá com a figura abaixo (para Stop Loss)

Figura 50. Obtendo o melhor valor StopLoss do resultado da otimização

Figura 35. Obtendo o melhor valor StopLoss do resultado da otimização

Na verdade, a partir do resultado da otimização, fica claro que o melhor StopLoss é 34, o melhor TakeProfit é 78 e o melhor CCI_Period1 é 62. Para obter os melhores valores para MAPeriod e CCI_Period2, selecione cada um deles conforme acima.

Figura 51. Obtendo o melhor valor de período de média móvel a partir do resultado da otimização

Figura 36. Obtendo o melhor valor de período de média móvel a partir do resultado da otimização

Este gráfico mostra um valor de 26 como o MA_Period com o melhor resultado.

Figura 52. Obtendo o melhor valor CCI_Period1 do resultado da otimização

Figura 37. Obtendo o melhor valor CCI_Period1 do resultado da otimização

Este gráfico mostra um valor de 62 como o CCI_Period1 com o melhor resultado.

Figura 53. Obtendo o melhor valor CCI_Period2 do resultado da otimização

Figura 38. Obtendo o melhor valor CCI_Period2 do resultado da otimização

Este gráfico mostra valores de 28 ou 30 como o CCI_Period2 com os melhores resultados.

Tendo obtido os melhores valores para cada parâmetro, agora é hora do teste final de nosso Expert Advisor.

2,5. O teste final

O teste final envolve juntar os melhores parâmetros para o teste do Expert Advisor. Neste caso, usaremos os melhores valores que descobrimos na seção INPUT (entrada) do Strategy Tester, conforme mostrado abaixo.

Valores de entrada para o teste final

Figura 39. Os parâmetros finais de entrada de teste

Na aba SETTINGS do Strategy Tester, desabilitaremos a otimização, conforme mostrado abaixo.

As configurações para o teste final

Figura 40. As configurações do teste final

Agora clicaremos no botão START para iniciarmos o teste. Uma vez que o teste tenha sido concluído, temos os resultados na aba RESULTS (resultados), conforme mostrado abaixo.

Figura 56. Os resultados do teste final

Figura 41. Os resultados do teste final

Da mesma maneira, temos o gráfico para o teste na aba GRAPH (gráfico)

Figura 57. O resultado do gráfico do teste final

Figura 42. O resultado do gráfico do teste final

Conclusão

Neste artigo, discutimos as maneiras de identificar e corrigir erros de código, e também discutimos como testar e otimizar um Expert Advisor para o melhor símbolo a partir do Market Watch.

Com este artigo, acredito que a verificação do código por erros usando o editor e a otimização e teste de Expert Advisors usando o Strategy Tester facilitam a escrita do melhor e mais lucrativo Expert Advisor possível.

Traduzido do Inglês pela MetaQuotes Software Corp.
Artigo original: https://www.mql5.com/en/articles/156

Arquivos anexados |
cci_ma_ea.mq5 (14.23 KB)
Últimos Comentários | Ir para discussão (1)
Joao Carlos Marcuschi
Joao Carlos Marcuschi | 22 abr 2015 em 21:20
Excelente artigo Samuel. Muito me ajudou a esclarecer dúvidas sobre otimizar meu AE. grato pela disposição em ajudar e esclarecer.
Sistemas de negociação adaptativos e seu uso no terminal do cliente do MetaTrader 5 Sistemas de negociação adaptativos e seu uso no terminal do cliente do MetaTrader 5

Este artigo sugere uma variável de um sistema adaptativo que consiste em várias estratégias, cada uma realizando suas operações de negociação "virtuais". Negociações reais são realizadas de acordo com os sinais da estratégia mais rentável no momento. Obrigado por utilizar a abordagem orientada a objeto, classes para trabalhar com dados e classes de negociação da biblioteca padrão, a arquitetura do sistema pareceu ser simples e escalável; agora você pode facilmente criar e analisar os sistemas adaptativos que incluem centenas de estratégias de negociação.

OOP no MQL5 por exemplo: Processando os avisos e os códigos de erro OOP no MQL5 por exemplo: Processando os avisos e os códigos de erro

O artigo descreve um exemplo de criação de classe para trabalho com os códigos de retorno do servidor de negócio e todos os erros que ocorrem durante a execução do programa MQL. Leia o artigo e você aprenderá como trabalhar com classes e objetos no MQL5. Ao mesmo tempo, esta é uma ferramenta conveniente para manipular erros; e você ainda pode mudar esta ferramenta de acordo com suas necessidades específicas.

Ordens, posições e negócios no MetaTrader 5 Ordens, posições e negócios no MetaTrader 5

A criação robusta de um robô de negócio não pode ser feita sem um entendimento dos mecanismos do sistema de negócio do MetaTrader 5. O terminal do cliente recebe as informações sobre as posições, ordens e negócios a partir do servidor de negócio. Para manipular estes dados adequadamente utilizando o MQL5, é necessário ter um bom entendimento da interação entre o programa MQL5 e o terminal do cliente.

Eventos de negociação no MetaTrader 5 Eventos de negociação no MetaTrader 5

Um monitoramento do estado atual de uma conta de negócio implica no controle das posições abertas e ordens. Antes de um sinal de negócio se tornar um negócio, ele deve ser enviado a partir de um terminal de cliente como uma solicitação para o servidor de negócio, onde será posicionado na fila de ordem aguardando ser processado. Aceitação de uma solicitação por um servidor de negócio, a excluindo quando expirar ou realizando um negócio em sua base - todas essas ações são seguidas por eventos de negócio; e o servidor de negócio informa o terminal sobre eles.