Sistemi Esperti: MQL5 Programming for Traders – Source Codes from the Book. Parte 6

 

MQL5 Programming for Traders – Source Codes from the Book. Parte 6:

Nella sesta parte di "MQL5 Programming for Traders ", studieremo un componente chiave del linguaggio MQL5 – l'automazione del trading. Inizieremo con una descrizione delle entità fondamentali, come le specifiche degli strumenti finanziari e le impostazioni del conto di trading. Questi sono i prerequisiti per creare Expert Advisor che funzionino correttamente.

MQL5 Programming for Traders – Source Codes from the Book. Parte 6

Autore: MetaQuotes

 
Grande
 

Utilizzare ilpulsante CODICE (Alt-S) quando si inserisce il codice.

Un moderatore ha formattato il codice incollato in modo errato. Di solito, tale codice viene rimosso.

@StanislavKorotky Per favore, potete aiutarmi a esaminare questo errore, credo sia iniziato dopo gli aggiornamenti di MT5 perché sapevo che il codice funzionava nei mesi precedenti senza alcuna modifica.

parameter convertion type 'long[][2]' to 'string[][] &' is not allowed SymbolFilter.mqh 199 20

il tipo di conversione dei parametri 'double[][2]' in 'string[][] &' non è consentito TradeFilter.mqh 332 20
la conversione del tipo di parametro 'long[][2]' in 'string[][] &' non è consentita TradeFilter.mqh 163 17


Sospetto che il codice seguente possa aiutare a replicare il problema:

void printSymbols() {
   SymbolFilter f;                      // oggetto filtro
   string symbols[];                    // array per i nomi 
   long permissions[][2];               // array per i dati (valori delle proprietà)
   
   // elenco delle proprietà del simbolo richieste
   ENUM_SYMBOL_INFO_INTEGER modes[] = {
      SYMBOL_TRADE_MODE,
      SYMBOL_ORDER_MODE
   };
   
   // applicare il filtro, ottenere gli array con i risultati
   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) {
         // visualizzare le descrizioni dei bit e dei numeri "così come sono".
         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 Per favore, puoi aiutarmi a esaminare questo errore, credo che sia iniziato dopo gli aggiornamenti di MT5 perché sapevo che il codice funzionava nei mesi precedenti senza alcuna modifica.

parameter convertion type 'long[][2]' to 'string[][] &' is not allowed SymbolFilter.mqh 199 20
il tipo di conversione dei parametri 'double[][2]' in 'string[][] &' non è consentito TradeFilter.mqh 332 20
la conversione del tipo di parametro 'long[][2]' in 'string[][] &' non è consentita TradeFilter.mqh 163 17


Sospetto che il codice seguente possa aiutare a replicare il problema:


Si prega di trovare le linee:

   // abbiamo bisogno di questo sovraccarico perché ArraySort integrato
   // non supporta gli array di stringhe
   void ArraySort(string &s[][]) const
   {
      QuickSortTm<string> qt(s);
   }

nei file di intestazione SymbolFilter.mqh e TradeFilter.mqh e aggiungere il seguente sovraccarico del metodo accanto ad essi:

   // abbiamo bisogno di questo sovraccarico perché ArraySort integrato
   // non supporta gli array di stringhe
   void ArraySort(string &s[][]) const
   {
      QuickSortTm<string> qt(s);
   }
   
   template<typename T>
   void ArraySort(T &s[][]) const
   {
      ::ArraySort(s);
   }
PS. Questa domanda non sembra correlata all'articolo.
 
Stanislav Korotky #:

Trovate le linee:

nei file di intestazione SymbolFilter.mqh e TradeFilter.mqh e aggiungere il seguente sovraccarico del metodo accanto ad essi:

PS. Questa domanda non sembra correlata all'articolo.

Grazie per la risposta rapida, dopo aver effettuato l'aggiornamento, ho ricevuto altri errori:

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..

Ho notato che chiamare direttamente il QuickSortTm generico invece dell'ArraySort risolve temporaneamente il problema, anche se non credo che sia la soluzione ottimale.

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

Grazie per la risposta rapida, dopo aver effettuato l'aggiornamento, ho ricevuto altri errori che dicono:

È strano, dopo la correzione suggerita sopra ho compilato ed eseguito questo script /MQL5/Scripts/MQL5Book/p6/SymbolFilterTradeMode.mq5 con successo sulla build 5346. Non hai mostrato il tuo codice sorgente.
 
Stanislav Korotky #:
È strano, dopo la correzione suggerita sopra ho compilato ed eseguito questo script /MQL5/Scripts/MQL5Book/p6/SymbolFilterTradeMode.mq5 con successo sulla build 5346. Non hai mostrato il tuo codice sorgente.
Perdonami per aver omesso il mio codice sorgente, quindi sono tornato alla correzione da te suggerita in modo da ottenere nuovamente gli errori e sembra che queste parti del mio codice siano quelle che portano all'errore secondo il log
Sto eseguendo la versione 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]);
   }
}


Sul lato, vedo spesso questi messaggi:

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
File:
log.txt  34 kb
 
pauldic #:
Perdonami per aver omesso la mia fonte, quindi sono tornato alla tua correzione suggerita in modo da ottenere nuovamente gli errori e sembra che queste parti del mio codice siano le parti che portano all'errore secondo il log

Sul lato, vedo spesso questi messaggi:

Mi è sfuggito che la lettera T era già usata come typename del modello di classe (è strano che il compilatore non abbia prodotto un errore in questo caso), quindi cambiando T con qualsiasi altra lettera libera andrà bene, per esempio X:

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

Per quanto riguarda il primo avviso, ecco una spiegazione tratta dal forum (che vi ho fornito in precedenza):

Forum sul trading, sui sistemi di trading automatizzati e sulla verifica delle strategie di trading

Esperti: Programmazione MQL5 per trader - Codici sorgente dal libro. Parte 7

Stanislav Korotky, 2025.06.14 16:26

Questo è solo un avvertimento causato dal fatto che la corrispondente enumerazione incorporata di MQL5 ha un vuoto nelle costanti che normalmente sono assegnate consecutivamente. Questa lacuna si verifica perché MQL5 è in continua evoluzione e alcune costanti possono diventare obsolete e quindi essere eliminate. È possibile modificare il codice sorgente per evitare tali avvisi.

E per quanto riguarda la memoria persa, temo che ci sia un'omissione nel vostro codice sorgente personalizzato, il libro non mostra queste cose. Dovreste fornire un codice di prova completo per riprodurre il problema.

PS. È più efficiente eseguire una singola selezione per tutte le proprietà di interesse:

   // ESEMPIO: richiesta di profitto, simbolo, ticket per le posizioni
   // per numero magico specifico, ordinato per profitto
   
   #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: Credo che i moderatori dovrebbero spostare tutte le domande e le risposte sul libro (a partire da #41) in un thread appropriato, ad esempio qui - https://www.mql5.com/en/forum/459067.

Experts: MQL5 Programming for Traders – Source Codes from the Book. Part 6
Experts: MQL5 Programming for Traders – Source Codes from the Book. Part 6
  • 2023.12.15
  • www.mql5.com
MQL5 Programming for Traders – Source Codes from the Book. Part 6 : Author: MetaQuotes...
 
Stanislav Korotky #:

Mi è sfuggito che la lettera T era già usata come template typename della classe (è strano che il compilatore non abbia prodotto un errore in questo caso), quindi cambiare T con qualsiasi altra lettera libera andrà bene, per esempio X:

Per quanto riguarda il primo avviso, ecco una spiegazione tratta dai forum (che vi ho fornito in precedenza):

Per quanto riguarda la memoria persa, temo che ci sia un'omissione nel vostro codice sorgente personalizzato, il libro non mostrava queste cose. Dovreste fornire un codice di prova completo per riprodurre il problema.

PS. È più efficiente eseguire una singola selezione per tutte le proprietà di interesse:



NB: Credo che i moderatori dovrebbero spostare tutte le domande e le risposte sul libro (a partire dal #41) in un thread appropriato, ad esempio qui - https://www.mql5.com/en/forum/459067.

Grazie mille per la piccola modifica T -> X che ha fatto la magia. E grazie ancora per il suggerimento alla mia domanda precedente (avevo dimenticato di averla fatta prima) e il tuo promemoria mi ha aiutato a vedere l'aggiornamento di toyjson3.mqh che mi era sfuggito in precedenza e per il "select" am farò le correzioni.

Credo che tu abbia ragione sulla perdita, penso di avere già un'idea da dove proviene.

Grazie mille fratello.
 
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); // Filtrare per tempo
   Print("\nFound:  ", ArraySize(data), " Deals\nTIME, SYMBOL, TICKET, TYPE, VOLUME, PRICE, COMMISSION, PROFIT");
   ArrayPrint(data);
}

@StanislavKorotky
Sono in grado di accedere alle transazioni e agli ordini e con questo codice, ma non sono riuscito a capire come accedere allo stesso per un timeframe specifico. Per favore, puoi guidarmi su qualche documento o esempio su come fare lo stesso per un periodo di tempo specificato

 
pauldic #:

Sono in grado di accedere alle transazioni e agli ordini con questo codice, ma non sono riuscito a capire come accedere allo stesso per un timeframe specifico. Per favore, potete guidarmi su qualche documento o esempio su come fare lo stesso per un periodo di tempo specifico?

Gli ordini, le operazioni e le posizioni non sono comunque legati ai timeframe. O hai frainteso qualcosa o la tua formulazione non è corretta.