Bibliotecas: MT4Orders - página 86

 
¡¡¡Muchas gracias!!! Esto es super AWESOME
 
A veces es necesario utilizar un ticket cerrado para encontrar su posición en el historial de operaciones.
// Devuelve la posición del ticket en la tabla de pedidos históricos.
int OrderSelectPos( const long Ticket = -1 )
{
#ifdef  MT4ORDERS_ORDERS_SORT
  #ifdef __MQL5__
    #ifdef __VIRTUAL__
      if (!VIRTUAL::GetHandle())
    #endif // #ifdef __VIRTUAL__
    
    return(-1);  
  #endif // #ifdef __MQL5__ 
#else // #ifdef MT4ORDERS_ORDERS_SORT
  #ifdef __VIRTUAL__
    if (VIRTUAL::GetHandle())
      return(-1);  
  #endif // #ifdef __VIRTUAL__ 
#endif // #ifdef MT4ORDERS_ORDERS_SORT #else

  int Pos = -1;
  
  if (::OrderSelect(Ticket, SELECT_BY_TICKET, MODE_HISTORY) && ::OrderCloseTime())
  {
    static int PrevHistoryTotal = 0;
    static CHashMap<long, int> Tickets;
        
    const long SearchTicket = (::OrderType() <= OP_SELL) ? ::OrderTicket() : -::OrderTicket();    
    const int Total = ::OrdersHistoryTotal();
    
    while (PrevHistoryTotal < Total)
    {
      if (::OrderSelect(PrevHistoryTotal, SELECT_BY_POS, MODE_HISTORY))        
      {
        const long NewTicket = (::OrderType() <= OP_SELL) ? ::OrderTicket() : -::OrderTicket();
        
        if (NewTicket == SearchTicket)
          Pos = PrevHistoryTotal;
          
        Tickets.Add(NewTicket, PrevHistoryTotal);       
      }
      
      PrevHistoryTotal++;      
    }
    
    if ((Pos == -1) && !Tickets.TryGetValue(SearchTicket, Pos))
      Pos = -1;
  }
  
  return(Pos);
}


Compruébelo.

void OnStart()
{  
  long Tickets[];
  
  // Corrección.
  for (uint i = ArrayResize(Tickets, OrdersHistoryTotal()); (bool)i--;)
    if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
    {
      Tickets[i] = OrderTicket();
      
      if (OrderSelectPos(OrderTicket()) != i)
        Print(i);
    }

  const ulong StartTime = GetMicrosecondCount();

  // Rendimiento.
  for (uint i = ArraySize(Tickets); (bool)i--;)
    if (OrderSelectPos(Tickets[i]) == -1)
      Print(i);
      
  Print(DoubleToString((double)(GetMicrosecondCount() - StartTime) / ArraySize(Tickets), 2) + " mcs/unit.");
}


Resultado.

1.62 mcs/unit.
 

Con un gran número de operaciones/órdenes de MT5 en modo ByPass (que utilizo, por ejemplo, en CustomReport), el primer acceso al historial puede tardar mucho tiempo.

#define  MT4ORDERS_BYPASS_MAXTIME 1000000 // Tiempo máximo (en µs) de espera para la sincronización del entorno comercial 
#include <MT4Orders.mqh>

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

void OnStart()
{  
  for (int i = 0; i < 3; i++)
  {
    const ulong StartTime = GetMicrosecondCount();
    PRINT(OrdersHistoryTotal());
    PRINT(GetMicrosecondCount() - StartTime);
  }
  
  PRINT(HistoryDealsTotal());
  PRINT(HistoryOrdersTotal());
}
OrdersHistoryTotal() = 235627
GetMicrosecondCount() - StartTime = 14831029

HistoryDealsTotal() = 259381
HistoryOrdersTotal() = 619850

¡14 segundos!


Resultó que los frenos provienen de la función ArrayCopy.


Tal edición en Include\fxsaber\TradesID\ByPass.mqh

  bool IsPosDeal( const ulong Ticket )
  {
    bool Res = true;

    const ulong PositionID = ::HistoryDealGetInteger(Ticket, DEAL_POSITION_ID);

    if (PositionID)
    {
      static ulong Deals[];
// .....

  bool IsPosOrder( const ulong Ticket )
  {
    bool Res = true;

    const ulong PositionID = ::HistoryOrderGetInteger(Ticket, ORDER_POSITION_ID);

    if (PositionID)
    {
      const long TicketTime = ::HistoryOrderGetInteger(Ticket, ORDER_TIME_DONE_MSC);

      static ulong OldOrders[];
// .....

aumenta el rendimiento en 4,5 veces - ~3 segundos.

OrdersHistoryTotal() = 235627
GetMicrosecondCount() - StartTime = 3307875


Un claro ejemplo de que el trabajo frecuente con matrices debe hacerse con prudencia. En este caso, static permite no asignar memoria para un array en ArrayCopy cada vez. Y obtenemos un incremento múltiple del rendimiento en una tarea real, que se puede sentir a simple vista.

Проверь своего брокера!
Проверь своего брокера!
  • 2021.11.12
  • www.mql5.com
На просторах интернета можно видеть довольно частые сценарии торговли. Управляющий ПАММ-счетом набрал инвесторов. Хорошо торговал, но с какого-то момента прибыльность сильно уменьшилась, вплоть до
 
fxsaber #:

Con un gran número de operaciones/órdenes de MT5 en modo ByPass (que utilizo, por ejemplo, en CustomReport), el primer acceso al historial puede tardar mucho tiempo.

El ByPass.mqh actualizado permitió acelerar este procedimiento 15 veces en las pruebas.
 

Hola autor, al utilizar la función OrderSendAsync, me di cuenta de que MT4ORDERS::LastTradeResult.retcode es igual a TRADE_RETCODE_DONE . Sin embargo, en su código, se comprueba si MT4ORDERS::LastTradeResult.retcode == TRADE_RETCODE_PLACED. ¿Podría ser esto un error, o es mi malentendido?

#define  RETURN_ASYNC(A) return((A) && ::OrderSendAsync(MT4ORDERS::LastTradeRequest, MT4ORDERS::LastTradeResult) &&                        \
                               (MT4ORDERS::LastTradeResult.retcode == TRADE_RETCODE_PLACED) ? MT4ORDERS::LastTradeResult.request_id : 0);
 
hini #:

al utilizar la función OrderSendAsync, me di cuenta de que MT4ORDERS::LastTradeResult.retcode es igual a TRADE_RETCODE_DONE

¿Nombre del servidor?
 
fxsaber #:
¿Nombre del servidor?
Me olvidé de mencionar que estoy usando el probador MT5. No debería tener nada que ver con el servidor, ¿verdad?
 
hini #:
Me olvidé de mencionar que estoy usando el probador MT5. No debería tener nada que ver con el servidor, ¿verdad?
En el trading en vivo, MT4ORDERS::LastTradeResult.retcode == TRADE_RETCODE_PLACED es correcto, mientras que en el tester de MT5 es TRADE_RETCODE_DONE . Este fue mi error.
 
hini #:
Me olvidé de mencionar que estoy usando el probador MT5. No debería tener nada que ver con el servidor, ¿verdad?

En el Tester, para la primera ejecución exitosa de MT5-OrderSend/OrderSendAsync, MqlTradeResult.request_id == 0.

Considero que este comportamiento es un descuido por parte de MQ, ya que el request_id debería empezar por uno.


Esta es una de las razones por las que MT4Orders no implementa OrderSendAsync para Tester. Hay otra razón menos buena(del libro).

Advertencia. En Tester, la funciónOrderSendAsync funciona comoOrderSend. Esto dificulta la depuración del procesamiento retardado de peticiones asíncronas.
Учебник по MQL5: Автоматизация торговли / Создание экспертов / Отправка торгового запроса: OrderSend и OrderSendAsync
Учебник по MQL5: Автоматизация торговли / Создание экспертов / Отправка торгового запроса: OrderSend и OrderSendAsync
  • www.mql5.com
Для выполнения торговых операций MQL5 API предоставляет две функции: OrderSend и OrderSendAsync . Они, также как и OrderCheck , выполняют в...
 
fxsaber #:

En el Probador, para la primera ejecución exitosa de MT5-OrderSend/OrderSendAsync, siempre es MqlTradeResult.request_id == 0.

Considero que este comportamiento es un fallo por parte de MQ, ya que el request_id debería empezar por uno.


Esta es una de las razones por las que MT4Orders no implementa OrderSendAsync para Tester. Hay otra razón menos buena(del libro).

¡Gracias por la información adicional!