Tiki en tiempo real - página 4

 
Vladimir Mikhailov:

Un pequeño resumen de los experimentos con análisis de garrapatas.

1. el manejador OnTick se salta un número significativo de ticks.
Por lo tanto, si se quiere analizar la franja de tratos a través del tic tac entrante, no tiene sentido.
Con este enfoque, los resultados del algoritmo en el probador y los resultados de la negociación real serán diferentes.

Como alternativa, se puede analizar la franja de operaciones para un periodo seleccionado o una cantidad determinada de últimas operaciones obteniendo los ticks del historial mediante las funciones CopyTicks() o CopyTicksRange().
En este caso, los resultados de la prueba del algoritmo en el probador y los resultados comerciales reales son los mismos.
Las desventajas son el menor rendimiento del algoritmo.

Sí, el Asesor Experto puede perder ticks. Por lo tanto, es el indicador o CopyTicks.

¿Y la degradación del rendimiento debido a qué? Copie sólo el segmento requerido (que ha aparecido desde la última recuperación de datos con éxito).

 
Andrey Khatimlianskii:

¿Por qué recogerlos "en tiempo real" si se utiliza de todos modos CopyTicks?

Puedes copiar las garrapatas a la profundidad adecuada en el momento que quieras.

Andrew, lee el título del tema

Añadido

No puedes conseguir la profundidad correcta con CopyTicks(), ¡sólo son 2000 ticks!

 
prostotrader:

Andrei, lee el título del tema

¿Qué pasa con el hecho de que la tarea está originalmente establecida de forma incorrecta?

El análisis de los ticks en tiempo real es posible, pero es necesario utilizar el indicador o CopyTicks para evitar las brechas.


prostotrader:

Con CopyTicks() no se consigue la profundidad requerida, ¡sólo 2000 ticks!

No existe tal limitación, véase el ejemplo de la documentación:

Пример вывода
Si-12.16: received 11048387  ticks in 4937 ms
Last tick time = 2016.09.26 18:32:59.775 
First tick time = 2015.06.18 09:45:01.000 
Документация по MQL5: Доступ к таймсериям и индикаторам / CopyTicks
Документация по MQL5: Доступ к таймсериям и индикаторам / CopyTicks
  • www.mql5.com
[in]  Количество запрашиваемых тиков. Если параметры from и count не указаны, то в массив ticks_array[] будут записаны все доступные последние тики, но не более 2000. Первый вызов CopyTicks() инициирует синхронизацию базы тиков, хранящихся на жёстком диске по данному символу. Если тиков в локальной базе не хватает, то недостающие тики...
 
Andrey Khatimlianskii:

¿Qué pasa con el hecho de que la tarea está originalmente establecida de forma incorrecta?

El análisis de los ticks en tiempo real es posible, pero hay que utilizar un indicador o CopyTicks para asegurarse de que no hay omisiones.


No existe tal limitación, véase el ejemplo de la documentación:

1. No es necesariamente un indicador.

Si te refieres a la ayuda, que dice

En los Asesores Expertos y scripts, la función CopyTicks() puede esperar hasta 45 segundos....

Si lees hasta el final, dice

Velocidad de salida: el terminal almacena para cada carácter 4096 últimos ticks en la caché para un acceso rápido (65536 ticks para los caracteres con la pila en marcha ), las consultas a estos datos son las más rápidas.

El evento OnBookEvent() se activa cuando llega un nuevo paquete de ticks al terminal, por lo que

es posible recoger los ticks del Asesor Experto. Tome un ejemplo y compruébelo.

//+------------------------------------------------------------------+
//|                                                   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;
MqlTick ticks[];
ulong last_time, mem_time;
bool is_first;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
    is_first = false;
    is_book = MarketBookAdd(Symbol());
    int result = CopyTicks(Symbol(), ticks, COPY_TICKS_ALL, 0, 1);
    if(result > 0)
    {
      last_time = ticks[0].time_msc;
      is_first = true;
    }
    else
    {
      Alert("No start time!");
      return(INIT_FAILED);
    }   
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
    if(is_book == true) MarketBookRelease(Symbol());
   
  }
void PrintResult(const int cnt)
{
  if(cnt > 0)
  {
    for(int i= 0; i<cnt; i++)
    {
      if((ticks[i].flags&TICK_FLAG_ASK)==TICK_FLAG_ASK) Print("Tick is ", "TICK_FLAG_ASK"); else
      if((ticks[i].flags&TICK_FLAG_BID)==TICK_FLAG_BID) Print("Tick is ", "TICK_FLAG_BID"); else
      if((ticks[i].flags&TICK_FLAG_BUY)==TICK_FLAG_BUY) Print("Tick is ", "TICK_FLAG_BUY"); else
      if((ticks[i].flags&TICK_FLAG_LAST)==TICK_FLAG_LAST) Print("Tick is ", "TICK_FLAG_LAST"); else
      if((ticks[i].flags&TICK_FLAG_SELL)==TICK_FLAG_SELL) Print("Tick is ", "TICK_FLAG_SELL"); else
      if((ticks[i].flags&TICK_FLAG_VOLUME)==TICK_FLAG_VOLUME) Print("Tick is ", "TICK_FLAG_VOLUME"); else
      Print("Unknown flag is ", ticks[i].flags);
    }
  }
}  
//+------------------------------------------------------------------+
//| BookEvent function                                               |
//+------------------------------------------------------------------+
void OnBookEvent(const string &symbol)
  {
    if(Symbol() == symbol)
    {
      int result;
      if(is_first == true)
      {
        Print("First packet of ticks:");
        result = CopyTicks(Symbol(), ticks, COPY_TICKS_ALL, last_time, 0);
        if(result > 0)
       {
         PrintResult(result);
         is_first = false;
         mem_time = last_time;
         last_time = ticks[0].time_msc + 1;
       } 
      }
      else
      {
        result = CopyTicks(Symbol(), ticks, COPY_TICKS_ALL, mem_time, 0);
        if(result > 0)
        {
          for(int i= 0; i<result; i++)
          {
            if(ticks[i].time_msc == mem_time)
            {
              Print("Tick with old time:");
              if((ticks[i].flags&TICK_FLAG_ASK)==TICK_FLAG_ASK) Print("Tick is ", "TICK_FLAG_ASK"); else
              if((ticks[i].flags&TICK_FLAG_BID)==TICK_FLAG_BID) Print("Tick is ", "TICK_FLAG_BID"); else
              if((ticks[i].flags&TICK_FLAG_BUY)==TICK_FLAG_BUY) Print("Tick is ", "TICK_FLAG_BUY"); else
              if((ticks[i].flags&TICK_FLAG_LAST)==TICK_FLAG_LAST) Print("Tick is ", "TICK_FLAG_LAST"); else
              if((ticks[i].flags&TICK_FLAG_SELL)==TICK_FLAG_SELL) Print("Tick is ", "TICK_FLAG_SELL"); else
              if((ticks[i].flags&TICK_FLAG_VOLUME)==TICK_FLAG_VOLUME) Print("Tick is ", "TICK_FLAG_VOLUME"); else
              Print("Unknown flag is ", ticks[i].flags);
            }
          }
        }
        result = CopyTicks(Symbol(), ticks, COPY_TICKS_ALL, last_time, 0);
        if(result > 0)
        {
          Print("Ticks with new time:");
          PrintResult(result);
          mem_time = last_time;
          last_time = ticks[0].time_msc + 1;
        }
      }
    }
 }
//+------------------------------------------------------------------+


2. Existe esta limitación, compruébalo tú mismo(CopyTicksRange() no tiene ninguna limitación)


 
prostotrader:

1. No es necesariamente un indicador.

El evento OnBookEvent() se activa cuando llega un nuevo paquete de ticks al terminal, por lo que

es posible recoger los ticks del Asesor Experto. Tome un ejemplo y compruébelo.

OnBookEvent no garantiza que los ticks no se pierdan. Si hay cálculos pesados allí, habrá el mismo salto que en OnTick.

Y no importa de dónde copiar la profundidad necesaria de ticks a través de CopyTicks.


prostotrader:

2. Existe tal limitación, compruébelo usted mismo

Existe sólo para los parámetros 0, 0, lo que se menciona explícitamente en la ayuda:

Если параметры from и count не указаны, то в массив ticks_array[] будут записаны все доступные последние тики, но не более 2000.
 
Andrey Khatimlianskii:

OnBookEvent no garantiza que los ticks no se pierdan.

Repito

OnBookEvent() precisamente da esa garantía de que ha llegado un nuevo lote de garrapatas.

De la referencia:

Tasa de emisión: El terminal almacena para cada carácter 4096 últimos ticks en la caché de acceso rápido (para los caracterescon la pila en marcha, 65536 ticks), las consultas a estos datos sonlas más rápidas.

Fin de la cita----

Si el OnBookEvent no se activara, ¡todas las operaciones (de intercambio) en MT5 podrían tirarse a la basura!

Llegó un nuevo paquete de ticks - 100% disparó OnBookEvent, y el CopyTicks() muestra cuántos ticks llegaron,

¡datos ya almacenados en la caché y es el acceso más rápido!

Por eso el recolector de ticks puede ser implementado en tiempo real en el indicador y en el EA(cuando el mercado está en marcha).

Añadido por

Toma el código de arriba y compruébalo, luego argumenta...

 

El código del recolector de garrapatas es correcto, pero hay algunos errores de implementación.

y publicarlo más tarde.

Añadido

Recogida de todos los ticks en tiempo real de Expert Advisor

Por favor, utilice

//+------------------------------------------------------------------+
//|                                                   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;
MqlTick ticks[];
ulong last_time, mem_cnt;
bool is_first;
int t_cnt, result;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
  is_book = MarketBookAdd(Symbol());
  result = CopyTicks(Symbol(), ticks, COPY_TICKS_ALL, 0, 1);
  if(result > 0)
  {
    last_time = ulong(ticks[0].time_msc);
    is_first = true;
  }
  else
  {
    is_first = false;
    Alert("No start time!");
    return(INIT_FAILED);
  }   
  return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+ 
//| возвращает строковое описание тика                               | 
//+------------------------------------------------------------------+ 
string GetTickDescription(MqlTick &tick) 
  { 
   string res = string(tick.time) + "." +  string(tick.time_msc%1000); 
// 
   bool buy_tick = ((tick.flags&TICK_FLAG_BUY)==TICK_FLAG_BUY); 
   bool sell_tick = ((tick.flags&TICK_FLAG_SELL)==TICK_FLAG_SELL); 
   bool ask_tick = ((tick.flags&TICK_FLAG_ASK)==TICK_FLAG_ASK); 
   bool bid_tick = ((tick.flags&TICK_FLAG_BID)==TICK_FLAG_BID); 
   bool last_tick = ((tick.flags&TICK_FLAG_LAST)==TICK_FLAG_LAST); 
   bool volume_tick = ((tick.flags&TICK_FLAG_VOLUME)==TICK_FLAG_VOLUME); 
// 
   if((buy_tick== true) || (sell_tick == true)) 
   { 
     res = res + (buy_tick?StringFormat(" Buy Tick: Last=%G Volume=%d ",tick.last,tick.volume):""); 
     res = res + (sell_tick?StringFormat(" Sell Tick: Last=%G Volume=%d ",tick.last,tick.volume):""); 
     res = res + (ask_tick?StringFormat(" Ask=%G ",tick.ask):""); 
     res = res + (bid_tick?StringFormat(" Bid=%G ",tick.ask):""); 
   } 
   else 
   { 
     res = res + (ask_tick?StringFormat(" Ask=%G ",tick.ask):""); 
     res = res + (bid_tick?StringFormat(" Bid=%G ",tick.ask):""); 
     res = res + (last_tick?StringFormat(" Last=%G ",tick.last):""); 
     res = res + (volume_tick?StringFormat(" Volume=%d ",tick.volume):""); 
   } 
   return res; 
  } 
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
  if(is_book == true) MarketBookRelease(Symbol());
}
//+------------------------------------------------------------------+
//| BookEvent function                                               |
//+------------------------------------------------------------------+
//void OnTick()
void OnBookEvent(const string &symbol)
{
  if(Symbol() == symbol)
  {
    if(is_first == true)
    {
      result = CopyTicks(Symbol(), ticks, COPY_TICKS_ALL, last_time, 0);
      if(result > 0)
      {
        Print("First packet of ticks:");
        t_cnt = 0;
        for(int i= 0; i<result; i++)
        {
          if(ticks[i].time_msc == ticks[0].time_msc) t_cnt++;
          Print(GetTickDescription(ticks[i]));
        }
        is_first = false;
        last_time = ulong(ticks[0].time_msc);
      } 
    }
    else
    {
      result = CopyTicks(Symbol(), ticks, COPY_TICKS_ALL, last_time, 0);
      if(result > 0)
      {
        if(result > t_cnt)
        {
          mem_cnt = t_cnt;
          t_cnt = 0;
          for(int i= 0; i<(result - int(mem_cnt)); i++)
          {
            if(ticks[i].time_msc == ticks[0].time_msc) t_cnt++;
            Print(GetTickDescription(ticks[i]));
          } 
          if(last_time == ulong(ticks[0].time_msc))
          {
            t_cnt += int(mem_cnt);
          }
          else last_time = ulong(ticks[0].time_msc + 1);
        }
        else
        {
          t_cnt = 0;
          last_time++;
        }
      }
      else
      {
        t_cnt = 0;
        last_time++;
      }
    }
  }
}
//+------------------------------------------------------------------+
 

Para comparar cómo funciona el recolector de ticks, puedes hacer una cinta de todos los oficios de él en un punto

(sustituyendo COPY_TICKS_ALL por COPY_TICKS_TRADE en dos lugares) y compárelo con la cinta de operaciones,

incrustado en el cristal del instrumento.

Si el instrumento es muy líquido, las impresiones pueden ir con mucho retraso

 
prostotrader:
 if((ticks[i].flags&TICK_FLAG_ASK)==TICK_FLAG_ASK) {Print("Tick is ", "TICK_FLAG_ASK", " Tick time: ", ticks[i].time, ".", string(t_msc));} else
          if((ticks[i].flags&TICK_FLAG_BID)==TICK_FLAG_BID) {Print("Tick is ", "TICK_FLAG_BID", " Tick time: ", ticks[i].time,  ".", string(t_msc));} else
          if((ticks[i].flags&TICK_FLAG_BUY)==TICK_FLAG_BUY) {Print("Tick is ", "TICK_FLAG_BUY", " Tick time: ", ticks[i].time,  ".", string(t_msc));} else
          if((ticks[i].flags&TICK_FLAG_LAST)==TICK_FLAG_LAST) {Print("Tick is ", "TICK_FLAG_LAST", " Tick time: ", ticks[i].time,  ".", string(t_msc));} else
          if((ticks[i].flags&TICK_FLAG_SELL)==TICK_FLAG_SELL) {Print("Tick is ", "TICK_FLAG_SELL", " Tick time: ", ticks[i].time,  ".", string(t_msc));} else
          if((ticks[i].flags&TICK_FLAG_VOLUME)==TICK_FLAG_VOLUME) {Print("Tick is ", "TICK_FLAG_VOLUME", " Tick time: ", ticks[i].time,  ".", string(t_msc));} else

¿Las garrapatas no pueden tener más de una bandera a la vez?

 
prostotrader:

Repita

OnBookEvent() es exactamente el tipo de garantía de queha llegado un nuevo lote de garrapatas.


Pero, ¿significa eso que hay una garantía de que manejará TODOS los eventos OnBookEvent?