MT5 y la velocidad en acción - página 2

 
fxsaber:

Por favor, dé un diagrama-código rudimentario para esta idea. A primera vista parece un completo malentendido.

Durante la ejecución de la función OnMain no hay forma de conocer el estado de la cola real actual. La única solución para hacer esto es un programa espía, como se indica en el enlace.

En su forma más simple:

OnXXX( параметры )
{
        запомнить параметры (поместить в очередь)
        OnMain();
}
On2XX( параметры )
{
/*вычисления*/
        поменять приоритет обработки событий (если нужно)
/*вычисления*/
        промежуточный return (если нужно) 
/*вычисления*/
}
void OnMain()
{
        прочитать приоритет обработки событий
        для каждой группы событий
                извлечь параметры из очереди
                OnTradeXXX( параметры )
                удалить событие из очереди
}

Sólo hay que cambiar el enfoque de los propios cálculos (hacer la vuelta intermedia con la frecuencia que requiera la tarea). Pero si es difícil, considera en el 1er paso que OnMain no existe para ti (mueves el código principal no en OnMain, sino en On2XX), respectivamente, en OnMain no necesitas aprender nada

 
A100:

Se están haciendo muletas en la dirección equivocada:

Deje las funciones OnXXX sólo copiando eventos (parámetros) en la cola y llamando a la función principal OnMain. Mueve todo su código para duplicar las funciones de On2XX. Y llame a estas funciones duplicadas On2XX desde el OnMain en la secuencia que necesite, pasándoles a su vez los datos de las colas como parámetros.

A continuación, ejecute las mediciones y mostrar la ganancia de velocidad, y entonces usted puede sugerir para complementar MQL con la funcionalidad adecuada. Pero, ¿por qué añadir, si ya lo has hecho todo tú aquí y ahora?

No es eso lo que estás escribiendo.
El problema es que la funcionalidad de rellenar los campos en las variables de entrada de la función "OntaredeTransaction" no se corresponde con la descripción dada en la Ayuda, para peor:
es decir, muchos campos no se rellenan en las llamadas e incluso en la llamada final de TRADE_TRANSACTION_HISTORY_ADD.
Por lo tanto, todos los comerciantes están agonizando aquí para determinar de alguna manera estos parámetros que faltan en el momento de la llegada.
Hubo muchas discusiones aquí, basta con hacer una búsqueda en el foro - la pobre funcionalidad de "OntaredeTransaction" causa gastos adicionales tanto en tiempo como "carga" a los comerciantes con el tiempo extra dedicado al desarrollo de un código que funcione adecuadamente (es decir, enormes pérdidas de tiempo y una ineficacia colosal a nivel de la comunidad).
Las respuestas actuales de los desarrolladores como "Si tiene un símbolo de ejecución de mercado, tendrá un valor de precio cero; debería ser así" (Enlace).(Link) - esto es UNNORMAL, una vez más -
falta de valores exhaustivos en la última llamada a la función conduce a un montón de trabajo extra.

Новая версия платформы MetaTrader 5 build 2450: Сервис "Подписки", улучшения в интерфейсе и удобные функции в MetaEditor
Новая версия платформы MetaTrader 5 build 2450: Сервис "Подписки", улучшения в интерфейсе и удобные функции в MetaEditor
  • 2020.05.18
  • www.mql5.com
В пятницу 22 мая 2020 года будет выпущена обновленная версия платформы MetaTrader 5...
 
fxsaber:

HistorySelect.


Esta es una característica increíblemente cara. Y, por desgracia, ninguna cantidad de caché puede hacer que su velocidad sea aceptable ahora.


Por ejemplo, en los EA de campo de batalla es importante trabajar con datos reales. En particular, que los ticks de Market Watch y CopyTicks no estén desactualizados si es posible.

Para ello, existen mecanismos no muy buenos, pero obligados, para comprobar la pertinencia de los datos de precios actuales. Una parte de este mecanismo consiste en detectar situaciones en las que una operación sobre un símbolo ha pasado más tarde del último tick. Esto no ocurre raramente, por lo que es importante saber si la garrapata actual está actualizada o no.


Para esta detección, es necesario poder acceder al historial de ofertas recientes. Se hace utilizando el HistorySelect de la siguiente manera esquemática.


Desgraciadamente, esa llamada de HistorySelect tarda entre 5 y 30 milisegundos (lo he medido yo mismo en Release-EX5). Cuando el Asesor Experto hace varias de estas actualizaciones en OnTick (debería hacerse después de cualquier pausa, por ejemplo, después de cada OrderSend), entonces todo se vuelve insanamente caro/largo. HistorySelect puede consumir colectivamente varios segundos en un solo OnTick.


Queridos desarrolladores, ¿por qué es tan caro? Esta función puede ejecutarse instantáneamente con una implementación adecuada.

¿Tienes pruebas de que "una llamada a HistorySelect dura entre 5 y 30 milisegundos"?

Si he entendido bien tu idea, el código de prueba debería ser así:

void OnStart()
  {
   MqlTick Tick;
   SymbolInfoTick(_Symbol, Tick);
   ulong start=GetMicrosecondCount();
   for(int i=0; i<100000; i++)
     {
      HistorySelect(Tick.time, INT_MAX);
     }
   ulong end=GetMicrosecondCount()-start;
   Print("100000 HistorySelect = ",DoubleToString(end/1000.0,2)," ms");
  }

Así es como funcionan las consultas 100000:

100000 HistorySelect = 141.63 ms
 
Anton:

¿Tienes pruebas de que "una llamada a HistorySelect dura entre 5 y 30 milisegundos"?

Si he entendido bien lo que dices, el código de prueba debería ser así:

Así es como funcionan las 100.000 consultas:

¿Y una pregunta? No me sorprendería que el compilador, al optimizar, hiciera precisamente eso))
 
Anton:

¿Tienes pruebas de que "una llamada a HistorySelect dura entre 5 y 30 milisegundos"?

Si he entendido bien lo que dices, el código de prueba debería ser así:

Así es como funcionan las 100.000 consultas:

Ejecutando su script.

        100000 HistorySelect = 19493.96 ms


Lanza otra secuencia de comandos.

#define  PRINT(A) Print(#A + " = " + (string)(A))

void OnStart()
{
  if (HistorySelect(0, INT_MAX))
  {
    PRINT(HistoryDealsTotal());
    PRINT(HistoryOrdersTotal());
  }
}


HistoryDealsTotal() = 17828
HistoryOrdersTotal() = 22142


Cuenta de batalla normal. No es HFT.


Por cierto, tu script mostró que HistorySelect recalcula todo cada vez. Y los parámetros de entrada no cambiaron, la tabla del historial no se actualizó, no se llamaron otras funciones de HistorySelect.

 
fxsaber:

Ejecutando su script.

Entonces se necesitan detalles.

Mi prueba se ejecutaba en el no más rápido "Intel Xeon E5-2630 v4 @ 2.20GHz" con muchos otros procesos en el fondo.

El historial de mi cuenta de prueba muestra 31315 órdenes más o menos uniformes desde 2009, incluyendo 8 órdenes para hoy.

Tal vez, usted tenía algún script o Asesor Experto corriendo al mismo tiempo causando una carga drástica de las bases de datos del terminal. Pruébalo en un terminal "limpio".

Prueba más informativa:

void OnStart()
  {
   MqlTick Tick;
   SymbolInfoTick(_Symbol, Tick);
//---   
   ulong start=GetMicrosecondCount();
   int count=100000;
   for(int i=0; i<count; i++)
     {
      HistorySelect(Tick.time, INT_MAX);
     }
   ulong end=GetMicrosecondCount()-start;

   Print(count," HistorySelect = ",DoubleToString(end/1000.0,2)," ms");
   Print("Selected = ",HistoryOrdersTotal());
//---   
   Tick.time=(Tick.time/86400)*86400;
   
   start=GetMicrosecondCount();
   count=1000;
   for(int i=0; i<count; i++)
     {
      HistorySelect(Tick.time, INT_MAX);
     }
   end=GetMicrosecondCount()-start;

   Print(count," HistorySelect = ",DoubleToString(end/1000.0,2)," ms");
   Print("Selected = ",HistoryOrdersTotal());
//---   
   HistorySelect(0, INT_MAX);
   Print("Selected = ",HistoryOrdersTotal());
  }

Tres carreras:

2020.05.29 13:53:14.281 TestHistorySelect (EURUSD,H1)   100000 HistorySelect = 141.76 ms
2020.05.29 13:53:14.281 TestHistorySelect (EURUSD,H1)   Selected = 0
2020.05.29 13:53:14.284 TestHistorySelect (EURUSD,H1)   1000 HistorySelect = 2.82 ms
2020.05.29 13:53:14.284 TestHistorySelect (EURUSD,H1)   Selected = 8
2020.05.29 13:53:15.566 TestHistorySelect (EURUSD,H1)   Selected = 31315
2020.05.29 13:53:16.930 TestHistorySelect (EURUSD,H1)   100000 HistorySelect = 138.30 ms
2020.05.29 13:53:16.930 TestHistorySelect (EURUSD,H1)   Selected = 0
2020.05.29 13:53:16.933 TestHistorySelect (EURUSD,H1)   1000 HistorySelect = 2.61 ms
2020.05.29 13:53:16.933 TestHistorySelect (EURUSD,H1)   Selected = 8
2020.05.29 13:53:18.176 TestHistorySelect (EURUSD,H1)   Selected = 31315
2020.05.29 13:53:22.217 TestHistorySelect (EURUSD,H1)   100000 HistorySelect = 142.94 ms
2020.05.29 13:53:22.217 TestHistorySelect (EURUSD,H1)   Selected = 0
2020.05.29 13:53:22.220 TestHistorySelect (EURUSD,H1)   1000 HistorySelect = 2.57 ms
2020.05.29 13:53:22.220 TestHistorySelect (EURUSD,H1)   Selected = 8
2020.05.29 13:53:23.498 TestHistorySelect (EURUSD,H1)   Selected = 31315
 
Anton:

Entonces se necesitan detalles.

Mi prueba se ejecutaba en el no más rápido "Intel Xeon E5-2630 v4 @ 2.20GHz" con muchos otros procesos en el fondo.

La cuenta de prueba tenía 31315 órdenes en su historia más o menos uniforme desde 2009, incluyendo 8 órdenes para hoy.

Tal vez, usted tenía algún script o Asesor Experto corriendo al mismo tiempo causando una carga drástica de las bases de datos del terminal. Pruébalo en un terminal "limpio".

Terminal vacía en la misma cuenta y máquina.

        100000 HistorySelect = 19367.01 ms


En otras cuentas y terminales la misma imagen. Configuración.

2020.05.29 13:53:44.766 Terminal        ICMarkets - MetaTrader 5 x64 build 2453 started for International Capital Markets Pty Ltd.
2020.05.29 13:53:44.766 Terminal        Windows 7 Service Pack 1 build 7601, Intel Core i7-2700 K  @ 3.50 GHz, 6 / 15 Gb memory, 4 / 29 Gb disk, IE 11, Admin, GMT+2


Pido a los lectores que den sus resultados de este guión.

void OnStart()
{
  // https://www.mql5.com/ru/forum/342090/page2#comment_16607997
#define  PRINT(A) Print(#A + " = " + (string)(A))
  
  if (HistorySelect(0, INT_MAX))
  {
    PRINT(HistoryDealsTotal());
    PRINT(HistoryOrdersTotal());
  }

   // https://www.mql5.com/ru/forum/342090/page2#comment_16607922
   MqlTick Tick;
   SymbolInfoTick(_Symbol, Tick);
   ulong start=GetMicrosecondCount();
   for(int i=0; i<100000; i++)
     {
      HistorySelect(Tick.time, INT_MAX);
     }
   ulong end=GetMicrosecondCount()-start;
   Print("100000 HistorySelect = ",DoubleToString(end/1000.0,2)," ms");
}
 
Anton:

Una prueba más informativa:

Tres salidas:

        100000 HistorySelect = 18344.01 ms
        Selected = 0
        1000 HistorySelect = 602.77 ms
        Selected = 1169
        Selected = 22142
        100000 HistorySelect = 18331.15 ms
        Selected = 0
        1000 HistorySelect = 446.45 ms
        Selected = 1169
        Selected = 22142
        100000 HistorySelect = 18495.35 ms
        Selected = 0
        1000 HistorySelect = 549.40 ms
        Selected = 1169
        Selected = 22142

Terminal vacía 2460.


ZZY Corre con la cuenta vacía.

        100000 HistorySelect = 28.30 ms
        Selected = 0
        1000 HistorySelect = 0.28 ms
        Selected = 0
        Selected = 0


La velocidad parece estar fuertemente influenciada por el número de operaciones, no de órdenes.

 
fxsaber:

Terminal vacía en la misma cuenta y máquina.


En otras cuentas y terminales el mismo patrón. Configuración.


Pido a los lectores que citen los resultados de este guión.

No demuestra nada, pero el hecho de que con cada nueva ejecución (en un símbolo diferente), el tiempo aumenta - es alarmante...

2020.05.29 13:59:36.625 test1 (USDJPY,H1)       HistoryDealsTotal() = 1
2020.05.29 13:59:36.626 test1 (USDJPY,H1)       HistoryOrdersTotal() = 0
2020.05.29 13:59:36.642 test1 (USDJPY,H1)       100000 HistorySelect = 16.00 ms
2020.05.29 13:59:53.522 test1 (EURUSD,H1)       HistoryDealsTotal() = 1
2020.05.29 13:59:53.522 test1 (EURUSD,H1)       HistoryOrdersTotal() = 0
2020.05.29 13:59:53.546 test1 (EURUSD,H1)       100000 HistorySelect = 24.36 ms
2020.05.29 14:00:03.640 test1 (USDCHF,H1)       HistoryDealsTotal() = 1
2020.05.29 14:00:03.640 test1 (USDCHF,H1)       HistoryOrdersTotal() = 0
2020.05.29 14:00:03.669 test1 (USDCHF,H1)       100000 HistorySelect = 29.25 ms
2020.05.29 14:00:14.994 test1 (GBPUSD,H1)       HistoryDealsTotal() = 1
2020.05.29 14:00:14.994 test1 (GBPUSD,H1)       HistoryOrdersTotal() = 0
2020.05.29 14:00:15.026 test1 (GBPUSD,H1)       100000 HistorySelect = 31.76 ms
 
Сергей Таболин:

Necesidad de ejecutar en una cuenta con un largo historial de operaciones.