Librerías: TesterBenchmark - página 2

 

La idea es buena, pero la implementación no es correcta. Respondido en un mensaje privado:

fxsaber

¡Buenas tardes!

¿Podrías adaptar la lógica de trading a tu librería de trading para medir su rendimiento?

Foro sobre trading, sistemas automatizados de trading y testeo de estrategias de trading.

Bibliotecas: TesterBenchmark

fxsaber, 2017.08.15 19:31

Las plazas se han repartido de la siguiente manera

  1. MQL5 puro - 100% de rendimiento.
  2. MT4Orders.mqh - ~95% de rendimiento.
  3. SB Trade\Trade.mqh - ~84% de rendimiento.
SB comenzó a retrasarse menos.


ZЫ Me pregunto cuánto otras bibliotecas de comercio muestran...

¡Gracias!

No entiendo el rendimiento de qué? ¿La biblioteca? No funciona sin una estrategia. Se necesita una estrategia. Entonces tenemos que medir el rendimiento de la estrategia escrita con la ayuda de la biblioteca. Digamos que lo medimos, tenemos el resultado. ¿Con qué debemos compararlo? Necesitamos compararlo con la misma estrategia escrita en MQL puro. ¿Dónde obtener dos estrategias? Supongamos que tenemos esas dos estrategias. Pero, ¿dónde está la garantía de que son idénticos en términos de comercio de entradas / salidas entre sí? Supongamos que tenemos dos estrategias que están garantizados para ser idénticos entre sí, medimos sus velocidades. Las velocidades difieren sólo ligeramente. ¿Significa esto que el motor es eficiente? No, porque la estrategia no utiliza todas las capacidades del motor/MQL. De repente resulta que si usted solicita un largo historial de cotizaciones en otra estrategia, el motor empieza a trabajar muchas veces más lento. ¿Significa esto que el motor trabaja muchas veces más lento que el MQL puro? No, no significa que esta operación en concreto sea más lenta, pero digamos que si optimizas las clases que proporcionan datos, en nuevas versiones resultará que el motor trabajará más rápido que el sistema CopyXXX en la misma operación. Por eso lo principal no está claro en toda esta historia: qué somos y con qué nos comparamos.

 
Vasiliy Sokolov:

La idea es buena, pero la aplicación no es correcta. Respondido en un mensaje privado:

Aquí está el código del EA de prueba.

Contiene la misma lógica de negociación simple, pero en tres formas: pura MQL5, Trade.mqh y MT4Orders.mqh

Debido a esto es posible medir el rendimiento de cada variante con resultados de trading absolutamente idénticos.

Hasta ahora resulta que Trade.mqh está un 15% por detrás. Pero el enfoque de la medición del rendimiento es universal - se puede repetir la lógica de comercio en cualquier API de comercio. Aquí te sugiero que la escribas en tu biblia multiplataforma y midas la velocidad comparándola con MQL5 puro.

Gracias a estas mediciones, pude encontrar cuellos de botella en mi biblia y erradicarlos. Y a la hora de optimizar, esto a veces se traduce en horas ahorradas. En general, creo que es útil.


En tu asesor, sólo haces
#include <TesterBenchmark.mqh>

y no necesitas nada más. A continuación, seleccione Optimización y ejecútelo. Verás el rendimiento en los registros.

 

En su código del Asesor Experto de prueba, en cada tick, se realiza una búsqueda completa de operaciones en el historial, teniendo en cuenta su lote total y el beneficio, y se calcula el volumen de la operación actual:

if (HistorySelect(0, TimeCurrent()))
    {
      const int Total = HistoryDealsTotal() - 1;
      double SumProfit = 0;
      double SumLots = 0;
      for (int i = Total, Count = 0; (i >= 0) && (Count < AmountLastDeals); i--)
      {
        const ulong Ticket = HistoryDealGetTicket(i);

        if ((ENUM_DEAL_ENTRY)HistoryDealGetInteger(Ticket, DEAL_ENTRY) == DEAL_ENTRY_OUT)
        {
          SumProfit += HistoryDealGetDouble(Ticket, DEAL_PROFIT) * (AmountLastDeals - Count);
          SumLots += HistoryDealGetDouble(Ticket, DEAL_VOLUME) * (AmountLastDeals - Count);

          Count++;
        }
      }
      SumLots /= (AmountLastDeals * (1 + AmountLastDeals)) >> 1;
      ...
   }

Su Asesor Experto no hace nada más que cargar en HistorySelect. Por lo tanto, no puede ser un punto de referencia para medir el rendimiento de otra cosa que no sea el propio HistorySelect. Por lo tanto, sus declaraciones que cito:"¡MT5 es 4,4 veces más rápido que MT4!" debería al menos corregirse a HistorySelect en MT5 es 4,4 veces más rápido que un procedimiento similar e interno en MT4.

En cuanto a mi motor CStrategy, actualmente no permite trabajar con operaciones en absoluto, sino sólo con posiciones, por lo que el ejemplo tal y como está escrito ahora no se puede utilizar en CStrategy.

P.D. Observaré que en su ejemplo la velocidad de trabajo es igual a O(n). Y la única diferencia entre MT4 y MT5 en este caso es la velocidad de HistorySelect/HistoryOrderSelect. Naturalmente, CStrategy en tareas con complejidad O(n) utilizará llamadas básicas, en este caso HistorySelect y naturalmente, será un poco más lento que llamar directamente a HistorySelect. Pero cuando necesite llamar, digamos, a HistoryOrderSelect(ticket) - aquí todo puede ser mucho más interesante y en algunas tareas CStrategy romperá el acceso estándar al entorno, debido al acceso por diccionario y al almacenamiento de datos en la memoria del programa.

 
Vasiliy Sokolov:

En su código del Asesor Experto de prueba, en cada tick, se realiza una búsqueda completa de operaciones en el historial, teniendo en cuenta su lote total y el beneficio, y se calcula el volumen de la operación actual:

Su Asesor Experto no hace nada más que cargar en HistorySelect. Por lo tanto, no puede ser un punto de referencia para medir el rendimiento de otra cosa que no sea el propio HistorySelect. Por lo tanto, sus declaraciones que cito:"¡MT5 es 4,4 veces más rápido que MT4!" debería al menos corregirse a HistorySelect en MT5 es 4,4 veces más rápido que un procedimiento interno similar en MT4.

Has sacado conclusiones precipitadas. La pieza dada se ejecuta sólo en la apertura de una posición una vez cada intervalo-segundos. Es decir, muy raramente.

En cuanto a mi motor CStrategy, actualmente no permite trabajar con operaciones en absoluto, pero sólo con las posiciones, por lo que el ejemplo tal como está escrito ahora no se puede utilizar en CStrategy.

Aquí está el código MQL4 del EA de prueba OnTick, que también funciona sólo con posiciones.

if (!OrderSelect(0, SELECT_BY_POS))
{
  const int Total = OrdersHistoryTotal() - 1;

  double SumProfit = 0;
  double SumLots = 0;

  for (int i = Total, Count = 0; (i >= 0) && (Count < AmountLastDeals); i--)
    if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY) && (OrderType() <= OP_SELL))
    {
      SumProfit += OrderProfit() * (AmountLastDeals - Count);
      SumLots += OrderLots() * (AmountLastDeals - Count);

      Count++;
    }

  SumLots /= (AmountLastDeals * (1 + AmountLastDeals)) >> 1;

  const int Type = (Total >= 0) && OrderSelect(Total, SELECT_BY_POS, MODE_HISTORY) && (OrderType() == OP_BUY) ? OP_SELL : OP_BUY;

  OrderSend(_Symbol, Type, (SumProfit >= 0) ? Lots : CorrectLot(SumLots),
            SymbolInfoDouble(_Symbol, (Type == OP_BUY) ? SYMBOL_ASK : SYMBOL_BID), 0, 0, 0); // , NULL, 0, 0, 0, INT_MIN);
}
else if (TimeCurrent() - OrderOpenTime() >= Interval)
  OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 0);

No es difícil reescribir una lógica tan simple en su API, por supuesto. Pero si usted tiene una sugerencia para una mejor EA para analizar el rendimiento de la API de comercio (sólo el comercio, no series de tiempo, etc), estaré encantado de ver su versión de la lógica de comercio. Puedo reescribirlo rápidamente para MQL5 puro, MQL4 y Trade.mqh.


ZY Al iniciar un asesor de prueba elegir saldo = 1e7. Para tener siempre fondos suficientes para abrir una posición.

 
fxsaber:

Has sacado conclusiones precipitadas. La pieza dada se ejecuta sólo en la posición de apertura una vez cada Intervalo-segundos. Es decir, muy raramente.

Aquí está el código MQL4 de OnTick del Asesor Experto de prueba, que también funciona sólo con posiciones.

No es difícil reescribir una lógica tan simple en su API, por supuesto. Pero si usted tiene una sugerencia para una mejor EA para analizar el rendimiento de la API de comercio (sólo el comercio, no series de tiempo, etc), estaré encantado de ver su versión de la lógica de comercio. Puedo reescribirlo rápidamente para MQL5 puro, MQL4 y Trade.mqh.

Echa un vistazo de cerca a su código y dime lo que mide

if (!OrderSelect(0, SELECT_BY_POS))
{
  const int Total = OrdersHistoryTotal() - 1;

  double SumProfit = 0;
  double SumLots = 0;

  for (int i = Total, Count = 0; (i >= 0) && (Count < AmountLastDeals); i--)
    if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY) && (OrderType() <= OP_SELL))
    {
      SumProfit += OrderProfit() * (AmountLastDeals - Count);
      SumLots += OrderLots() * (AmountLastDeals - Count);

      Count++;
    }

  SumLots /= (AmountLastDeals * (1 + AmountLastDeals)) >> 1;

  const int Type = (Total >= 0) && OrderSelect(Total, SELECT_BY_POS, MODE_HISTORY) && (OrderType() == OP_BUY) ? OP_SELL : OP_BUY;

  OrderSend(_Symbol, Type, (SumProfit >= 0) ? Lots : CorrectLot(SumLots),
            SymbolInfoDouble(_Symbol, (Type == OP_BUY) ? SYMBOL_ASK : SYMBOL_BID), 0, 0, 0); // , NULL, 0, 0, 0, INT_MIN);
}
else if (TimeCurrent() - OrderOpenTime() >= Interval)
  OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 0);

Hay dos cuellos de botella aquí: el bucle for y el propio envío de la orden. ¿Quieres comparar donde el bucle for funciona más rápido? ¿En CTrade o en MQL puro? ¿Dónde es más rápido enviar una orden? ¿En CTrade o en OrderSend? Por supuesto que en OrderSend puro es más rápido, porque en CTrade se hacen muchas comprobaciones antes de enviar la orden. Pero, ¿qué conclusiones hay que sacar de esto?

 
Vasiliy Sokolov:

Echa un vistazo a tu código y dime qué mide

Aquí hay dos cuellos de botella: el bucle for y el envío real del pedido. ¿Quieres comparar dónde funciona más rápido el bucle for?

Por alguna razón no lo ves

fxsaber:

El trozo dado se ejecuta sólo al abrir una posición una vez cada Intervalo-segundos. Es decir, muy raramente.


Vasiliy Sokolov:

¿Dónde es más rápido enviar una orden? ¿En CTrade o en OrderSend? Por supuesto en puro OrderSend es más rápido, porque en CTrade se hacen muchas comprobaciones antes de enviar la orden. ¿Pero qué implicaciones tiene esto?

CTrade hace muchas menos comprobaciones que la misma MT4Orders. Las conclusiones son simples ahora - SB va a la zaga de MQL5 puro en un 16% y se puede acelerar con absoluta precisión. Y cualquiera que utilice CTrade pierde dinero extra en la Nube durante la Optimización y tiempo para la propia Optimización.

 

Sigues sin entender lo que hace tu código. Ejecuté el perfilador a propósito y en una hora hice 1800 operaciones con intervalos de 1 segundo. 99,66% del tiempo de ejecución OnTick es ocupado por dos funciones OrderSend:

¿Qué vas a optimizar? El 0,34% restante no tiene sentido. No puedes optimizar OrderSend.

De acuerdo. La parte más interesante. Pon #include <Trade\Trade.mqh> y mira lo que ha cambiado al usar la librería CTrade:


Ahora se tarda el 100% del tiempo en llamar a Trade.Buy/Sell y a Trade.PositionClose. Vamos a Trade.PositionClose y ta-da-mmmm:

Es decir, el 99,97% de las veces Trade.PositionClose toma el mismo OrderSend. Lo mismo ocurre con Trade.Buy y Trade.Sell.

Entonces, ¿qué vas a optimizar en SB? ¿Dónde está el objeto de la prueba? ¿Qué estás probando en general?

(Para aquellos que no entienden las cifras de perfiles, voy a explicar: 99,97% del tiempo de ejecución del programa se toma por el envío directo de órdenes a través de OrderSend, el 0,03% restante se toma por CTrade vinculante con los controles necesarios antes de enviar la orden. Es decir, el uso de un OOP competente introduce retrasos tan insignificantes que pueden despreciarse y considerarse iguales a cero. No es 0.03%, pero aún menos, porque la mayoría del tiempo de este 0.03% es tomado por chequeos obligatorios, los cuales deben ser implementados de una manera competente, ya sea en código procedimental o en algún otro lugar).

 
Vasiliy Sokolov:

Específicamente corrí el perfilador y en una hora estaba llegando a 1800 operaciones en intervalos de 1 segundo.

¿Qué tiene que ver el online con esto? Tiene que ver con el probador.

 
Andrey Khatimlianskii:

¿Qué tiene que ver Internet? Tiene que ver con el probador.

Si estamos hablando de MT5 y su probador de estrategias, el mismo 99% del tiempo (bueno, tal vez un poco menos) se gasta allí en recrear el entorno de negociación (de ahí las ejecuciones tan lentas en comparación con MT4). Y no hay razón para pensar que si OrderSend en la vida real tarda el 99,9% del tiempo, entonces en el probador de estrategias de repente funcionará dos órdenes de magnitud más rápido.
 
Vasiliy Sokolov:
Si estamos hablando de MT5 y su probador de estrategias, el mismo 99% del tiempo (bueno, tal vez un poco menos) se gasta allí en recrear el entorno de negociación (de ahí esas ejecuciones tan lentas en comparación con MT4). Y no hay razón para pensar que si OrderSend en la vida real tarda el 99,9% del tiempo, de repente funcionará dos órdenes de magnitud más rápido en el probador de estrategias.

Vasily, ¿estás hablando en serio de la conmensurabilidad de la velocidad de ejecución de OrderSend en el tester y en tiempo real?

Online es la más lenta porque envía información al servidor y espera respuesta, mientras que en el tester (si no incluyes el retardo, pero no venía a cuento) envía y espera instantáneamente.

La tarea de esta biblioteca es medir la velocidad del probador (en términos de funciones comerciales).