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

 
Renat Fatkhullin:

El temporizador de milisegundos existe desde hace mucho tiempo: EventSetMillisecondTimer()

Estás completamente fuera de onda. Suponga que necesita abrir dos posiciones en OnTick. El primer OrderSend dura unos milisegundos. Después hay que hacer una foto instantánea. Y luego se debe llamar al segundo OrderSend.

Sólo OnTick puede ejecutarse durante cientos de milisegundos. Y sugieres que se haga un snapshot de OnTimer.

 
Renat Fatkhullin:

También hay problemas con la propia biblioteca de medición. Hay muchas cosas innecesarias, incluidos los gastos generales.

¡Discusiones en el estudio!

 
Renat Fatkhullin:

Aquí está mi código y el tiempo de ejecución estable: no hay cientos o miles de microsegundos en 20 gráficos en paralelo

¿Cuántos núcleos tiene y qué tipo de procesador? ¿i7-2600?

8 núcleos.

2020.10.06 02:27:59.464 Terminal        MetaTrader 5 x64 build 2630 started for MetaQuotes Software Corp.
2020.10.06 02:27:59.465 Terminal        Windows 10 build 19042, Intel Core i7-2700 K  @ 3.50 GHz, 7 / 15 Gb memory, 19 / 29 Gb disk, IE 11, Admin, GMT+3

¿Prueba de estrés oculta de nuevo con millones de peticiones en paralelo?

Te he dicho muchas veces que el asesor de combate. Se ha minimizado el número de llamadas en la medida de lo posible. En teoría (no lo he medido) hasta 10 llamadas por OnTick.


Sea más transparente. El hecho de que hayas publicado un par de simples llamadas _B no es una prueba de tus otras afirmaciones. Se olvida bruscamente del código y de la descripción real de las condiciones en cuanto hace afirmaciones extravagantes.

No necesitas imaginar nada en tu mente: cuenta y muestra lo que realmente llamas y pruebas. No un resultado arrancado de "ejecutó una prueba de estrés desconocida y espera una alerta para mostrar al mundo", sino exactamente el código completo de la prueba.

Voy a publicar los resultados del EA en vivo. Hay 70 archivos mqh allí, incluyendo WinAPI. Si realmente lo entiendes y no son sólo palabras, te daré el código fuente. Reproducirás los frenos muy rápidamente.

 
fxsaber:

Estás completamente fuera de onda. Digamos que necesita abrir dos posiciones en OnTick. El primer OrderSend dura unos milisegundos. Después hay que hacer una foto instantánea. Y luego se debe llamar al segundo OrderSend.

Sólo OnTick puede ejecutarse durante cientos de milisegundos. Y sugieres que se haga un snapshot de OnTimer.

Yo no he sugerido que se haga un chasquido, he respondido a una pregunta directa sobre el temporizador de milisegundos.

Está ahí, aunque en el probador actual se sigue disparando a 1 segundo. En el nuevo probador que estamos escribiendo, intentaremos cambiar esto.
 
fxsaber:

8 núcleos.

Muchas veces dijo asesor de combate. Se ha minimizado el número de llamadas en la medida de lo posible. En teoría (no lo he medido) hasta 10 llamadas por OnTick.


Voy a publicar los resultados del Asesor Experto. Hay 70 archivos mqh allí, incluyendo WinAPI. Si no te limitas a hablar de ello, sino que lo entiendes de verdad, te daré el código fuente. Tocarás los frenos muy rápidamente.

Lo resolveremos, danos el código fuente.
 
fxsaber:

¡Argumentos sobre la mesa!

Todo tu benchmark está sobrecargado de basura y de hecho aquí hay una versión limpia y comprensible (a diferencia de tu desorden de código) del mismo:


//--- benchmark macros
#define _B(_function,_alert_interval)               \
          {                                         \
           ulong _latency=GetMicrosecondCount();    \
           _function;                               \
           _latency=GetMicrosecondCount()-_latency; \
           if(_latency > _alert_interval)           \
              ::Alert("Time[" + __FILE__ + " " + (string)__LINE__ + " in " + __FUNCTION__+ ": " + #_function + "] = " + (string)_latency + " mсs"); \
          }



//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnTick()
  {
   MqlTick Tick;
   
   _B(SymbolInfoTick(_Symbol,Tick),0);
   _B(SymbolInfoTick(_Symbol,Tick),0);
  }

Cuáles son sus problemas:

  1. código ilegible

  2. Vinculación a una clase con muchos gastos generales

  3. el coste de almacenar 50 resultados en la pila
      static bool Set( const string Str )
      {
        if (BENCHMARK::Amount == BENCHMARK::ReserveSize)
          BENCHMARK::ReserveSize = ::ArrayResize(BENCHMARK::Bench, BENCHMARK::ReserveSize + BENCHMARK_RESERVE);
    
        BENCHMARK::Bench[BENCHMARK::Amount++].Set(Str);
    
        return(true);
      }
    
  4. tomando resultados - una sobrecarga sólida y basura en los enlaces de objetos
      static ulong Get( const uint AlertInterval = 0 )
      {
        const int Pos = BENCHMARK::Amount - 1;
        const ulong Res = (Pos < 0) ? 0 : BENCHMARK::Bench[Pos].Get();
    
        if (Pos >= 0)
        {
          if (AlertInterval && (Res > AlertInterval))
            ::Alert("Time[" + BENCHMARK::Bench[Pos].Str + "] = " + (string)Res + " mсs.");
    
          BENCHMARK::Amount = Pos;
        }
    
        return(Res);
      }
    


Espero que no hayas desactivado la optimización del código para las pruebas.

Me refiero al parámetro global Optimize=0 en metaeditor.ini

 
Renat Fatkhullin:

Todo tu benchmark está sobrecargado de basura y de hecho aquí tienes una versión limpia y comprensible (en contraste con tu desorden de código) del mismo:

Su versión está, por desgracia, en la fase inicial de comprensión de la conveniencia. Conveniente es cuando se puede hacer así.

Foro sobre comercio, sistemas de comercio automatizados y pruebas de estrategias

Bibliotecas: Punto de referencia

fxsaber, 2020.10.01 23:49

Ahora tratamos de averiguar dónde está el hipo en la variante estándar. Añadimos algunos símbolos al código fuente.

    for (long Chart = _B2(::ChartFirst()); (Chart != -1) && !Res; Chart = _B2(::ChartNext(Chart)))
      Res = (Chart != chartID) && _B2(::ChartGetInteger(Chart, CHART_IS_MAXIMIZED));

Y ver inmediatamente la razón.

2020.10.02 00:45:14.113 Alert: Time[Test9.mq5 36 in IsInvisible: ::ChartGetInteger(Chart,CHART_IS_MAXIMIZED)] = 878 mсs.
2020.10.02 00:45:14.114 Alert: Time[Test9.mq5 36 in IsInvisible: ::ChartGetInteger(Chart,CHART_IS_MAXIMIZED)] = 943 mсs.
2020.10.02 00:45:14.114 Alert: Time[Test9.mq5 36 in IsInvisible: ::ChartGetInteger(Chart,CHART_IS_MAXIMIZED)] = 297 mсs.
2020.10.02 00:45:14.116 Alert: Time[Test9.mq5 36 in IsInvisible: ::ChartGetInteger(Chart,CHART_IS_MAXIMIZED)] = 1787 mсs.
2020.10.02 00:45:14.116 Alert: Time[Test9.mq5 35 in IsInvisible: ::ChartNext(Chart)] = 2 mсs.
2020.10.02 00:45:14.117 Alert: Time[Test9.mq5 36 in IsInvisible: ::ChartGetInteger(Chart,CHART_IS_MAXIMIZED)] = 980 mсs.
2020.10.02 00:45:14.117 Alert: Time[Test9.mq5 35 in IsInvisible: ::ChartNext(Chart)] = 2 mсs.
2020.10.02 00:45:14.117 Alert: Time[Test9.mq5 36 in IsInvisible: ::ChartGetInteger(Chart,CHART_IS_MAXIMIZED)] = 59 mсs.
2020.10.02 00:45:14.118 Alert: Time[Test9.mq5 36 in IsInvisible: ::ChartGetInteger(Chart,CHART_IS_MAXIMIZED)] = 803 mсs.
2020.10.02 00:45:14.119 Alert: Time[Test9.mq5 36 in IsInvisible: ::ChartGetInteger(Chart,CHART_IS_MAXIMIZED)] = 1059 mсs.

CHART_IS_MAXIMIZED es demasiado lento para los gráficos de otros. ¡El informe de errores está listo! Fue muy fácil con la biblioteca.


¿Cuál es el problema?

  1. código ilegible

  2. entrar en una clase con mucha sobrecarga

  3. coste de almacenamiento de la pila de 50 resultados
  4. obtener resultados - una sobrecarga masiva y basura en los enlaces de objetos

La facilidad de uso anula los escasos gastos generales. Es miserable si se mira de cerca cómo se implementa. Por ejemplo, ArrayResize es una sobrecarga, por lo que su uso se minimiza.

Espero que no hayas desactivado la optimización del código para las pruebas.

Me refiero al parámetro global Optimize=0 en metaeditor.ini

No me interesan los modos lentos. Estoy mirando el rendimiento del EA de combate, prestando atención a la optimización algorítmica y la optimización del compilador también, por supuesto.

 
Renat Fatkhullin:

Todo tu benchmark está sobrecargado de basura y de hecho aquí tienes una versión limpia y comprensible (a diferencia de tu desorden de código) del mismo:

¿Cuál es tu problema?

  1. código ilegible

  2. vincularse a una clase con muchos gastos generales

  3. coste de almacenamiento de la pila de 50 resultados
  4. obtener resultados - una sobrecarga masiva y basura en los enlaces de objetos


Espero que no hayas desactivado la optimización del código para las pruebas.

Me refiero al parámetro global Optimize=0 en metaeditor.ini

Aquí está el estilo C, es simple y realmente libre de basura. Gracias por el ejemplo.

Uno de los profesores de lenguaje C recomendó mejor no utilizar el guión bajo _B en los nombres de usuario
Porque este prefijo es utilizado por los desarrolladores de bibliotecas, programas, etc.
Y para no tropezar con el solapamiento, recomendó mejor no utilizarlo.

¿En mql5 es posible superponer sus nombres?
¿O los nombres personalizados están completamente protegidos de los nombres MQ?

 
Roman:

Uno de los profesores de C recomendó no utilizar el guión bajo _B en los nombres de usuario
, porque este prefijo es utilizado por los desarrolladores de bibliotecas, software, etc.
Y para evitar solapamientos, recomendó no utilizarlo.

En C, los nombres que empiezan por "_" se utilizan como nombres de servicio, de sistema o especiales. En este caso, creo que es aceptable. Dado que esta función se utiliza para el mantenimiento y el examen del código.

 
Edgar Akhmadeev:

Los nombres que empiezan por "_" se utilizan en C como nombres de servicio, de sistema o especiales. En este caso - aceptable, creo. Dado que esta función se utiliza para el mantenimiento y el examen del código.

Esa es la cuestión, además de mql5, hay nombres de servicios MQ para desarrolladores.