Discussão do artigo "Desenvolvendo um Trading System com base no Livro de Ofertas (Parte I): o indicador"

 

Novo artigo Desenvolvendo um Trading System com base no Livro de Ofertas (Parte I): o indicador foi publicado:

O livro de ofertas - Depth of Market - é sem dúvidas algo de bastante relevância para a execução de trades rápidos, sobretudo em algoritmos de alta frequência - os HFT. Nessa série de artigos, iremos explorar esse tipo de evento de mercado que podemos obeter através do broker em muitos dos ativos negociados. Começaremos com um indicador em que são configuráveis a paleta de cores, a posição e o tamanho do histograma a ser exibido diretamente no gráfico. Também abordaremos uma forma de gerar eventos BookEvent para fins de testes do indicador em condições específicas. Como possíveis temas a serem abordados nos artigos futuros estão o armazenamento dessas distribuições de preços e formas de usá-las no testador de estratégia.

Recapitulando sobre o que venha a ser o Depth of Market, sabemos que se trata de uma fila de ordens pendentes do tipo limite. Essas ordens representam as intenções de negociações dos agentes de mercado, e frequentemente não resultam em uma negociação propriamente dita. Isso porque os players tem a possibilidade de cancelar suas ordens previamente apregoadas por diversos motivos. Dentre eles estão mudança nas condições do mercado, e o consequente desinteresse na execução daquela ordem na quantidade e no preço especificado anteriormente.

O valor retornado pela função SymbolInfoInteger(_Symbol, SYMBOL_TICKS_BOOKDEPTH) é justamente a profundidade do livro de ofertas, e representa metade do array a ser preenchido com os níveis de preços a serem trabalhados. Metade desse array se destina à quantidade de ordens limite de venda, e a outra metade para ordens limite de compra que foram apregoadas. Conforme a documentação, para ativos que não tem fila de solicitações, o valor dessa propriedade é igual a zero. Temos um exemplo dessa ideia na próxima figura, que é de um livro de ofertas cuja profundidade tem valor 10. Além disso, todos os níveis de preços disponibilizados estão visíveis:

Exemplo: Livro de Ofertas com profundidade 10

Note que a profundidade pode ser obtida do símbolo, e não necessariamente do livro de ofertas. A função o uso da SymbolInfoInteger seria suficiente para a obtenção do valor da propriedade, e ainda não precisaríamos do manipulador OnBookEvent ou das funções relacionadas tais como  MarketBookAdd. Claro que podemos chegar ao mesmo resultado através contagem do número de elementos do array do tipo MqlBookInfo que o manipulador OnBookEvent preenche, conforme veremos mais detalhadamente adiante.

Autor: Daniel Santos

 
Não vejo nenhuma razão para que você precise de um símbolo personalizado. É perfeitamente possível salvar e reproduzir eventos de livro no próprio símbolo padrão - tanto no histórico de um gráfico normal (para exibição de indicador) quanto no testador (para teste de EA).
 

Este é um artigo muito curto, com muito pouco código. Vamos ver na próxima parte se faz sentido ter a parte 1, 2 e assim por diante.

SYMBOL_TICKS_BOOKDEPTH fornece o número máximo de solicitações mostradas em Depth of Market. É incorreto que essa propriedade forneça o mesmo resultado que contar o número de níveis no DOM. Ela fornece o número máximo, não o número exato.

Você pode fazer isso usando este script:

//+------------------------------------------------------------------+
//|TestOnderBook.mq5
//|Direitos autorais 2025, Samuel Manoel De Souza |
//| https://www.mql5.com/pt/users/samuelmnl |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, Samuel Manoel De Souza"
#property link      "https://www.mql5.com/en/users/samuelmnl"
#property version   "1.00"
//+------------------------------------------------------------------+
//| Função de início do programa de script|
//+------------------------------------------------------------------+
int OnInit(void)
  {
   MarketBookAdd(_Symbol);

   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {

   MarketBookRelease(_Symbol);
  }
//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
void OnTick(void)
  {

  }
//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
void OnBookEvent(const string& symbol)
  {
   double tick_size = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);
   MqlBookInfo book[];
   MarketBookGet(_Symbol, book);
   int total = ArraySize(book);
   if(total == 0)
     {
      Print("there is no order available on the book");
      ExpertRemove();
      return;
     }

   int buy_levels = 0, sell_levels = 0;
   int buy_gaps = 0, sell_gaps = 0, gaps = 0;
   for(int i = 0; i < total; i++)
     {
      Print("price: ", book[i].price, ", volume: ", book[i].volume, ", type: ", EnumToString(book[i].type));
      buy_levels += book[i].type == BOOK_TYPE_BUY ? 1 : 0;
      sell_levels += book[i].type == BOOK_TYPE_SELL ? 1 : 0;
      if(i > 0)
        {
         bool is_gap = fabs(book[i].price - book[i - 1].price) >= 2 * tick_size;
         gaps += is_gap ? 1 : 0;
         buy_gaps += is_gap && book[i].type == book[i - 1].type && book[i].type == BOOK_TYPE_BUY ? 1 : 0;
         sell_gaps += is_gap && book[i].type == book[i - 1].type && book[i].type == BOOK_TYPE_SELL ? 1 : 0;
        }
     }

   Print("max levels: ", SymbolInfoInteger(_Symbol, SYMBOL_TICKS_BOOKDEPTH));
   Print("levels: ", total);
   Print("buy levels: ", buy_levels);
   Print("sell levels: ", sell_levels);
   Print("gaps: ", gaps);
   Print("buy gaps: ", buy_gaps);
   Print("sell gap: ", sell_gaps);
   ExpertRemove();
  }
//+------------------------------------------------------------------+
 
O que aconteceu com o sistema de negociação que seria desenvolvido com esse indicador?
 
Samuel Manoel De Souza #:

Este é um artigo muito curto com muito pouco código. Veremos na próxima parte se faz sentido ter a parte 1, 2 e assim por diante.

SYMBOL_TICKS_BOOKDEPTH fornece o número máximo de solicitações exibidas no Depth of Market. É incorreto que essa propriedade forneça o mesmo resultado que contar o número de níveis no DOM. Ela fornece um número máximo, não um número exato.

Você pode fazer isso com este script:

O artigo é excelente! Eu também queria escrever um TS sobre a pilha - mais precisamente com o uso da pilha de aspas!