English Русский 中文 Español Deutsch 日本語
Proteção contra falsos positivos do robô de negociação

Proteção contra falsos positivos do robô de negociação

MetaTrader 4Sistemas de negociação | 19 setembro 2016, 10:47
1 465 2
Aleksandr Masterskikh
Aleksandr Masterskikh

Introdução

Neste artigo vamos nos concentrar na estabilidade do robô de negociação através da eliminação de possíveis execuções repetidas (pulo) de diferentes maneiras: tanto separadamente como conjuntamente nos algoritmos de entrada e saída.


Natureza do problema

Os falsos positivos são especialmente evidentes durante as oscilações e colapsos repentinos do mercado, quando a amplitude da vela é tão grande que o algoritmo do robô não previstas medidas especiais contra o "pulo". Isso faz com que na vela atual aconteçam aberturas e fechamentos consecutivos de posições.

As conseqüências financeiras podem ser varias e também depender de certos algoritmos que levam em conta parâmetros de negociação estabelecidos pelo desenvolvedor do robô. Mas, em todo caso, as perdas do trader, durante os pulos, são diretamente proporcionais ao número de execuções involuntárias.

Neste artigo, não vou considerar questões sobre a análise de instrumentos financeiros (de natureza técnica e fundamental) que podem afetar a estabilidade do EA e ajudá-lo a evitar a pulos. Aqui falamos sobre medidas sobre programação informática que não dependem dos métodos de análise de mercados financeiros.

Então, passamos a lidar com o problema. Como modelo, eu usarei o EA "MACD Sample" do conjunto padrão disponível no terminal de cliente Metatrader 4.

A seguir é apresentado um problema de pulo ou alteração brusca de preço para o par EURUSD no dia 2 de outubro deste ano (timeframe M15, EA "MACD Sample" com configurações padrão):

Na imagem você pode ver que existem 8 execuções consecutivas (entradas Buy) em uma vela. Aqui, em termos de lógica de mercado normal, apenas a primeira entrada é correta, as 7 restantes são pulos.

Razões pelas quais acontecem esses falsos positivos:

  • um valor pequeno de TakeProfit nas configurações padrão (e este algoritmo de saída) faz com que cada posição seja fechada rapidamente;
  • o algoritmo de entrada do EA "MACD Sample", que opera imediatamente após a posição anterior, permitindo a reentrada, independentemente do número de entradas na vela.

Concordamos que deliberadamente não vamos tomar em conta questões sobre filtragens de flutuações do mercado (porque cada trader tem seu algoritmo de entrada e saída), por isso, para resolver o problema, de modo universal, consideraremos os seguintes fatores, eles são de natureza mais geral:

  • tempo (duração da vela)
  • número de execuções (contador)
  • amplitude de movimento (proporção da vela).


Decisão no algoritmo de entrada

A opção mais simples, mas, ao mesmo tempo, mais confiável para fixar o ponto de entrada é o fator de tempo, a seguir, as causas:

  • A contagem do número de execuções implica a criação de um ciclo no programa, isso não apenas complica o algoritmo, más também reduz o desempenho do EA.
  • A amplitude e controle dos níveis de preços, associados a ela, podem ser repetidos devido ao retorno de preços, durante reversões dentro da vela, isso faz com que o critério de nível de preço seja ambíguo.
  • O tempo é irreversível, se move em apenas uma direção (ascensão), e, portanto, é o critério mais preciso e inequívoco para resolver tarefas, garantir ema única execução e eliminar o pulo.

Assim, o tempo de execução do algoritmo de entrada é o fator principal, ou melhor, o tempo de execução da ordem para abrir a posição (OrderSend), já que estas duas coisas podem não corresponder, se, no algoritmo, houver algum atraso na apertura da ordem.

Então, você pode memorizar o tempo (tempo atual) de abertura da posição. Mas como usar este parâmetro no algoritmo para evitar entradas subseqüentes nessa vela? Pois, não conhecemos com antecedência esse tempo (nem seu valor absoluto), portanto, não podemos "introduzi-lo" antecipadamente no algoritmo de entrada. O algoritmo deve levar em conta (incluir) uma condição geral, que permita a primeira entrada na vela, mas impedirá todas as entradas subseqüentes na vela, sem contar as execuções (a versão com contador foi rejeitada anteriormente).

A solução é bastante simples. Em primeiro lugar, vou escrever o código com alguns comentários, a seguir, vou explicar mais detalhadamente. Você precisa inserir o código adicional abaixo (marcado com fundo amarelo) no algoritmo do EA (ver o arquivo MACD_Sample_plus1.mq4):

//+------------------------------------------------------------------+
//|                                                  MACD Sample.mq4 |
//|                   Copyright 2005-2014, MetaQuotes Software Corp. |
//|                                              https://www.mql4.com |
//+------------------------------------------------------------------+
#property copyright   "2005-2014, MetaQuotes Software Corp."
#property link        "https://www.mql4.com"

input double TakeProfit    =50;
input double Lots          =0.1;
input double TrailingStop  =30;
input double MACDOpenLevel =3;
input double MACDCloseLevel=2;
input int    MATrendPeriod =26;
//--- inserimos uma nova variável (dimensão em segundos para uma barra desse timeframe, para M15 igual a 60 c x 15 = 900 c)
datetime Time_open=900;
//--- inserimos a nova variável (tempo de abertura da barra onde será a primeira entrada)
datetime Time_bar = 0;

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnTick(void)
  {
   double MacdCurrent,MacdPrevious;
   double SignalCurrent,SignalPrevious;
   double MaCurrent,MaPrevious;
   int    cnt,ticket,total;
//---
// initial data checks
// it is important to make sure that the expert works with a normal
// chart and the user did not make any mistakes setting external 
// variables (Lots, StopLoss, TakeProfit, 
// TrailingStop) in our case, we check TakeProfit
// on a chart of less than 100 bars
//---
   if(Bars<100)
     {
      Print("bars less than 100");
      return;
     }
   if(TakeProfit<10)
     {
      Print("TakeProfit less than 10");
      return;
     }
//--- to simplify the coding and speed up access data are put into internal variables
   MacdCurrent=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,0);
   MacdPrevious=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,1);
   SignalCurrent=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,0);
   SignalPrevious=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,1);
   MaCurrent=iMA(NULL,0,MATrendPeriod,0,MODE_EMA,PRICE_CLOSE,0);
   MaPrevious=iMA(NULL,0,MATrendPeriod,0,MODE_EMA,PRICE_CLOSE,1);

   total=OrdersTotal();
   if(total<1)
     {
      //--- no opened orders identified
      if(AccountFreeMargin()<(1000*Lots))
        {
         Print("We have no money. Free Margin = ",AccountFreeMargin());
         return;
        }
      //--- check for long position (BUY) possibility
      
      //--- inserimos a nova cadeia de caracteres (remove a proibição de re-entrada, se você abriu um novo bar)
      if( (TimeCurrent() - Time_bar) > 900 ) Time_open = 900; 
      
      if(MacdCurrent<0 && MacdCurrent>SignalCurrent && MacdPrevious<SignalPrevious && 
         MathAbs(MacdCurrent)>(MACDOpenLevel*Point) && MaCurrent>MaPrevious && 
         (TimeCurrent()-Time[0])<Time_open) //inserimos uma nova cadeia de caracteres no algoritmo de entrada (é executado apenas 1 vez, pois outra condição nessa vela não é viável)
        {
         ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,3,0,Ask+TakeProfit*Point,"macd sample",16384,0,Green);
         if(ticket>0)
           {
            if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
             {
              Print("BUY order opened : ",OrderOpenPrice());
              Time_open = TimeCurrent()-Time[0]; //inserimos uma nova cadeia de caracteres (é preciso memorizamos o intervalo a partir do tempo de abertura da barra, onde foi feita a entrada, até o momento da entrada)
              Time_bar = Time[0]; //inserimos uma nova cadeia de caracteres (memorizamos o tempo de abertura dessa barra onde foi feita a primeira entrada)
             }
           }
         else
            Print("Error opening BUY order : ",GetLastError());
         return;
        }

Detalhes:

Em vez do tempo absoluto (de entrada), usamos o tempo relativo, ele é o intervalo de tempo desde o momento da abertura da vela atual até o momento da entrada. A seguir, comparamos este valor com valor de tempo -suficientemente grande - especificado com antecedência (comprimento da vela inteira), isso irá permitir que você execute a primeira entrada. No momento de abertura da posição, mudamos (reduzimos) o valor da variável Time_open, escrevendo nela o valor do intervalo de tempo desde o início da vela até o momento de abertura real. Como, em qualquer momento posterior, o valor (TimeCurrent() - Time[0]) < Time_open será superior à dimensão registrada por nós no momento da entrada, e a condição (TimeCurrent() - Time[0]) < Time_open se tornará inaplicável, é assim como é conseguido o bloqueio das seguintes entradas na vela atual.

Desse modo nós resolvemos o problema de falsos positivos, sem usar um contador de número de entradas e análise de amplitude de movimentos de preços.

A seguir, o resultado desse simples refinamento do algoritmo fonte de entrada do EA ("MACD Sample_plus1"):

Podemos ver que, na vela, existe apenas uma entrada, sem falsos positivos, ademais, o pulo foi eliminado completamente. Além disso, as configurações padrão foram salvas, para deixar claro que o problema foi resolvido sem alterar as configurações do EA.

Agora que o problema, na entrada, está resolvido, refinamos o algoritmo de saída, para excluir um possível pulo ao fechar rapidamente a posição, o que, neste caso em particular, aumenta o lucro (bom impulso com uma saída rápida, prematura).


Solução no algoritmo de saída

Não vou abordar questões da análise da dinâmica dos instrumentos financeiros em relação ao aumento de lucros, porque o problema prioritário é a eliminação do possível pulo do robô, também me vou limitar tendo em conta a fixação do parâmero selecionado sem consideração desta dinâmica.

Antes usávamos o factor tempo, e vamos usá-lo novamente. Definimos estritamente o momento de fechamento da posição no momento da abertura da próxima (após a entrada) vela. Então vamos refletir este momento no algoritmo de saída assim:

if(!OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))
         continue;
      if(OrderType()<=OP_SELL &&   // check for opened position 
         OrderSymbol()==Symbol())  // check for symbol
        {
         //--- long position is opened
         if(OrderType()==OP_BUY)
           {
            //--- should it be closed?
            if(/* MacdCurrent>0 && MacdCurrent<SignalCurrent && MacdPrevious>SignalPrevious && // removemos o código de gatilho para MACD, para não perturbar os novos critérios (ver seguinte)
               MacdCurrent>(MACDCloseLevel*Point) &&
             */
               Bid > OrderOpenPrice() &&  // inserimos uma nova cadeia de caracteres (o preço na zona positiva depende do nível de entrada)
               TimeCurrent() == Time[0] ) // inserimos uma nova cadeia de caracteres (simples edição do algoritmo de saída: a saída é estritamente no momento da abertura da vela atual)
              {
               //--- close order and exit
               if(!OrderClose(OrderTicket(),OrderLots(),Bid,3,Violet))
                  Print("OrderClose error ",GetLastError());

               return;
              }

Essa pequena modificação permite "trabalhar" para o algoritmo de entrada (a posição é aberta, sem condições para fechar), a posição dura até TimeCurrent() == Time[0] tempo [0] e é fechada simultaneamente no início de uma nova após o impulso de velas. Como resultado, além da proteção contra o pulo, tiramos lucro (ver imagem, "MACD Sample_plus2"):

Além disso, foi necessário remover, do algoritmo de saída, o gatilho no MACD, caso contrário a condição de saída não poderia ser realizada.

Assim, vemos que podemos resolver o problema de pulo separadamente no algoritmo de entrada, separadamente no algoritmo de saída. Agora vamos falar sobre a resolução de problemas devidos à coordenação entre estes algoritmos para abrir e fechar posições.


Coordenação dos algoritmos de entrada e saída

A coordenação consiste em uma simulação preliminar de todo o processo: abertura de posição — seguimento — fechamento de posição. Isto é refletido, nomeadamente, na escolha do deslocamento nos indicadores e funções usadas nos algoritmos de entrada e saída.

Por exemplo, se você usar o algoritmo TimeCurrent() = Time[0], isto é, se o ponto de saída for definido estritamente pelo início da vela atual, o algoritmo de entrada deverá funcionar nas barras anteriores fechadas, para que a condição de saída possa ocorrer. Ou seja, para fechar a posição na condição TimeCurrent() = Time[0] sem condições adicionais, é necessário que todo o algoritmo de comparação (na entrada) seja realizado (concluído) na barra anterior. Para isso, nas configurações dos indicadores envolvidos na comparação de valores, deve existir uma deslocação igual a 1. Neste caso, a comparação de valores seria correta, e o início da vela atual será a conclusão lógica do algoritmo de saída.

Assim, a coordenação dos algoritmos de entrada e saída também está relacionada com o fator tempo.


Conclusão

O problema das falsos execuções dos EA é eficientemente resolvido usando o fator tempo no algoritmo de saída. Além disso, é possível fornecer - à durabilidade do trabalho do EA - a fixação do ponto de entrada (por exemplo por tempo), bem como a coordenação dos algoritmos de entrada e saída usando uma simulação prévia não apenas da logica base de gatilho, mas também do cálculo de deslocamento (barra one será calculado o indicador ou função).

A seguir encontram-se os códigos dos EA: na sua forma original (MACD_Sample.mq4), com modificação da entrada (MACD_Sample_plus1.mq4), com modificação da saída (MACD_Sample_plus2.mq4). Além disso, estão modificados apenas os canais Buy, enquanto os canais Sell foram deixados intencionalmente inalterados, para que fosse possível comparar os algoritmos fonte com os modificados.

E, claro, todos estes EA são demonstrações e não estão destinados à negociação em mercados financeiros.

Traduzido do russo pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/ru/articles/2110

Arquivos anexados |
MACD_Sample.mq4 (6.1 KB)
Últimos Comentários | Ir para discussão (2)
ermis
ermis | 5 mar 2019 em 03:02
Bn, teria essa explicação ou um modo de fazer essa mesma coisa no MT5?
জচেলিনো
জচেলিনো | 5 mar 2019 em 16:21
ermis:
Bn, teria essa explicação ou um modo de fazer essa mesma coisa no MT5?

O código esta bem comentado e eh simples de fazer. Se você programa em MQL5 basta fazer a conversão. Se não programa, tente ver algo no Codebase, contrate um Freelance ou aguarde novo artigo.

[ ]'s

Criação de estratégias de negociação manuais usando lógica fuzzy Criação de estratégias de negociação manuais usando lógica fuzzy
No artigo é considerada a possibilidade de melhorar as estratégias de negociação manuais usando a teoria dos conjuntos difusos (fuzzy). Como exemplo, é descrito passo a passo o motor de busca de estratégias e a seleção de seus parâmetros, o uso de lógica fuzzy para diluir os critérios demasiado formais de entrada no mercado. Assim, Depois da modificação da estratégia, nós obtemos condições flexíveis de abertura de posição que respondem melhor à situação de mercado.
Interfaces Gráficas V: O Controle Lista (Capítulo 2) Interfaces Gráficas V: O Controle Lista (Capítulo 2)
No capítulo anterior, nós escrevemos as classes para criar a barra de rolagem vertical e horizontal. Neste capítulo, nós vamos implementá-las. Nós vamos escrever uma classe para criar o controle lista, sendo que a barra de rolagem vertical será sua parte integrante.
Interfaces Gráficas V: O Controle Combobox (Capítulo 3) Interfaces Gráficas V: O Controle Combobox (Capítulo 3)
Nos dois primeiros capítulos da quinta parte da série, nós desenvolvemos as classes para criar uma barra de rolagem e uma lista. Neste capítulo, nós falaremos sobre a criação de uma classe para o controle combobox. Este é também um controle composto que contém, entre outros, os elementos considerados nos capítulos anteriores desta quinta parte.
Módulo de sinais de negociação utilizando o sistema Bill Williams Módulo de sinais de negociação utilizando o sistema Bill Williams
O artigo descreve as regras do sistema de negociação Bill Williams, o procedimento da aplicação de um módulo MQL5 desenvolvido com o objetivo de procurar e marcar padrões deste sistema no gráfico, as negociações automatizadas de acordo com os padrões encontrados e por fim, apresenta os resultados dos testes em vários instrumentos de negociação.