Tiki en tiempo real - página 19

 
Yuriy Zaytsev:

Alternativamente, para evitar la preocupación de que Symbol() se coma el tiempo, entonces deje que ambos manejadores se "alimenten" por igual.

Podemos sustituir la función Symbol() por una variable predefinida _Symbol

 

Symbol() no tiene nada que ver. La hora en el registro es correcta.

El retraso está en la cola de eventos o en las funciones SymbolInfo.

A eso me refiero.


Así que, si necesita el cristal, trabaje con OnBook. Si no es necesario, trabaja en OnTick (sin colas ni llamadas innecesarias).

Lo que queda por averiguar es la forma más rápida de obtener el historial de ticks real para ambos métodos.

Creo que, si sólo se necesita el último tick, SymbolInfo es mejor. Si necesitamos un historial sin huecos, entonces sólo CopyTicks.

 
Andrey Khatimlianskii:

Symbol() no tiene nada que ver. La hora en el registro es correcta.

El retraso está en la cola de eventos o en las funciones SymbolInfo.

A eso me refiero.

Estoy de acuerdo en que el Símbolo no puede masticar mucho, pero puede hacer alguna contribución, y sin duda para la pureza de la prueba tomar el tiempoantes de cualquier llamada.

En cuanto a la cola - tengo curiosidad por este punto - hasta qué punto OnBook puede ir por detrás del mismo OnTick en condiciones ideales. Es decir, cuando sólo se suscribe este Símbolo, el terminal no está ocupado con nada más, etc., y qué lo provoca.

Hasta ahora no puedo estar de acuerdo en que se trate sólo de la cola, porque si los manejadores no están haciendo nada, entonces la cola de 5-6 OnBooks no debería consumir más que la operación de comprobar el Símbolo.

Deberíamos eliminar todas las comprobaciones y ver lo que caeentre OnTick y OnBook para el mismo tick.

void OnBookEvent(const string &symbol)
{
ul=GetMicrosecondCount();  
  Print(__FUNCTION__, "; Time: ", ul, " mcs");
}
void OnTick()
{
ul=GetMicrosecondCount();  
  Print(__FUNCTION__, "; Time: ", ul, " mcs");
}
//+--

ap: Quedó claro que el voraz Print no permite comprobar limpiamente, porque la cola será larga a causa del Print)

Tengo que poner el tiempo sin la impresión en el array ulong, y luego ya una vez cada 5 minutos para que salga todo a Prints, luego lo codificaré.

 

Quería poner el código a prueba primero

//---
bool is_book;
enum ENUM_BOOK_OR_TICK
{
        USE_BOOK,       // Use OnBookEvent
        USE_TICK        // Use OnTick
};
input ENUM_BOOK_OR_TICK Mode = USE_BOOK;
input int   SecForPrint =  120;
ulong TimeArrayBook[65536];
ulong TimeArrayTick[65536];
ushort curBook,curTick;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   curBook=0;
   curTick=0; 
   ArrayInitialize(TimeArrayBook,INT_MAX);
   ArrayInitialize(TimeArrayTick,INT_MAX);
  if(Mode == USE_BOOK) is_book = MarketBookAdd(Symbol());
  if (EventSetTimer(SecForPrint)) 
  return(INIT_SUCCEEDED);
  else return (INIT_FAILED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
  if(Mode == USE_BOOK)
  {
    if(is_book == true) MarketBookRelease(Symbol());
  }  
}
//+------------------------------------------------------------------+
//| BookEvent function                                               |
//+------------------------------------------------------------------+
void OnBookEvent(const string &symbol)
{
  TimeArrayBook[curBook++]=GetMicrosecondCount();
}
void OnTick()
{
  TimeArrayTick[curTick++]=GetMicrosecondCount();
}
//+------------------------------------------------------------------+
void OnTimer()
  {  
   int total=MathMax(curBook,curTick);
   int i=0,k=0;
   while(i<total)
     {
      while(i<total && TimeArrayBook[i]<TimeArrayTick[k])
        {
          Print("Book ",TimeArrayBook[i++]);
        }    
      if(k<curTick-1)
        {
         Print("Tick ",TimeArrayTick[k++]);
        }       
        i++;
     }
     if (curTick>0)Print("Tick ",TimeArrayTick[curTick-1], " last");
     curBook=0;
     curTick=0;
  }
//---

Pero no puedo abrir la cuenta de apertura demo por algo. El tiempo está probablemente fuera de servicio, ¿o hay algo más que no funciona?



Luego el código para dopilizar para comparar exactamente desde un tick de evento.

 
Aleksey Mavrin:

Quería poner el código a prueba primero

Pero no puedo abrir la cuenta de apertura demo por algo. El tiempo está probablemente fuera de servicio, ¿o hay algo más que no funciona?



Luego el código para dopilizar para comparar exactamente desde un tick de evento.

Tienes que abrirlo en su página web. A continuación, envían un código a la oficina de correos.

 
Andrey Khatimlianskii:


Creo que si sólo se necesita el último tick, SymbolInfo es mejor. Si necesitas un historial sin huecos, entonces sólo CopyTicks.

La cuestión es que el Mercado Urgente (FORTS), incluso en los instrumentos "altamente líquidos", es muy débil,

Esto significa que al precio adecuado se puede comprar unnúmero muylimitado de contratos, por lo que no sólo necesitamos el precio,

pero el volumen de contratos a este precio es muy importante.


Y SymbolInfo no da el volumen de este precio.

Debido a esto, necesitamos utilizarMarketBookGet() que proporciona tanto el precio como el volumen de todo el libro.

Puede utilizarMarketBookGet() sólo en pareja con MarketBookAdd, obteniendo los cambios de la copa del mercado.

en OnBookEvent. Puede añadir el mercado (MarketBookAdd) y utilizarMarketBookGet() desde OnTck(),

pero en este caso, se perderán otros deslizamientos del mercado(órdenes pendientes que no están al mejor precio).

Es cierto, el mercado puede jugar con esto y construir el deslizamiento del mercado de las garrapatas entrantes, pero ¿es realmente necesario?

Añadido por

Y no estoy de acuerdo en que podamos obtener ticks del historial cuando se dispara OnTck().

Recordando el último tiempo de ticks, cuando se dispara OnTck() podemos obtener ticks

en tiempo real un nuevo tick(s) entró - disparó OnTck() lo leemos inmediatamente, es decir, no es historia.

 
Andrey Khatimlianskii:

Queda por averiguar la forma más rápida de obtener el historial de garrapatas real para ambos métodos.


Mi OnTick() es igual o ligeramente más rápido que OnBook (pero OnBook tiene enormes retrasos).

Estaba probando la velocidad de las funciones(microsegundos)

2020.02.04 13:09:13.101 Ticks_test (GOLD-3.20,M1)       SymbolInfoTick: time = 2 mcs 2020.02.04 13:09:10.720 Bid=1573.1 
2020.02.04 13:09:13.101 Ticks_test (GOLD-3.20,M1)       SymbolInfoDouble: time = 28 mcs ask = 1573.3
2020.02.04 13:09:13.101 Ticks_test (GOLD-3.20,M1)       SymbolInfoDouble: time = 33 mcs bid = 1573.1
2020.02.04 13:09:13.101 Ticks_test (GOLD-3.20,M1)       SymbolInfoDouble: time = 36 mcs last = 1573.4
2020.02.04 13:09:13.101 Ticks_test (GOLD-3.20,M1)       OnTick: time = 41 mcs 2020.02.04 13:09:10.720 Bid=1573.1 
2020.02.04 13:09:13.101 Ticks_test (GOLD-3.20,M1)       OnTick: time = 41 mcs 2020.02.04 13:09:00.328 Ask=1573.3 
OnTick - имеется ввиду CopyTicks из OnTick

¡La más rápida esSymbolInfoTick, pero esta función no pone volumen en el tick!

Ver para ayuda.

tick

[out]  Ссылка на структуру типа MqlTick, в которую будут помещены текущие цены и время последнего обновления цен.

Es decir, sólo el tiempo y el precio, pero no el volumen :(

 

En el caso de los instrumentos negociados en bolsa (especialmente los FORTS), no sólo importa el precio,

sino también el volumen de contratos a ese precio.

 

Intenté tomar el vaso por OnTick() - ¡enormes retrasos claramente visibles "a ojo"!

//+------------------------------------------------------------------+
//|                                                   Ticks_test.mq5 |
//|                                      Copyright 2019 prostotrader |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019 prostotrader"
#property link      "https://www.mql5.com"
#property version   "1.00"
//---
bool is_book;
MqlBookInfo BookInfo[];
int book_cnt;
struct MARKET_DATA
{
  double ask;
  long   ask_vol;
  double bid;
  long   bid_vol;
  double prev_ask;
  long   prev_ask_vol;
  double next_bid;
  long   next_bid_vol; 
};
MARKET_DATA m_data;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
  is_book = MarketBookAdd(Symbol());
  if(is_book == false)
  {
    Alert("No add book!");
    return(INIT_FAILED);
  }
  return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
  if(is_book == true) MarketBookRelease(Symbol());
}
//+------------------------------------------------------------------+
//| Expert OnTick function                                           |
//+------------------------------------------------------------------+
bool GetBook(const string a_symb, int &cnt)
{
  cnt = 0;
  if(MarketBookGet(a_symb, BookInfo) == true)//getBook )
  {
    m_data.ask = 0;
    m_data.ask_vol = 0;
    m_data.prev_ask = 0;
    m_data.prev_ask_vol = 0;
    m_data.bid = 0;
    m_data.bid_vol = 0;
    m_data.next_bid = 0;
    m_data.next_bid_vol = 0;
    cnt = ArraySize(BookInfo);
    if(cnt > 0)
    {
      for(int i = 0; i < cnt; i++)
      {
        if(BookInfo[i].type == BOOK_TYPE_BUY) //Стакан агрегирован, т.е от наибольшего Sell к наименьшему Buy
        {
          if((i + 1) <= (cnt- 1))
          {
            m_data.ask = BookInfo[i-1].price;
            m_data.ask_vol = BookInfo[i-1].volume;
            m_data.prev_ask = BookInfo[i-2].price;
            m_data.prev_ask_vol = BookInfo[i-2].volume;
            m_data.bid = BookInfo[i].price;
            m_data.bid_vol = BookInfo[i].volume;
            m_data.next_bid = BookInfo[i+1].price;
            m_data.next_bid_vol = BookInfo[i+1].volume;
            break;
          } else break;
        }
      }
      return(true);
    }
  }
  return(false);
}  
//+------------------------------------------------------------------+
//| Expert OnTick function                                           |
//+------------------------------------------------------------------+
void OnTick()
{
  if(GetBook(Symbol(), book_cnt) == true)
  {
    if(book_cnt >= 4)
    {
      Print("Prev Sell: ask = ", m_data.prev_ask, " volume = ",m_data.prev_ask_vol); 
      Print("Sell: ask = ", m_data.ask, " volume = ",m_data.ask_vol);
      Print("Buy: bid = ", m_data.bid, " volume = ",m_data.bid_vol);
      Print("Next Buy: bid = ", m_data.next_bid, " volume = ",m_data.next_bid_vol);
    }  
  }
}
//+------------------------------------------------------------------+
 

Lo tienes todo desordenado.

Ya escribí antes que las operaciones y el nivel 2 son suscripciones de datos diferentes, por lo que son manejadores de eventos diferentes.
Por eso, las operaciones deben llamarse desde OnTick, y las bandas de volumen desde OnBook.
Estás tratando de llamar a las operaciones desde los eventos OnBook y a las bandas desde OnTick. Pensando que OnBook será más rápido para los intercambios.
No será más rápido, creo que es un engaño comparar dos manejadores de eventos, cada uno dedicado a su propio flujo de datos.
Entiendo que todo son experimentos, pero sin entender la lógica de que hay dos flujos de datos (trades y Level2), confundirás infinitamente estos manejadores OnTick y OnBook.

Razón de la queja: