Bibliotecas: MT4Orders - página 52

 
// Lista de cambios:
// 29.08.2020
// Fix: Se ha acelerado el trabajo con el historial de operaciones.
 

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

Bibliotecas: MT4Orders

fxsaber, 2020.08.29 00:03

2020.08.29 00:57:38.561 HistoryDealsTotal() = 9435
2020.08.29 00:57:38.813 2046.04.30 00:13:20
2020.08.29 00:57:38.813 Time[Bench(LastTimeMQL4)] = 252274
2020.08.29 00:57:38.820 2046.04.30 00:13:20
2020.08.29 00:57:38.820 Time[Bench(LastTimeMQL5)] = 7162

MQL5 puro fue 40 veces más rápido en esta tarea. ¡Aprenda MQL5!

Después de la actualización

        HistoryDealsTotal() = 9435
        2046.04.30 00:13:20
        Time[Bench(LastTimeMQL4)] = 16984
        2046.04.30 00:13:20
        Time[Bench(LastTimeMQL5)] = 4194

la velocidad en esta tarea ha aumentado 15 veces. No es una maniobra obvia se hizo después de estudiar las peculiaridades de las funciones HistorySelect.

 
Vergonzosa pérdida de MT4Orders a MQL5+SB.
// El script calcula la duración total de todas las posiciones cerradas.

#include <MT4Orders.mqh> // https://www.mql5.com/en/code/16006

// Devuelve la duración total de todas las posiciones cerradas.
int SumPositionsLengthMQL4( void )
{
  int Res = 0;
  
  for (int i = OrdersHistoryTotal() - 1; i >= 0; i--)
    if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY) && (OrderType() <= OP_SELL))
      Res += (int)(OrderCloseTime() - OrderOpenTime());
      
  return(Res);
}

#include <Generic\HashMap.mqh>

// Devuelve la duración total de todas las posiciones cerradas.
int SumPositionsLengthMQL5( void )
{
  int Res = 0;
  
  if (HistorySelect(0, INT_MAX))
  {
    CHashMap<ulong, ulong> DealsIn;  // Por PositionID devuelve DealIn.
    const int TotalDeals = HistoryDealsTotal();
    
    for (int i = 0; i < TotalDeals; i++)
    {
      const ulong TicketDeal = HistoryDealGetTicket(i);
      
      if (HistoryDealGetInteger(TicketDeal, DEAL_ENTRY) == DEAL_ENTRY_IN)
        DealsIn.Add(HistoryDealGetInteger(TicketDeal, DEAL_POSITION_ID), TicketDeal);
      else if (HistoryDealGetInteger(TicketDeal, DEAL_TYPE) <= DEAL_TYPE_SELL)
      {
        ulong TicketDealIn;
        
        if (DealsIn.TryGetValue(HistoryDealGetInteger(TicketDeal, DEAL_POSITION_ID), TicketDealIn))
          Res += (int)(HistoryDealGetInteger(TicketDeal, DEAL_TIME) - HistoryDealGetInteger(TicketDealIn, DEAL_TIME));        
      }        
    }
  }
      
  return(Res);
}

typedef int (*SumPositionsLength)( void );

void Bench( SumPositionsLength GetSumPositionsLength, const int Amount = 100 )
{
  long Tmp = 0;

  for (int i = 0; !IsStopped() && (i < Amount); i++)
    Tmp += GetSumPositionsLength();
  
  Print(Tmp);
}

#define  BENCH(A)                                                              \
{                                                                             \
  const ulong StartTime = GetMicrosecondCount();                              \
  A;                                                                          \
  Print("Time[" + #A + "] = " + (string)(GetMicrosecondCount() - StartTime)); \
}

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

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

  BENCH(Bench(SumPositionsLengthMQL4))
  BENCH(Bench(SumPositionsLengthMQL5))
}


Resultado.

        HistoryDealsTotal() = 9435
        3132754100
        Time[Bench(SumPositionsLengthMQL4)] = 871406
        3132754100
        Time[Bench(SumPositionsLengthMQL5)] = 109411


9 veces de diferencia en rendimiento. Aprenda MQL5.

 
fxsaber:

Resultado.

si no es mucha molestia, mostrar la diferencia entre 4k y MT5 ( terminales ) tiempo de ejecución de esta prueba

fxsaber:
vergonzosa perdida de MT4Orders ante MQL5+SB.

todo es relativo.... 5 líneas de código y una docena de líneas para MT5 - si se prueba la idea, a continuación, 5-acción es preferible, si se optimiza, entonces definitivamente la segunda opción

 
Igor Makanu:

si no es difícil, la diferencia entre 4 y MT5 ( terminales ) mostrar el tiempo de ejecución de esta prueba

MT4:

OrdersHistoryTotal() = 10291
Time[Bench(SumPositionsLengthMQL4)] = 56548

OrdersHistoryTotal() = 32020
Time[Bench(SumPositionsLengthMQL4)] = 186761

OrdersHistoryTotal() = 41815
Time[Bench(SumPositionsLengthMQL4)] = 249371


MT4x32 es más de cuatro veces más rápido que MT5x64, con el mismo número de posiciones cerradas.


ZЫ Probablemente, si te olvidas de ahorro de memoria en MT4Orders, guardando la historia en una matriz interna, entonces usted puede vencer MT4 también. Quizás debería hacerse así.

 
fxsaber:

MT4x32 es más de cuatro veces más rápida que MT5x64, con el mismo número de posiciones cerradas.

gracias, imho esto es un defecto de MK, pero tienen su propia visión para qué fines se debe utilizar un MT5 productiva.

fxsaber:

ZЫ Probablemente, si nos olvidamos de ahorro de memoria en MT4Orders, guardar la historia en una matriz interna, entonces podemos vencer MT4. Tal vez debería hacerse de esa manera.

Bueno, definitivamente se puede hacer con una opción de deshabilitar, al menos sus códigos siempre tenían tales características.

SZY: He probado tamaños de cadena para matar a la terminal, MT5 no es matable - siempre se las arregla para asignar memoria, creo que sólo en un probador en varios núcleos puede llegar a tener fallos al asignar grandes cantidades de memoria..... en general, usted necesita para poner a prueba


SZYZY: ¿nunca has comprobado cuanta memoria puede ocupar un array de estructuras con datos del historial comercial? Bueno, que la estructura pese 200 bytes, y el historial comercial 100K registros - resulta que 20 Mb... imho no es un problema en absoluto si no matas el terminal con tareas sofisticadas... en general, la prueba de todos modos - entonces será claro

 
Igor Makanu:

ZYZY: nunca lo he comprobado, ¿cuánta memoria puede ocupar una matriz de estructuras con datos del historial comercial?

        sizeof(MT4_ORDER) = 280
 

Parece que no puedo volver a ponerme en forma después de los días de verano...

fxsaber:

MT4:

MT4x32 es más de cuatro veces más rápida que MT5x64, con el mismo número de posiciones cerradas.

@fxsaber ¿podrías comprobar esta prueba en un entorno virtual? ( Virtual.mqh library )

 
Igor Makanu:

@fxsaber ¿podrías comprobar esta prueba en un entorno virtual? ( Biblioteca virtual.mqh )

#include <MT4Orders.mqh> // https://www.mql5.com/en/code/16006
#include <fxsaber\Virtual\Virtual.mqh>

// Devuelve la duración total de todas las posiciones cerradas.
int SumPositionsLengthMQL4( void )
{
  int Res = 0;
  
  for (int i = OrdersHistoryTotal() - 1; i >= 0; i--)
    if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY) && (OrderType() <= OP_SELL))
      Res += (int)(OrderCloseTime() - OrderOpenTime());
      
  return(Res);
}

typedef int (*SumPositionsLength)( void );

void Bench( SumPositionsLength GetSumPositionsLength, const int Amount = 100 )
{
  long Tmp = 0;

  for (int i = 0; !IsStopped() && (i < Amount); i++)
    Tmp += GetSumPositionsLength();
  
  Print(Tmp);
}

#define  BENCH(A)                                                              \
{                                                                             \
  const ulong StartTime = GetMicrosecondCount();                              \
  A;                                                                          \
  Print("Time[" + #A + "] = " + (string)(GetMicrosecondCount() - StartTime)); \
}

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

bool CreateHistory( const int Amount = 10000 )
{
  const bool Res = VIRTUAL::GetHandle();
  
  if (Res)
  {
    MqlTick Tick;
    
    _V(0, SymbolInfoTick(_Symbol, Tick));
    VIRTUAL::NewTick(Tick);
        
    for (int i = 0; i < Amount; i++)
    {      
      const TICKET_TYPE Ticket = OrderSend(_Symbol, OP_BUY, 1, Tick.ask, 0, 0, 0);
      
      Tick.time_msc += 1000;
      VIRTUAL::NewTick(Tick);
      
      OrderClose(Ticket, 1, Tick.bid, 0);            
    }
  }
  
  return(Res);
}

void OnStart()
{    
  PRINT(OrdersHistoryTotal());
  BENCH(Bench(SumPositionsLengthMQL4))
  
  VIRTUAL::SelectByHandle(VIRTUAL::Create());

  if (CreateHistory())  
  {
    PRINT(OrdersHistoryTotal());
    BENCH(Bench(SumPositionsLengthMQL4))
  }    
}


Resultado

// MT4
// Real:
VIRTUAL::VirtualOrdersHistoryTotal() = 10291
Time[Bench(SumPositionsLengthMQL4)] = 63774

// Virtual
VIRTUAL::VirtualOrdersHistoryTotal() = 10001
Time[Bench(SumPositionsLengthMQL4)] = 158218

// MT5
// Virtual
VIRTUAL::VirtualOrdersHistoryTotal() = 10001
Time[Bench(SumPositionsLengthMQL4)] = 43343

Puedes ver claramente que el historial de MT4 es tres veces más rápido que el entorno virtual en MT4. Al mismo tiempo en MT5 el mismo entorno virtual es cuatro veces más rápido que en MT4.

Es decir, el entorno virtual en MT5 es más rápido que el entorno real en MT4.

 
fxsaber:

Es decir, el entorno virtual de MT5 es más rápido que el entorno real de MT4.

... y el entorno real de órdenes de MT4 es más rápido que el entorno real de MT5.


¡Genial!

Tenía pensado operar en el entorno virtual y copiar las operaciones al real con el copiador, enseguida separas el algoritmo TS y los problemas de ejecución.

¡GRACIAS!