Discusión sobre el artículo "Desarrollo de un sistema comercial basado en el libro de órdenes (Parte I): el indicador"

 

Artículo publicado Desarrollo de un sistema comercial basado en el libro de órdenes (Parte I): el indicador:

El libro de órdenes —Depth of Market— es, sin duda, un elemento muy relevante para la ejecución de operaciones rápidas, especialmente en algoritmos de alta frecuencia (HFT). En esta serie de artículos, exploraremos este tipo de evento comercial que podemos obtener a través del bróker en muchos de los símbolos negociados. Empezaremos con un indicador en el que se pueden configurar la paleta de colores, la posición y el tamaño del histograma que se mostrará directamente en el gráfico. También veremos cómo generar eventos BookEvent para probar el indicador en condiciones específicas. Otros posibles temas que trataremos en artículos futuros son el almacenamiento de estas distribuciones de precios y las formas de utilizarlas en el simulador de estrategias.

Recordemos qué es el Depth of Market: se trata de una fila de órdenes pendientes del tipo límite. Estas órdenes representan las intenciones de transacción de los agentes del mercado y, con frecuencia, no se convierten en una transacción propiamente dicha. Esto se debe a que los participantes tienen la posibilidad de cancelar sus órdenes previamente publicadas por diversos motivos. Entre estos motivos se incluyen cambios en las condiciones del mercado y el consiguiente desinterés en ejecutar la orden en la cantidad y al precio especificados anteriormente.

El valor devuelto por la función `SymbolInfoInteger(_Symbol, SYMBOL_TICKS_BOOKDEPTH)` es precisamente la profundidad del libro de órdenes y representa la mitad del array que se llenará con los niveles de precios a trabajar. Una mitad de este array se destina a la cantidad de órdenes límite de venta y la otra mitad, a las órdenes límite de compra que han sido publicadas. Según la documentación, para los símbolos que no tienen fila de solicitudes, el valor de esta propiedad es igual a cero. Tenemos un ejemplo de esto en la siguiente figura, que muestra un libro de órdenescuya profundidad es 10 y en el que se pueden ver todos los niveles de precios disponibles.

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 MqlBookInfoque o manipulador OnBookEvent preenche, conforme veremos mais detalhadamente adiante.

Autor: Daniel Santos

 
No veo ninguna razón por la que necesites un símbolo personalizado. Es perfectamente posible guardar y reproducir los eventos del libro en el propio símbolo estándar - tanto en la historia de un gráfico normal (para la visualización del indicador) y en el probador (para la prueba de EA).
 

Este es un artículo muy corto con muy poco código. Vamos a ver en la próxima parte si tiene sentido tener parte 1, 2 y así sucesivamente.

SYMBOL_TICKS_BOOKDEPTH da el número máximo de peticiones mostradas en Profundidad de Mercado. Es incorrecto que esta propiedad da el mismo resultado que contar el número de niveles en el DOM. Da el número máximo, no el número exacto.

Puede hacerlo usando este script:

//+------------------------------------------------------------------+
//|TestOnderBook.mq5
//|Copyright 2025, Samuel Manoel De Souza ||
//| https://www.mql5.com/es/users/samuelmnl ||
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, Samuel Manoel De Souza"
#property link      "https://www.mql5.com/es/users/samuelmnl"
#property version   "1.00"
//+------------------------------------------------------------------+
//| Función de inicio del 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();
  }
//+------------------------------------------------------------------+
 
¿Qué ha pasado con el sistema de trading que se iba a desarrollar con este indicador?
 
Samuel Manoel De Souza #:

Este es un artículo muy corto con muy poco código. Veremos en la siguiente parte si tiene sentido tener parte 1, 2 y así sucesivamente.

SYMBOL_TICKS_BOOKDEPTH da el número máximo de peticiones mostradas en la Profundidad de Mercado. Es incorrecto que esta propiedad dé el mismo resultado que contar el número de niveles en el DOM. Da un número máximo, no un número exacto.

Puede hacerlo con este script:

El artículo es super! También quería escribir un TS sobre la pila - más precisamente con el uso de la pila de comillas!