Problema em capturar o book de ofertas (Depth of Market)

 
Olá a todos,

hoje fui começar a trabalhar com o book de ofertas, montei um EA simples, apenas pra capturar o book de ofertas e exibi-lo na aba do log do Expert. Ele é igual ao código de exemplo encontrado na referência MQL5.

Segue o código:

//+------------------------------------------------------------------+
//|                                                       DOM-EA.mq5 |
//|                                    Copyright 2014, Romeu Bertho. |
//|                         https://www.mql5.com/en/users/c4b3l3r4 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2014, Romeu Bertho."
#property link      "https://www.mql5.com/en/users/c4b3l3r4"
#property version   "1.00"
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   MarketBookAdd(Symbol());
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   MarketBookRelease(Symbol());
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   MqlBookInfo mbook[];
   if(MarketBookGet(Symbol(),mbook))
     {

      int size=ArraySize(mbook);
      Print(size);
      Print("MarketBookInfo para ",Symbol());
      for(int i=0;i<size;i++)
        {
         Print(i+":",mbook[i].price
               +"    Volume = "+mbook[i].volume,
               " tipo = ",mbook[i].type);
        }
     }
   else
     {
      Print("Could not get contents of the symbol DOM ",Symbol());
     }

  }
//+------------------------------------------------------------------+
//| BookEvent function                                               |
//+------------------------------------------------------------------+
void OnBookEvent(const string &symbol)
  {
//---

  }
//+------------------------------------------------------------------+


Eu compilei ele e fui rodar primeiramente no par EURUSD de uma conta live da Alpari. A mensagem que eu recebi no log do EA foi "Could not get contents of the symbol DOM EURUSD"

Depois rodei no WINFUT@ da conta demo MetaBrazil e recebi o mesmo erro.

Após esses erros, eu lembrei que já tinha feito algo relacionado com o book de ofertas e coloquei ele (já estava compilado) pra rodar. Ele rodou muito bem em todas as contas, sem erros.

Aqui em baixo segue a parte relevante do código, que em questões de exibição no log é o mesmo que o código acima:

//+------------------------------------------------------------------+
//|                                                MACD-Analyser.mq5 |
//|                                    Copyright 2013, Romeu Bertho. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, Romeu Bertho."
#property link      "http://www.mql5.com"
#property version   "1.00"

#include <ChartObjects\ChartObjectsArrows.mqh>
input string MACD_Settings = "------------------------------"; // --------------MACD Settings--------------
input ENUM_TIMEFRAMES    TimeFrame = PERIOD_CURRENT;  // TimeFrame
input int                InpFastEMA=12;               // Fast EMA period
input int                InpSlowEMA=26;               // Slow EMA period
input int                InpSignalSMA=9;              // Signal SMA period
input ENUM_APPLIED_PRICE InpAppliedPrice=PRICE_CLOSE; // Applied price

//MACD Structure
struct MACD
{
   double open;
   double high[];
   double low[];
   double close[];
};

//global variables
int handle,wait,h,l,c;
MACD macd[4];
double Value[];
MqlRates mrate[];
MqlTick mtick;
MqlBookInfo mbook[];
CChartObjectArrow arrow;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   MarketBookAdd(Symbol());
   handle = iMACD(Symbol(),TimeFrame,InpFastEMA,InpSlowEMA,InpSignalSMA,InpAppliedPrice);
   wait = 4;
   ArraySetAsSeries(mrate,true);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   MarketBookRelease(Symbol());
   IndicatorRelease(handle);
   ArrayFree(macd);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   
   getData();
   if(wait > -3) return;
   SymbolInfoTick(Symbol(),mtick);
   Print(mtick.volume);
   if(MarketBookGet(Symbol(),mbook))
   {
    int size=ArraySize(mbook);
      Print("MarketBookInfo para ",Symbol());
      for(int i=0;i<size;i++)
        {
         Print(i+":",mbook[i].price
               +"    Volume = "+mbook[i].volume,
               " tipo = ",mbook[i].type);
        }
     }
   else
     {
      Print("Could not get contents of the symbol DOM ",Symbol());
     }
   CopyRates(Symbol(),TimeFrame,0,4,mrate);
   
  }

Indagado do porque o segundo código funciona e o primeiro não, eu coloquei exatamente o mesmo código de captura do book de ofertas do segundo no primeiro. Eu compilei e o erro foi o mesmo.

Eu até criei um novo EA e copiei o código do que funciona e colei no novo EA, o resultado foi de erro.

Como eu não consegui encontrar a falha em meu código e já que o meu segundo código foi compilado com uma versão mais antiga do mt5 (21/05/2014), eu comecei a suspeitar que o erro poderia ser dessa nova versão do compilador (se é que isso é possível).

Eu posso estar errado ou não sobre a minha teoria, por isso, eu gostaria que vocês deixassem suas opiniões.

Grande abraço,

Romeu.
Negociação Automatizada e Análise de Estratégia
Negociação Automatizada e Análise de Estratégia
  • www.mql5.com
MQL5: linguagem de estratégias de negociação inseridas no Terminal do Cliente MetaTrader 5. A linguagem permite escrever seus próprios sistemas automáticos de negócios, indicadores técnicos, scripts e bibliotecas de funções
 
c4b3l3r4:
Olá a todos,
Grande abraço,
Romeu.

Prezado Romeu,

Suspeito que seu problema seja muito mais simples do que parece... Você tem certeza que os ativos que você está testando POSSUEM livro de ofertas??? Alguns servidores simplesmente não disponibilizam livro de ofertas... É o caso do servidor MetaBrazil-Demo...

A propósito, as informações do DOM para backstests não são nada confiáveis, mesmo em servidores que fornecem dados em tempo real do livro de ofertas. Logo, vale a pena você diferenciar entre obter informações em tempo real do servidor e obter essas mesmas informações ao fazer backtests de ativos.

 
Malacarne:

Prezado Romeu,

Suspeito que seu problema seja muito mais simples do que parece... Você tem certeza que os ativos que você está testando POSSUEM livro de ofertas??? Alguns servidores simplesmente não disponibilizam livro de ofertas... É o caso do servidor MetaBrazil-Demo...

A propósito, as informações do DOM para backstests não são nada confiáveis, mesmo em servidores que fornecem dados em tempo real do livro de ofertas. Logo, vale a pena você diferenciar entre obter informações em tempo real do servidor e obter essas mesmas informações ao fazer backtests de ativos.

Olá Malacarne,

eu sei que o DOM não funciona no strategy tester (pelo menos no metaBrazil e na Alpari), mas se vc deixar rodar em sua conta normalmente, funciona sim.

vou deixar as imagens de exemplo do EA que foi compilado com uma build do mt5 mais antiga :

DOM com EA compilado com mt5 antigo


Agora vou deixar com o EA simples que eu montei:


DOM com EA simples compilado com a versao atual do mt5


Isso esta me matando hahaha pq eu não consegui encontrar nada de errado no EA de código simples "DOM-EA"

já no "MACD-Analyser" a porção de código responsável pela exibição do book no log é idêntica a do "DOM-EA" e funciona. 

Mas foi o que eu disse anteriormente, se eu modifico alguma coisinha no "MACD-Analyser", por exemplo, adiciono uma variável a mais e compilo, da erro.

Se eu crio um novo EA com o mesmo código do "MACD-Analyser" tbm da erro.

Por isso que eu estou com essa ideia maluca de que possa haver algo de errado com a nova build do mt5.

Alguma sugestão?

Abraço,

Romeu.

 
c4b3l3r4:

Olá Malacarne,

eu sei que o DOM não funciona no strategy tester (pelo menos no metaBrazil e na Alpari), mas se vc deixar rodar em sua conta normalmente, funciona sim.

vou deixar as imagens de exemplo do EA que foi compilado com uma build do mt5 mais antiga :


Agora vou deixar com o EA simples que eu montei:



Isso esta me matando hahaha pq eu não consegui encontrar nada de errado no EA de código simples "DOM-EA"

já no "MACD-Analyser" a porção de código responsável pela exibição do book no log é idêntica a do "DOM-EA" e funciona. 

Mas foi o que eu disse anteriormente, se eu modifico alguma coisinha no "MACD-Analyser", por exemplo, adiciono uma variável a mais e compilo, da erro.

Se eu crio um novo EA com o mesmo código do "MACD-Analyser" tbm da erro.

Por isso que eu estou com essa ideia maluca de que possa haver algo de errado com a nova build do mt5.

Alguma sugestão?

Abraço,

Romeu.

Olá Romeu, a meu ver os dois códigos possuem uma falha que é não testarem o retorno da função MarketBookAdd().

Eu comecaria corrigindo isso e depois repetindo tua bateria de testes.

 
figurelli:

Olá Romeu, a meu ver os dois códigos possuem uma falha que é não testarem o retorno da função MarketBookAdd().

Eu comecaria corrigindo isso e depois repetindo tua bateria de testes.

Olá Figurelli,

agora na OnInit() eu coloquei "if(!MarketBookAdd(Symbol())) return -1;", eu repeti os testes e apareceu o mesmo erro "Could not get contents of the symbol DOM EURUSD"

Lembrando que eu nunca testei no strategy tester, eu sempre estou testando na conta live da Alpari ou da MetaBrazil....

se não for pedir muito, teria como vocês compilarem um EA de captura do book no compilador de vocês e rodar pra ver o que acontece?

Abraço,

Romeu.

 
c4b3l3r4:

Olá Figurelli,

agora na OnInit() eu coloquei "if(!MarketBookAdd(Symbol())) return -1;", eu repeti os testes e apareceu o mesmo erro "Could not get contents of the symbol DOM EURUSD"

Lembrando que eu nunca testei no strategy tester, eu sempre estou testando na conta live da Alpari ou da MetaBrazil....

se não for pedir muito, teria como vocês compilarem um EA de captura do book no compilador de vocês e rodar pra ver o que acontece?

Abraço,

Romeu.

Perfeitamente Romeu, vamos testar durante a semana com o mercado aberto.
 
c4b3l3r4:

Olá Figurelli,

agora na OnInit() eu coloquei "if(!MarketBookAdd(Symbol())) return -1;", eu repeti os testes e apareceu o mesmo erro "Could not get contents of the symbol DOM EURUSD"

Lembrando que eu nunca testei no strategy tester, eu sempre estou testando na conta live da Alpari ou da MetaBrazil....

se não for pedir muito, teria como vocês compilarem um EA de captura do book no compilador de vocês e rodar pra ver o que acontece?

Abraço,

Romeu.

Olá Romeu,

fiz aqui alguns testes e realmente, depois dessa última versão do MetaTrader 5 (build 965), parece que que a função MarketBookGet não está conseguindo capturar de maneira correta as informações do DoM. Chequei o retorno de todas as funções envolvidas no processo, e a única função que retorna falso o tempo inteiro é justamente MarketBookGet... Também verifiquei a lista de mudanças na última build do MT5, e me parece que no tópico 7 eles reportam que foram fixados erros nas funções IndicatorParamenters e também MarketBookGet. Logo, acredito que possa ter havido alguma modificação que fez com que essa última função passasse a não mais funcionar da maneira correta.

Vou abrir um ticket pra MetaQuotes pra informar esse problema ainda hoje.

Entretanto, tenho uma boa notícia: fiz aqui alguns testes e encontrei uma maneira minimalista de contornar essa situação e retornar os dados do DoM, como você quer. Por favor não tome essa solução como definitiva, uma vez que pode ser possível que a MetaQuotes volte a alterar a função MarketBookGet e que ela volte a funcionar corretamente.

Pelos meus testes, a função MarketBookGet passa a funcionar corretamente se você adicionar duas outras structs MQL dentro do seu código, a saber: MqlRates e MqlDateTime. Além disso, é necessário fazer a definição de alguma função que faça uso da struct MqlDateTime... não me pergunte (por enquanto) porque isso está acontecendo... a única informação que posso te dar no momento é que essa solução de contorno está funcionando.. :-)

Segue abaixo o código:

//+------------------------------------------------------------------+
//|                                                       DOM-EA.mq5 |
//|                                Copyright 2014, Rodrigo Malacarne |
//|                        https://www.mql5.com/pt/users/malacarne |
//+------------------------------------------------------------------+
#property copyright "Copyright 2014, Rodrigo Malacarne"
#property link      "https://www.mql5.com/pt/users/malacarne"
#property version   "1.00"
//---
MqlRates    myRates[];
MqlDateTime myTime;
MqlBookInfo myBook[];
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   datetime myTimeVar = myTime.day;
//---
   bool ok=MarketBookAdd(_Symbol);
   if(ok) Print("init ok = ",ok);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   bool ok=MarketBookRelease(_Symbol);
   if(ok) Print("deinit ok = ",ok);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   bool success=MarketBookGet(_Symbol,myBook);
   if(success) 
     {
      for(int i=0;i<ArraySize(myBook);i++)
        {
         Print(IntegerToString(i),
               " : Preço = ",DoubleToString(myBook[i].price,_Digits),
               " / Volume = ",IntegerToString(myBook[i].volume),
               " / Tipo = ",myBook[i].type);
        }
     }
  }
//+------------------------------------------------------------------+
 

Olá Romeu,

recebi agora pela manhã uma resposta to ticket que abri sobre o erro na função MarketBookGet. O Service Desk da MetaQuotes pediu para que eu atualizasse o meu terminal para a versão 975 e, aparentemente, parece que o problema está resolvido.

Logo, realmente parece que a build 965 introduziu um pequeno bug na função MarketBookGet. Já fiz meus testes aqui com a versão 975 e, aparentemente, parece que voltou tudo ao normal.

Parabéns!

Abraços,
Malacarne

 
Boa descoberta do Romeu, espero que se confirme com os novos testes dele.
 

Muito obrigado Malacarne e Figurelli!

no decorrer da semana eu farei mais testes e posto os resultados.

Muito obrigado!

Romeu.

 

Olá Malacarne e Figurelli,

peguei o dia pra brincar com o book, ele está perfeito , tudo corrigido, show de bola! hehehe

mais uma vez, muito obrigado!

Grande abraço!

Razão: