Expert Advisors: MQL5 Programming for Traders – Quellcodes aus dem Buch. Teil 6

 

MQL5 Programming for Traders – Quellcodes aus dem Buch. Teil 6:

In Teil 6 von „MQL5 Programming for Traders“ werden wir eine Schlüsselkomponente der MQL5-Sprache untersuchen - die Automatisierung des Handels. Wir beginnen mit einer Beschreibung der grundlegenden Einheiten, wie z. B. der Spezifikationen für Finanzinstrumente und der Einstellungen für Handelskonten. Dies sind die Voraussetzungen für die Erstellung ordnungsgemäß funktionierender Expert Advisors.

MQL5 Programming for Traders – Quellcodes aus dem Buch. Teil 6

Autor: MetaQuotes

 
Großartig
 

Verwenden Sie dieCODE-Taste (Alt-S), wenn Sie Code einfügen.

Ein Moderator hat den falsch eingefügten Code formatiert. Normalerweise wird solcher Code entfernt.

@StanislavKorotky Bitte können Sie helfen, diesen Fehler zu untersuchen, ich glaube, es begann nach MT5-Updates, weil ich wusste, dass der Code in den vergangenen Monaten ohne Änderungen funktioniert.

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

Parameter conversion type 'double[][2]' to 'string[][] &' is not allowed TradeFilter.mqh 332 20
Parameter Konvertierung Typ 'long[][2]' in 'string[][] &' ist nicht erlaubt TradeFilter.mqh 163 17


Ich vermute, dass der folgende Code helfen wird, das Problem zu lösen:

void printSymbols() {
   SymbolFilter f;                      // Filterobjekt
   string symbols[];                    // Array für Namen 
   long permissions[][2];               // Array für Daten (Eigenschaftswerte)
   
   // Liste der gewünschten Symboleigenschaften
   ENUM_SYMBOL_INFO_INTEGER modes[] = {
      SYMBOL_TRADE_MODE,
      SYMBOL_ORDER_MODE
   };
   
   // Filter anwenden, Arrays mit Ergebnissen erhalten
   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) {
         // Anzeige der Bit- und Zahlenbeschreibungen "wie sie sind"
         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 Bitte können Sie helfen, diesen Fehler zu untersuchen, ich glaube, es begann nach MT5 Updates, weil ich wusste, dass der Code in den vergangenen Monaten ohne Änderungen funktioniert.

parameter convertion type 'long[][2]' to 'string[][] &' is not allowed SymbolFilter.mqh 199 20
Parameter conversion type 'double[][2]' to 'string[][] &' is not allowed TradeFilter.mqh 332 20
Parameter Konvertierung Typ 'long[][2]' in 'string[][] &' ist nicht erlaubt TradeFilter.mqh 163 17


Ich vermute, dass der folgende Code helfen wird, das Problem zu lösen:


Bitte finden Sie die Zeilen:

   // wir brauchen diese Überladung, weil die eingebaute ArraySort
   // unterstützt keine Arrays von Strings
   void ArraySort(string &s[][]) const
   {
      QuickSortTm<string> qt(s);
   }

in den Header-Dateien SymbolFilter.mqh und TradeFilter.mqh, und fügen Sie die folgende Methodenüberladung daneben ein:

   // wir brauchen diese Überladung, weil die eingebaute ArraySort
   // unterstützt keine Arrays von Strings
   void ArraySort(string &s[][]) const
   {
      QuickSortTm<string> qt(s);
   }
   
   template<typename T>
   void ArraySort(T &s[][]) const
   {
      ::ArraySort(s);
   }
PS. Diese Frage scheint in keinem Zusammenhang mit dem Artikel zu stehen.
 
Stanislav Korotky #:

Bitte finden Sie die Zeilen:

in den Header-Dateien SymbolFilter.mqh und TradeFilter.mqh, und fügen Sie die folgende Methodenüberladung daneben ein:

PS. Diese Frage scheint in keinem Zusammenhang mit dem Artikel zu stehen.

Vielen Dank für Ihre schnelle Antwort, nachdem ich das Update gemacht habe, bekam ich mehr Fehler sagen:

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

Ich habe festgestellt, dass der direkte Aufruf des generischen QuickSortTm anstelle des ArraySort das Problem vorübergehend behebt, obwohl ich nicht glaube, dass dies die optimale Lösung ist

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

Vielen Dank für Ihre schnelle Antwort, nachdem ich das Update gemacht habe, bekam ich mehr Fehler sagen:

Das ist seltsam, nach dem oben vorgeschlagenen Fix habe ich dieses Skript /MQL5/Scripts/MQL5Book/p6/SymbolFilterTradeMode.mq5 erfolgreich auf Build 5346 kompiliert und ausgeführt. Sie haben Ihren Quellcode nicht gezeigt.
 
Stanislav Korotky #:
Das ist seltsam, nach der oben vorgeschlagenen Korrektur habe ich dieses Skript /MQL5/Scripts/MQL5Book/p6/SymbolFilterTradeMode.mq5 erfolgreich auf Build 5346 kompiliert und ausgeführt. Sie haben Ihren Quellcode nicht gezeigt.
Verzeihen Sie mir, dass ich meinen Quellcode ausgelassen habe, also habe ich auf die von Ihnen vorgeschlagene Lösung zurückgegriffen, damit ich die Fehler wieder bekomme, und es sieht so aus, als ob diese Teile meines Codes die Teile sind, die zu dem Fehler führen, wie aus dem Protokoll hervorgeht
Ich arbeite mit Version 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]);
   }
}


Nebenbei sehe ich oft diese Meldungen:

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
Dateien:
log.txt  34 kb
 
pauldic #:


Verzeihen Sie mir, dass ich meinen Quellcode ausgelassen habe, also bin ich auf den von Ihnen vorgeschlagenen Fix zurückgegangen, damit ich die Fehler wieder bekomme, und es sieht so aus, als ob diese Teile meines Codes die Teile sind, die laut dem Log

zu dem Fehler führen.

Ich habe übersehen, dass der Buchstabe T bereits als Klassenvorlage typename verwendet wurde (es ist seltsam, dass der Compiler in diesem Fall keinen Fehler produziert hat), so dass es in Ordnung ist, T in einen anderen freien Buchstaben zu ändern, zum Beispiel X:

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

Was die erste Warnung betrifft, hier eine Erklärung aus den Foren (die ich Ihnen bereits gegeben habe):

Forum zum Thema Handel, automatisierte Handelssysteme und Testen von Handelsstrategien

Experten: MQL5 Programmierung für Trader - Source Codes aus dem Buch. Teil 7

Stanislav Korotky, 2025.06.14 16:26

Dies ist nur eine Warnung, die durch die Tatsache verursacht wird, dass die entsprechende eingebaute Aufzählung von MQL5 eine Lücke in den Konstanten hat, die normalerweise fortlaufend zugewiesen werden. Diese Lücke entsteht, weil sich MQL5 ständig ändert und einige Konstanten veraltet sein können und dann eliminiert werden. Sie können den Quellcode bearbeiten, um solche Warnungen zu verhindern.

Und was den ausgelaufenen Speicher angeht - ich fürchte, es gibt eine Lücke in Ihrem benutzerdefinierten Quellcode, das Buch hat solche Dinge nicht gezeigt. Sie sollten einen vollständigen Testcode bereitstellen, um das Problem zu reproduzieren.

PS. Es ist effizienter, einen einzigen Select für alle interessierenden Eigenschaften auszuführen:

   // BEISPIEL: Gewinn, Symbol, Ticket für Positionen anfordern
   // nach bestimmter magischer Zahl, sortiert nach Gewinn
   
   #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: Ich denke, die Moderatoren sollten alle Fragen und Antworten zum Buch (ab #41) in den entsprechenden Thread verschieben, zum Beispiel hier - https://www.mql5.com/en/forum/459067.

 
Stanislav Korotky #:

Ich habe übersehen, dass der Buchstabe T bereits als Klassenvorlage typename verwendet wurde (es ist seltsam, dass der Compiler in diesem Fall keinen Fehler produzierte), so dass es in Ordnung ist, T durch einen anderen freien Buchstaben zu ersetzen, zum Beispiel X:

Was die erste Warnung betrifft, hier eine Erklärung aus dem Forum (die ich Ihnen bereits gegeben habe):

Und was den ausgelaufenen Speicher angeht - ich fürchte, es gibt eine Lücke in Ihrem benutzerdefinierten Quellcode, das Buch hat solche Dinge nicht gezeigt. Sie sollten einen vollständigen Testcode bereitstellen, um das Problem zu reproduzieren.

PS. Es ist effizienter, einen einzigen Select für alle Eigenschaften auszuführen, die Sie interessieren:



NB: Ich denke, die Moderatoren sollten alle Fragen und Antworten zum Buch (ab #41) in den entsprechenden Thread verschieben, zum Beispiel hier - https://www.mql5.com/en/forum/459067.

Vielen Dank, dass die kleine Änderung T -> X den Zauber bewirkt hat. Und nochmals vielen Dank für den Hinweis auf meine frühere Frage (ich hatte vergessen, dass ich sie schon einmal gestellt hatte), und Ihre Erinnerung hat mir geholfen, die Aktualisierung von toyjson3.mqh zu sehen, die ich zuvor übersehen hatte, und für das "select" werde ich die Korrekturen vornehmen.

Ich glaube, Sie haben Recht mit dem Leck, ich glaube, ich habe schon eine Idee, woher es kommt.

Vielen Dank, Bruder.
 
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); // Filter nach Zeit
   Print("\nFound:  ", ArraySize(data), " Deals\nTIME, SYMBOL, TICKET, TYPE, VOLUME, PRICE, COMMISSION, PROFIT");
   ArrayPrint(data);
}

@StanislavKorotky
Ich kann auf die Deals und Orders und mit diesem Code zugreifen, aber ich habe nicht herausfinden können, wie man auf dieselben für einen bestimmten Zeitrahmen zugreifen kann. Bitte können Sie mir eine Anleitung oder ein Beispiel geben, wie man das gleiche für einen bestimmten Zeitraum macht.

 
pauldic #:

Ich kann mit diesem Code auf die Deals und Orders zugreifen, aber ich habe nicht herausfinden können, wie man auf dieselben für einen bestimmten Zeitraum zugreifen kann. Bitte können Sie mir eine Anleitung für ein Dokument oder ein Beispiel geben, wie man dasselbe für einen bestimmten Zeitrahmen tun kann

Orders, Deals und Positionen sind ohnehin nicht an Zeitrahmen gebunden. Entweder haben Sie etwas missverstanden oder Ihre Formulierung ist falsch.