English Русский 中文 Español Deutsch 日本語
Escolha automatizada de corretora para um funcionamento eficiente do Expert Advisors

Escolha automatizada de corretora para um funcionamento eficiente do Expert Advisors

MetaTrader 4Negociação | 22 fevereiro 2016, 09:51
972 0
Shashev Sergei
Shashev Sergei

Introdução

Muitas vezes nos deparamos com situações em que um Expert Advisor funciona com sucesso com uma corretora e não é rentável ou até mesmo gera prejuízos com outra corretora. Os motivos podem ser diferentes. Diferentes corretoras têm diferentes configurações:

  • Cotações. Eles diferem ligeiramente por causa de dois fatores: diferentes dados e filtração que suavizam as cotações. Para alguns Expert Advisors isto pode ser relevante. Algumas situações podem ocorrer quando um EA negocia frequentemente com uma corretora e raramente com outra.
  • Deslize. Pode ser bem diferente em diferentes corretoras. Isso também pode levar a piores características de um EA por causa de baixo lucro esperado.
  • Requotes. Em algumas corretoras são mais freqüentemente do que em outras. Neste caso, um EA perderá pontos de entrada de sucesso por causa do grande número de requotes.
Assim, a operação de alguns EAs depende muito da corretora com que eles trabalham. Se não houvesse escolha, poderíamos aumentar cotações, deslize e requotes. Mas agora temos escolha e ela está ficando cada vez mais ampla. Assim, podemos comparar diferentes corretoras e ver suas características técnicas, e utilizar estas informações para escolhermos as melhores corretoras para o nosso EA.

Estatística

Claro que podemos iniciar vários terminais de diferentes corretoras, usá-los um mês ou dois e, em seguida, escolher o que fornecer maiores lucros. Mas este teste é de baixa informação. Seria melhor obter mais informações: deslizamento médio por trade, número de requotes que ocorrem na abertura de cada trade, o tempo de abertura e assim por diante. A fim de não ter de analisar logs, o projeto Estatística foi desenvolvido. Baseia-se no seguinte conjunto de regras:

  1. Um EA analisa o mercado, realiza transações, recebe todos os dados necessários sobre o trade e passa isso para um módulo comum.
  2. Este módulo contém todas as informações sobre as ofertas atuais e fechadas. Também contabiliza a estatística sobre todas as características técnicas das corretoras.
  3. Deve ser maximamente confortável para a operação com grandes quantidades de dados, para que pudéssemos ver apenas as informações necessárias, e não tudo o que pode ser coletado e contabilizado.

Analisando a estatística (número de requotes, o tempo de execução de um trade, deslize) e visualizando todos os trades, podemos concluir com qual corretora queremos trabalhar. Se a estatística de todas as corretoras forem negativas, devemos mudar alguns parâmetros do EA, por exemplo, tempo no mercado e frequência de trades. E alterá-los até que o EA comece a trabalhar com lucro. Se um determinado estágio do EA parar de trazer lucro com uma corretora e ser lucrativo com outras, paramos de testar esta corretora.



Teoria

Podemos organizar o envio de dados a partir de uma EA em uma aplicação através de arquivos ou através de dll. A variante com arquivos é mais fácil em termos técnicos de execução já que não exige uma grande programação do sistema. No entanto, trabalhar com estes arquivos não é muito conveniente porque não sabemos de antemão onde os terminais MetaTrader 4 de diferentes corretoras estarão, em quais moedas serão testados, o que fazer se os arquivos forem perdidos e etc. Se precisarmos que tudo seja feito de forma dinâmica, com o máxima de segurança, é melhor organizar os dados que passam através de dll.


Para diferentes terminais operarem com uma dll, ele deve estar localizado no diretório de sistema do Windows\system32. É importante que EAs de um terminal baixe um e a mesma copia dll, porque todos eles operam dentro de um processo, que é o terminal (terminal.exe), isto significa que eles têm o mesmo espaço de endereço, ou seja, eles operam com as mesmas variáveis. Um terminal com EAs tem sua própria cópia dll para todos os EAs e as mesmas variáveis anunciadas dentro da dll, outro terminal tem outra cópia com outras variáveis. Assim, um terminal não tem acesso a variáveis de outro terminal.


Queremos criar um único, onde os dados de diferentes terminais serão coletados. Existem diferentes maneiras de organizar uma operação sincronizada de diferentes processos com um campo de dados. Isto pode ser implementado através de arquivos, mas novamente teremos de enfrentar o problema do caminho indicado, assim como o problema com a velocidade de processamento, caso tenhamos muitos terminais e EAs. A melhor solução é uma memória de núcleo divisível. Trabalhar com isto requer maior atenção e conhecimento das características do sistema operacional utilizado (no nosso caso, Windows), no entanto, as possibilidades são infinitas. Para a organização de um acesso sucessivo para um determinado bloco de memória compartilhada de um programa de mecanismo especial de semáforos é utilizado.


Conclusão da teoria: através da DLL os EAs escrevem dados em uma memória compartilhada, e, em seguida, no aplicativo, vamos chamá-lo de Monitor, ele lê os dados da memória, exibe-os e realiza cálculos estatísticos necessários. Quando o MetaTrader 4 chama a DLL pela primeira vez, o sistema operacional gera uma cópia deste DLL para cada terminal, porque cada terminal é um processo separado. O esquema de funcionamento está na imagem abaixo.


Prática

Expert Advisor

Certamente, os dados sobre o trade atual devem ser formados por um Expert Advisor. Para passar os dados precisamos formar a interface da função dll. Para a tarefa implementada precisamos de três funções:


 bool NewExpert(string  isBrokerName, string isInstrument, int Digit);

Criar um novo Expert Advisor, identificando-o pelo nome e segurança de uma corretora. Para o cálculo de algumas características estatísticas passamos o número de figuras depois de um ponto em um preço de segurança.

bool NewDeal(string isInstrument, int Action, int magik, 
double PriceOpen, int Slippage, int TimeForOpen, int Requotes);

O registro de um novo trade é realizado da seguinte maneira. Enquanto o processo terminal já é identificado pelo nome de uma corretora, para um novo trade, o nome de uma segurança sobre a qual o comércio é executado é suficiente. Outros parâmetros são as características do trade.


Tabela 1. Abertura de trade

Parâmetro

Valor

Ação

0 – comprar, 1 - vender

magik

Número mágico

PreçoAberto

Abertura de preço

Deslizagem

Deslizagem

TempoParaAbertura

Duração da abertura

Requotes

Número de requotes recebidas


bool CloseDeal(string isInstrument, int magik, double PriceClose, 
               int Slippage, int TimeForClose, int Requotes);

Um fechamento de trade é identificado por segurança e magia. Parâmetros passados:

Tabela 2. Fechamento de trade

Parâmetro

Valor

PreçoFechado

Preço de fechamento

Deslizagem

Deslizagem

TempoParaFechamento

Duração de Fechamento

Requotes

Número de requotes recebidas


Devido a esta interface, a inicialização, a abertura e o fechamento de funções serão parecidos com isto:


Inicialização:

int init()
  {
   int Digit;
   if(IsDllsAllowed() == false)
     {
       Print("Calling from libraries (DLL) is impossible." + 
             " EA cannot be executed.");
       return(0);
     }
   if(!IsTradeAllowed())
     {
       Print("Trade is not permitted!");
       return(0);     
     }
   Digit = MarketInfo(Symbol(), MODE_DIGITS);
   if((Digit > 0) && (Bid > 0))
     {  
       if(!NewExpert(AccountServer(), Symbol(), Digit))
         {
           Print("Creation of a new broker failed");
           return (0);
         }                      
       Print("A broker is successfully created ");                    
       return(0);      
     }   
   Print("No symbol in MarketInfo!");       
   return(0);  
  }

Durante a inicialização, depois de verificar os parâmetros do terminal (permissão de trade e de confirmação de chamada DLL), recebemos a informação sobre dígitos de segurança e seu preço atual. Se ambos os parâmetros forem maiores que zero, a segurança no terminal é adequada e podemos trabalhar com ele. Cada corretora difere seu nome que pode ser recebido através da função AccountServer(), mediante este nome, terminais diferem uns dos outros na memória partilhada. EAs diferem em nome da segurança que estão realizando trading. Por isso, se diferentes EAs forem anexadas ao mesmo par de moedas, eles vão baixar a mesma cópia DLL que pode levar a colisão.

Função de abrir uma nova ordem:

int Deal(int act, double Lot)
  {
   int N = 0;
   int ticket;
   int err;
   double Price_open;
   double Real_price;
   datetime begin_deal;
   double Lots;
   int cmd;
   int magik;
   magik = GenericMagik() + 1;   
   Lots = NormalizeDouble(Lot, 1);
// checking margin for a position opening
   AccountFreeMarginCheck(Symbol(), cmd, Lots);
   err = GetLastError();
   if(err > 0)
     {
       Print("No money for new position");
       return(0);
     }      
   begin_deal=TimeCurrent(); 
   while(N < count)
     {
       if(act == 1)
         {
           Price_open = NormalizeDouble(Ask, Digits);
           cmd = OP_BUY;
         }
       if(act == 2)
         {
           Price_open = NormalizeDouble(Bid, Digits);
           cmd = OP_SELL;
         }
       ticket = OrderSend(Symbol(), cmd, Lots, Price_open,
                          slippage, 0, 0, 0, magik);
       if(ticket > 0)
         {
           if(OrderSelect(ticket, SELECT_BY_TICKET) == true)
             {
               Real_price = OrderOpenPrice();
               NewDeal(Symbol(), cmd,magik, Real_price ,
                       MathAbs(Real_price - Price_open),
                       (TimeCurrent() - begin_deal), N);
             }                   
           return(ticket);
         }
       N++;
       Sleep(5000);
       RefreshRates();
     } 
   return(0);
  }

Uma ordem é aberta pela função Deal with two parameters (Lidar com dois parâmetros): ação (1 - comprar, 2 - vender) e quantidade. Cada ordem difere da anterior na magia, é incrementada. A posição tenta abrir tentativas de contagem. As informações sobre o número de tentativas de abertura em conjunto com a duração, preço e deslize é transferida para uma memória partilhada de onde é lida pelo monitor.


Ordenar função de fechamento:

bool CloseOrder(int magik)
  {
   int ticket, i;
   double Price_close;
   int count = 0;
   datetime begin_time;
   double Real_close; 
   begin_time = TimeCurrent();    
   for(i = OrdersTotal() - 1; i >= 0; i--) 
     {
       if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
           if(OrderSymbol() == Symbol()) 
               if(OrderMagicNumber() == magik)
                 {                  
                   while(count < 10)
                     {                       
                       if(OrderType() == OP_BUY)        
                           Price_close = NormalizeDouble(Bid, Digits);
                       if(OrderType() == OP_SELL)        
                           Price_close = NormalizeDouble(Ask, Digits);
                       if(OrderClose(OrderTicket(), OrderLots(),
                                     Price_close, slippage))
                         { 
                           Real_close = OrderClosePrice();
                           CloseDeal(Symbol(), magik, Real_close,
                                     MathAbs(Real_close - Price_close),
                                     (TimeCurrent() - begin_time), count); 
                           return(true);
                         }
                       count++;
                       Sleep(5000);
                       RefreshRates();
                     }
                 }
     }
   return(false); 
  }

A função de fechamento CloseOrder() possui apenas um parâmetro de entrada, a magia. Uma ordem tenta o fechamento diversas vezes e este número de tentativas será transferido juntamente com o tempo de execução da transação, preço de fechamento e deslize para a memória e, em seguida, lidos pelo monitor.

O código restante é a EA testado. Portanto, para usar Estatísticas em seus próprios EAs, você precisa importar as funções dll necessárias; para inicialização e abertura/fechamento de posições utilize as funções Deal e CloseOrder. Se você quiser, você pode reescrever essas funções, mas os dados sobre transações devem ser passados em conformidade com a interface contida no dll.


Abaixo está o exemplo da implementação de tal EA utilizando DLL (o código das funções enumeradas acima não está incluído).

// Enable dll for operation with monitor
#import "statistik.dll"
  bool NewExpert(string  isBrokerName, string isInstrument, 
                 int Digit);   // Create a broker
  bool NewDeal(string isInstrument, int Action, int magik, 
               double PriceOpen, int Slippage, int TimeForOpen,
               int Requotes);
  bool CloseDeal(string isInstrument, int magik, double PriceClose, 
                 int Slippage, int TimeForClose,
                 int Requotes);
#import
//---- 
extern int Num_Deals = 3;
extern int TimeInMarket = 4;
// maximally acceptable slippage
int  slippage = 10;
// time for rest after a trade
int TimeForSleep = 10;
// period of request
int time_for_action = 1;
// number of attempts for opening a position
int count = 5;
// Function of a new bar
bool isNewBar()
  {
    static datetime BarTime;
    bool res = false; 
    if(BarTime != Time[0]) 
      {
        BarTime = Time[0];  
        res = true;
      } 
   return(res);
  }
//+------------------------------------------------------------------+
//| Generation of magic                                                  |
//+------------------------------------------------------------------+ 
int GenericMagic()
  {
   int deals;
//----  
   for(int i = OrdersTotal() - 1; i >= 0; i--) 
     {
       if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
           if(OrderSymbol() == Symbol())
               if(OrderMagicNumber() != 0)
                   deals++;
     }       
   return (deals);
  }
//+------------------------------------------------------------------+
//| forming signals to open/close a position                         |
//+------------------------------------------------------------------+
int GetAction(int &action, double &lot, int &magic)
   {
    int cnt, total;  
    if(OrdersTotal() <= Num_Deals)
      {
        if(Close[1] > Close[2])
          {
            action = 1;
            lot = 1;
            return(0);
          }
        if(Close[2] < Close[1])
          {
            action = 2;
            lot = 1;         
            return(0);               
          }
      }
    total = OrdersTotal();
    for(cnt = total - 1; cnt >= 0; cnt--)
      {
        if(OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES))
            if(OrderSymbol() == Symbol())  
                if((TimeCurrent() - OrderOpenTime()) > TimeInMarket*60)
                  {
                    action = 3;
                    magic = OrderMagicNumber();
                    return(0); 
                  }
      }
   }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
   int action = 0;
   double lot = 1;
   int magic = 0;     
   while(!IsStopped())
     {
       Sleep(time_for_action*1000);      
       RefreshRates();
       if(isNewBar())
         {
           GetAction(action, lot, magic);
           if(((action == 1) || (action == 2)))
             {                                        
               if(IsTradeAllowed())
                   Deal(action, lot);
               Sleep(TimeForSleep*1000);
             }
           if(action == 3)
             {
               if(IsTradeAllowed())
                   if(!CloseOrder(magik))
                     {
                       Print("MANUAL CLOSING OF A POSITION IS NEEDED");
                       Sleep(TimeForSleep*1000);   
                     } 
             }
           action = 0;
           lot = 0;
           magik = 0;
         }
     }
   Print("A serious error occurred, the EA stopped operating");  
   return(0);
  }
//+------------------------------------------------------------------+
O bloco executivo do EA é um ciclo infinito na função de partida. Em um frequência predefinida time_for_action o EA chama a função analítica GetAction() , que por referência retorna uma ação que deveria ser feita pelo EA, quantidade com que uma posição deve ser aberta, e magia, caso você precise fechar uma posição.

O bloco analítico é fundamental aqui - compre, se a última barra for maior do que a anterior, e venda se vice-versa. As posições são fechadas pelo tempo. Para testar seus próprios EAs simplesmente reescreva este bloco de acordo com seu algoritmo. Você não pode fazer nenhuma alteração na parte executiva.

DLL

O DLL podem ser aplicado em diferentes ambientes e em diferentes linguagens. O dll necessário para o nosso trabalho foi criado em Visual C++. Os trades terão a seguinte estrutura:

struct DealRec
  {
    int Index;
    int Magic;
    int Cur;
    int Broker;
    double PriceOpen;
    double PriceClose;
    int SlipOpen;
    int SlipClose;
    int Action;  // 0 = BUY 1 = SELL
    int TimeForOpen;
    int TimeForClose;
    int ReqOpen;
    int ReqClose;
    int Profit;
    bool Checked; // indication that the position is closed
  };


Eles serão cumpridos em duas etapas - na abertura e no fechamento. Isto é, uma parte dos dados (preço de abertura, deslize na abertura etc.) é passado na abertura, uma outra parte (preço de fechamento, tempo de fechamento etc.) é passado no fechamento. Protótipos de chamar uma função no dll

__declspec(dllexport) bool __stdcall NewExpert (char *isBrokerName, 
                                                char *isInstrument, 
                                                int Digit);
__declspec(dllexport) bool __stdcall NewDeal (char *isInstrument, 
                                              int Action, 
                                              int magic, 
                                              double PriceOpen, 
                                              int Slippage, 
                                              int TimeForOpen, 
                                              int Requotes);
__declspec(dllexport) bool __stdcall CloseDeal (char *isInstrument, 
                                                int magic, 
                                                double PriceClose, 
                                                int Slippage, 
                                                int TimeForClose, 
                                                int Requotes);


diferem dos protótipos em MQL4 apenas nas linhas de passagem. Você pode olhar através do dll de origem, isto pode ajudar na criação de outros projetos. Para recompilar o projeto abra o arquivo statistic.dsw utilizando o programa Visual C++. A código completo do dll está nos arquivos statistic.cpp e statistic.h, os restantes são subsidiários. Todos os arquivos enumerados estão em Statistic.zip.

Monitor

Uma ferramenta ideal para uma escrita rápida de aplicações com tabelas e interface gráfica, solução da Borland. Delphi e C++ Builder.

Funções do Monitor: criar uma memória compartilhada, ler dados da memória compartilhada e exibi-los em tabelas, manter as estatísticas de deslize. Existem mais algumas opções que tornam o trabalho mais conveniente. Portanto, esta é a função do monitor:

  1. Manter o registro de posições abertas;
  2. Manter o registro de posições fechadas;
  3. Estatísticas de deslilzagem e requotes;
  4. Tabelas ajustáveis;
  5. Salvar trades em arquivo html.



A implementação está no arquivo zip Statistic Monitor.zip. Para a compilação do projeto utilize o programa C++ Builder. A extensão do arquivo do projeto é *.bpr. O código principal é em в main.cpp.

Teste

Para testes, foi criado um EA especial. Ele tem as condições mais simples de entrar e fechar posições por tempo (a implementação foi mostrada anteriormente). O EA com dll e monitor.exe é no monitor de arquivo zip monitor+dll+expert.zip. Ao iniciar, clique START, criando assim uma memória compartilhada. O DLL deve estar na pasta system32. Depois disso, inicie vários terminais e anexe o EA no gráfico de moedas no qual irá negociar. Uma série de estatísticas de trade é acumulada. Os dados são coletados no monitor/ Registro. De tempos em tempos, eles devem ser transferidos para um ficheiro armazenado no formato de páginas de HTML.



A operação real da aplicação será a mesma. Ele permite que os operadores comparem o funcionamento de diferentes corretoras em termos de características técnicas e escolham as melhores para trading automatizado.

Conclusão

Habilitar dll em MQL4 permite desenvolver diferentes programas de aplicação, que ajudam não só a tomar decisões sobre trading, mas também coletar estatísticas. Este último pode ser muito útil na negociação e na escolha de uma corretora. O aplicativo criado deve ajudar os desenvolvedores nesta difícil busca. Para analisar corretoras, anexe statistic.dll a um Expert Advisor como descrito no exemplo analisado neste artigo. Os arquivos necessários para o trabalho estão em monitor+dll+expert.zip. Para esta operação copie statistic.dll para a pasta system32, inicie Statistic. exe de qualquer local e abra o terminal que fez o dowload dll com Expert Advisors. Inicie o trading e transfira os dados para a memória compartilhada. Statistic.exe cria arquivos auxiliares, por isso é melhor iniciar o aplicativo a partir de uma pasta vazia. Se o programa é interessante para os desenvolvedores de robôs de trading, ele pode ser modificado e alterado.

Observe que nem todas as corretoras oferecem condições semelhantes para o trading automatizado.

  1. Uma corretora pode proibir o trading automatizado.
  2. Uma corretora pode proibir indicar a ordem de colocação SL ou TP https://www.mql5.com/ru/forum/103341.
  3. Níveis não simétricos para SL e TP.
  4. Pode não ter nenhuma opção de uma abertura recíproca de ordens.
  5. Restrição sobre o número de posições abertas simultaneamente em uma conta. Se o número de ordens (posições abertas + ordens pendentes) exceder a restrição, a função OrderSend mostrará o código de erro ERR_TRADE_TOO_MANY_ORDERS.
  6. Outras restrições.

É por isso que é fortemente recomendada a leitura cuidadosa dos regulamentos da corretora que você irá trabalhar.


A Estatística do projeto mostra que complexos podem ser criados se você adicionar as possibilidades de outras linguagens e ambientes de programação nas opções da MQL4. O programa criado será útil para que os Expert Advisors trabalhem com diferentes corretoras, ele ajuda a analisar características técnicas de uma forma conveniente. Se uma corretora tem deslizagens, os trades são executados pelo tempo e requotes ocorrem seguidamente, então, para que precisamos de tal corretora? Há muitas alternativas!


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

Arquivos anexados |
Statistic_Monitor.zip (219.41 KB)
Statistic.zip (24.28 KB)
O mercado Forex pode ser previsto? Como criar uma estratégia de trading própria para este mercado? O mercado Forex pode ser previsto? Como criar uma estratégia de trading própria para este mercado?
Todo mundo que começa a trabalhar no Forex tenta responder estas questões. Mas nem todos encontram a resposta, mesmo depois de muitos anos de trabalho duro e pesquisas. Eu, pessoalmente, respondi esta questão, assim como muitas outras questões deste artigo. Como resultado dessas respostas, uma maneira de criar uma estratégia eficiente de trading foi determinada.
Linguagem MQL4 para Iniciantes. Introdução Linguagem MQL4 para Iniciantes. Introdução
Esta sequência de artigos destina-se para operadores que não sabem nada sobre programação, mas desejam aprender a linguagem MQL4 o mais rápido possível em pouco tempo e sem dificuldades. Se você tem medo de frases como "orientação de objetos" ou "três matrizes dimensionais", este artigo é o que você precisa. As aulas são projetadas para fornecerem resultados rapidamente. Além disso, a informação é entregue de forma compreensível. Não iremos aprofundar na parte teórica, mas você vai ganhar o benefício prático já a partir da primeira aula.
O básico de codificação de um Expert Advisor de cobertura O básico de codificação de um Expert Advisor de cobertura
Um exemplo de um Expert Advisor de cobertura é apresentado neste artigo. O autor escolherá o seu próprio par de cobertura favorito que é EURJPY e GBPJPY. Ele sempre se move da mesma maneira, sendo assim, mais fácil definir o tipo de ordem de cobertura.
Strings: Tabela de Símbolos ASCII e seus usos Strings: Tabela de Símbolos ASCII e seus usos
Neste artigo iremos analisar a tabelo de símbolos ASCII e o modo de utilização. Também vamos lidar com algumas novas funções com o princípio de funcionamento baseado nas peculiaridades da tabela ASCII, e, em seguida, vamos criar uma nova biblioteca que incluirá essas funções. Elas são muito populares em outras linguagens de programação mas não são incluídos na lista de funções embutidas. Além disso, vamos examinar em detalhes os conceitos básicos do trabalho com strings. Acho que você certamente aprenderá algo novo sobre este tipo útil de dados.