Asesores Expertos: Programación en MQL5 para tráders: códigos fuente del libro: Parte 6. - página 2

 
Stanislav Korotky #:
De todos modos, las órdenes, las operaciones y las posiciones no están relacionadas con los plazos. O ha entendido algo mal o su redacción es incorrecta.
Lo siento, creo que mi elección de la palabra es confusa por"marco de tiempo" me refiero a "rango de fechas". Digamos que quiero seleccionar Operaciones/Ordenes transaccionadas dentro de un rango de fechas dado como por ejemplo Operaciones desde 2025-10-01 00:00:00 hasta 2025-10-22 23:59:59.
 
pauldic #:
Lo siento, creo que mi elección de palabras es confusa, por"marco de tiempo" me refiero a "intervalo de fechas". Digamos que quiero seleccionar transacciones/pedidos realizados dentro de un intervalo de fechas determinado, por ejemplo, transacciones desde 2025-10-01 00:00:00 hasta 2025-10-22 23:59:59.

Si se quiere analizar un subrango de un histórico de operaciones, cuando es más eficiente solicitar sólo esta parte del histórico antes del filtrado, sin afectar al propio código de filtrado:

input datetime SubrangeFrom = 0;
input datetime SubrangeTo = 0;

...

{
   HistorySelect(SubrangeFrom, SubrangeTo);
   // ... el código del filtro va aquí tal cual
}

Si, por alguna razón, desea seleccionar un subrango (más estrecho) dentro del rango global que aplicó con HistorySelect, entonces todavía puede hacerlo en el código de filtrado así:

{
      // algunos de ellos van aquí

      // HistorySelect(0, LONG_MAX);
      // HistorySelectByPosition(PositionID);
      ...
      DealTuple deals[];
      if(SubrangeFrom != SubrangeTo && SubrangeFrom < SubrangeTo)
      {
         filter.let(DEAL_TIME, SubrangeFrom - 1, IS::GREATER).let(DEAL_TIME, SubrangeTo + 1, IS::LESS);
      }
      filter.let(DEAL_POSITION_ID, PositionID).select(deals, true);
      ...
}

La línea resaltada en amarillo establece 2 condiciones para el rango datetime [SubrangoDesde, SubrangoHasta] utilizando calificadores adicionales IS::MAYOR y IS::MENOR (por defecto, no se especifican en otras llamadas a let(), y entonces IS::IGUAL se utiliza normalmente para campos de valor único).

Sólo conozco una razón para aplicar el subfiltro por intervalo de fechas - es para el tiempo de preparación de las órdenes (ORDER_TIME_SETUP), porque HistorySelect se aplica a otra propiedad datetime de las órdenes - a saber, el tiempo de ejecución de la orden (ORDER_TIME_DONE). También puede ser interesante filtrar un subrango de órdenes activas (no en el histórico), si hay muchas.

Puede mirar el ejemplo de script MQL5/Scripts/MQL5Book/p6/TradeHistoryPrint.mq5, como punto de partida.
 
Stanislav Korotky #:

Si desea analizar un subrango de un historial de operaciones, cuando sea más eficiente solicitar sólo esta parte del historial antes del filtrado, sin afectar al propio código de filtrado:

Si, por alguna razón, desea seleccionar un subrango (más estrecho) dentro del rango global que aplicó con HistorySelect, entonces todavía puede hacerlo en el código de filtrado así:

La línea resaltada en amarillo establece 2 condiciones para el rango datetime [SubrangoDesde, SubrangoHasta] utilizando calificadores adicionales IS::MAYOR y IS::MENOR (por defecto, no se especifican en otras llamadas a let(), y entonces IS::IGUAL se utiliza normalmente para campos de valor único).

Sólo conozco una razón para aplicar el subfiltro por intervalo de fechas - es para el tiempo de preparación de las órdenes (ORDER_TIME_SETUP), porque HistorySelect se aplica a otra propiedad datetime de las órdenes - a saber, el tiempo de ejecución de la orden (ORDER_TIME_DONE). También puede ser interesante filtrar un subrango de órdenes activas (no en el histórico), si hay muchas.

Puedes mirar el script de ejemplo MQL5/Scripts/MQL5Book/p6/TradeHistoryPrint.mq5, como punto de partida.
@StanislavKorotky Gracias una vez más... Es un gran punto de partida para mí y voy a empezar a trabajar con él
 

Corrección de errores MQL5/Include/MQL5Book/TradeUtils.mqh.

   bool Equal(const double v1, const double v2)
   {
      return v1 == v2 || fabs(v1 - v2) < DBL_EPSILON * fmax(1.0, fmax(fabs(v1), fabs(v2)));
   }
Archivos adjuntos:
TradeUtils.mqh  12 kb
 
pauldic #:

Utilice elbotón CÓDIGO (Alt-S) al insertar código.

Un moderador ha formateado el código pegado incorrectamente. Normalmente, dicho código se elimina.

@StanislavKorotky Por favor, ¿puede ayudar a mirar en este error, creo que comenzó después de las actualizaciones MT5 porque sabía que el código funciona en los meses anteriores sin ninguna modificación.

parámetro tipo de conversión 'long[][2]' a 'string[][] &' no está permitido SymbolFilter.mqh 199 20

tipo de conversión de parámetro 'double[][2]' a 'string[][] &' no está permitido TradeFilter.mqh 332 20
la conversión del parámetro 'long[][2]' en 'string[][] &' no está permitida TradeFilter.mqh 163 17


Sospecho que el siguiente código ayudará a reproducir el problema:


Hola @Paul Dick

Prueba este https://www.mql5.com/es/code/57233 para ordenar matrices

Introsort (Introspective sort) using Function Pointers
Introsort (Introspective sort) using Function Pointers
  • 2025.03.18
  • www.mql5.com
A hybrid sorting algorithm that provide fast performance for sorting arrays of simple types, structures or object pointers.
 

Adjunto una versión actualizada del archivo de cálculo del criterio deoptimización personalizado basado en R2 - RSquared.mqh, en la que se ha corregido el cálculo para el caso de lotes variables.

Se ha mejorado notablemente la calidad de la estimación - a juzgar por la tabla de resultados de la optimización, se ha obtenido la combinación del factor de recuperación y los parámetros de Sharpe.

Ejemplo de utilización.

double OnTester()
{
   HistorySelect(0, LONG_MAX);
   
   #define  STAT_PROPS 5
   
   const ENUM_DEAL_PROPERTY_DOUBLE props[STAT_PROPS] =
   {
      DEAL_PROFIT, DEAL_SWAP, DEAL_COMMISSION, DEAL_FEE, DEAL_VOLUME
   };
   double expenses[][STAT_PROPS];
   ulong tickets[]; // usado aquí sólo para coincidir con el prototipo 'select', pero útil para depuración
   
   DealFilter filter;
   filter.let(DEAL_TYPE, (1 << DEAL_TYPE_BUY) | (1 << DEAL_TYPE_SELL), IS::OR_BITWISE)
      .let(DEAL_ENTRY, (1 << DEAL_ENTRY_OUT) | (1 << DEAL_ENTRY_INOUT) | (1 << DEAL_ENTRY_OUT_BY), IS::OR_BITWISE)
      .select(props, tickets, expenses);

   const int n = ArraySize(tickets);
   
   double balance[];
   double volumes[]; // tener en cuenta los volúmenes comerciales para utilizar el criterio R2
   
   ArrayResize(balance, n + 1);
   balance[0] = 0;
   ArrayResize(volumes, n + 1);
   volumes[0] = 0;
   
   for(int i = 0; i < n; ++i)
   {
      double result = 0;
      for(int j = 0; j < STAT_PROPS - 1; ++j)
      {
         result += expenses[i][j];
      }
      // utilizar los volúmenes como modelo - más inversiones - más beneficios esperados
      volumes[i + 1] = expenses[i][STAT_PROPS - 1] + volumes[i];
      balance[i + 1] = result + balance[i];
   }
   
   const double r2 = RSquaredTest(balance, volumes);
   
   #undef  STAT_PROPS
   
   return r2 * 100;
}
Archivos adjuntos:
RSquared.mqh  4 kb
 

Recientemente he estado aprendiendo Frame y he probado su código, FrameTransfer.mq5. Esta línea está lanzando un error en el compilador MT5 actual. Por favor verifíquelo: #property tester_set "FrameTransfer.set" (extensión de archivo tester set inválida, '*.set' esperado FrameTransfer.mq5)

Debe cambiarse así para que compile correctamente: #property tester_set "\Presets\FrameTransfer.set"

Incluso `#property tester_set "/Presets/FrameTransfer.set"` fallará.

Tal vez usted podría modificar la descripción en el libro de algoritmos:


 
hini #property tester_set "FrameTransfer.set" (extensión de archivo tester set inválida, se espera '*.set' FrameTransfer.mq5)

Para que la compilación tenga éxito, debe cambiarse de la siguiente manera: #property tester_set "\Presets\\FrameTransfer.set"

Incluso `#property tester_set "/Presets/FrameTransfer.set"` fallará.

Tal vez usted podría cambiar la descripción en el libro de algoritmos:


Esto es un error obvio del compilador - da el error: "invalid tester set file extension, '*.set' expected" al código:

#property tester_set "FrameTransfer.set"

donde el archivo tiene la extensión requerida. La ruta de ubicación del archivo no tiene nada que ver.

El error existe desde hace mucho tiempo, desde al menos 2024. Por qué MQ no se afana en arreglarlo, no lo sé.

En cuanto a las ediciones del libro, no son necesarias en este caso, pero en cualquier caso el libro está ahora totalmente bajo el control de MQ.

 
Stanislav Korotky control de MQ.
Confirmado y reportado. A ver si se arregla.
 
Stanislav Korotky #:

Este es un error obvio del compilador - da el error: "extensión de archivo tester set inválida, se espera '*.set'" al código:

Gracias, ¡arreglado!

Para permanecer en su versión de MetaEditor agregue cero al final del nombre de archivo: "myset.set\0"