Bibliotecas: MT4Orders - página 82

 
elavr #:

No puedo ver si este problema de velocidad de prueba puede ser resuelto sin usar las características de lenguaje de MT5.

En los tres casos el resultado final es el mismo?
 
fxsaber #:
En los tres casos, ¿el resultado final es el mismo?

Sí, por supuesto.

Empezó a ocurrir después de otra actualización del terminal. No cambié su librería y compilé el bot en el terminal antiguo para que funcionara como antes.

 
elavr #:

Esto empezó a pasar después de otra actualización del terminal. No cambié su biblioteca y compilé el bot en el terminal antiguo para que funcionara como antes.

Investigué un poco.


Asesor Experto.

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

#define  VIRTUAL_SNAPSHOT_REFRESHTIME 1000
#include <fxsaber\Virtual\Virtual.mqh> // https://www.mql5.com/es/code/22577

input int inMod = 5;
input int inRange = 0;
input bool inVirtual = false;

const bool Init = inVirtual ? VIRTUAL::SelectByHandle(VIRTUAL::Create()) : false;;

#define  Bid SymbolInfoDouble(_Symbol, SYMBOL_BID)
#define  Ask SymbolInfoDouble(_Symbol, SYMBOL_ASK)

ulong lOnTester = 0;

void OnTick()
{  
  static int i = 0;
  
  VIRTUAL::NewTick();
  
  if (!(i++ % inMod))
    OrderClose(OrderSend(_Symbol, OP_BUY, 0.1, Ask, 0, 0, 0), 0.1, Bid, 0);
    
// VIRTUAL::Instantánea(); 
  lOnTester += LastCloseTimeMQL4() % 100;
  
// lOnTester += LastCloseTimeMQL5() % 100;
}

double OnTester()
{
  if (HistorySelect(0, INT_MAX))
    Print(HistoryDealsTotal());
  
  return((double)lOnTester);
}

En cada tick inMod se abre y cierra una posición. Y en cada tick se calcula el OrderCloseTime.

OnTester sirve como un criterio para comprobar la identidad de los resultados en diferentes configuraciones.


Funciones correspondientes del trabajo con el historial.

datetime LastCloseTimeMQL4()
{  
  datetime Res = 0;
  
  for (int i = OrdersHistoryTotal() - 1; i >= 0; i--)
    if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY) && (OrderType() <= OP_SELL))
    {
      Res = OrderCloseTime();
      
      break;
    }

  return(Res);
}

datetime LastCloseTimeMQL5()
{
  datetime Res = 0;
  
  if (HistorySelect(0, INT_MAX))
    for (int i = HistoryDealsTotal() - 1; i >= 0; i--)
    {
      const ulong Ticket = HistoryDealGetTicket(i);
      
      if (HistoryDealGetInteger(Ticket, DEAL_ENTRY) != DEAL_ENTRY_IN)
      {
        Res = (datetime)HistoryDealGetInteger(Ticket, DEAL_TIME);
        
        break;
      }
    }
    
  return(Res);
}

#define  MACROS(A, B)          \
  datetime A##_2()            \
  {                           \
    static datetime Res = 0;  \
    static int PrevTotal = 0; \
                              \
    const int Total = B;      \
                              \
    if (PrevTotal != Total)   \
    {                         \
      Res = A();              \
                              \
      PrevTotal = Total;      \
    }                         \
                              \
    return(Res);              \
  }

// LastCloseTimeMQL4_2
MACROS(LastCloseTimeMQL4, OrdersHistoryTotal())

// LastCloseTimeMQL5_2
MACROS(LastCloseTimeMQL5, HistorySelect(0, INT_MAX) ? HistoryDealsTotal() : 0)


Metodología.

Una sola ejecución en la configuración como en la fuente (inMod = 5).

2023.07.06 23:59:59   28179
final balance 99996992.20 pips
OnTester result 2761115
EURUSD,M1: 274413 ticks, 70443 bars generated. Environment synchronized in 0:00:00.021. Test passed in 0:00:03.712 (including ticks preprocessing 0:00:00.031).

28.000 transacciones, casi cuatro segundos. Dado que necesitamos medir el rendimiento en modo de optimización, todas las lecturas de rendimiento siguientes se realizaron de esta forma.

shortest pass 0:00:02.875, longest pass 0:00:03.094, average pass 0:00:02.919

Con recompilación obligatoria antes de la ejecución y sólo un Agente habilitado para la ejecución secuencial de pasadas.


Rendimiento.

Tabla de rendimiento (tiempo de ejecución en milisegundos) para b3815 y b2958.

Construcción MT5 LastCloseTimeMQL4 LastCloseTimeMQL5 LastCloseTimeMQL4_2 LastCloseTimeMQL4+VIRTUAL::Instantánea LastCloseTimeMQL4+VirtualTester
b3815 2875 113 708 732 45
b2958 2718 107 675 715 50

MT4Orders del 20.07.2022 se utilizó en todas partes.


Conclusiones.

  • OrderSelect es lento. Esto se debe al hecho de que OrderSelect calcula absolutamente todos los datos de la orden seleccionada de la historia (OrderPrint es libre). Esta es una gran combinación de funciones HistoryOrderGet* y HistoryDealGet*, manejando cualquier complejidad de situaciones de mercado y un gran número de trampas. Echa un vistazo a MT4ORDERS::GetHistoryPositionData(). Se trata de una única función para el Terminal y para el Tester, pero está especialmente acelerada para el Tester, ya que muchos pitfalls del Terminal no están presentes en el Tester. Ejemplos de configuraciones: una, dos, tres.
  • En consecuencia, es necesario lograr una reducción de las llamadas OrderSelect para las órdenes históricas. Esto se puede conseguir de las formas indicadas en las tres columnas de la derecha de la tabla.
  • El trabajo más rápido (por delante del MQL5 puro) es operar en un entorno virtual. Yo recomendaría optimizar en el entorno virtual, y pasadas individuales - fuera de él.
  • El rendimiento de Tester b2958 y b3815 es casi idéntica.
  • No recomiendo atar la lógica del TS para el Probador a la historia de comercio con referencia a ella. Por ejemplo, puede conocer el OrderCloseTime de su TS sin hacer referencia al historial.
 
elavr #:

La duración de la prueba es de aproximadamente 1 hora y 10 minutos.

Retrocedo la biblioteca a la versión __MT4ORDERS__ "2020.01.12" y compilo el Asesor Experto en la compilación 2980.

El tiempo de funcionamiento del Asesor Experto con la función get_last_order_close_time es de unos 20 minutos.

Pruebe el código anterior en una versión antigua de la biblioteca (yo no la tengo).

Si hay una diferencia en el rendimiento, enviarlo a PM.

 
¡Muchas gracias! Lo comprobaré la semana que viene.
 

¿Es posible que haya una fuga de memoria o un uso de memoria mayor del necesario? ¿Quizás en this.tickets o en this.amount (::ArrayResize) o quizás en algún otro lugar?

El tamaño de las matrices sólo se incrementa con el tiempo. ¿Es esto imprescindible? ¿Es posible vaciarlas o quizás no cargar todas las operaciones anteriores?

 
pcdeni #:

¿Es posible que haya una fuga de memoria o un uso de memoria mayor del necesario? ¿Quizás en this.tickets o en this.amount (::ArrayResize) o quizás en algún otro lugar?

El tamaño de las matrices sólo se incrementa con el tiempo. ¿Es esto imprescindible? ¿Es posible vaciarlas o quizás no cargar todas las operaciones anteriores?

La biblioteca no almacena completamente en caché los datos históricos. La falta de memoria es posible sólo en teoría, pero no en la práctica.

Escriba un script que ordene todo el historial de operaciones utilizando la librería y vea cuánta memoria se consume.

 
fxsaber #:

La biblioteca no almacena completamente en caché los datos del historial. Conseguir una escasez de memoria es posible sólo en teoría, pero no en la práctica.

Escriba un script que ordene todo el historial de operaciones utilizando la biblioteca y vea cuánta memoria se consume.

en pruebas de estrategia el ea esta usando 25 GB por core.

editar: es una prueba de marco de tiempo de 1 año, por lo que no mucho.
 
pcdeni #:

en pruebas de estrategia el ea esta usando 25 GB por core.

edit: es una prueba de marco de tiempo de 1 año, así que no mucho.

La biblioteca (MT4Orders.mqh) no consume esa cantidad de memoria. Puedes ejecutar, por ejemplo, este EA para verlo por ti mismo.

Lo más probable es que estés trabajando con indicadores de forma incorrecta: creas nuevos manejadores de indicadores, pero no borras los antiguos.

 
fxsaber #:

La librería (MT4Orders.mqh) no consume esa cantidad de memoria. Puedes ejecutar, por ejemplo, este EA para comprobarlo.

Lo más probable es que estés trabajando con indicadores de forma incorrecta: creas nuevos manejadores de indicadores, pero no borras los antiguos.

Yo no uso ningún indicador.

Aunque tienes razón, la librería no consume esa cantidad de memoria, sin embargo sí la utiliza:

HistorySelect(0,INT_MAX);

Según esta página:

https://www.mql5.com/es/articles/211

"El intento de manejar todo el histórico de operaciones, en la mayoría de los casos, es erróneo. Cuando el número de operaciones/órdenes procesadas ronda los miles y decenas de miles, el trabajo del programa se ralentiza drásticamente."

En caso de que haya más de 1M de operaciones, tu librería las almacena todas en un array.

Aprecio que hayas hecho esta libreria, puente entre mt4 y mt5, y que la hayas compartido con todo el mundo, no tratando de destrozarla. Sólo me parece lamentable que sólo hay un lugar en línea que describe cómo obtener valores de swap y comisión correctamente (dado que el corredor en realidad les proporciona), y está escrito de una manera tan ofuscado.

Orders, Positions and Deals in MetaTrader 5
Orders, Positions and Deals in MetaTrader 5
  • www.mql5.com
Creating a robust trading robot cannot be done without an understanding of the mechanisms of the MetaTrader 5 trading system. The client terminal receives the information about the positions, orders, and deals from the trading server. To handle this data properly using the MQL5, it's necessary to have a good understanding of the interaction between the MQL5-program and the client terminal.