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

 

Programación en MQL5 para tráders: códigos fuente del libro: Parte 6.:

En la sexta parte del libro “Programación en MQL5 para tráders”, estudiaremos un componente clave del lenguaje MQL5: la automatización del trading. Comenzaremos con una descripción de las entidades principales, como las especificaciones de los instrumentos financieros y la configuración de la cuenta comercial, elementos necesarios para crear asesores correctos.

Programación en MQL5 para tráders: códigos fuente del libro: Parte 6.

Autor: MetaQuotes

 
Genial
 

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:

void printSymbols() {
   SymbolFilter f;                      // objeto filtro
   string symbols[];                    // array para nombres 
   long permissions[][2];               // array para los datos (valores de las propiedades)
   
   // lista de propiedades de los símbolos solicitados
   ENUM_SYMBOL_INFO_INTEGER modes[] = {
      SYMBOL_TRADE_MODE,
      SYMBOL_ORDER_MODE
   };
   
   // aplicar el filtro, obtener arrays con resultados
   f.let(SYMBOL_VISIBLE, true).select(true, modes, symbols, permissions);
   
   const int n = ArraySize(symbols);
   PrintFormat("===== Trade permissions for the symbols (%d) ===== ", n);
   for(int i = 0; i < n; ++i)  {
      Print(symbols[i] + ":");
      for(int j = 0; j < ArraySize(modes); ++j) {
         // mostrar descripciones de bits y números "tal cual"
         PrintFormat("  %s (%d)",
            SymbolMonitor::stringify(permissions[i][j], modes[j]),
            permissions[i][j]);
      }
   }
}

Stanislav Korotky - marketeer - Trader's profile
Stanislav Korotky - marketeer - Trader's profile
  • 2025.07.05
  • www.mql5.com
Trader's profile
 
pauldic #:
@StanislavKorotky Por favor, ¿puede ayudar a mirar en este error, creo que comenzó después de las actualizaciones de 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:


Por favor, encontrar las líneas:

   // necesitamos esta sobrecarga porque ArraySort incorporado
   // no admite matrices de cadenas
   void ArraySort(string &s[][]) const
   {
      QuickSortTm<string> qt(s);
   }

en los ficheros de cabecera SymbolFilter.mqh y TradeFilter.mqh, y añada la siguiente sobrecarga de método junto a ellas:

   // necesitamos esta sobrecarga porque ArraySort incorporado
   // no admite matrices de cadenas
   void ArraySort(string &s[][]) const
   {
      QuickSortTm<string> qt(s);
   }
   
   template<typename T>
   void ArraySort(T &s[][]) const
   {
      ::ArraySort(s);
   }
PS. Esta pregunta parece no estar relacionada con el artículo.
 
Stanislav Korotky #:

Por favor, encuentre las líneas:

en los ficheros de cabecera SymbolFilter.mqh y TradeFilter.mqh, y añada la siguiente sobrecarga de método junto a ellas:

PS. Esta pregunta parece no estar relacionada con el artículo.

Gracias por su rápida respuesta, después de hacer la actualización, tengo más errores diciendo:

parameter convertion type 'double[][2]' to 'string[][] &' is not allowed                TradeFilter.mqh 338     20
cannot convert parameter 'double[][2]' to 'OrderMonitor&[][]'                   TradeFilter.mqh 338     20
parameter convertion type 'double[][2]' to 'string[][] &' is not allowed                TradeFilter.mqh 338     20
cannot convert parameter 'double[][2]' to 'PositionMonitor&[][]'                        TradeFilter.mqh 338     20
parameter convertion type 'long[][2]' to 'string[][] &' is not allowed          TradeFilter.mqh 163     17
cannot convert parameter 'long[][2]' to 'OrderMonitor&[][]'                             TradeFilter.mqh 163     17
parameter convertion type 'long[][2]' to 'string[][] &' is not allowed          TradeFilter.mqh 163     17
cannot convert parameter 'long[][2]' to 'PositionMonitor&[][]'                  TradeFilter.mqh 163     17
etc..

Me he dado cuenta de que llamar directamente al QuickSortTm genérico en lugar de al ArraySort soluciona temporalmente el problema, aunque no creo que sea la solución óptima.

QuickSortTm<V> qt(array);
//ArraySort(array);
 
pauldic #:

Gracias por su rápida respuesta, después de hacer la actualización, tengo más errores diciendo:

Eso es extraño, después de la corrección sugerida anteriormente he compilado y ejecutado este script /MQL5/Scripts/MQL5Book/p6/SymbolFilterTradeMode.mq5 con éxito en build 5346. No has mostrado tu código fuente.
 
Stanislav Korotky #:
Es extraño, después de la corrección sugerida arriba he compilado y ejecutado este script /MQL5/Scripts/MQL5Book/p6/SymbolFilterTradeMode.mq5 con éxito en build 5346. Usted no mostró su código fuente.
Perdóname por omitir mi fuente, así que volví a su solución sugerida para que pueda obtener los errores de nuevo y parece que estas partes de mi código son las partes que conducen al error de acuerdo con el registro
Estoy corriendo en la versión 5 build 5327

void printActiveOrders() {
   
   OrderFilter filter;
   ENUM_ORDER_PROPERTY_DOUBLE properties[] = {ORDER_VOLUME_INITIAL, ORDER_PRICE_OPEN, ORDER_SL, ORDER_TP};
   double d[][4];
   ENUM_ORDER_TYPE types[];
   ulong tickets[], magics[];
   string symbols[], comments[];
   
   filter.select(properties, tickets, d);
   filter.select(ORDER_SYMBOL, tickets, symbols);
   filter.select(ORDER_COMMENT, tickets, comments);
   filter.select(ORDER_TYPE, tickets, types);
   filter.select(ORDER_MAGIC, tickets, magics);
   
   Print("Orders ..................  ", ArraySize(tickets));
   for (int i=0; i < ArraySize(tickets); i++) {
      Print(tickets[i], "\t", magics[i], "\t", symbols[i], "\t", EnumToString(types[i]), " \t", NormalizeDouble(d[i][0],3), "\t", d[i][1], " \t ",  d[i][2], " \t", d[i][3], "\t", comments[i]);
   }
}


void printPositions() {
   PositionFilter filter;
   
   ENUM_POSITION_PROPERTY_DOUBLE properties[] = {POSITION_PRICE_OPEN, POSITION_VOLUME, POSITION_SL, POSITION_TP, POSITION_PROFIT, POSITION_SWAP};
   
   ENUM_POSITION_TYPE types[];
   double d[][6];
   ulong tickets[], extIds[];
   string symbols[], comments[];
   
   filter.let(POSITION_MAGIC, sets.MagicNumber).select(properties, tickets, d);
   filter.select(POSITION_SYMBOL, tickets, symbols);
   filter.select(POSITION_COMMENT, tickets, comments);
   filter.select(POSITION_TYPE, tickets, types);
   filter.select(POSITION_IDENTIFIER, tickets, extIds);

   Print("Tickets\t  Parent Id\tSymbols \t Trade Type \t\t\t\t\t\tEntry \t Lots \t\t SL  \t\t\t TP \t\t\t\t Profit \tSwat \t\tComments");
   for ( int i =0; i < ArraySize(tickets); i++) {
      Print(tickets[i], "\t", extIds[i] == 0 ? "\t\t\t\t\t\t\t\t\t" : (string)extIds[i], "\t", symbols[i], "\t", EnumToString(types[i]), " \t", (string)NormalizeDouble(d[i][0],3), "\t", d[i][1], " \t ",  d[i][2], " \t", d[i][3], " \t", d[i][4], " \t ", d[i][5], "\t", comments[i]);
      //Print(tickets[i], "\t", extIds[i] == 0 ? "\t\t\t\t\t\t\t\t\t" : extIds[i], "\t", symbols[i], "\t", EnumToString(types[i]), " \t", NormalizeDouble(d[i][0],3), "\t", d[i][1], " \t ",  d[i][2], " \t", d[i][3], " \t", d[i][4], " \t ", d[i][5]);
   }
}


En el lado, a menudo veo estos mensajes:

This single line message always shows whenever I attach my EA to a chart:
Unresolved int value as enum: 8 for MonitorInterface<ENUM_POSITION_PROPERTY_INTEGER,ENUM_POSITION_PROPERTY_DOUBLE,ENUM_POSITION_PROPERTY_STRING>::TradeState


While these ones below shows when it is detached

2025.10.17 19:30:01.347 Deriv Trader (Volatility 10 (1 s) Index.0,M15)   8 leaked strings left
2025.10.17 19:30:01.347 Deriv Trader (Volatility 10 (1 s) Index.0,M15)   2 undeleted dynamic objects found:
2025.10.17 19:30:01.347 Deriv Trader (Volatility 10 (1 s) Index.0,M15)      1 object of class 'WebSocketConnectionHybi'
2025.10.17 19:30:01.347 Deriv Trader (Volatility 10 (1 s) Index.0,M15)      1 object of class 'MqlWebSocketTransport'
2025.10.17 19:30:01.347 Deriv Trader (Volatility 10 (1 s) Index.0,M15)   576 bytes of leaked memory found
Archivos adjuntos:
log.txt  34 kb
 
pauldic #:
Perdóname por omitir mi fuente, así que he revertido a su solución sugerida para que pueda obtener los errores de nuevo y parece que estas partes de mi código son las partes que conducen al error de acuerdo con el registro

En el lado, a menudo veo estos mensajes:

Pasé por alto que la letra T ya se usaba como typename de la plantilla de la clase (es extraño que el compilador no produjera un error en este caso), así que cambiando T por cualquier otra letra libre estará bien, por ejemplo X:

   template<typename X>
   void ArraySort(X &s[][]) const
   {
      ::ArraySort(s);
   }

En cuanto a la primera advertencia, aquí tienes una explicación de los foros (que te he dado antes):

Foro sobre trading, sistemas automáticos de trading y testeo de estrategias de trading

Expertos: Programación MQL5 para Traders - Códigos fuente del libro. Parte 7

Stanislav Korotky, 2025.06.14 16:26

Esto es sólo una advertencia causada por el hecho de que la correspondiente enumeración incorporada de MQL5 tiene una brecha en las constantes que normalmente se asignan consecutivamente. Este hueco se produce porque MQL5 cambia constantemente, y algunas constantes pueden quedar obsoletas y ser eliminadas. Puedes editar el código fuente para evitar estas advertencias.

Y acerca de la memoria filtrada - Me temo que hay una omisión en su código fuente personalizado, el libro no muestra tales cosas. Deberías proporcionar un código de prueba completo para reproducir el problema.

PS. Es más eficiente ejecutar una sola selección para todas las propiedades de su interés:

   // EJEMPLO: solicitar beneficio, símbolo, ticket para posiciones
   // por número mágico específico, ordenados por beneficio
   
   #include <MQL5Book/Tuples.mqh>
   #include <MQL5Book/PositionFilter.mqh>
   #property script_show_inputs
   
   input ulong Magic;
   
   void OnStart()
   {
      int props[] = {POSITION_PROFIT, POSITION_SYMBOL, POSITION_TICKET};
      Tuple3<double,string,ulong> tuples[];
      PositionFilter filter;
      filter.let(POSITION_MAGIC, Magic).select(props, tuples, true);
      ArrayPrint(tuples);
   }



NB: Creo que los moderadores deberían mover todas las preguntas y respuestas sobre el libro (a partir de #41) al hilo apropiado, por ejemplo, aquí - https://www.mql5.com/en/forum/459067.

 
Stanislav Korotky #:

Pasé por alto que la letra T ya se utilizaba como el typename de la plantilla de clase (es extraño que el compilador no produjera un error en este caso), por lo que cambiar T por cualquier otra letra libre estará bien, por ejemplo X:

En cuanto a la primera advertencia, aquí tienes una explicación de los foros (que te he dado antes):

Y acerca de la memoria filtrada - Me temo que hay una omisión en su código fuente personalizado, el libro no muestra tales cosas. Deberías proporcionar un código de prueba completo para reproducir el problema.

PS. Es más eficiente ejecutar una sola selección para todas las propiedades de su interés:



NB: Creo que los moderadores deberían mover todas las preguntas y respuestas sobre el libro (a partir de #41) al hilo apropiado, por ejemplo, aquí - https://www.mql5.com/en/forum/459067.

Muchas gracias por ese pequeño cambio T -> X hizo la magia. Y gracias de nuevo por el puntero a mi pregunta anterior (se me olvidó que he preguntado antes) y su recordatorio ayudó a ver la actualización en toyjson3.mqh que me perdí antes y para el 'select' soy voy a hacer las correcciones.

Creo que tienes razón acerca de la fuga, creo que ya tengo una idea de dónde viene.

Muchas gracias hermano.
 
void printActiveOrders() {
   int properties[] = {ORDER_VOLUME_INITIAL, ORDER_PRICE_OPEN, ORDER_SL, ORDER_TP, ORDER_TICKET, ORDER_MAGIC, ORDER_TYPE, ORDER_SYMBOL, ORDER_COMMENT};
   Tuple9<double,double,double,double,long,long,long,string,string> values[]; 
   OrderFilter filter;
   filter.select(properties, values);
   Print("\nFound:  ", ArraySize(values), " Orders\n{ORDER_VOLUME_INITIAL, ORDER_PRICE_OPEN, ORDER_SL, ORDER_TP, ORDER_TICKET, ORDER_MAGIC, ORDER_TYPE, ORDER_SYMBOL, ORDER_COMMENT}");
   ArrayPrint(values);
}

void printDeals() {
   DealFilter filter;    
   int properties[] = {DEAL_TIME, DEAL_SYMBOL, DEAL_TICKET, DEAL_TYPE, DEAL_VOLUME, DEAL_PRICE, DEAL_COMMISSION, DEAL_PROFIT};
   
   Tuple8<long,string,long,long,double,double,double,double> data[];   
   filter.select(properties, data, true); // Filtrar por tiempo
   Print("\nFound:  ", ArraySize(data), " Deals\nTIME, SYMBOL, TICKET, TYPE, VOLUME, PRICE, COMMISSION, PROFIT");
   ArrayPrint(data);
}

@StanislavKorotky
Estoy puede acceder a las operaciones y órdenes y con este código, pero no he sido capaz de encontrar la manera de acceder a la misma para un plazo específico. Por favor, me puede guiar en cualquier documento o muestra sobre cómo hacer lo mismo para un período de tiempo especificado

 
pauldic #:

Puedo acceder a las operaciones y órdenes con este código, pero no he sido capaz de averiguar cómo acceder a la misma para un plazo específico. Por favor, ¿puede guiarme en cualquier documento o muestra sobre cómo hacer lo mismo para un período de tiempo especificado?

Órdenes, operaciones, posiciones no están relacionadas con los plazos de todos modos. O ha entendido algo mal o su redacción es incorrecta.