English 日本語
preview
MQL5 Handels-Toolkit (Teil 3): Entwicklung einer EX5-Bibliothek zur Verwaltung schwebenden Aufträge

MQL5 Handels-Toolkit (Teil 3): Entwicklung einer EX5-Bibliothek zur Verwaltung schwebenden Aufträge

MetaTrader 5Beispiele | 13 Januar 2025, 10:18
41 0
Wanateki Solutions LTD
Kelvin Muturi Muigua

Einführung

Im ersten und zweiten Artikel wurden Sie in die Entwicklung und Programmierung von EX5-Bibliotheken von Grund auf eingeführt. Sie erfuhren, wie Sie eine ausführliche Dokumentation erstellen, um Endnutzern bei der Implementierung in ihre MQL5-Projekte zu helfen, und erhielten eine praktische Schritt-für-Schritt-Demonstration, wie Sie sie in verschiedene MQL5-Anwendungen importieren und implementieren können.

In diesem Artikel entwickeln wir eine umfassende EX5-Bibliothek für die Verwaltung schwebender Aufträge (pending Orders) und erstellen eine grafische Nutzeroberfläche (GUI), um zu demonstrieren, wie die Bibliothek als praktisches Beispiel importiert und implementiert wird. Diese Bibliothek zur Verwaltung schwebender Aufträge verwendet nur MQL5-Standardfunktionen zum Öffnen, Ändern und Löschen verschiedener Arten schwebender Aufträge. Es dient als wertvolle Lernressource für neue MQL5-Programmierer, die lernen wollen, wie man einfache bis fortgeschrittene Module für die Verwaltung schwebender Aufträge programmiert. Sie lernen auch, wie Sie schwebende Aufträge nach verschiedenen Kategorien filtern und sortieren können.

Die Funktionen, die wir im Folgenden erstellen, werden exportiert und in die EX5-Bibliothek kompiliert, was sie zu einer wertvollen Ressource macht, die die Entwicklungszeit zukünftiger MQL5-Projekte drastisch verkürzt. Durch den einfachen Import der EX5-Bibliothek für die Verwaltung schwebender Aufträge können Sie diese Funktionen implementieren und so sowohl die Codebasis als auch den gesamten Entwicklungs- und Codierungsprozess erheblich verkürzen.


Erstellen einer neuen EX5-Bibliotheksdatei(.mq5) mit den Quellcodes

Um zu beginnen, öffnen Sie Ihre MetaEditor-IDE und starten Sie den MQL-Assistenten über die Schaltfläche „New“ im Menü. Sie müssen eine neue Quellcodedatei für die Bibliothek erstellen, die wir PendingOrdersManager.mq5 nennen werden. Diese Datei enthält die wichtigsten Funktionen für die Verwaltung der schwebenden Aufträge. Speichern Sie es in dem Ordner Libraries\Toolkit, den wir im ersten Artikel eingerichtet haben. Dies ist dasselbe Verzeichnis, in dem wir zuvor die Bibliothek von Positionsmanager-EX5 gespeichert haben, damit unser Projekt übersichtlich und konsistent bleibt.

PendingOrdersManager.mql5 Saved_Directory

Wenn Sie eine Auffrischung brauchen, wie man eine EX5-Bibliothek in MQL5 erstellt, empfehle ich Ihnen, zum ersten Artikel zurückzugehen. Dort haben wir die schrittweise Einrichtung Ihrer Ordnerstruktur und die Erstellung von Bibliotheken im Detail beschrieben. Die Befolgung dieses Ansatzes trägt nicht nur zur Rationalisierung der Entwicklung bei, sondern erleichtert auch die Wartung und Wiederverwendung Ihrer Bibliotheken in zukünftigen MQL5-Projekten.


Präprozessor-Direktiven, globale Variablen und Positionsmanager EX5-Bibliotheksimporte

In unserer neu erstellten Bibliotheksquellcodedatei PendingOrdersManager.mq5 werden wir zunächst alle Präprozessoranweisungen, globalen Variablen, Bibliotheksimporte und Handelsstrukturen definieren. Dadurch wird sichergestellt, dass sie in der gesamten Bibliothek für die Verwaltung schwebender Aufträge zur Verfügung stehen und je nach Bedarf in verschiedenen Funktionen wiederverwendet werden können.

Wir beginnen mit der Definition eines Präprozessormakros mit #define, um eine Konstante zu erstellen, die eine leere Zeichenkette darstellt. Diese Konstante mit dem Namen ALL_SYMBOLS dient als Platzhalter in den Funktionen zur Verwaltung anstehender Aufträge, die eine Symbolzeichenkette als Eingabeparameter erfordern. Wenn Sie diese leere Zeichenkette übergeben, interpretieren die Funktionen sie als einen Befehl, die angegebene Aktion auf alle verfügbaren Symbole anzuwenden, anstatt nur auf ein einziges.

Dieser Ansatz ist einfach, aber sehr effektiv, insbesondere bei der Verwaltung mehrerer Instrumente, da er die Bearbeitung schwebender Aufträge über verschiedene Symbole hinweg rationalisiert. Um dies zu implementieren, definieren Sie die Konstante ALL_SYMBOLS und platzieren Sie sie direkt unter den #property-Anweisungen in Ihrem Code.

#define ALL_SYMBOLS "" //-- Used as a function parameter to select all symbols

Außerdem müssen wir zwei zusätzliche Konstanten erstellen: eine, um die maximale Anzahl der Versuche festzulegen, die wir unternehmen können, um einen Auftrag an den Handelsserver zu senden, wenn er fehlschlägt, und eine weitere, um die Verzögerungsdauer zwischen den Versuchen festzulegen. Dadurch wird verhindert, dass der Handelsserver mit schnellen, aufeinanderfolgenden Anfragen überlastet wird. Wir nennen die erste Konstante MAX_ORDER_RETRIES und setzen ihren Wert auf 600. Die zweite Konstante ist ORDER_RETRY_DELAY, mit einem Wert von 500 (Millisekunden).

Das bedeutet, dass wir, wenn kein kritischer Fehler auftritt, bis zu 600 Mal versuchen können, einen Auftrag zu öffnen, zu ändern oder zu löschen. Nach jedem Versuch pausiert die Funktion für eine halbe Sekunde (500 Millisekunden), bevor sie es erneut versucht. Diese Verzögerung sorgt dafür, dass der Server nicht überlastet wird und die Ressourcen effizient genutzt werden. Außerdem können Verzögerungen, wie z. B. Inaktivität des Marktes oder die Nichtverfügbarkeit von Tickdaten, behoben werden, bevor alle Wiederholungsversuche ausgeschöpft sind, was die Wahrscheinlichkeit einer erfolgreichen Auftragsausführung erhöht.

#define MAX_ORDER_RETRIES 600 //-- Sets the order sending retry limit
#define ORDER_RETRY_DELAYS 500//-- Sets the duration to pause before re-sending a failed order request in milliseconds

Als Nächstes fügen Sie die MQL5-Datenstrukturen MqlTradeRequest und MqlTradeResult hinzu. Diese Strukturen sind wichtig, da sie die gesamte Kommunikation mit dem Handelsserver abwickeln, wenn wir verschiedene schwebende Aufträge öffnen, ändern und löschen. Die Struktur tradeRequest ist für die Speicherung der Details der auszuführenden Handelsaktion verantwortlich, einschließlich der Auftragsparameter wie Preis, Stop Loss und Take Profit. In der Zwischenzeit erfasst und speichert die Struktur tradeResult das Ergebnis des Handelsvorgangs und liefert uns eine Rückmeldung des Servers, ob unsere Anfrage erfolgreich war oder ein Fehler aufgetreten ist.

//-- Trade operations request and result data structures global variables
MqlTradeRequest tradeRequest;
MqlTradeResult  tradeResult;

Um den Status der verschiedenen schwebenden Aufträge zu verfolgen und zu speichern, müssen wir verschiedene Arten von Variablen erstellen, die diese Statusinformationen enthalten. Diese Auftragsstatusvariablen werden als globale Variablen deklariert, um sicherzustellen, dass sie von jedem Bereich innerhalb unserer Bibliothek aus zugänglich sind, sodass jede Funktion sie bei Bedarf referenzieren und aktualisieren kann. Wir initialisieren diese Variablen mit Standardwerten, wenn wir sie deklarieren, und aktualisieren sie dann später mit genauen Echtzeitdaten innerhalb der Funktion GetPendingOrdersData(...), die wir später in diesem Artikel entwickeln werden. Dadurch wird sichergestellt, dass der Status aller anhängigen Aufträge während der Ausführung der aufrufenden Funktionen konsistent und genau aktualisiert bleibt.

//-- Pending orders status global variables
//-------------------------------------------------------------------------------------------------------------------
int accountBuyStopOrdersTotal = 0, accountSellStopOrdersTotal = 0,
    accountBuyLimitOrdersTotal = 0, accountSellLimitOrdersTotal = 0,

    symbolPendingOrdersTotal = 0,
    symbolBuyStopOrdersTotal = 0, symbolSellStopOrdersTotal = 0,
    symbolBuyLimitOrdersTotal = 0, symbolSellLimitOrdersTotal = 0,

    magicPendingOrdersTotal = 0,
    magicBuyStopOrdersTotal = 0, magicSellStopOrdersTotal = 0,
    magicBuyLimitOrdersTotal = 0, magicSellLimitOrdersTotal = 0;

double accountPendingOrdersVolumeTotal = 0.0,
       accountBuyStopOrdersVolumeTotal = 0.0, accountSellStopOrdersVolumeTotal = 0.0,
       accountBuyLimitOrdersVolumeTotal = 0.0, accountSellLimitOrdersVolumeTotal = 0.0,

       symbolPendingOrdersVolumeTotal = 0.0,
       symbolBuyStopOrdersVolumeTotal = 0.0, symbolSellStopOrdersVolumeTotal = 0.0,
       symbolBuyLimitOrdersVolumeTotal = 0.0, symbolSellLimitOrdersVolumeTotal = 0.0,

       magicPendingOrdersVolumeTotal = 0.0,
       magicBuyStopOrdersVolumeTotal = 0.0, magicSellStopOrdersVolumeTotal = 0.0,
       magicBuyLimitOrdersVolumeTotal = 0.0, magicSellLimitOrdersVolumeTotal = 0.0;

Beim Öffnen, Ändern oder Löschen von Aufträgen treten häufig verschiedene Arten von Fehlern auf. Um diese Fehler effizient zu behandeln und zu beheben, benötigen wir eine spezielle Funktion, die diese Fehler verwaltet. Darüber hinaus benötigen wir eine Funktion, mit der wir kritische Handelsberechtigungen überprüfen können, z. B. ob unser Expert Advisor zum Handel berechtigt ist, ob der algorithmische Handel im Terminal aktiviert ist oder ob unser Broker den algorithmischen Handel für das Konto zugelassen hat.

Glücklicherweise haben wir ähnliche Funktionen bereits in der PositionsManager.ex5-Bibliothek aus den vorherigen Artikeln entwickelt. Anstatt diese Funktionen neu zu erstellen, werden wir diese Bibliothek einfach importieren, sodass diese Funktionen zur Fehlerbehandlung und Berechtigungsprüfung für die Verwendung in unserer Bibliothek „Pending Orders Manager“ leicht verfügbar sind. Importieren Sie die Funktionen ErrorAdvisor(...) und TradingIsAllowed().

//+----------------------------------------------------------------------------+
//| PositionsManager.ex5 imports                                               |
//+----------------------------------------------------------------------------+
#import "Toolkit/PositionsManager.ex5" //-- Opening import directive
//-- Function descriptions for the imported function prototypes

//-- Error Handling and Permission Status Functions
bool   ErrorAdvisor(string callingFunc, string symbol, int tradeServerErrorCode);
bool   TradingIsAllowed();

#import //--- Closing import directive


Funktion Auftragsdetails drucken

Die Funktion PrintOrderDetails(...) protokolliert detaillierte Informationen über eine Handelsanfrage und die Antwort des Servers im Expert Advisor Log des MetaTrader 5. Sie benötigt zwei String-Parameter: Header, der eine nutzerdefinierte Nachricht enthält, und Symbol, das das zu verarbeitende Handelssymbol oder Instrument darstellt. Die Funktion gibt einen umfassenden Bericht aus, der wesentliche Auftragsdetails wie Symbol, Auftragsart, Volumen, Preis, Stop-Loss, Take-Profit, Kommentar, magische Zahl und eventuelle Abweichungen enthält. Darüber hinaus werden wichtige Informationen über das Handelsergebnis, einschließlich der Serverantwort und etwaiger Laufzeitfehler, protokolliert. Der Hauptzweck dieser Funktion besteht darin, die Fehlersuche und die Überwachung von Handelsvorgängen zu erleichtern, indem ein klarer, formatierter Überblick über die Parameter und den Status der einzelnen Aufträge gegeben wird.

void PrintOrderDetails(string header, string symbol)
  {
   string orderDescription;
   int symbolDigits = (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS);
//-- Print the order details
   orderDescription += "_______________________________________________________________________________________\r\n";
   orderDescription += "--> "  + tradeRequest.symbol + " " + EnumToString(tradeRequest.type) + " " + header +
                       " <--\r\n";
   orderDescription += "Volume: " + StringFormat("%d", tradeRequest.volume) + "\r\n";
   orderDescription += "Price: " + DoubleToString(tradeRequest.price, symbolDigits) + "\r\n";
   orderDescription += "Stop Loss: " + DoubleToString(tradeRequest.sl, symbolDigits) + "\r\n";
   orderDescription += "Take Profit: " + DoubleToString(tradeRequest.tp, symbolDigits) + "\r\n";
   orderDescription += "Comment: " + tradeRequest.comment + "\r\n";
   orderDescription += "Magic Number: " + StringFormat("%d", tradeRequest.magic) + "\r\n";
   orderDescription += "Order filling: " + EnumToString(tradeRequest.type_filling)+ "\r\n";
   orderDescription += "Deviation points: " + StringFormat("%G", tradeRequest.deviation) + "\r\n";
   orderDescription += "RETCODE: " + (string)(tradeResult.retcode) + "\r\n";
   orderDescription += "Runtime Code: " + (string)(GetLastError()) + "\r\n";
   orderDescription += "---";
   Print(orderDescription);
  }


Die Funktion zum Eröffnen von „BuyLimit“

Die Funktion OpenBuyLimit(...) wird mit der Aufgabe betraut, neue Kauflimit-Aufträge im MetaTrader 5-Handelsterminal zu platzieren. Diese Funktion stellt sicher, dass alle erforderlichen Bedingungen erfüllt sind, bevor die Bestellanforderung übermittelt wird, und bietet eine integrierte Fehlerbehandlung, um mögliche Probleme zu bewältigen. Er prüft, ob alle Parameter gültig sind und den Anforderungen des Brokers entsprechen. Darüber hinaus ist eine Wiederholungsschleife implementiert, die die Wahrscheinlichkeit einer erfolgreichen Auftragserteilung erhöht und das System zu einem zuverlässigen und effizienten Instrument für die Verwaltung schwebender Aufträge macht. Die umfassenden Fehlerbehandlungs- und Protokollierungsfunktionen der Funktion helfen außerdem bei der Identifizierung und Lösung von Problemen, die während des Bestellvorgangs auftreten können. Die Funktion gibt den booleschen Wert true zurück, wenn sie erfolgreich eine Kauf-Limit-Order eröffnet hat, und false, wenn die Anfrage nicht erfolgreich war.

Was ist eine „Buy Limit Order“?


Ein BuyLimit-Auftrag ist eine Aufforderung, zu einem Briefkurs (Ask) zu kaufen, der gleich oder niedriger ist als der angegebene Eingangskurs. Das „Buy Limit“ ist nur gültig, wenn der aktuelle Marktpreis höher ist als der Eröffnungspreis des Auftrags. Diese Art von Auftrag ist nützlich, wenn Sie davon ausgehen, dass der Kurs des Symbols auf das von Ihnen gewünschte Einstiegsniveau fallen und dann steigen wird, sodass Sie von der Aufwärtsbewegung profitieren können.

BuyLimit Order

Beginnen wir mit der Definition der Funktion, die sieben Parameter akzeptiert, von denen jeder eine spezifische Rolle im Prozess der Platzierung einer Kauf-Limit-Order hat. Die Funktion kann exportiert werden, sodass sie von außen in der EX5-Bibliothek aufgerufen werden kann. Diese Parameter sind:

  1. magicNumber (unsigned long): Eine eindeutige Kennung für den Handel, die dazu dient, die von unserem Expert Advisor erteilten Aufträge von anderen zu unterscheiden.
  2. symbol (string): Das Handelsinstrument oder -symbol (z. B. EURUSD), für das der Auftrag erteilt werden soll.
  3. entryPrice (double): Das Preisniveau, bei dem der Kauf-Limitauftrag ausgelöst wird. Dies ist der Zielpreis, zu dem Sie den Vermögenswert kaufen möchten.
  4. lotSize (double): Das Volumen oder die Größe des zu erteilenden Auftrags, die angibt, wie viele Lots des Vermögenswerts gehandelt werden sollen.
  5. sl (int): Der Stop-Loss-Wert, gemessen in Pips. Damit wird der maximale Verlust festgelegt, den der Handel erleiden kann, bevor er automatisch geschlossen wird.
  6. tp (int): Der Take-Profit-Wert, ebenfalls in Pips gemessen. Damit wird das Kursniveau festgelegt, bei dem die Gewinne automatisch durch Schließen des Auftrags gesichert werden.
  7. orderComment (string): Ein Kommentar oder eine Notiz, beigefügt zur Identifizierung oder Nachverfolgung des Auftrags.
bool OpenBuyLimit(ulong magicNumber, string symbol, double entryPrice, double lotSize, int sl, int tp, string orderComment) export
  {

Nach der Definition der Funktion und ihrer Parameter wird im ersten Schritt der Funktion geprüft, ob der algorithmische Handel oder der Expert Advisor-Handel im MetaTrader 5 aktiviert ist. Wenn sie deaktiviert ist, wird die Funktion sofort beendet, sodass der Auftrag nicht aufgegeben werden kann.

if(!TradingIsAllowed())
     {
      return(false); //--- algo trading is disabled, exit function
     }

Als Nächstes erstellen wir die Variablen tpPrice und slPrice, um die Take-Profit- und Stop-Loss-Kurswerte zu speichern und dann wichtige Informationen über das Handelssymbol abzurufen, wie z. B. die Anzahl der Dezimalstellen (digits), das minimale Stop-Level und den Spread. Anhand dieser Angaben können wir sicherstellen, dass der Einstiegskurs und die Auftragsparameter für das gewählte Symbol korrekt eingestellt sind.

double tpPrice = 0.0, slPrice = 0.0;

//-- Get some information about the orders symbol
   int symbolDigits = (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS);
   int symbolStopLevel = (int)SymbolInfoInteger(symbol, SYMBOL_TRADE_STOPS_LEVEL);
   double symbolPoint = SymbolInfoDouble(symbol, SYMBOL_POINT);
   int spread = (int)SymbolInfoInteger(symbol, SYMBOL_SPREAD);

//-- Save the order type enumeration
   ENUM_ORDER_TYPE orderType = ORDER_TYPE_BUY_LIMIT;

Bevor wir die Order abschicken, müssen wir prüfen, ob der Einstiegskurs gültig ist, indem wir sicherstellen, dass der Kurs nicht zu nahe am Marktpreis oder unter dem Stop-Level des Brokers liegt. Wenn der Preis ungültig ist, wird ein Fehler protokolliert und die Funktion beendet.

//-- check if the entry price is valid
   if(
      SymbolInfoDouble(symbol, SYMBOL_ASK) - (symbolStopLevel * symbolPoint) <
      entryPrice + (spread * symbolPoint)
   )
     {
      Print(
         "\r\n", __FUNCTION__, ": Can't open a new ", EnumToString(orderType),
         ". (Reason --> INVALID ENTRY PRICE: ", DoubleToString(entryPrice, symbolDigits), ")\r\n"
      );
      return(false); //-- Invalid entry price, log the error, exit the function and return false
     }

Stellen Sie sicher, dass die Werte für Stop Loss (SL) und Take Profit (TP) den Mindestanforderungen des Brokers entsprechen. Falls erforderlich, werden wir die SL und TP anpassen, um diese Regeln zu erfüllen, bevor wir fortfahren.

//-- Check the validity of the sl and tp
   if(sl > 0 && sl < symbolStopLevel)
     {
      sl = symbolStopLevel;
     }
   if(tp > 0 && tp < symbolStopLevel)
     {
      tp = symbolStopLevel;
     }

   slPrice = (sl > 0) ? NormalizeDouble(entryPrice - sl * symbolPoint, symbolDigits) : 0;
   tpPrice = (tp > 0) ? NormalizeDouble(entryPrice + tp * symbolPoint, symbolDigits) : 0;

Sobald wir den Preis und andere Parameter validiert haben, bereiten wir die Struktur TradeRequest mit Details wie Auftragstyp, Symbol, Preis, Volumen, Stop Loss, Take Profit und einem Kommentar vor. Wir stellen auch sicher, dass die Losgröße innerhalb der zulässigen Grenzen des Brokers liegt und setzen alle früheren Handelsergebnisse oder Fehler zurück.

//-- reset the the tradeRequest and tradeResult values by zeroing them
   ZeroMemory(tradeRequest);
   ZeroMemory(tradeResult);

//-- initialize the parameters to open a buy limit order
   tradeRequest.type = orderType;
   tradeRequest.action = TRADE_ACTION_PENDING;
   tradeRequest.magic = magicNumber;
   tradeRequest.symbol = symbol;
   tradeRequest.price = NormalizeDouble(entryPrice, symbolDigits);
   tradeRequest.tp = tpPrice;
   tradeRequest.sl = slPrice;
   tradeRequest.comment = orderComment;
   tradeRequest.deviation = SymbolInfoInteger(symbol, SYMBOL_SPREAD) * 2;

//-- Set and moderate the lot size or volume
//-- Verify that volume is not less than allowed minimum
   lotSize = MathMax(lotSize, SymbolInfoDouble(symbol, SYMBOL_VOLUME_MIN));

//-- Verify that volume is not more than allowed maximum
   lotSize = MathMin(lotSize, SymbolInfoDouble(symbol, SYMBOL_VOLUME_MAX));

//-- Round down to nearest volume step
   lotSize = MathFloor(lotSize / SymbolInfoDouble(symbol, SYMBOL_VOLUME_STEP)) * SymbolInfoDouble(symbol, SYMBOL_VOLUME_STEP);
   tradeRequest.volume = lotSize;

//--- Reset error cache so that we get an accurate runtime error code in the ErrorAdvisor function
   ResetLastError();

Wenn die Auftragsanfrage gültig ist, versuchen wir, sie an den Handelsserver des Brokers zu senden. Wenn die Auftragserteilung fehlschlägt, versuchen wir, den Auftrag bis zu 600 Mal erneut zu senden, wobei wir eine halbe Sekunde (500 Millisekunden) pausieren, bevor wir es erneut versuchen, um sicherzustellen, dass der Auftrag erfolgreich erteilt wird. Dieser Wiederholungsmechanismus erhöht die Chance auf eine erfolgreiche Öffnung des Auftrags erheblich, insbesondere bei vorübergehenden Netzwerk- oder Serverproblemen.

Wenn der Auftrag erfolgreich erteilt wurde, protokollieren wir die Einzelheiten des Auftrags und bestätigen, dass der Handelsserver ihn bearbeitet hat. Wenn der Auftrag auch nach mehreren Versuchen fehlschlägt, verwenden wir die Funktion ErrorAdvisor(..), die wir aus der Bibliothek PositionsManager.ex5 importiert haben, um das Problem zu diagnostizieren, und geben false zurück, um anzuzeigen, dass der Auftrag nicht erteilt wurde.

for(int loop = 0; loop <= MAX_ORDER_RETRIES; loop++) //-- try opening the order until it is successful
     {
      //--- send order to the trade server
      if(OrderSend(tradeRequest, tradeResult))
        {
         //-- Print the order details
         PrintOrderDetails("Sent OK", symbol);

         //-- Confirm order execution
         if(tradeResult.retcode == 10008 || tradeResult.retcode == 10009)
           {
            Print(
               __FUNCTION__, ": CONFIRMED: Successfully openend a ", symbol,
               " ", EnumToString(orderType), " #", tradeResult.order, ", Price: ", tradeResult.price
            );
            PrintFormat("retcode=%u  deal=%I64u  order=%I64u", tradeResult.retcode, tradeResult.deal, tradeResult.order);
            Print("_______________________________________________________________________________________");
            return(true); //-- exit the function
            //break; //--- success - order placed ok. exit the for loop
           }
        }
      else //-- Order request failed
        {
         //-- Print the order details
         PrintOrderDetails("Sending Failed", symbol);

         //-- order not sent or critical error found
         if(!ErrorAdvisor(__FUNCTION__, symbol, tradeResult.retcode) || IsStopped())
           {
            Print(
               __FUNCTION__, ": ", symbol, " ERROR opening a ", EnumToString(orderType),
               " at: ", tradeRequest.price, ", Lot\\Vol: ", tradeRequest.volume
            );
            Print("_______________________________________________________________________________________");
            return(false); //-- exit the function
            //break; //-- exit the for loop

            Sleep(ORDER_RETRY_DELAYS);//-- Small pause before retrying to avoid overwhelming the trade server
           }
        }
     }

Hier ist die vollständige Funktion mit allen Codesegmenten in der richtigen Reihenfolge. Stellen Sie sicher, dass Ihre OpenBuyLimit(...) Funktion den folgenden Code vollständig enthält.

bool OpenBuyLimit(ulong magicNumber, string symbol, double entryPrice, double lotSize, int sl, int tp, string orderComment) export
  {
//-- first check if the EA is allowed to trade
   if(!TradingIsAllowed())
     {
      return(false); //--- algo trading is disabled, exit function
     }

   double tpPrice = 0.0, slPrice = 0.0;

//-- Get some information about the orders symbol
   int symbolDigits = (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS);
   int symbolStopLevel = (int)SymbolInfoInteger(symbol, SYMBOL_TRADE_STOPS_LEVEL);
   double symbolPoint = SymbolInfoDouble(symbol, SYMBOL_POINT);
   int spread = (int)SymbolInfoInteger(symbol, SYMBOL_SPREAD);

//-- Save the order type enumeration
   ENUM_ORDER_TYPE orderType = ORDER_TYPE_BUY_LIMIT;

//-- check if the entry price is valid
   if(
      SymbolInfoDouble(symbol, SYMBOL_ASK) - (symbolStopLevel * symbolPoint) <
      entryPrice + (spread * symbolPoint)
   )
     {
      Print(
         "\r\n", __FUNCTION__, ": Can't open a new ", EnumToString(orderType),
         ". (Reason --> INVALID ENTRY PRICE: ", DoubleToString(entryPrice, symbolDigits), ")\r\n"
      );
      return(false); //-- Invalid entry price, log the error, exit the function and return false
     }

//-- Check the validity of the sl and tp
   if(sl > 0 && sl < symbolStopLevel)
     {
      sl = symbolStopLevel;
     }
   if(tp > 0 && tp < symbolStopLevel)
     {
      tp = symbolStopLevel;
     }

   slPrice = (sl > 0) ? NormalizeDouble(entryPrice - sl * symbolPoint, symbolDigits) : 0;
   tpPrice = (tp > 0) ? NormalizeDouble(entryPrice + tp * symbolPoint, symbolDigits) : 0;

//-- reset the the tradeRequest and tradeResult values by zeroing them
   ZeroMemory(tradeRequest);
   ZeroMemory(tradeResult);

//-- initialize the parameters to open a buy limit order
   tradeRequest.type = orderType;
   tradeRequest.action = TRADE_ACTION_PENDING;
   tradeRequest.magic = magicNumber;
   tradeRequest.symbol = symbol;
   tradeRequest.price = NormalizeDouble(entryPrice, symbolDigits);
   tradeRequest.tp = tpPrice;
   tradeRequest.sl = slPrice;
   tradeRequest.comment = orderComment;
   tradeRequest.deviation = SymbolInfoInteger(symbol, SYMBOL_SPREAD) * 2;

//-- Set and moderate the lot size or volume
//-- Verify that volume is not less than allowed minimum
   lotSize = MathMax(lotSize, SymbolInfoDouble(symbol, SYMBOL_VOLUME_MIN));

//-- Verify that volume is not more than allowed maximum
   lotSize = MathMin(lotSize, SymbolInfoDouble(symbol, SYMBOL_VOLUME_MAX));

//-- Round down to nearest volume step
   lotSize = MathFloor(lotSize / SymbolInfoDouble(symbol, SYMBOL_VOLUME_STEP)) * SymbolInfoDouble(symbol, SYMBOL_VOLUME_STEP);
   tradeRequest.volume = lotSize;

//--- Reset error cache so that we get an accurate runtime error code in the ErrorAdvisor function
   ResetLastError();

   for(int loop = 0; loop <= MAX_ORDER_RETRIES; loop++) //-- try opening the order until it is successful
     {
      //--- send order to the trade server
      if(OrderSend(tradeRequest, tradeResult))
        {
         //-- Print the order details
         PrintOrderDetails("Sent OK", symbol);

         //-- Confirm order execution
         if(tradeResult.retcode == 10008 || tradeResult.retcode == 10009)
           {
            Print(
               __FUNCTION__, ": CONFIRMED: Successfully openend a ", symbol,
               " ", EnumToString(orderType), " #", tradeResult.order, ", Price: ", tradeResult.price
            );
            PrintFormat("retcode=%u  deal=%I64u  order=%I64u", tradeResult.retcode, tradeResult.deal, tradeResult.order);
            Print("_______________________________________________________________________________________");
            return(true); //-- exit the function
            //break; //--- success - order placed ok. exit the for loop
           }
        }
      else //-- Order request failed
        {
         //-- Print the order details
         PrintOrderDetails("Sending Failed", symbol);

         //-- order not sent or critical error found
         if(!ErrorAdvisor(__FUNCTION__, symbol, tradeResult.retcode) || IsStopped())
           {
            Print(
               __FUNCTION__, ": ", symbol, " ERROR opening a ", EnumToString(orderType),
               " at: ", tradeRequest.price, ", Lot\\Vol: ", tradeRequest.volume
            );
            Print("_______________________________________________________________________________________");
            return(false); //-- exit the function
            //break; //-- exit the for loop

            Sleep(ORDER_RETRY_DELAYS);//-- Small pause before retrying to avoid overwhelming the trade server
           }
        }
     }
   return(false);
  }


Die Funktion „OpenBuyStop“

Die Funktion OpenBuyStop(...) ist für die Platzierung von neuen schwebenden Aufträge „BuyStop“ verantwortlich. Sie folgt einem ähnlichen Ansatz wie die zuvor beschriebene Funktion OpenBuyLimit(...). Die Funktion gibt true zurück, wenn sie erfolgreich eine Stop-Buy-Order platziert hat, und false, wenn die Orderanfrage fehlgeschlagen ist.

Was ist ein BuyStop-Auftrag?


Ein BuyStop-Auftrag ist eine Aufforderung, zu einem Briefkurs (Ask) zu kaufen, der gleich oder höher ist als der angegebene Eingangskurs. Der Einstiegskurs des BuyStops ist nur dann gültig, wenn der aktuelle Marktpreis niedriger ist als der Einstiegskurs des Auftrags. Diese Art von Auftrag ist nützlich, wenn Sie davon ausgehen, dass der Kurs des Symbols bis zum angegebenen Einstiegsniveau steigt und sich dann weiter nach oben bewegt, sodass Sie vom Aufwärtstrend profitieren können.

BuyStop-Order

Nachfolgend finden Sie die Funktion OpenBuyStop(...) mit erklärenden Kommentaren, damit Sie schnell verstehen, wie jeder Teil des Codes funktioniert.

bool OpenBuyStop(ulong magicNumber, string symbol, double entryPrice, double lotSize, int sl, int tp, string orderComment) export
  {
//-- first check if the EA is allowed to trade
   if(!TradingIsAllowed())
     {
      return(false); //--- algo trading is disabled, exit function
     }

   double tpPrice = 0.0, slPrice = 0.0;

//-- Get some information about the orders symbol
   int symbolDigits = (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS);
   int symbolStopLevel = (int)SymbolInfoInteger(symbol, SYMBOL_TRADE_STOPS_LEVEL);
   double symbolPoint = SymbolInfoDouble(symbol, SYMBOL_POINT);
   int spread = (int)SymbolInfoInteger(symbol, SYMBOL_SPREAD);

//-- Save the order type enumeration
   ENUM_ORDER_TYPE orderType = ORDER_TYPE_BUY_STOP;

//-- check if the entry price is valid
   if(
      SymbolInfoDouble(symbol, SYMBOL_ASK) + (symbolStopLevel * symbolPoint) >
      entryPrice + (spread * symbolPoint)
   )
     {
      Print(
         "\r\n", __FUNCTION__, ": Can't open a new ", EnumToString(orderType),
         ". (Reason --> INVALID ENTRY PRICE: ", DoubleToString(entryPrice, symbolDigits), ")\r\n"
      );
      return(false); //-- Invalid entry price, log the error, exit the function and return false
     }


//--- Validate Stop Loss (sl) and Take Profit (tp)
   if(sl > 0 && sl < symbolStopLevel)
     {
      sl = symbolStopLevel;
     }
   if(tp > 0 && tp < symbolStopLevel)
     {
      tp = symbolStopLevel;
     }

   slPrice = (sl > 0) ? NormalizeDouble(entryPrice - sl * symbolPoint, symbolDigits) : 0;
   tpPrice = (tp > 0) ? NormalizeDouble(entryPrice + tp * symbolPoint, symbolDigits) : 0;

//-- reset the the tradeRequest and tradeResult values by zeroing them
   ZeroMemory(tradeRequest);
   ZeroMemory(tradeResult);

//-- initialize the parameters to open a buy stop order
   tradeRequest.type = orderType;
   tradeRequest.action = TRADE_ACTION_PENDING;
   tradeRequest.magic = magicNumber;
   tradeRequest.symbol = symbol;
   tradeRequest.price = NormalizeDouble(entryPrice, symbolDigits);
   tradeRequest.tp = tpPrice;
   tradeRequest.sl = slPrice;
   tradeRequest.comment = orderComment;
   tradeRequest.deviation = SymbolInfoInteger(symbol, SYMBOL_SPREAD) * 2;

//-- Set and moderate the lot size or volume
//-- Verify that volume is not less than allowed minimum
   lotSize = MathMax(lotSize, SymbolInfoDouble(symbol, SYMBOL_VOLUME_MIN));

//-- Verify that volume is not more than allowed maximum
   lotSize = MathMin(lotSize, SymbolInfoDouble(symbol, SYMBOL_VOLUME_MAX));

//-- Round down to nearest volume step
   lotSize = MathFloor(lotSize / SymbolInfoDouble(symbol, SYMBOL_VOLUME_STEP)) * SymbolInfoDouble(symbol, SYMBOL_VOLUME_STEP);
   tradeRequest.volume = lotSize;

//--- Reset error cache so that we get an accurate runtime error code in the ErrorAdvisor function
   ResetLastError();

   for(int loop = 0; loop <= MAX_ORDER_RETRIES; loop++) //-- try opening the order until it is successful
     {
      //--- send order to the trade server
      if(OrderSend(tradeRequest, tradeResult))
        {
         //-- Print the order details
         PrintOrderDetails("Sent OK", symbol);

         //-- Confirm order execution
         if(tradeResult.retcode == 10008 || tradeResult.retcode == 10009)
           {
            Print(
               __FUNCTION__, ": CONFIRMED: Successfully openend a ", symbol,
               " ", EnumToString(orderType), " #", tradeResult.order, ", Price: ", tradeResult.price
            );
            PrintFormat("retcode=%u  deal=%I64u  order=%I64u", tradeResult.retcode, tradeResult.deal, tradeResult.order);
            Print("_______________________________________________________________________________________");
            return(true); //-- exit the function
            //break; //--- success - order placed ok. exit the for loop
           }
        }
      else //-- Order request failed
        {
         //-- Print the order details
         PrintOrderDetails("Sending Failed", symbol);

         //-- order not sent or critical error found
         if(!ErrorAdvisor(__FUNCTION__, symbol, tradeResult.retcode) || IsStopped())
           {
            Print(
               __FUNCTION__, ": ", symbol, " ERROR opening a ", EnumToString(orderType),
               " at: ", tradeRequest.price, ", Lot\\Vol: ", tradeRequest.volume
            );
            Print("_______________________________________________________________________________________");
            return(false); //-- exit the function
            //break; //-- exit the for loop

            Sleep(ORDER_RETRY_DELAYS);//-- Small pause before retrying to avoid overwhelming the trade server
           }
        }
     }
   return(false);
  }


Die Funktion zum Eröffnen von „SellLimit“

Die Funktion OpenSellLimit(...) ist für die Platzierung neuer schwebender Aufträge „SellLimit“ zuständig. Die Funktion gibt true zurück, wenn eine SellLimit-Order erfolgreich platziert wurde, und false, wenn die Orderanfrage nicht erfolgreich war.

Was ist eine SellLimit-Order?


Eine SellLimit-Order ist eine Aufforderung, zu einem Geldkurs (Bid) zu verkaufen, der gleich oder höher ist als der angegebene Eingangskurs des Auftrags. Die SellLimit-Order ist nur dann gültig, wenn der aktuelle Marktpreis niedriger ist als der Eingangspreis des Auftrags. Diese Art von Auftrag ist nützlich, wenn Sie erwarten, dass der Kurs des Symbols bis zum angegebenen Einstiegskurs steigt und dann die Richtung umkehrt, sodass Sie von der erwarteten Abwärtsbewegung oder dem Abwärtstrend profitieren können.

SellLimit-Order

Nachfolgend finden Sie die Funktion OpenSellLimit(...) mit erklärenden Kommentaren, damit Sie besser verstehen, wie jeder Teil des Codes funktioniert.

bool OpenSellLimit(ulong magicNumber, string symbol, double entryPrice, double lotSize, int sl, int tp, string orderComment) export
  {
//-- first check if the EA is allowed to trade
   if(!TradingIsAllowed())
     {
      return(false); //--- algo trading is disabled, exit function
     }

   double tpPrice = 0.0, slPrice = 0.0;

//-- Get some information about the orders symbol
   int symbolDigits = (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS);
   int symbolStopLevel = (int)SymbolInfoInteger(symbol, SYMBOL_TRADE_STOPS_LEVEL);
   double symbolPoint = SymbolInfoDouble(symbol, SYMBOL_POINT);
   int spread = (int)SymbolInfoInteger(symbol, SYMBOL_SPREAD);

//-- Save the order type enumeration
   ENUM_ORDER_TYPE orderType = ORDER_TYPE_SELL_LIMIT;

//-- check if the entry price is valid
   if(
      SymbolInfoDouble(symbol, SYMBOL_BID) + (symbolStopLevel * symbolPoint) >
      entryPrice - (spread * symbolPoint)
   )
     {
      Print(
         "\r\n", __FUNCTION__, ": Can't open a new ", EnumToString(orderType),
         ". (Reason --> INVALID ENTRY PRICE: ", DoubleToString(entryPrice, symbolDigits), ")\r\n"
      );
      return(false); //-- Invalid entry price, log the error, exit the function and return false
     }

//-- Check the validity of the sl and tp
   if(sl > 0 && sl < symbolStopLevel)
     {
      sl = symbolStopLevel;
     }
   if(tp > 0 && tp < symbolStopLevel)
     {
      tp = symbolStopLevel;
     }

   slPrice = (sl > 0) ? NormalizeDouble(entryPrice + sl * symbolPoint, symbolDigits) : 0;
   tpPrice = (tp > 0) ? NormalizeDouble(entryPrice - tp * symbolPoint, symbolDigits) : 0;

//-- reset the the tradeRequest and tradeResult values by zeroing them
   ZeroMemory(tradeRequest);
   ZeroMemory(tradeResult);

//-- initialize the parameters to open a sell limit order
   tradeRequest.type = orderType;
   tradeRequest.action = TRADE_ACTION_PENDING;
   tradeRequest.magic = magicNumber;
   tradeRequest.symbol = symbol;
   tradeRequest.price = NormalizeDouble(entryPrice, symbolDigits);
   tradeRequest.tp = tpPrice;
   tradeRequest.sl = slPrice;
   tradeRequest.comment = orderComment;
   tradeRequest.deviation = SymbolInfoInteger(symbol, SYMBOL_SPREAD) * 2;

//-- Set and moderate the lot size or volume
//-- Verify that volume is not less than allowed minimum
   lotSize = MathMax(lotSize, SymbolInfoDouble(symbol, SYMBOL_VOLUME_MIN));

//-- Verify that volume is not more than allowed maximum
   lotSize = MathMin(lotSize, SymbolInfoDouble(symbol, SYMBOL_VOLUME_MAX));

//-- Round down to nearest volume step
   lotSize = MathFloor(lotSize / SymbolInfoDouble(symbol, SYMBOL_VOLUME_STEP)) * SymbolInfoDouble(symbol, SYMBOL_VOLUME_STEP);
   tradeRequest.volume = lotSize;

//--- Reset error cache so that we get an accurate runtime error code in the ErrorAdvisor function
   ResetLastError();

   for(int loop = 0; loop <= MAX_ORDER_RETRIES; loop++) //-- try opening the order until it is successful
     {
      //--- send order to the trade server
      if(OrderSend(tradeRequest, tradeResult))
        {
         //-- Print the order details
         PrintOrderDetails("Sent OK", symbol);

         //-- Confirm order execution
         if(tradeResult.retcode == 10008 || tradeResult.retcode == 10009)
           {
            Print(
               __FUNCTION__, ": CONFIRMED: Successfully openend a ", symbol,
               " ", EnumToString(orderType), " #", tradeResult.order, ", Price: ", tradeResult.price
            );
            PrintFormat("retcode=%u  deal=%I64u  order=%I64u", tradeResult.retcode, tradeResult.deal, tradeResult.order);
            Print("_______________________________________________________________________________________");
            return(true); //-- exit the function
            //break; //--- success - order placed ok. exit the for loop
           }
        }
      else //-- Order request failed
        {
         //-- Print the order details
         PrintOrderDetails("Sending Failed", symbol);

         //-- order not sent or critical error found
         if(!ErrorAdvisor(__FUNCTION__, symbol, tradeResult.retcode) || IsStopped())
           {
            Print(
               __FUNCTION__, ": ", symbol, " ERROR opening a ", EnumToString(orderType),
               " at: ", tradeRequest.price, ", Lot\\Vol: ", tradeRequest.volume
            );
            Print("_______________________________________________________________________________________");
            return(false); //-- exit the function
            //break; //-- exit the for loop

            Sleep(ORDER_RETRY_DELAYS);//-- Small pause before retrying to avoid overwhelming the trade server
           }
        }
     }
   return(false);
  }


Die Funktion „Open Sell Stop“

Die Funktion OpenSellStop(...) dient dazu, neue schwebende Aufträge SellStop zu platzieren. Die Funktion gibt true zurück, wenn ein Verkaufsstoppauftrag erfolgreich platziert wurde, was bedeutet, dass die Anfrage ohne Probleme bearbeitet wurde. Wenn die Auftragserteilung aus irgendeinem Grund fehlschlägt, wird false zurückgegeben, was einen erfolglosen Versuch signalisiert.

Was ist eine SellStop-Order?


Eine SellStop-Order ist eine Aufforderung, zu einem Geldkurs (Bid) zu verkaufen, der gleich oder niedriger ist als der angegebene Eröffnungskurs des Auftrags. Der Eröffnungskurs des Verkaufsstopps ist nur gültig, wenn der aktuelle Marktpreis höher ist als der Einstiegskurs des Auftrags. Diese Art von Auftrag ist nützlich, wenn Sie davon ausgehen, dass der Kurs eines Symbols auf das angegebene Einstiegsniveau fällt und dann weiter sinkt, sodass Sie von der erwarteten Abwärtsbewegung oder dem Abwärtstrend profitieren können.

SellStop-Order

Die Funktion OpenSellStop(...) wird im Folgenden zusammen mit ausführlichen Kommentaren dargestellt, die Sie durch die Funktionalität der einzelnen Teile des Codes führen.

bool OpenSellStop(ulong magicNumber, string symbol, double entryPrice, double lotSize, int sl, int tp, string orderComment) export
  {
//-- first check if the EA is allowed to trade
   if(!TradingIsAllowed())
     {
      return(false); //--- algo trading is disabled, exit function
     }

   double slPrice = 0.0, tpPrice = 0.0;

//-- Get some information about the orders symbol
   int symbolDigits = (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS);
   int symbolStopLevel = (int)SymbolInfoInteger(symbol, SYMBOL_TRADE_STOPS_LEVEL);
   double symbolPoint = SymbolInfoDouble(symbol, SYMBOL_POINT);
   int spread = (int)SymbolInfoInteger(symbol, SYMBOL_SPREAD);

//-- Save the order type enumeration
   ENUM_ORDER_TYPE orderType = ORDER_TYPE_SELL_STOP;

//-- check if the entry price is valid
   if(
      SymbolInfoDouble(symbol, SYMBOL_BID) - (symbolStopLevel * symbolPoint) <
      entryPrice - (spread * symbolPoint)
   )
     {
      Print(
         "\r\n", __FUNCTION__, ": Can't open a new ", EnumToString(orderType),
         ". (Reason --> INVALID ENTRY PRICE: ", DoubleToString(entryPrice, symbolDigits), ")\r\n"
      );
      return(false); //-- Invalid entry price, log the error, exit the function and return false
     }

//-- Check the validity of the sl and tp
   if(sl > 0 && sl < symbolStopLevel)
     {
      sl = symbolStopLevel;
     }
   if(tp > 0 && tp < symbolStopLevel)
     {
      tp = symbolStopLevel;
     }

   slPrice = (sl > 0) ? NormalizeDouble(entryPrice + sl * symbolPoint, symbolDigits) : 0;
   tpPrice = (tp > 0) ? NormalizeDouble(entryPrice - tp * symbolPoint, symbolDigits) : 0;

//-- reset the the tradeRequest and tradeResult values by zeroing them
   ZeroMemory(tradeRequest);
   ZeroMemory(tradeResult);

//-- initialize the parameters to open a sell stop order
   tradeRequest.type = orderType;
   tradeRequest.action = TRADE_ACTION_PENDING;
   tradeRequest.magic = magicNumber;
   tradeRequest.symbol = symbol;
   tradeRequest.price = NormalizeDouble(entryPrice, symbolDigits);
   tradeRequest.tp = tpPrice;
   tradeRequest.sl = slPrice;
   tradeRequest.comment = orderComment;
   tradeRequest.deviation = SymbolInfoInteger(symbol, SYMBOL_SPREAD) * 2;

//-- Set and moderate the lot size or volume
//-- Verify that volume is not less than allowed minimum
   lotSize = MathMax(lotSize, SymbolInfoDouble(symbol, SYMBOL_VOLUME_MIN));

//-- Verify that volume is not more than allowed maximum
   lotSize = MathMin(lotSize, SymbolInfoDouble(symbol, SYMBOL_VOLUME_MAX));

//-- Round down to nearest volume step
   lotSize = MathFloor(lotSize / SymbolInfoDouble(symbol, SYMBOL_VOLUME_STEP)) * SymbolInfoDouble(symbol, SYMBOL_VOLUME_STEP);
   tradeRequest.volume = lotSize;

//--- Reset error cache so that we get an accurate runtime error code in the ErrorAdvisor function
   ResetLastError();

   for(int loop = 0; loop <= MAX_ORDER_RETRIES; loop++) //-- try opening the order until it is successful
     {
      //--- send order to the trade server
      if(OrderSend(tradeRequest, tradeResult))
        {
         //-- Print the order details
         PrintOrderDetails("Sent OK", symbol);

         //-- Confirm order execution
         if(tradeResult.retcode == 10008 || tradeResult.retcode == 10009)
           {
            Print(
               __FUNCTION__, ": CONFIRMED: Successfully openend a ", symbol,
               " ", EnumToString(orderType), " #", tradeResult.order, ", Price: ", tradeResult.price
            );
            PrintFormat("retcode=%u  deal=%I64u  order=%I64u", tradeResult.retcode, tradeResult.deal, tradeResult.order);
            Print("_______________________________________________________________________________________");
            return(true); //-- exit the function
            //break; //--- success - order placed ok. exit the for loop
           }
        }
      else //-- Order request failed
        {
         //-- Print the order details
         PrintOrderDetails("Sending Failed", symbol);

         //-- order not sent or critical error found
         if(!ErrorAdvisor(__FUNCTION__, symbol, tradeResult.retcode) || IsStopped())
           {
            Print(
               __FUNCTION__, ": ", symbol, " ERROR opening a ", EnumToString(orderType),
               " at: ", tradeRequest.price, ", Lot\\Vol: ", tradeRequest.volume
            );
            Print("_______________________________________________________________________________________");
            return(false); //-- exit the function
            //break; //-- exit the for loop

            Sleep(ORDER_RETRY_DELAYS);//-- Small pause before retrying to avoid overwhelming the trade server
           }
        }
     }
   return(false);
  }


Ändern des schwebenden Auftrags per Ticket-Funktion

Die Funktion ModifyPendingOrderByTicket(...) dient dazu, den Stop-Loss (SL), den Take-Profit (TP) oder den Einstiegspreis eines aktiven schwebenden Auftrags zu ändern. Es führt Validierungen durch, um sicherzustellen, dass die Änderungen mit den Regeln des Brokers übereinstimmen, protokolliert den Fortschritt und alle auftretenden Fehler und verwendet einen Wiederholungsmechanismus, um die Änderung im Falle eines Fehlschlags oder ungünstiger Auftragseingangsbedingungen mehrfach zu versuchen.

Die Funktion nimmt vier Parameter entgegen:

  1. orderTicket (ulong): Der eindeutige Bezeichner für den Auftrag. Diese Ticketnummer wird verwendet, um auf den spezifischen Auftrag zu verweisen, den Sie ändern möchten.
  2. newEntryPrice (double): Der neue Einstiegspreis für den schwebenden Auftrag. Wenn der Wert auf 0 gesetzt wird, behält die Funktion den aktuellen Einstiegskurs bei.
  3. newSl (int): Der neue Wert von Stop-Loss (SL), ausgedrückt in Punkten. Wenn der Wert auf 0 gesetzt wird, wird die SL entweder entfernt oder bleibt unverändert.
  4. newTp (int): Der neue Wert von Take-Profit (TP), ausgedrückt in Punkten. Wenn der Wert auf 0 gesetzt wird, wird der TP entweder entfernt oder bleibt unverändert.

Diese Funktion ist vom Typ bool und soll den booleschen Wert true zurückgeben, wenn der Auftrag erfolgreich durchgeführt wurde, oder den booleschen Wert false, wenn die Änderung fehlgeschlagen ist, entweder aufgrund ungültiger Parameter, Fehler bei der Auswahl des Auftrags oder bei Serverproblemen. Beginnen wir mit der Codierung der nachstehenden Funktionsdefinition.

bool ModifyPendingOrderByTicket(ulong orderTicket, double newEntryPrice, int newSl, int newTp) export
  {

Bevor wir den Auftrag ändern, müssen wir sicherstellen, dass die Handelsumgebung den algorithmischen Handel zulässt. Wir werden die Funktion TradingIsAllowed() verwenden, um dies zu bestätigen.

if(!TradingIsAllowed())
     {
      return(false); //--- algo trading is disabled, exit function
     }

Um sicherzustellen, dass wir der richtige Auftrag ändern, müssen wir der Auftrag mit der Standard-MQL5-Funktion OrderSelect() und dem mitgelieferten Funktionsparameter orderTicket auswählen. Wenn orderTicket nicht gültig ist oder nicht erfolgreich ausgewählt wurde, wird dieser Fehler protokolliert und die Funktion beendet, wobei der boolesche Wert false zurückgegeben wird. Wenn die Auswahl von orderTicket erfolgreich ist, drucken wir eine kurze Protokollmeldung aus und fahren mit der Bearbeitung des Auftrags fort.

//--- Confirm and select the order using the provided orderTicket
   ResetLastError(); //--- Reset error cache incase of ticket selection errors
   if(OrderSelect(orderTicket))
     {
      //---Order selected
      Print("\r\n_______________________________________________________________________________________");
      Print(__FUNCTION__, ": Order with ticket:", orderTicket, " selected and ready to set SLTP.");
     }
   else
     {
      Print("\r\n_______________________________________________________________________________________");
      Print(__FUNCTION__, ": Selecting order with ticket:", orderTicket, " failed. ERROR: ", GetLastError());
      return(false); //-- Exit the function
     }

Sobald der Auftrag ausgewählt ist, erstellen wir einige Variablen vom Typ double , um unsere Kurse für Take-Profit und Stop-Loss zu speichern, und initialisieren sie mit dem Standardwert Null (0.0). Dann rufen wir Details über den Auftrag ab (wie Symbol, Volumen, aktueller SL/TP, etc.), die für die Validierung und Änderung benötigt werden.

double newTpPrice = 0.0, newSlPrice = 0.0;

//--- Order ticket selected, save the order properties
   string orderSymbol = OrderGetString(ORDER_SYMBOL);
   double currentEntryPrice = OrderGetDouble(ORDER_PRICE_OPEN);
   double volume = OrderGetDouble(ORDER_VOLUME_INITIAL);
   double currentOrderSlPrice = OrderGetDouble(ORDER_SL);
   double currentOrderTpPrice = OrderGetDouble(ORDER_TP);
   ENUM_ORDER_TYPE orderType = (ENUM_ORDER_TYPE)OrderGetInteger(ORDER_TYPE);
   double orderPriceCurrent = OrderGetDouble(ORDER_PRICE_CURRENT);

//-- Get some information about the orders symbol
   int symbolDigits = (int)SymbolInfoInteger(orderSymbol, SYMBOL_DIGITS); //-- Number of symbol decimal places
   int symbolStopLevel = (int)SymbolInfoInteger(orderSymbol, SYMBOL_TRADE_STOPS_LEVEL);
   double symbolPoint = SymbolInfoDouble(orderSymbol, SYMBOL_POINT);
   int spread = (int)SymbolInfoInteger(orderSymbol, SYMBOL_SPREAD);

Als Nächstes überprüfen wir den neuen Einstiegskurs, um sicherzustellen, dass er je nach Auftragsart (z. B. Kauflimit, Kaufstopp, Verkaufsstopp und Verkaufslimit) korrekt ist. So wird sichergestellt, dass wir ungültige Preise frühzeitig erkennen und ablehnen.

if(newEntryPrice > 0.0)
     {
      if(orderType == ORDER_TYPE_BUY_STOP || orderType == ORDER_TYPE_SELL_LIMIT)
        {
         if(
            SymbolInfoDouble(orderSymbol, SYMBOL_ASK) + (symbolStopLevel * symbolPoint) >
            newEntryPrice - (spread * symbolPoint)
         )
           {
            Print(
               "\r\n", __FUNCTION__, ": Can't MODIFY ", EnumToString(orderType),
               ". (Reason --> INVALID NEW ENTRY PRICE: ", DoubleToString(newEntryPrice, symbolDigits), ")\r\n"
            );
            return(false); //-- Invalid new entry price, log the error, exit the function and return false
           }
        }

      if(orderType == ORDER_TYPE_BUY_LIMIT || orderType == ORDER_TYPE_SELL_STOP)
        {
         if(
            SymbolInfoDouble(orderSymbol, SYMBOL_BID) - (symbolStopLevel * symbolPoint) <
            newEntryPrice + (spread * symbolPoint)
         )
           {
            Print(
               "\r\n", __FUNCTION__, ": Can't MODIFY ", EnumToString(orderType),
               ". (Reason --> INVALID NEW ENTRY PRICE: ", DoubleToString(newEntryPrice, symbolDigits), ")\r\n"
            );
            return(false); //-- Invalid new entry price, log the error, exit the function and return false
           }
        }
     }
   else
     {
      newEntryPrice = currentEntryPrice; //-- Do not modify the entry price
     }

Außerdem müssen wir die neuen Stop-Loss- und Take-Profit-Kurse auf der Grundlage der Eingabeparameter berechnen und diese Werte mit dem Stop-Level des Brokers abgleichen.

if(orderType == ORDER_TYPE_BUY_STOP || orderType == ORDER_TYPE_BUY_LIMIT)
     {
      if(newSl == 0)
        {
         newSlPrice = 0.0; //-- Remove the sl
        }
      else
        {
         newSlPrice = newEntryPrice - (newSl * symbolPoint);
        }
      if(newTp == 0)
        {
         newTpPrice = 0.0; //-- Remove the tp
        }
      else
        {
         newTpPrice = newEntryPrice + (newTp * symbolPoint);
        }

      //-- Check the validity of the newSlPrice
      if(newSlPrice > 0 && newEntryPrice - newSlPrice < symbolStopLevel * symbolPoint)
        {
         Print(
            "\r\n", __FUNCTION__, ": Can't modify ", EnumToString(orderType),
            ". (Reason --> INVALID NEW SL PRICE: ", DoubleToString(newSlPrice, symbolDigits), ")\r\n"
         );
         return(false); //-- Invalid sl price, log the error, exit the function and return false
        }

      //-- Check the validity of the newTpPrice
      if(newTpPrice > 0 && newTpPrice - newEntryPrice < symbolStopLevel * symbolPoint)
        {
         Print(
            "\r\n", __FUNCTION__, ": Can't modify ", EnumToString(orderType),
            ". (Reason --> INVALID NEW TP PRICE: ", DoubleToString(newTpPrice, symbolDigits), ")\r\n"
         );
         return(false); //-- Invalid tp price, log the error, exit the function and return false
        }
     }

   if(orderType == ORDER_TYPE_SELL_STOP || orderType == ORDER_TYPE_SELL_LIMIT)
     {
      if(newSl == 0)
        {
         newSlPrice = 0.0; //-- Remove the sl
        }
      else
        {
         newSlPrice = newEntryPrice + (newSl * symbolPoint);
        }
      if(newTp == 0)
        {
         newTpPrice = 0.0; //-- Remove the tp
        }
      else
        {
         newTpPrice = newEntryPrice - (newTp * symbolPoint);
        }

      //-- Check the validity of the newSlPrice
      if(newSlPrice > 0 && newSlPrice - newEntryPrice < symbolStopLevel * symbolPoint)
        {
         Print(
            "\r\n", __FUNCTION__, ": Can't modify ", EnumToString(orderType),
            ". (Reason --> INVALID NEW SL PRICE: ", DoubleToString(newSlPrice, symbolDigits), ")\r\n"
         );
         return(false); //-- Invalid sl price, log the error, exit the function and return false
        }

      //-- Check the validity of the newTpPrice
      if(newTpPrice > 0 && newEntryPrice - newTpPrice < symbolStopLevel * symbolPoint)
        {
         Print(
            "\r\n", __FUNCTION__, ": Can't modify ", EnumToString(orderType),
            ". (Reason --> INVALID NEW TP PRICE: ", DoubleToString(newTpPrice, symbolDigits), ")\r\n"
         );
         return(false); //-- Invalid tp price, log the error, exit the function and return false
        }
     }

Da wir nun alle Werte validiert haben, fahren wir mit der Vorbereitung der Handelsanfrage fort, um den schwebenden Auftrag zu ändern, indem wir die entsprechenden Parameter einstellen. Wir setzen zunächst die Datenstruktur tradeRequest zurück und initialisieren sie dann mit unseren verifizierten und gültigen Auftragsdaten.

   ZeroMemory(tradeRequest);
   ZeroMemory(tradeResult);

//-- initialize the parameters to set the sltp
   tradeRequest.action = TRADE_ACTION_MODIFY; //-- Trade operation type for modifying the pending order
   tradeRequest.order = orderTicket;
   tradeRequest.symbol = orderSymbol;
   tradeRequest.price = newEntryPrice;
   tradeRequest.sl = newSlPrice;
   tradeRequest.tp = newTpPrice;
   tradeRequest.deviation = SymbolInfoInteger(orderSymbol, SYMBOL_SPREAD) * 2;

Als Nächstes implementieren wir einen Wiederholungsmechanismus, um die Änderungsanforderung mehrmals zu senden, wenn der erste Versuch fehlschlägt, um die Wahrscheinlichkeit einer erfolgreichen Änderung des Auftrags zu erhöhen. Im Falle eines kritischen Fehlers oder wenn alle Wiederholungsversuche erschöpft sind, gibt die Funktion falsezurück und wird beendet. Wenn der Auftrag erfolgreich geändert wurde, gibt die Funktion true zurück und wird beendet. Um zu vermeiden, dass der Handelsserver mit einer schnellen Reihe von aufeinanderfolgenden Anfragen überfordert wird, werden wir auch eine Verzögerung zwischen den Iterationen einführen, indem wir die Funktion Sleep(...) verwenden.

ResetLastError(); //--- reset error cache so that we get an accurate runtime error code in the ErrorAdvisor function

   for(int loop = 0; loop <= MAX_ORDER_RETRIES; loop++) //-- try modifying the price open, sl, and tp until the request is successful
     {
      //--- send order to the trade server
      if(OrderSend(tradeRequest, tradeResult))
        {
         //-- Confirm order execution
         if(tradeResult.retcode == 10008 || tradeResult.retcode == 10009)
           {
            PrintFormat("Successfully modified Pending Order: #%I64d %s %s", orderTicket, orderSymbol, EnumToString(orderType));
            PrintFormat("retcode=%u  runtime_code=%u", tradeResult.retcode, GetLastError());
            Print("_______________________________________________________________________________________\r\n\r\n");
            return(true); //-- exit function
            //break; //--- success - order placed ok. exit for loop
           }
        }
      else  //-- Order request failed
        {
         //-- order not sent or critical error found
         if(!ErrorAdvisor(__FUNCTION__, orderSymbol, tradeResult.retcode) || IsStopped())
           {
            PrintFormat("ERROR modifying Pending Order: #%I64d %s %s", orderTicket, orderSymbol, EnumToString(orderType));
            Print("_______________________________________________________________________________________\r\n\r\n");
            return(false); //-- exit function
            //break; //-- exit for loop

            Sleep(ORDER_RETRY_DELAYS);//-- Small pause before retrying to avoid overwhelming the trade server
           }
        }
     }

Hier ist der vollständige Funktionscode einschließlich einiger der fehlenden Teile mit allen Codesegmenten in der richtigen Reihenfolge.

bool ModifyPendingOrderByTicket(ulong orderTicket, double newEntryPrice, int newSl, int newTp) export
  {
//-- first check if the EA is allowed to trade
   if(!TradingIsAllowed())
     {
      return(false); //--- algo trading is disabled, exit function
     }

//--- Confirm and select the order using the provided orderTicket
   ResetLastError(); //--- Reset error cache incase of ticket selection errors
   if(OrderSelect(orderTicket))
     {
      //---Order selected
      Print("\r\n_______________________________________________________________________________________");
      Print(__FUNCTION__, ": Order with ticket:", orderTicket, " selected and ready to set SLTP.");
     }
   else
     {
      Print("\r\n_______________________________________________________________________________________");
      Print(__FUNCTION__, ": Selecting order with ticket:", orderTicket, " failed. ERROR: ", GetLastError());
      return(false); //-- Exit the function
     }

//-- create variables to store the calculated tp and sl prices to send to the trade server
   double newTpPrice = 0.0, newSlPrice = 0.0;

//--- Order ticket selected, save the order properties
   string orderSymbol = OrderGetString(ORDER_SYMBOL);
   double currentEntryPrice = OrderGetDouble(ORDER_PRICE_OPEN);
   double volume = OrderGetDouble(ORDER_VOLUME_INITIAL);
   double currentOrderSlPrice = OrderGetDouble(ORDER_SL);
   double currentOrderTpPrice = OrderGetDouble(ORDER_TP);
   ENUM_ORDER_TYPE orderType = (ENUM_ORDER_TYPE)OrderGetInteger(ORDER_TYPE);
   double orderPriceCurrent = OrderGetDouble(ORDER_PRICE_CURRENT);

//-- Get some information about the orders symbol
   int symbolDigits = (int)SymbolInfoInteger(orderSymbol, SYMBOL_DIGITS); //-- Number of symbol decimal places
   int symbolStopLevel = (int)SymbolInfoInteger(orderSymbol, SYMBOL_TRADE_STOPS_LEVEL);
   double symbolPoint = SymbolInfoDouble(orderSymbol, SYMBOL_POINT);
   int spread = (int)SymbolInfoInteger(orderSymbol, SYMBOL_SPREAD);

//-- Check the validity of the newEntryPrice
   if(newEntryPrice > 0.0)
     {
      if(orderType == ORDER_TYPE_BUY_STOP || orderType == ORDER_TYPE_SELL_LIMIT)
        {
         if(
            SymbolInfoDouble(orderSymbol, SYMBOL_ASK) + (symbolStopLevel * symbolPoint) >
            newEntryPrice - (spread * symbolPoint)
         )
           {
            Print(
               "\r\n", __FUNCTION__, ": Can't MODIFY ", EnumToString(orderType),
               ". (Reason --> INVALID NEW ENTRY PRICE: ", DoubleToString(newEntryPrice, symbolDigits), ")\r\n"
            );
            return(false); //-- Invalid new entry price, log the error, exit the function and return false
           }
        }

      if(orderType == ORDER_TYPE_BUY_LIMIT || orderType == ORDER_TYPE_SELL_STOP)
        {
         if(
            SymbolInfoDouble(orderSymbol, SYMBOL_BID) - (symbolStopLevel * symbolPoint) <
            newEntryPrice + (spread * symbolPoint)
         )
           {
            Print(
               "\r\n", __FUNCTION__, ": Can't MODIFY ", EnumToString(orderType),
               ". (Reason --> INVALID NEW ENTRY PRICE: ", DoubleToString(newEntryPrice, symbolDigits), ")\r\n"
            );
            return(false); //-- Invalid new entry price, log the error, exit the function and return false
           }
        }
     }
   else
     {
      newEntryPrice = currentEntryPrice; //-- Do not modify the entry price
     }

//-- Calculate and store the non-validated sl and tp prices
   if(orderType == ORDER_TYPE_BUY_STOP || orderType == ORDER_TYPE_BUY_LIMIT)
     {
      if(newSl == 0)
        {
         newSlPrice = 0.0; //-- Remove the sl
        }
      else
        {
         newSlPrice = newEntryPrice - (newSl * symbolPoint);
        }
      if(newTp == 0)
        {
         newTpPrice = 0.0; //-- Remove the tp
        }
      else
        {
         newTpPrice = newEntryPrice + (newTp * symbolPoint);
        }

      //-- Check the validity of the newSlPrice
      if(newSlPrice > 0 && newEntryPrice - newSlPrice < symbolStopLevel * symbolPoint)
        {
         Print(
            "\r\n", __FUNCTION__, ": Can't modify ", EnumToString(orderType),
            ". (Reason --> INVALID NEW SL PRICE: ", DoubleToString(newSlPrice, symbolDigits), ")\r\n"
         );
         return(false); //-- Invalid sl price, log the error, exit the function and return false
        }

      //-- Check the validity of the newTpPrice
      if(newTpPrice > 0 && newTpPrice - newEntryPrice < symbolStopLevel * symbolPoint)
        {
         Print(
            "\r\n", __FUNCTION__, ": Can't modify ", EnumToString(orderType),
            ". (Reason --> INVALID NEW TP PRICE: ", DoubleToString(newTpPrice, symbolDigits), ")\r\n"
         );
         return(false); //-- Invalid tp price, log the error, exit the function and return false
        }
     }

   if(orderType == ORDER_TYPE_SELL_STOP || orderType == ORDER_TYPE_SELL_LIMIT)
     {
      if(newSl == 0)
        {
         newSlPrice = 0.0; //-- Remove the sl
        }
      else
        {
         newSlPrice = newEntryPrice + (newSl * symbolPoint);
        }
      if(newTp == 0)
        {
         newTpPrice = 0.0; //-- Remove the tp
        }
      else
        {
         newTpPrice = newEntryPrice - (newTp * symbolPoint);
        }

      //-- Check the validity of the newSlPrice
      if(newSlPrice > 0 && newSlPrice - newEntryPrice < symbolStopLevel * symbolPoint)
        {
         Print(
            "\r\n", __FUNCTION__, ": Can't modify ", EnumToString(orderType),
            ". (Reason --> INVALID NEW SL PRICE: ", DoubleToString(newSlPrice, symbolDigits), ")\r\n"
         );
         return(false); //-- Invalid sl price, log the error, exit the function and return false
        }

      //-- Check the validity of the newTpPrice
      if(newTpPrice > 0 && newEntryPrice - newTpPrice < symbolStopLevel * symbolPoint)
        {
         Print(
            "\r\n", __FUNCTION__, ": Can't modify ", EnumToString(orderType),
            ". (Reason --> INVALID NEW TP PRICE: ", DoubleToString(newTpPrice, symbolDigits), ")\r\n"
         );
         return(false); //-- Invalid tp price, log the error, exit the function and return false
        }
     }

//-- Print order properties before modification
   string orderProperties = "--> "  + orderSymbol + " " + EnumToString(orderType) + " SLTP Modification Details" +
                            " <--\r\n";
   orderProperties += "------------------------------------------------------------\r\n";
   orderProperties += "Ticket: " + (string)orderTicket + "\r\n";
   orderProperties += "Volume: " + DoubleToString(volume, symbolDigits) + "\r\n";
   orderProperties += "Price Open: " + DoubleToString(currentEntryPrice, symbolDigits) +
                      "   -> New Proposed Price Open: " + DoubleToString(newEntryPrice, symbolDigits) + "\r\n";
   orderProperties += "Current SL: " + DoubleToString(currentOrderSlPrice, symbolDigits) +
                      "   -> New Proposed SL: " + DoubleToString(newSlPrice, symbolDigits) + "\r\n";
   orderProperties += "Current TP: " + DoubleToString(currentOrderTpPrice, symbolDigits) +
                      "   -> New Proposed TP: " + DoubleToString(newTpPrice, symbolDigits) + "\r\n";
   orderProperties += "Comment: " + OrderGetString(ORDER_COMMENT) + "\r\n";
   orderProperties += "Magic Number: " + (string)OrderGetInteger(ORDER_MAGIC) + "\r\n";
   orderProperties += "---";

//-- Print verified order properties before modification
   orderProperties += "--> Validated and Confirmed NewEntry, SL, and TP Prices: <--\r\n";
   orderProperties += "Order Price Current: " + DoubleToString(orderPriceCurrent, symbolDigits) + "\r\n";
   orderProperties += "Current Entry Price: " + DoubleToString(currentEntryPrice, symbolDigits) +
                      ", New Entry Price: " + DoubleToString(newEntryPrice, symbolDigits) + "\r\n";
   orderProperties += "Current SL: " + DoubleToString(currentOrderSlPrice, symbolDigits) +
                      "   -> New SL: " + DoubleToString(newSlPrice, symbolDigits) + "\r\n";
   orderProperties += "Current TP: " + DoubleToString(currentOrderTpPrice, symbolDigits) +
                      "   -> New TP: " + DoubleToString(newTpPrice, symbolDigits) + "\r\n";
   Print(orderProperties);

//-- reset the the tradeRequest and tradeResult values by zeroing them
   ZeroMemory(tradeRequest);
   ZeroMemory(tradeResult);

//-- initialize the parameters to set the sltp
   tradeRequest.action = TRADE_ACTION_MODIFY; //-- Trade operation type for modifying the pending order
   tradeRequest.order = orderTicket;
   tradeRequest.symbol = orderSymbol;
   tradeRequest.price = newEntryPrice;
   tradeRequest.sl = newSlPrice;
   tradeRequest.tp = newTpPrice;
   tradeRequest.deviation = SymbolInfoInteger(orderSymbol, SYMBOL_SPREAD) * 2;

   ResetLastError(); //--- reset error cache so that we get an accurate runtime error code in the ErrorAdvisor function

   for(int loop = 0; loop <= MAX_ORDER_RETRIES; loop++) //-- try modifying the price open, sl, and tp until the request is successful
     {
      //--- send order to the trade server
      if(OrderSend(tradeRequest, tradeResult))
        {
         //-- Confirm order execution
         if(tradeResult.retcode == 10008 || tradeResult.retcode == 10009)
           {
            PrintFormat("Successfully modified Pending Order: #%I64d %s %s", orderTicket, orderSymbol, EnumToString(orderType));
            PrintFormat("retcode=%u  runtime_code=%u", tradeResult.retcode, GetLastError());
            Print("_______________________________________________________________________________________\r\n\r\n");
            return(true); //-- exit function
            //break; //--- success - order placed ok. exit for loop
           }
        }
      else  //-- Order request failed
        {
         //-- order not sent or critical error found
         if(!ErrorAdvisor(__FUNCTION__, orderSymbol, tradeResult.retcode) || IsStopped())
           {
            PrintFormat("ERROR modifying Pending Order: #%I64d %s %s", orderTicket, orderSymbol, EnumToString(orderType));
            Print("_______________________________________________________________________________________\r\n\r\n");
            return(false); //-- exit function
            //break; //-- exit for loop

            Sleep(ORDER_RETRY_DELAYS);//-- Small pause before retrying to avoid overwhelming the trade server
           }
        }
     }
   return(false);
  }


Löschen eines schwebenden Auftrags nach Ticketfunktion

Die Funktion DeletePendingOrderByTicket(...) ist für die Löschung eines schwebenden Auftrags anhand seiner eindeutigen Ticketnummer zuständig. Er prüft zunächst, ob der algorithmische Handel aktiviert ist, wählt den Auftrag aus und versucht dann, ihn auf dem Handelsserver zu löschen. Während des gesamten Prozesses protokolliert die Funktion wichtige Details über den Auftrag in verschiedenen Stadien und setzt einen Wiederholungsmechanismus ein, um die Chancen auf eine erfolgreiche Löschung zu maximieren, indem sie es bei Bedarf mehrmals versucht.

Die Funktion akzeptiert einen Parameter vom Typ ulong, nämlich das orderTicket , das die eindeutige Ticketnummer des zu löschenden Auftrags darstellt. Sie gibt ein boolschen Wert zurück, wobei true bedeutet, dass der schwebende Auftrag erfolgreich gelöscht wurde, und false, dass die Löschung fehlgeschlagen ist oder ein kritischer Fehler aufgetreten ist.

Nachfolgend finden Sie den vollständigen Funktionscode mit ausführlichen Kommentaren, um das Verständnis zu erleichtern.

bool DeletePendingOrderByTicket(ulong orderTicket) export
  {
//-- first check if the EA is allowed to trade
   if(!TradingIsAllowed())
     {
      return(false); //--- algo trading is disabled, exit function
     }

//--- Confirm and select the order using the provided orderTicket
   ResetLastError(); //--- Reset error cache incase of ticket selection errors
   if(OrderSelect(orderTicket))
     {
      //---Order selected
      Print("...........................................................................................");
      Print(__FUNCTION__, ": Order with ticket:", orderTicket, " selected and ready to be deleted.");
     }
   else
     {
      Print("...........................................................................................");
      Print(__FUNCTION__, ": Selecting order with ticket:", orderTicket, " failed. ERROR: ", GetLastError());
      return(false); //-- Exit the function
     }

//--- Order ticket selected, save the order properties
   string orderSymbol = OrderGetString(ORDER_SYMBOL);
   double orderVolume = OrderGetDouble(ORDER_VOLUME_CURRENT);
   int symbolDigits = (int)SymbolInfoInteger(orderSymbol, SYMBOL_DIGITS);
   ENUM_ORDER_TYPE orderType = (ENUM_ORDER_TYPE)OrderGetInteger(ORDER_TYPE);

//-- Print order properties before deleting it
   string orderProperties;
   orderProperties += "-- "  + orderSymbol + " " + EnumToString(orderType) + " Details" +
   " -------------------------------------------------------------\r\n";
   orderProperties += "Ticket: " + (string)orderTicket + "\r\n";
   orderProperties += "Volume: " + DoubleToString(orderVolume) + "\r\n";
   orderProperties += "Price Open: " + DoubleToString(OrderGetDouble(ORDER_PRICE_OPEN), symbolDigits) + "\r\n";
   orderProperties += "SL: " + DoubleToString(OrderGetDouble(ORDER_SL), symbolDigits) + "\r\n";
   orderProperties += "TP: " + DoubleToString(OrderGetDouble(ORDER_TP), symbolDigits) + "\r\n";
   orderProperties += "Comment: " + OrderGetString(ORDER_COMMENT) + "\r\n";
   orderProperties += "Magic Number: " + (string)OrderGetInteger(ORDER_MAGIC) + "\r\n";
   orderProperties += "_______________________________________________________________________________________";
   Print(orderProperties);

//-- reset the the tradeRequest and tradeResult values by zeroing them
   ZeroMemory(tradeRequest);
   ZeroMemory(tradeResult);

//-- initialize the trade reqiest parameters to delete the order
   tradeRequest.action = TRADE_ACTION_REMOVE; //-- Trade operation type for deleting an order
   tradeRequest.order = orderTicket;

   ResetLastError(); //--- reset error cache so that we get an accurate runtime error code in the ErrorAdvisor function

   for(int loop = 0; loop <= MAX_ORDER_RETRIES; loop++) //-- try deleting the order until the request is successful
     {
      //--- send order to the trade server
      if(OrderSend(tradeRequest, tradeResult))
        {
         //-- Confirm order execution
         if(tradeResult.retcode == 10008 || tradeResult.retcode == 10009)
           {
            Print(__FUNCTION__, "_________________________________________________________________________");
            PrintFormat("Successfully deleted order #%I64d %s %s", orderTicket, orderSymbol, EnumToString(orderType));
            PrintFormat("retcode=%u  runtime_code=%u", tradeResult.retcode, GetLastError());
            Print("_______________________________________________________________________________________");
            return(true); //-- exit function
            //break; //--- success - order placed ok. exit for loop
           }
        }
      else  //-- order deleting request failed
        {
         //-- order not sent or critical error found
         if(!ErrorAdvisor(__FUNCTION__, orderSymbol, tradeResult.retcode) || IsStopped())
           {
            Print(__FUNCTION__, "_________________________________________________________________________");
            PrintFormat("ERROR deleting order #%I64d %s %s", orderTicket, orderSymbol, EnumToString(orderType));
            Print("_______________________________________________________________________________________");
            return(false); //-- exit function
            //break; //-- exit for loop

            Sleep(ORDER_RETRY_DELAYS);//-- Small pause before retrying to avoid overwhelming the trade server
           }
        }
     }
   return(false);
  }


Funktion „DeleteAllPendingOrders“

Die Funktion DeleteAllPendingOrders(...) löscht alle schwebenden Aufträge für ein bestimmtes Symbol und eine magische Zahl. Er stellt zunächst sicher, dass der algorithmische Handel aktiviert ist, bevor er fortfährt. Die Funktion durchläuft alle offenen Aufträge, prüft, ob sie mit dem angegebenen Symbol und der magischen Zahl übereinstimmen, und versucht, sie einen nach dem anderen zu löschen. In Fällen, in denen einige Aufträge nicht sofort gelöscht werden können, verwendet die Funktion einen Rückruf- und Wiederholungsmechanismus, um die Löschung kontinuierlich zu versuchen, bis alle betroffenen Aufträge entfernt sind. Während des gesamten Prozesses werden Fehler protokolliert und auf kritische Probleme geprüft, um ein mögliches Festfahren in einer Endlosschleife zu vermeiden.

Die Funktion akzeptiert zwei optionale Parameter:

  1. symbol (string): Ein Parameter von Typ string für das Handelssymbol. Der Standardwert ist ALL_SYMBOLS, d.h. es werden Aufträge für alle Symbole angestrebt, es sei denn, es wird ein bestimmtes Symbol angegeben.
  2. magicNumber (ulong): Ein Long-Integer-Parameter ohne Vorzeichen, der die eindeutige, magische Nummer der Aufträge angibt. Der Standardwert ist 0, d. h. die Funktion zielt auf alle Aufträge ab, unabhängig von ihrer magischen Zahl, es sei denn, es wird ein bestimmter Wert angegeben.

Die Funktion gibt einen boolschen Wert (bool) zurück, wobei true bedeutet, dass alle anvisierten, schwebenden Aufträge erfolgreich gelöscht wurden, und false bedeutet, dass einige oder alle Aufträge nicht gelöscht werden konnten oder dass ein kritischer Fehler aufgetreten ist.

Nachstehend finden Sie den vollständigen Funktionscode, der zum besseren Verständnis mit Kommentaren versehen ist:

bool DeleteAllPendingOrders(string symbol = ALL_SYMBOLS, ulong magicNumber = 0) export
  {
//-- first check if the EA is allowed to trade
   if(!TradingIsAllowed())
     {
      return(false); //--- algo trading is disabled, exit function
     }

   bool returnThis = false;

//-- Scan for symbol and magic number for the specified orders and close them
   int totalOpenOrders = OrdersTotal();
   for(int x = 0; x < totalOpenOrders; x++)
     {
      //--- Get order properties
      ulong orderTicket = OrderGetTicket(x); //-- Get ticket to select the order
      string selectedSymbol = OrderGetString(ORDER_SYMBOL);
      ulong orderMagicNo = OrderGetInteger(ORDER_MAGIC);

      //-- Filter orders by symbol and magic number
      if(
         (symbol != ALL_SYMBOLS && symbol != selectedSymbol) ||
         (magicNumber != 0 && orderMagicNo != magicNumber)
      )
        {
         continue;
        }

      //-- Delete the order
      DeletePendingOrderByTicket(orderTicket);
     }

//-- Confirm that we have closed all the orders being targeted
   int breakerBreaker = 0; //-- Variable that safeguards and makes sure we are not locked in an infinite loop
   while(SymbolOrdersTotal(symbol, magicNumber) > 0)
     {
      breakerBreaker++;
      DeleteAllPendingOrders(symbol, magicNumber); //-- We still have some open orders, do a function callback
      Sleep(ORDER_RETRY_DELAYS); //-- Micro sleep to pace the execution and give some time to the trade server

      //-- Check for critical errors so that we exit the loop if we run into trouble
      if(!ErrorAdvisor(__FUNCTION__, symbol, GetLastError()) || IsStopped() || breakerBreaker > MAX_ORDER_RETRIES)
        {
         break;
        }
     }

//-- Final confirmations that all targeted orders have been closed
   if(SymbolOrdersTotal(symbol, magicNumber) == 0)
     {
      returnThis = true; //-- Save this status for the function return value
     }

   return(returnThis);
  }

Um das Löschen aller anhängigen Aufträge schneller und weniger mühsam zu machen, werden wir die Funktion DeleteAllPendingOrders(...) mit einer zweiten Version überladen, die keine Argumente benötigt. Wenn sie aufgerufen wird, werden alle schwebenden Aufträge im Konto gelöscht. Nachstehend finden Sie die überladene Funktion DeleteAllPendingOrders():

bool DeleteAllPendingOrders() export
  {
   return(DeleteAllPendingOrders(ALL_SYMBOLS, 0));
  }


Die Funktion „DeleteAllBuyStops“

Die Funktion DeleteAllBuyStops(...) ist verantwortlich für das Löschen aller schwebenden BuyStop-Orders für ein bestimmtes Symbol und eine magische Zahl. Ähnlich wie bei anderen Löschfunktionen wird zunächst geprüft, ob der algorithmische Handel aktiviert ist. Die Funktion durchsucht dann alle offenen Aufträge, identifiziert diejenigen, die mit dem Symbol, der magischen Zahl und dem Auftragstyp (BuyStop) übereinstimmen, und versucht, sie zu löschen. Werden Aufträge beim ersten Durchlauf nicht gelöscht, versucht die Funktion mit Hilfe eines Callback- und Retry-Mechanismus kontinuierlich, sie zu löschen. Es stellt sicher, dass keine Endlosschleifen auftreten, indem es Sicherheitsvorkehrungen trifft und auf Fehler prüft. Während des gesamten Prozesses protokolliert die Funktion relevante Informationen und verwaltet kritische Fehler.

Die Funktion akzeptiert zwei optionale Parameter:

  1. symbol (string): Eine Zeichenfolge , die das Handelssymbol darstellt. Die Standardeinstellung ist ALL_SYMBOLS, d.h. es werden BuyStop-Orders für alle Symbole ausgeführt, es sei denn, es wird ein bestimmtes Symbol angegeben.
  2. magicNumber (ulong): Eine ganze Zahl ohne Vorzeichen, die die eindeutige magische Nummer darstellt, die den Aufträgen zugewiesen wurde. Der Standardwert ist 0, was bedeutet, dass die Funktion alle BuyStop-Aufträge unabhängig von ihrer magischen Zahl anvisiert, es sei denn, es wird eine bestimmte magische Zahl angegeben.

Die Funktion gibt einen boolschen Wert (bool) zurück, wobei true bedeutet, dass alle angestrebten BuyStop-Aufträge erfolgreich gelöscht wurden, und false bedeutet, dass die Funktion einige oder alle Aufträge nicht löschen konnte oder ein kritisches Problem aufgetreten ist.

Nachstehend finden Sie den vollständigen Funktionscode mit hilfreichen Kommentaren, die das Verständnis erleichtern:

bool DeleteAllBuyStops(string symbol = ALL_SYMBOLS, ulong magicNumber = 0) export
  {
//-- first check if the EA is allowed to trade
   if(!TradingIsAllowed())
     {
      return(false); //--- algo trading is disabled, exit function
     }

   bool returnThis = false;

//-- Scan for symbol and magic number specific buy stop orders and close them
   int totalOpenOrders = OrdersTotal();
   for(int x = 0; x < totalOpenOrders; x++)
     {
      //--- Get order properties
      ulong orderTicket = OrderGetTicket(x); //-- Get ticket to select the order
      string selectedSymbol = OrderGetString(ORDER_SYMBOL);
      ulong orderMagicNo = OrderGetInteger(ORDER_MAGIC);
      ulong orderType = OrderGetInteger(ORDER_TYPE);

      //-- Filter order by symbol, type and magic number
      if(
         (symbol != ALL_SYMBOLS && symbol != selectedSymbol) || (orderType != ORDER_TYPE_BUY_STOP) ||
         (magicNumber != 0 && orderMagicNo != magicNumber)
      )
        {
         continue;
        }

      //-- Close the order
      DeletePendingOrderByTicket(orderTicket);
     }

//-- Confirm that we have closed all the buy stop orders being targeted
   int breakerBreaker = 0; //-- Variable that safeguards and makes sure we are not locked in an infinite loop
   while(SymbolBuyStopOrdersTotal(symbol, magicNumber) > 0)
     {
      breakerBreaker++;
      DeleteAllBuyStops(symbol, magicNumber); //-- We still have some open buy stop orders, do a function callback
      Sleep(ORDER_RETRY_DELAYS); //-- Micro sleep to pace the execution and give some time to the trade server

      //-- Check for critical errors so that we exit the loop if we run into trouble
      if(!ErrorAdvisor(__FUNCTION__, symbol, GetLastError()) || IsStopped() || breakerBreaker > MAX_ORDER_RETRIES)
        {
         break;
        }
     }

   if(SymbolBuyStopOrdersTotal(symbol, magicNumber) == 0)
     {
      returnThis = true;
     }
   return(returnThis);
  }


Die Funktion „DeleteAllBuyLimits“

Die Funktion DeleteAllBuyLimits(...) hat die Aufgabe, alle schwebenden BuyLimit-Orders für ein bestimmtes Symbol und eine magische Zahl zu löschen. Die Funktion gibt einen boolschen Wert (bool) zurück, wobei true bedeutet, dass alle angestrebten Kauf-Limit-Orders erfolgreich gelöscht wurden, und false bedeutet, dass die Funktion einige oder alle Orders nicht löschen konnte oder ein kritisches Problem aufgetreten ist.

bool DeleteAllBuyLimits(string symbol = ALL_SYMBOLS, ulong magicNumber = 0) export
  {
//-- first check if the EA is allowed to trade
   if(!TradingIsAllowed())
     {
      return(false); //--- algo trading is disabled, exit function
     }

   bool returnThis = false;

//-- Scan for symbol and magic number specific buy limit orders and close them
   int totalOpenOrders = OrdersTotal();
   for(int x = 0; x < totalOpenOrders; x++)
     {
      //--- Get order properties
      ulong orderTicket = OrderGetTicket(x); //-- Get ticket to select the order
      string selectedSymbol = OrderGetString(ORDER_SYMBOL);
      ulong orderMagicNo = OrderGetInteger(ORDER_MAGIC);
      ulong orderType = OrderGetInteger(ORDER_TYPE);

      //-- Filter order by symbol, type and magic number
      if(
         (symbol != ALL_SYMBOLS && symbol != selectedSymbol) || (orderType != ORDER_TYPE_BUY_LIMIT) ||
         (magicNumber != 0 && orderMagicNo != magicNumber)
      )
        {
         continue;
        }

      //-- Close the order
      DeletePendingOrderByTicket(orderTicket);
     }

//-- Confirm that we have closed all the buy limit orders being targeted
   int breakerBreaker = 0; //-- Variable that safeguards and makes sure we are not locked in an infinite loop
   while(SymbolBuyLimitOrdersTotal(symbol, magicNumber) > 0)
     {
      breakerBreaker++;
      DeleteAllBuyLimits(symbol, magicNumber); //-- We still have some open buy limit orders, do a function callback
      Sleep(ORDER_RETRY_DELAYS); //-- Micro sleep to pace the execution and give some time to the trade server

      //-- Check for critical errors so that we exit the loop if we run into trouble
      if(!ErrorAdvisor(__FUNCTION__, symbol, GetLastError()) || IsStopped() || breakerBreaker > MAX_ORDER_RETRIES)
        {
         break;
        }
     }

   if(SymbolBuyLimitOrdersTotal(symbol, magicNumber) == 0)
     {
      returnThis = true;
     }
   return(returnThis);
  }


Funktion „DeleteAllSellStops“

Die Funktion DeleteAllSellStops(...) ist verantwortlich für das Löschen aller schwebenden SellStop-Order, die mit einem bestimmten Symbol und einer magischen Zahl verbunden sind. Sie gibt einen boolschen Wert (bool) zurück, wobei true bedeutet, dass alle angestrebten Verkaufsstopp-Aufträge erfolgreich gelöscht wurden, und false, dass die Funktion entweder einige oder alle Aufträge nicht löschen konnte oder ein kritischer Fehler aufgetreten ist.

bool DeleteAllSellStops(string symbol = ALL_SYMBOLS, ulong magicNumber = 0) export
  {
//-- first check if the EA is allowed to trade
   if(!TradingIsAllowed())
     {
      return(false); //--- algo trading is disabled, exit function
     }

   bool returnThis = false;

//-- Scan for symbol and magic number specific sell stop orders and close them
   int totalOpenOrders = OrdersTotal();
   for(int x = 0; x < totalOpenOrders; x++)
     {
      //--- Get order properties
      ulong orderTicket = OrderGetTicket(x); //-- Get ticket to select the order
      string selectedSymbol = OrderGetString(ORDER_SYMBOL);
      ulong orderMagicNo = OrderGetInteger(ORDER_MAGIC);
      ulong orderType = OrderGetInteger(ORDER_TYPE);

      //-- Filter order by symbol, type and magic number
      if(
         (symbol != ALL_SYMBOLS && symbol != selectedSymbol) || (orderType != ORDER_TYPE_SELL_STOP) ||
         (magicNumber != 0 && orderMagicNo != magicNumber)
      )
        {
         continue;
        }

      //-- Close the order
      DeletePendingOrderByTicket(orderTicket);
     }

//-- Confirm that we have closed all the sell stop orders being targeted
   int breakerBreaker = 0; //-- Variable that safeguards and makes sure we are not locked in an infinite loop
   while(SymbolSellStopOrdersTotal(symbol, magicNumber) > 0)
     {
      breakerBreaker++;
      DeleteAllSellStops(symbol, magicNumber); //-- We still have some open sell stop orders, do a function callback
      Sleep(ORDER_RETRY_DELAYS); //-- Micro sleep to pace the execution and give some time to the trade server

      //-- Check for critical errors so that we exit the loop if we run into trouble
      if(!ErrorAdvisor(__FUNCTION__, symbol, GetLastError()) || IsStopped() || breakerBreaker > MAX_ORDER_RETRIES)
        {
         break;
        }
     }

   if(SymbolSellStopOrdersTotal(symbol, magicNumber) == 0)
     {
      returnThis = true;
     }
   return(returnThis);
  }


Die Funktion „DeleteAllSellLimits“

Die Funktion DeleteAllSellLimits(...) löscht alle schwebenden SellLimit-Orders, die mit einem bestimmten Symbol und einer magischen Zahl verknüpft sind. Sie gibt den booleschen Wert true zurück, wenn alle angegebenen Limit-Verkaufsaufträge erfolgreich gelöscht wurden, und false, wenn die Funktion einige oder alle Aufträge nicht löschen konnte oder ein kritischer Fehler auftrat.

bool DeleteAllSellLimits(string symbol = ALL_SYMBOLS, ulong magicNumber = 0) export
  {
//-- first check if the EA is allowed to trade
   if(!TradingIsAllowed())
     {
      return(false); //--- algo trading is disabled, exit function
     }

   bool returnThis = false;

//-- Scan for symbol and magic number specific sell limit orders and close them
   int totalOpenOrders = OrdersTotal();
   for(int x = 0; x < totalOpenOrders; x++)
     {
      //--- Get order properties
      ulong orderTicket = OrderGetTicket(x); //-- Get ticket to select the order
      string selectedSymbol = OrderGetString(ORDER_SYMBOL);
      ulong orderMagicNo = OrderGetInteger(ORDER_MAGIC);
      ulong orderType = OrderGetInteger(ORDER_TYPE);

      //-- Filter order by symbol, type and magic number
      if(
         (symbol != ALL_SYMBOLS && symbol != selectedSymbol) || (orderType != ORDER_TYPE_SELL_LIMIT) ||
         (magicNumber != 0 && orderMagicNo != magicNumber)
      )
        {
         continue;
        }

      //-- Close the order
      DeletePendingOrderByTicket(orderTicket);
     }

//-- Confirm that we have closed all the sell limit orders being targeted
   int breakerBreaker = 0; //-- Variable that safeguards and makes sure we are not locked in an infinite loop
   while(SymbolSellLimitOrdersTotal(symbol, magicNumber) > 0)
     {
      breakerBreaker++;
      DeleteAllSellLimits(symbol, magicNumber); //-- We still have some open sell limit orders, do a function callback
      Sleep(ORDER_RETRY_DELAYS); //-- Micro sleep to pace the execution and give some time to the trade server

      //-- Check for critical errors so that we exit the loop if we run into trouble
      if(!ErrorAdvisor(__FUNCTION__, symbol, GetLastError()) || IsStopped() || breakerBreaker > MAX_ORDER_RETRIES)
        {
         break;
        }
     }

   if(SymbolSellLimitOrdersTotal(symbol, magicNumber) == 0)
     {
      returnThis = true;
     }
   return(returnThis);
  }


Die Funktion „DeleteAllMagicOrders“

Die Funktion DeleteAllMagicOrders(...) ist für die Löschung aller schwebende Aufträge zuständig, die mit einer bestimmten magischen Zahl verbunden sind. Sie gibt einen boolschen Wert zurück, wobei true bedeutet, dass alle relevanten, „magischen“ Aufträge erfolgreich gelöscht wurden, und false, dass die Funktion entweder einige oder alle Aufträge nicht löschen konnte oder ein kritischer Fehler aufgetreten ist.

bool DeleteAllMagicOrders(ulong magicNumber) export
  {
//-- first check if the EA is allowed to trade
   if(!TradingIsAllowed())
     {
      return(false); //--- algo trading is disabled, exit function
     }

   bool returnThis = false;

//-- Variables to store the selected orders data
   ulong orderTicket, orderMagicNo;
   string orderSymbol;

//-- Scan for magic number specific orders and delete them
   int totalOpenOrders = OrdersTotal();
   for(int x = 0; x < totalOpenOrders; x++)
     {
      //--- Get order properties
      orderTicket = OrderGetTicket(x); //-- Get ticket to select the order
      orderMagicNo = OrderGetInteger(ORDER_MAGIC);
      orderSymbol = OrderGetString(ORDER_SYMBOL);

      //-- Filter orders by magic number
      if(magicNumber == orderMagicNo)
        {
         //-- Delete the order
         DeletePendingOrderByTicket(orderTicket);
        }
     }

//-- Confirm that we have deleted all the orders being targeted
   int breakerBreaker = 0; //-- Variable that safeguards and makes sure we are not locked in an infinite loop
   while(MagicOrdersTotal(magicNumber) > 0)
     {
      breakerBreaker++;
      DeleteAllMagicOrders(magicNumber); //-- We still have some open orders, do a function callback
      Sleep(ORDER_RETRY_DELAYS); //-- Micro sleep to pace the execution and give some time to the trade server

      //-- Check for critical errors so that we exit the loop if we run into trouble
      if(!ErrorAdvisor(__FUNCTION__, orderSymbol, GetLastError()) || IsStopped() || breakerBreaker > MAX_ORDER_RETRIES)
        {
         break;
        }
     }

   if(MagicOrdersTotal(magicNumber) == 0)
     {
      returnThis = true;
     }
   return(returnThis);
  }


Funktion zum Abrufen von Daten zu schwebenden Aufträgen

Damit ein autonomes, algorithmisches Handelssystem oder ein Expert Advisor verlässlich und dauerhaft profitabel sein kann, muss es alle Positions- und Auftragsstatus des Kontos kennen. Im zweiten Artikel haben wir eine Funktion zur Überwachung von Positionen entwickelt, die Daten über alle offenen Positionen sammelt. Da sich dieser Artikel auf schwebende Aufträge konzentriert, werden wir eine Funktion erstellen, die die Daten aller schwebenden Aufträge scannt und speichert, um sie in der gesamten Bibliothek für die Verwendung durch andere Funktionen verfügbar zu machen. Dazu verwenden wir die zu Beginn dieses Artikels festgelegten globalen Variablen.

Da diese globalen Variablen nicht exportiert werden können oder außerhalb der Quellcodedatei der Bibliothek oder der EX5-Binärdatei zugänglich sind, werden wir sie an verschiedene exportierbare Statusfunktionen für schwebende Aufträge übergeben, damit sie in der endgültigen EX5-Bibliothek zugänglich sind. Wir beginnen mit der Erstellung einer Funktion zum Abrufen aller Daten der schwebenden Aufträge, die wir GetPendingOrdersData(...) nennen.

Die Funktion GetPendingOrdersData(...) holt und speichert die Statusdetails offener, schwebender Aufträge in Bezug auf das Konto, bestimmte Handelssymbole und die magische Zahl des Expert Advisors. Zunächst werden verschiedene globale Variablen zurückgesetzt, in denen Summen und Volumina für verschiedene Arten von schwebenden Aufträgen gespeichert sind, einschließlich Kaufstopps, Kauflimits, Verkaufsstopps und Verkaufslimits. Nach dem Zurücksetzen prüft die Funktion, ob noch offene Aufträge vorhanden sind, und durchläuft diese, um die relevanten Daten zu sammeln. Es filtert dann die Aufträge auf der Grundlage des angegebenen Symbols und der magischen Zahl und sammelt die Summen und Volumina für die übereinstimmenden schwebenden Aufträge. Durch diesen umfassenden Ansatz wird sichergestellt, dass die Funktion Echtzeitdaten über den Status der schwebenden Aufträge erfasst, die von anderen Funktionen im Expert Advisor genutzt werden können.

Die Funktion akzeptiert zwei Parameter:

  1. symbol (string): Eine Zeichenkette, die das Handelssymbol angibt, für das die Daten der schwebenden Aufträge abgerufen werden sollen. Der Standardwert ist ALL_SYMBOLS, was bedeutet, dass Daten für alle Symbole gesammelt werden, sofern kein spezifisches Symbol angegeben wird.
  2. magicNumber (ulong): Eine Long-Integer-Zahl ohne Vorzeichen, die die eindeutige magische Nummer darstellt, die den schwebenden Aufträgen des Expert Advisors zugeordnet ist. Dieser Parameter ist standardmäßig auf 0 gesetzt, sodass die Funktion die Daten für alle anhängigen Aufträge unabhängig von ihrer magischen Zahl abrufen kann, sofern keine spezifische magische Zahl angegeben wird.

Die Funktion gibt keinen Wert zurück (void), da ihr Hauptzweck darin besteht, die globalen Statusvariablen mit den Details der schwebenden Aufträge zu füllen und zu aktualisieren. Auf diese Variablen wird dann von anderen Teilen der Bibliothek zugegriffen, um die Entscheidungsfindung und die Handelsstrategien zu unterstützen.

Nachstehend finden Sie den vollständigen Funktionscode mit ausführlichen Kommentaren zum besseren Verständnis:

void GetPendingOrdersData(string symbol, ulong magicNumber)
  {
//-- Reset the account open pending orders status
   accountBuyStopOrdersTotal = 0;
   accountBuyLimitOrdersTotal = 0;

   accountSellStopOrdersTotal = 0;
   accountSellLimitOrdersTotal = 0;

   accountPendingOrdersVolumeTotal = 0.0;

   accountBuyStopOrdersVolumeTotal = 0.0;
   accountBuyLimitOrdersVolumeTotal = 0.0;

   accountSellStopOrdersVolumeTotal = 0.0;
   accountSellLimitOrdersVolumeTotal = 0.0;

//-- Reset the EA's magic open pending orders status
   magicPendingOrdersTotal = 0;

   magicBuyStopOrdersTotal = 0;
   magicBuyLimitOrdersTotal = 0;

   magicSellStopOrdersTotal = 0;
   magicSellLimitOrdersTotal = 0;

   magicPendingOrdersVolumeTotal = 0.0;

   magicBuyStopOrdersVolumeTotal = 0.0;
   magicBuyLimitOrdersVolumeTotal = 0.0;

   magicSellStopOrdersVolumeTotal = 0.0;
   magicSellLimitOrdersVolumeTotal = 0.0;

//-- Reset the symbol open pending orders status
   symbolPendingOrdersTotal = 0;

   symbolBuyStopOrdersTotal = 0;
   symbolBuyLimitOrdersTotal = 0;

   symbolSellStopOrdersTotal = 0;
   symbolSellLimitOrdersTotal = 0;

   symbolPendingOrdersVolumeTotal = 0.0;

   symbolBuyStopOrdersVolumeTotal = 0.0;
   symbolBuyLimitOrdersVolumeTotal = 0.0;

   symbolSellStopOrdersVolumeTotal = 0.0;
   symbolSellLimitOrdersVolumeTotal = 0.0;

//-- Update and save the open pending orders status with realtime data
   int totalOpenPendingOrders = OrdersTotal();
   if(totalOpenPendingOrders > 0)
     {
      //-- Scan for symbol and magic number specific pending orders and save their status
      for(int x = 0; x < totalOpenPendingOrders; x++)
        {
         //--- Get the pending orders properties
         ulong  orderTicket = OrderGetTicket(x); //-- Get ticket to select the pending order
         string selectedSymbol = OrderGetString(ORDER_SYMBOL);
         ulong orderMagicNo = OrderGetInteger(ORDER_MAGIC);

         //-- Filter pending orders by magic number
         if(magicNumber != 0 && orderMagicNo != magicNumber)
           {
            continue;
           }

         //-- Save the account pending orders status first
         accountPendingOrdersVolumeTotal += OrderGetDouble(ORDER_VOLUME_CURRENT);

         if(OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_BUY_STOP)
           {
            //-- Account properties
            ++accountBuyStopOrdersTotal;
            accountBuyStopOrdersVolumeTotal += OrderGetDouble(ORDER_VOLUME_CURRENT);
           }
         if(OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_BUY_LIMIT)
           {
            //-- Account properties
            ++accountBuyLimitOrdersTotal;
            accountBuyLimitOrdersVolumeTotal += OrderGetDouble(ORDER_VOLUME_CURRENT);
           }
         if(OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_SELL_STOP)
           {
            //-- Account properties
            ++accountSellStopOrdersTotal;
            accountSellStopOrdersVolumeTotal += OrderGetDouble(ORDER_VOLUME_CURRENT);
           }
         if(OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_SELL_LIMIT)
           {
            //-- Account properties
            ++accountSellLimitOrdersTotal;
            accountSellLimitOrdersVolumeTotal += OrderGetDouble(ORDER_VOLUME_CURRENT);
           }


         //-- Filter pending orders openend by EA and save their status
         if(
            OrderGetInteger(ORDER_REASON) == ORDER_REASON_EXPERT &&
            orderMagicNo == magicNumber
         )
           {
            ++magicPendingOrdersTotal;
            magicPendingOrdersVolumeTotal += OrderGetDouble(ORDER_VOLUME_CURRENT);
            if(OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_BUY_STOP)
              {
               //-- Magic properties
               ++magicBuyStopOrdersTotal;
               magicBuyStopOrdersVolumeTotal += OrderGetDouble(ORDER_VOLUME_CURRENT);
              }
            if(OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_BUY_LIMIT)
              {
               //-- Magic properties
               ++magicBuyLimitOrdersTotal;
               magicBuyLimitOrdersVolumeTotal += OrderGetDouble(ORDER_VOLUME_CURRENT);
              }
            if(OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_SELL_STOP)
              {
               //-- Magic properties
               ++magicSellStopOrdersTotal;
               magicSellStopOrdersVolumeTotal += OrderGetDouble(ORDER_VOLUME_CURRENT);
              }
            if(OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_SELL_LIMIT)
              {
               //-- Magic properties
               ++magicSellLimitOrdersTotal;
               magicSellLimitOrdersVolumeTotal += OrderGetDouble(ORDER_VOLUME_CURRENT);
              }
           }

         //-- Filter positions by symbol
         if(symbol == ALL_SYMBOLS || selectedSymbol == symbol)
           {
            ++symbolPendingOrdersTotal;
            symbolPendingOrdersVolumeTotal += OrderGetDouble(ORDER_VOLUME_CURRENT);
            if(OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_BUY_STOP)
              {
               ++symbolBuyStopOrdersTotal;
               symbolBuyStopOrdersVolumeTotal += OrderGetDouble(ORDER_VOLUME_CURRENT);
              }
            if(OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_BUY_LIMIT)
              {
               ++symbolBuyLimitOrdersTotal;
               symbolBuyLimitOrdersVolumeTotal += OrderGetDouble(ORDER_VOLUME_CURRENT);
              }
            if(OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_SELL_STOP)
              {
               ++symbolSellStopOrdersTotal;
               symbolSellStopOrdersVolumeTotal += OrderGetDouble(ORDER_VOLUME_CURRENT);
              }
            if(OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_SELL_LIMIT)
              {
               ++symbolSellLimitOrdersTotal;
               symbolSellLimitOrdersVolumeTotal += OrderGetDouble(ORDER_VOLUME_CURRENT);
              }
           }
        }
     }
  }


Die Funktion „BuyStopOrdersTotal“

Gibt eine ganze Zahl zurück, die die Gesamtzahl der offenen BuyStop-Orders des Kontos angibt.

int BuyStopOrdersTotal() export
  {
   GetPendingOrdersData(ALL_SYMBOLS, 0);
   return(accountBuyStopOrdersTotal);
  }


Die Funktion „BuyLimitOrdersTotal“

Gibt eine ganze Zahl zurück, die die Gesamtzahl der offenen BuyLimit-Orders im Konto angibt.

int BuyLimitOrdersTotal() export
  {
   GetPendingOrdersData(ALL_SYMBOLS, 0);
   return(accountBuyLimitOrdersTotal);
  }


Die Funktion „SellStopOrdersTotal“

Gibt eine ganze Zahl zurück, die die Gesamtzahl der offenen SellStop-Orders im Konto angibt.

int SellStopOrdersTotal() export
  {
   GetPendingOrdersData(ALL_SYMBOLS, 0);
   return(accountSellStopOrdersTotal);
  }


Die Funktion „SellLimitOrdersTotal“

Gibt eine ganze Zahl zurück, die die Gesamtzahl der offenen SellLimit-Orders im Konto angibt.

int SellLimitOrdersTotal() export
  {
   GetPendingOrdersData(ALL_SYMBOLS, 0);
   return(accountSellLimitOrdersTotal);
  }


Die Funktion „OrdersTotalVolume“

Gibt einen „double“-Wert zurück, der das Gesamtvolumen/Losgröße/die Gesamtmenge aller offenen Aufträge des Kontos angibt.

double OrdersTotalVolume() export
  {
   GetPendingOrdersData(ALL_SYMBOLS, 0);
   return(accountPendingOrdersVolumeTotal);
  }


Die Funktion „BuyStopOrdersTotal“

Gibt einen Wert vom Typ double zurück, der das Gesamtvolumen/Losgröße/die Gesamtmenge aller offenen BuyStop-Aufträge im Konto angibt.

double BuyStopOrdersTotalVolume() export
  {
   GetPendingOrdersData(ALL_SYMBOLS, 0);
   return(accountBuyStopOrdersVolumeTotal);
  }


Die Funktion „BuyLimitOrdersTotal“

Gibt einen „double“-Wert zurück, der das Gesamtvolumen/Losgröße/die Gesamtmenge aller offenen Kauf-Limit-Aufträge des Kontos angibt.

double BuyLimitOrdersTotalVolume() export
  {
   GetPendingOrdersData(ALL_SYMBOLS, 0);
   return(accountBuyLimitOrdersVolumeTotal);
  }


Die Funktion „SellStopOrdersTotal“

Gibt einen „double“-Wert zurück, der das Gesamtvolumen/Losgröße/die Gesamtmenge aller offenen Verkaufsstopp-Aufträge im Konto angibt.

double SellStopOrdersTotalVolume() export
  {
   GetPendingOrdersData(ALL_SYMBOLS, 0);
   return(accountSellStopOrdersVolumeTotal);
  }


Die Funktion „SellLimitOrdersTotal“

Gibt einen „double“-Wert zurück, der das Gesamtvolumen/Losgröße/die Gesamtmenge aller offenen Limit-Verkaufsaufträge des Kontos angibt.

double SellLimitOrdersTotalVolume() export
  {
   GetPendingOrdersData(ALL_SYMBOLS, 0);
   return(accountSellLimitOrdersVolumeTotal);
  }


Die Funktion „MagicOrdersTotal“

Gibt einen ganzzahligen Wert für die Gesamtzahl aller offenen, schwebenden Aufträge für die angegebene magische Nummer des Kontos zurück.

int MagicOrdersTotal(ulong magicNumber) export
  {
   GetPendingOrdersData(ALL_SYMBOLS, magicNumber);
   return(magicPendingOrdersTotal);
  }


Die Funktion „MagicBuyStopOrdersTotal“

Gibt einen ganzzahligen Wert für die Gesamtzahl aller offenen BuyStop-Orders für die angegebene magische Zahl im Konto zurück.

int MagicBuyStopOrdersTotal(ulong magicNumber) export
  {
   GetPendingOrdersData(ALL_SYMBOLS, magicNumber);
   return(magicBuyStopOrdersTotal);
  }


Die Funktion „MagicBuyLimitOrdersTotal“

Gibt einen ganzzahligen Wert für die Gesamtzahl aller offenen BuyLimit-Orders für die angegebene magische Zahl im Konto zurück.

int MagicBuyLimitOrdersTotal(ulong magicNumber) export
  {
   GetPendingOrdersData(ALL_SYMBOLS, magicNumber);
   return(magicBuyLimitOrdersTotal);
  }


Die Funktion „MagicSellStopOrdersTotal“

Gibt einen ganzzahligen Wert für die Gesamtzahl aller offenen SellStop-Orders für die angegebene magische Nummer im Konto zurück.

int MagicSellStopOrdersTotal(ulong magicNumber) export
  {
   GetPendingOrdersData(ALL_SYMBOLS, magicNumber);
   return(magicSellStopOrdersTotal);
  }


Die Funktion „MagicSellLimitOrdersTotal“

Gibt einen ganzzahligen Wert für die Gesamtzahl aller offenen DellLimit-Orders für die angegebene magische Zahl im Konto zurück.

int MagicSellLimitOrdersTotal(ulong magicNumber) export
  {
   GetPendingOrdersData(ALL_SYMBOLS, magicNumber);
   return(magicSellLimitOrdersTotal);
  }


Die Funktion „MagicOrdersTotalVolume“

Gibt einen „double“-Wert zurück, der das Gesamtvolumen/Losgröße/die Gesamtmenge aller offenen schwebenden Aufträge für die angegebene magische Nummer im Konto angibt.

double MagicOrdersTotalVolume(ulong magicNumber) export
  {
   GetPendingOrdersData(ALL_SYMBOLS, magicNumber);
   return(magicPendingOrdersVolumeTotal);
  }


Die Funktion „MagicBuyStopOrdersVolume“

Gibt einen „double“-Wert zurück, der das Gesamtvolumen/Losgröße/die Gesamtmenge aller offenen BuyStop-Orders für die angegebene magische Zahl im Konto angibt.

double MagicBuyStopOrdersTotalVolume(ulong magicNumber) export
  {
   GetPendingOrdersData(ALL_SYMBOLS, magicNumber);
   return(magicBuyStopOrdersVolumeTotal);
  }


Die Funktion „MagicBuyLimitOrdersTotalVolume“

Gibt einen „double“-Wert zurück, der das Gesamtvolumen/Losgröße/die Gesamtmenge aller offenen Kauf-Limit-Aufträge für die angegebene magische Zahl im Konto angibt.

double MagicBuyLimitOrdersTotalVolume(ulong magicNumber) export
  {
   GetPendingOrdersData(ALL_SYMBOLS, magicNumber);
   return(magicBuyLimitOrdersVolumeTotal);
  }


Die Funktion „MagicSellStopOrdersTotalVolume“

Gibt einen „double“-Wert zurück, der das Gesamtvolumen/Losgröße/die Gesamtmenge aller offenen Verkaufsstoppaufträge für die angegebene magische Zahl im Konto angibt.

double MagicSellStopOrdersTotalVolume(ulong magicNumber) export
  {
   GetPendingOrdersData(ALL_SYMBOLS, magicNumber);
   return(magicSellStopOrdersVolumeTotal);
  }


Die Funktion „MagicSellLimitOrdersTotalVolume“

Gibt einen „double“-Wert zurück, der das Gesamtvolumen/Losgröße/die Gesamtmenge aller offenen SellLimit-Orders für die angegebene magische Zahl im Konto angibt.

double MagicSellLimitOrdersTotalVolume(ulong magicNumber) export
  {
   GetPendingOrdersData(ALL_SYMBOLS, magicNumber);
   return(magicSellLimitOrdersVolumeTotal);
  }


Die Funktion „SymbolOrdersTotal“

Gibt einen ganzzahligen Wert zurück, der die Gesamtzahl aller offenen schwebenden Aufträge für ein bestimmtes Symbol und eine magische Nummer im Konto angibt.

int SymbolOrdersTotal(string symbol, ulong magicNumber) export
  {
   GetPendingOrdersData(symbol, magicNumber);
   return(symbolPendingOrdersTotal);
  }


Die Funktion „SymbolBuyStopOrdersTotal“

Gibt einen ganzzahligen Wert zurück, der die Gesamtzahl aller offenen BuyStop-Orders für ein bestimmtes Symbol und eine magische Zahl im Konto angibt.

int SymbolBuyStopOrdersTotal(string symbol, ulong magicNumber) export
  {
   GetPendingOrdersData(symbol, magicNumber);
   return(symbolBuyStopOrdersTotal);
  }


Die Funktion „SymbolBuyLimitOrdersTotal“

Gibt einen ganzzahligen Wert zurück, der die Gesamtzahl aller offenen BuyLimit-Orders für ein bestimmtes Symbol und eine magische Zahl im Konto angibt.

int SymbolBuyLimitOrdersTotal(string symbol, ulong magicNumber) export
  {
   GetPendingOrdersData(symbol, magicNumber);
   return(symbolBuyLimitOrdersTotal);
  }


Die Funktion „SymbolSellStopOrdersTotal“

Gibt einen ganzzahligen Wert zurück, der die Gesamtzahl aller offenen Verkaufsstopp-Aufträge für ein bestimmtes Symbol und eine magische Zahl im Konto angibt.

int SymbolSellStopOrdersTotal(string symbol, ulong magicNumber) export
  {
   GetPendingOrdersData(symbol, magicNumber);
   return(symbolSellStopOrdersTotal);
  }


Die Funktion „SymbolSellLimitOrdersTotal“

Gibt einen ganzzahligen Wert zurück, der die Gesamtzahl aller offenen SellLimit-Orders für ein bestimmtes Symbol und eine magische Nummer im Konto angibt.

int SymbolSellLimitOrdersTotal(string symbol, ulong magicNumber) export
  {
   GetPendingOrdersData(symbol, magicNumber);
   return(symbolSellLimitOrdersTotal);
  }


Die Funktion „SymbolOrdersTotalVolume“

Gibt einen „double“-Wert zurück, der das Gesamtvolumen/Losgröße/die Gesamtmenge aller offenen schwebenden Aufträge für das angegebene Symbol und die magische Nummer im Konto angibt.

double SymbolOrdersTotalVolume(string symbol, ulong magicNumber) export
  {
   GetPendingOrdersData(symbol, magicNumber);
   return(symbolPendingOrdersVolumeTotal);
  }


Die Funktion „SymbolBuyStopOrdersTotalVolume“

Gibt einen „double“-Wert zurück, der das Gesamtvolumen/Losgröße/die Gesamtmenge aller offenen Buy-Stop-Aufträge für das angegebene Symbol und die magische Zahl im Konto angibt.

double SymbolBuyStopOrdersTotalVolume(string symbol, ulong magicNumber) export
  {
   GetPendingOrdersData(symbol, magicNumber);
   return(symbolBuyStopOrdersVolumeTotal);
  }


Die Funktion „SymbolBuyLimitOrdersTotalVolume“

Gibt einen „double“-Wert zurück, der das Gesamtvolumen/Losgröße/die Gesamtmenge aller offenen BuyLimit-Orders für das angegebene Symbol und die magische Zahl im Konto angibt.

double SymbolBuyLimitOrdersTotalVolume(string symbol, ulong magicNumber) export
  {
   GetPendingOrdersData(symbol, magicNumber);
   return(symbolBuyLimitOrdersVolumeTotal);
  }


Die Funktion „SymbolSellStopOrdersTotalVolume“

Gibt einen „double“-Wert zurück, der das Gesamtvolumen/die Gesamtmenge aller offenen SellStop-Orders für das angegebene Symbol und die magische Zahl im Konto angibt.

double SymbolSellStopOrdersTotalVolume(string symbol, ulong magicNumber) export
  {
   GetPendingOrdersData(symbol, magicNumber);
   return(symbolSellStopOrdersVolumeTotal);
  }


Die Funktion „SymbolSellLimitOrdersTotalVolume“

Gibt einen „double“-Wert zurück, der das Gesamtvolumen/Losgröße/die Gesamtmenge aller offenen SellLimit-Orders für das angegebene Symbol und die magische Zahl im Konto angibt.

double SymbolSellLimitOrdersTotalVolume(string symbol, ulong magicNumber) export
  {
   GetPendingOrdersData(symbol, magicNumber);
   return(symbolSellLimitOrdersVolumeTotal);
  }


Die Funktion „AccountOrdersStatus“

Gibt eine vorformatierte Zeichenkette zurück, die den Status der Kontoaufträge enthält und in das Protokoll gedruckt oder in den Diagrammkommentaren angezeigt werden kann. Die Funktion benötigt einen einzigen booleschen Parameter namens formatForComment. Wenn formatForComment auf true gesetzt ist, formatiert die Funktion die Daten für die Anzeige im Chart-Fenster; wenn false, formatiert sie die Daten für die Log-Registerkarte des Expert Advisors.

string AccountOrdersStatus(bool formatForComment) export
  {
   GetPendingOrdersData(ALL_SYMBOLS, 0); //-- Update the orders status variables before we display their data
   string spacer = "";
   if(formatForComment) //-- Add some formating space for the chart comment string
     {
      spacer = "                                        ";
     }
   string accountOrdersStatus = "\r\n" + spacer + "|---------------------------------------------------------------------------\r\n";
   accountOrdersStatus += spacer + "| " + (string)AccountInfoInteger(ACCOUNT_LOGIN) + " - ACCOUNT ORDERS STATUS \r\n";
   accountOrdersStatus += spacer + "|---------------------------------------------------------------------------\r\n";
   accountOrdersStatus += spacer + "|     Total Open:   " + (string)OrdersTotal() + "\r\n";
   accountOrdersStatus += spacer + "|     Total Volume: " + (string)accountPendingOrdersVolumeTotal + "\r\n";
   accountOrdersStatus += spacer + "|------------------------------------------------------------------\r\n";
   accountOrdersStatus += spacer + "| BUY STOP ORDERS: \r\n";
   accountOrdersStatus += spacer + "|     Total Open:   " + (string)accountBuyStopOrdersTotal + "\r\n";
   accountOrdersStatus += spacer + "|     Total Volume: " + (string)accountBuyStopOrdersVolumeTotal + "\r\n";
   accountOrdersStatus += spacer + "|------------------------------------------------------------------\r\n";
   accountOrdersStatus += spacer + "| BUY LIMIT ORDERS: \r\n";
   accountOrdersStatus += spacer + "|     Total Open:   " + (string)accountBuyLimitOrdersTotal + "\r\n";
   accountOrdersStatus += spacer + "|     Total Volume: " + (string)accountBuyLimitOrdersVolumeTotal + "\r\n";
   accountOrdersStatus += spacer + "|---------------------------------------------------------------------------\r\n";
   accountOrdersStatus += spacer + "| SELL STOP ORDERS: \r\n";
   accountOrdersStatus += spacer + "|     Total Open:   " + (string)accountSellStopOrdersTotal + "\r\n";
   accountOrdersStatus += spacer + "|     Total Volume: " + (string)accountSellStopOrdersVolumeTotal + "\r\n";
   accountOrdersStatus += spacer + "|---------------------------------------------------------------------------\r\n";
   accountOrdersStatus += spacer + "| SELL LIMIT ORDERS: \r\n";
   accountOrdersStatus += spacer + "|     Total Open:   " + (string)accountSellLimitOrdersTotal + "\r\n";
   accountOrdersStatus += spacer + "|     Total Volume: " + (string)accountSellLimitOrdersVolumeTotal + "\r\n";
   accountOrdersStatus += spacer + "|---------------------------------------------------------------------------\r\n";
   accountOrdersStatus += spacer + "\r\n";
   return(accountOrdersStatus);
  }


Die Funktion „MagicOrdersStatus“

Gibt eine vorformatierte Zeichenfolge zurück, die den Status der magischen Aufträge angibt und in das Protokoll gedruckt oder in den Diagrammkommentaren angezeigt werden kann. Die Funktion akzeptiert zwei Parameter: einen vorzeichenlosen „long“-Wert namens magicNumber , um die angestrebte magische Zahl anzugeben, und einen booleschen Wert namens formatForComment , um den Formatierungstyp zu bestimmen. Wenn formatForComment true ist, formatiert die Funktion die Daten für die Anzeige im Chart-Fenster; wenn false, formatiert sie die Daten für die Log-Registerkarte des Expert Advisors.

string MagicOrdersStatus(ulong magicNumber, bool formatForComment) export
  {
   GetPendingOrdersData(ALL_SYMBOLS, magicNumber); //-- Update the order status variables before we display their data
   string spacer = "";
   if(formatForComment) //-- Add some formating space for the chart comment string
     {
      spacer = "                                        ";
     }
   string magicOrdersStatus = "\r\n" + spacer + "|---------------------------------------------------------------------------\r\n";
   magicOrdersStatus += spacer + "| " + (string)magicNumber + " - MAGIC ORDERS STATUS \r\n";
   magicOrdersStatus += spacer + "|---------------------------------------------------------------------------\r\n";
   magicOrdersStatus += spacer + "|     Total Open:   " + (string)magicPendingOrdersTotal + "\r\n";
   magicOrdersStatus += spacer + "|     Total Volume: " + (string)magicPendingOrdersVolumeTotal + "\r\n";
   magicOrdersStatus += spacer + "|------------------------------------------------------------------\r\n";
   magicOrdersStatus += spacer + "| BUY STOP ORDERS: \r\n";
   magicOrdersStatus += spacer + "|     Total Open:   " + (string)magicBuyStopOrdersTotal + "\r\n";
   magicOrdersStatus += spacer + "|     Total Volume: " + (string)magicBuyStopOrdersVolumeTotal + "\r\n";
   magicOrdersStatus += spacer + "|------------------------------------------------------------------\r\n";
   magicOrdersStatus += spacer + "| BUY LIMIT ORDERS: \r\n";
   magicOrdersStatus += spacer + "|     Total Open:   " + (string)magicBuyLimitOrdersTotal + "\r\n";
   magicOrdersStatus += spacer + "|     Total Volume: " + (string)magicBuyLimitOrdersVolumeTotal + "\r\n";
   magicOrdersStatus += spacer + "|---------------------------------------------------------------------------\r\n";
   magicOrdersStatus += spacer + "| SELL STOP ORDERS: \r\n";
   magicOrdersStatus += spacer + "|     Total Open:   " + (string)magicSellStopOrdersTotal + "\r\n";
   magicOrdersStatus += spacer + "|     Total Volume: " + (string)magicSellStopOrdersVolumeTotal + "\r\n";
   magicOrdersStatus += spacer + "|------------------------------------------------------------------\r\n";
   magicOrdersStatus += spacer + "| SELL LIMIT ORDERS: \r\n";
   magicOrdersStatus += spacer + "|     Total Open:   " + (string)magicSellLimitOrdersTotal + "\r\n";
   magicOrdersStatus += spacer + "|     Total Volume: " + (string)magicSellLimitOrdersVolumeTotal + "\r\n";
   magicOrdersStatus += spacer + "|---------------------------------------------------------------------------\r\n";
   magicOrdersStatus += spacer + "\r\n";
   return(magicOrdersStatus);
  }


Die Funktion „SymbolOrdersStatus“

Gibt eine vorformatierte Zeichenkette zurück, die den Status der Symbolbestellungen angibt und in das Protokoll gedruckt oder in den Diagrammkommentaren angezeigt werden kann. Die Funktion akzeptiert drei Parameter: eine Zeichenkette namens symbol, einen vorzeichenlosen „long“-Wert namens magicNumber zur Angabe der angestrebten magischen Zahl (ein Wert von Null (0) deaktiviert den Filter für magische Zahlen) und einen booleschen Wert namens formatForComment zur Bestimmung der Formatierungsart. Wenn formatForComment true ist, formatiert die Funktion die Daten für die Anzeige im Chart-Fenster; wenn false, formatiert sie die Daten für die Log-Registerkarte des Expert Advisors.

string SymbolOrdersStatus(string symbol, ulong magicNumber, bool formatForComment) export
  {
   GetPendingOrdersData(symbol, magicNumber); //-- Update the order status variables before we display their data
   string spacer = "";
   if(formatForComment) //-- Add some formating space for the chart comment string
     {
      spacer = "                                        ";
     }
   string symbolOrdersStatus = "\r\n" + spacer + "|---------------------------------------------------------------------------\r\n";
   symbolOrdersStatus += spacer + "| " + symbol + " - SYMBOL ORDERS STATUS \r\n";
   symbolOrdersStatus += spacer + "|---------------------------------------------------------------------------\r\n";
   symbolOrdersStatus += spacer + "|     Total Open:   " + (string)symbolPendingOrdersTotal + "\r\n";
   symbolOrdersStatus += spacer + "|     Total Volume: " + (string)symbolPendingOrdersVolumeTotal + "\r\n";
   symbolOrdersStatus += spacer + "|------------------------------------------------------------------\r\n";
   symbolOrdersStatus += spacer + "| BUY STOP ORDERS: \r\n";
   symbolOrdersStatus += spacer + "|     Total Open:   " + (string)symbolBuyStopOrdersTotal + "\r\n";
   symbolOrdersStatus += spacer + "|     Total Volume: " + (string)symbolBuyStopOrdersVolumeTotal + "\r\n";
   symbolOrdersStatus += spacer + "|------------------------------------------------------------------\r\n";
   symbolOrdersStatus += spacer + "| BUY LIMIT ORDERS: \r\n";
   symbolOrdersStatus += spacer + "|     Total Open:   " + (string)symbolBuyLimitOrdersTotal + "\r\n";
   symbolOrdersStatus += spacer + "|     Total Volume: " + (string)symbolBuyLimitOrdersVolumeTotal + "\r\n";
   symbolOrdersStatus += spacer + "|---------------------------------------------------------------------------\r\n";
   symbolOrdersStatus += spacer + "| SELL STOP ORDERS: \r\n";
   symbolOrdersStatus += spacer + "|     Total Open:   " + (string)symbolSellStopOrdersTotal + "\r\n";
   symbolOrdersStatus += spacer + "|     Total Volume: " + (string)symbolSellStopOrdersVolumeTotal + "\r\n";
   symbolOrdersStatus += spacer + "|------------------------------------------------------------------\r\n";
   symbolOrdersStatus += spacer + "| SELL LIMIT ORDERS: \r\n";
   symbolOrdersStatus += spacer + "|     Total Open:   " + (string)symbolSellLimitOrdersTotal + "\r\n";
   symbolOrdersStatus += spacer + "|     Total Volume: " + (string)symbolSellLimitOrdersVolumeTotal + "\r\n";
   symbolOrdersStatus += spacer + "|---------------------------------------------------------------------------\r\n";
   symbolOrdersStatus += spacer + "\r\n";
   return(symbolOrdersStatus);
  }

Die umfangreichen Bibliotheksfunktionen, die wir oben erstellt haben, bilden unsere EX5-Bibliothek zur Verwaltung schwebender Aufträge. Am Ende dieses Artikels finden Sie die Quellcode-Datei, PendingOrdersManager.mq5, sowie die kompilierte ausführbare Binärdatei, PendingOrdersManager.ex5, die Sie einfach importieren und in Ihren MQL5-Projekten verwenden können.


So importieren und implementieren Sie unsere EX5-Bibliothek zur Verwaltung schwebender Aufträge

Wir haben eine robuste EX5-Bibliothek für die Verwaltung schwebender Aufträge entwickelt, die wesentliche Funktionen für die Bearbeitung schwebender Aufträge, die Abfrage ihres Status und die Anzeige relevanter Informationen enthält. Nun ist es an der Zeit zu dokumentieren und zu demonstrieren, wie man diese Bibliothek korrekt importiert und in einem MQL5-Projekt verwendet.

Um den Implementierungsprozess zu vereinfachen, werden wir zunächst alle Funktionen und Module der Bibliothek für die Verwaltung schwebender Aufträge zusammen mit praktischen Codebeispielen im nachstehenden Dokumentationsabschnitt erläutern. Dadurch erhalten die Nutzer ein klares Verständnis der in der Binärdatei PendingOrdersManager.ex5 enthaltenen Komponenten.


Die Dokumentation der Bibliothek von PendingOrdersManager.EX5

Schritt 1: Kopieren Sie die ausführbaren Bibliotheksdateien (PositionsManager.ex5 und PendingOrdersManager.ex5)

Platzieren Sie die PositionsManager.ex5 und PendingOrdersManager.ex5 Dateien im Verzeichnis MQL5/Bibliotheken/Toolkit oder im gleichen Ordner wie die Quellcodedatei, die die Bibliothek importiert. Vergewissern Sie sich, dass diese Dateien heruntergeladen und an den angegebenen Ort kopiert werden, falls sie dort noch nicht vorhanden sind. Kopien beider Dateien sind am Ende dieses Artikels zu Ihrer Information beigefügt.

Schritt 2: Importieren Sie die Beschreibungen der Funktionsprototypen

Fügen Sie im Header-Abschnitt Ihres Quellcodes die Importdirektiven für die Pending Orders Manager-Bibliothek und ihre Funktionsprototyp-Beschreibungen hinzu. Verwenden Sie das folgende Codesegment, um alle Funktionen oder Module aus der Bibliothek PendingOrdersManager.ex5 effizient zu importieren. Ich habe auch eine leere Expert Advisor-Vorlage erstellt (PendingOrdersManager_Imports_Template.mq5), die dieses Codesegment enthält. Sie können alle Funktionsbeschreibungen, die Sie für Ihr Projekt nicht benötigen, auskommentieren oder entfernen. Die Datei PendingOrdersManager_Imports_Template.mq5 ist ebenfalls am Ende dieses Artikels beigefügt.

//+------------------------------------------------------------------------------------------+
//-- Copy and paste the import derictives below to use the Pending Orders Manager EX5 Library
//---
//+-------------------------------------------------------------------------------------+
//| PendingOrdersManager.ex5 imports template                                           |
//+-------------------------------------------------------------------------------------+
#import "Toolkit/PendingOrdersManager.ex5" //-- Opening import directive
//-- Function descriptions for the imported function prototypes

//-- Pending Orders Execution and Modification Functions
bool OpenBuyLimit(ulong magicNumber, string symbol, double entryPrice, double lotSize, int sl, int tp, string orderComment);
bool OpenBuyStop(ulong magicNumber, string symbol, double entryPrice, double lotSize, int sl, int tp, string orderComment);
bool OpenSellLimit(ulong magicNumber, string symbol, double entryPrice, double lotSize, int sl, int tp, string orderComment);
bool OpenSellStop(ulong magicNumber, string symbol, double entryPrice, double lotSize, int sl, int tp, string orderComment);
bool ModifyPendingOrderByTicket(ulong orderTicket, double newEntryPrice, int newSl, int newTp);
bool DeletePendingOrderByTicket(ulong orderTicket);
bool DeleteAllPendingOrders(string symbol, ulong magicNumber);
bool DeleteAllPendingOrders();
bool DeleteAllBuyStops(string symbol, ulong magicNumber);
bool DeleteAllBuyLimits(string symbol, ulong magicNumber);
bool DeleteAllSellStops(string symbol, ulong magicNumber);
bool DeleteAllSellLimits(string symbol, ulong magicNumber);
bool DeleteAllMagicOrders(ulong magicNumber);

//-- Pending Orders Status Monitoring Functions
int BuyStopOrdersTotal();
int BuyLimitOrdersTotal();
int SellStopOrdersTotal();
int SellLimitOrdersTotal();
double OrdersTotalVolume();
double BuyStopOrdersTotalVolume();
double BuyLimitOrdersTotalVolume();
double SellStopOrdersTotalVolume();
double SellLimitOrdersTotalVolume();

//-- Pending Orders Filtered By Magic Number Status Monitoring Functions
int MagicOrdersTotal(ulong magicNumber);
int MagicBuyStopOrdersTotal(ulong magicNumber);
int MagicBuyLimitOrdersTotal(ulong magicNumber);
int MagicSellStopOrdersTotal(ulong magicNumber);
int MagicSellLimitOrdersTotal(ulong magicNumber);
double MagicOrdersTotalVolume(ulong magicNumber);
double MagicBuyStopOrdersTotalVolume(ulong magicNumber);
double MagicBuyLimitOrdersTotalVolume(ulong magicNumber);
double MagicSellStopOrdersTotalVolume(ulong magicNumber);
double MagicSellLimitOrdersTotalVolume(ulong magicNumber);

//-- Pending Orders Filtered By Symbol and/or Magic Number Status Monitoring Functions
int SymbolOrdersTotal(string symbol, ulong magicNumber);
int SymbolBuyStopOrdersTotal(string symbol, ulong magicNumber);
int SymbolBuyLimitOrdersTotal(string symbol, ulong magicNumber);
int SymbolSellStopOrdersTotal(string symbol, ulong magicNumber);
int SymbolSellLimitOrdersTotal(string symbol, ulong magicNumber);
double SymbolOrdersTotalVolume(string symbol, ulong magicNumber);
double SymbolBuyStopOrdersTotalVolume(string symbol, ulong magicNumber);
double SymbolBuyLimitOrdersTotalVolume(string symbol, ulong magicNumber);
double SymbolSellStopOrdersTotalVolume(string symbol, ulong magicNumber);
double SymbolSellLimitOrdersTotalVolume(string symbol, ulong magicNumber);

//-- Log and Data Display Functions
string AccountOrdersStatus(bool formatForComment);
string MagicOrdersStatus(ulong magicNumber, bool formatForComment);
string SymbolOrdersStatus(string symbol, ulong magicNumber, bool formatForComment);

#import //--- Closing import directive
//+-------------------------------------------------------------------------------------+

Nachdem die Prototyp-Funktionen der .EX5-Bibliothek in Ihr MQL5-Projekt oder Ihren Quellcode importiert wurden, finden Sie in der folgenden Tabelle eine ausführliche Dokumentation und praktische Beispiele für die Implementierung und Verwendung dieser Funktionen in Ihrem Code.

Funktion Prototyp Beschreibung Beschreibung Beispiel für einen Anwendungsfall
bool OpenBuyLimit(
   ulong magicNumber,
   string symbol,
   double entryPrice,
   double lotSize,
   int sl,
   int tp,
   string orderComment
);


Eröffnet eine neue BuyLimit-Order, der den angegebenen Parametern entspricht.
double symbolPoint = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
int spread = (int)SymbolInfoInteger(_Symbol, SYMBOL_SPREAD);
//---
ulong magicNo = 123;
string symbol = _Symbol;
double entryPrice = SymbolInfoDouble(
                       _Symbol, SYMBOL_ASK) - ((spread * 20) 
                       * symbolPoint
                    );
double lotSize = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MIN);
int sl = spread * 50;  //-- pips
int tp = spread * 100; //-- pips
string orderComment = "Pending Orders Manager Buy Limit Order";
OpenBuyLimit(
   magicNumber, symbol, entryPrice, 
   lotSize, sl, tp, orderComment
);

bool OpenBuyStop(
   ulong magicNumber,
   string symbol,
   double entryPrice,
   double lotSize,
   int sl,
   int tp,
   string orderComment
);


Eröffnet eine neue BuyStop-Order, der den angegebenen Parametern entspricht.
double symbolPoint = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
int spread = (int)SymbolInfoInteger(_Symbol, SYMBOL_SPREAD);
//---
ulong magicNo = 123;
string symbol = _Symbol;
double entryPrice = SymbolInfoDouble(
                       _Symbol, SYMBOL_ASK) + ((spread * 20) 
                       * symbolPoint
                    );
double lotSize = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MIN);
int sl = spread * 50;  //-- pips
int tp = spread * 100; //-- pips
string orderComment = "Pending Orders Manager Buy Stop Order";
OpenBuyStop(
   magicNumber, symbol, entryPrice, 
   lotSize, sl, tp, orderComment
);

bool OpenSellLimit(
   ulong magicNumber,
   string symbol,
   double entryPrice,
   double lotSize,
   int sl,
   int tp,
   string orderComment
);


Eröffnet einen neuen SellLimit-Order, der den angegebenen Parametern entspricht.
double symbolPoint = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
int spread = (int)SymbolInfoInteger(_Symbol, SYMBOL_SPREAD);
//---
ulong magicNo = 123;
string symbol = _Symbol;
double entryPrice = SymbolInfoDouble(
                       _Symbol, SYMBOL_ASK) + ((spread * 20) 
                       * symbolPoint
                    );
double lotSize = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MIN);
int sl = spread * 50;  //-- pips
int tp = spread * 100; //-- pips
string orderComment = "Pending Orders Manager Sell Limit Order";
OpenSellLimit(
   magicNumber, symbol, entryPrice, 
   lotSize, sl, tp, orderComment
);

bool OpenSellStop(
   ulong magicNumber,
   string symbol,
   double entryPrice,
   double lotSize,
   int sl,
   int tp,
   string orderComment
);


Eröffnet einen neuen SellStop-Order, der den angegebenen Parametern entspricht.
double symbolPoint = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
int spread = (int)SymbolInfoInteger(_Symbol, SYMBOL_SPREAD);
//---
ulong magicNo = 123;
string symbol = _Symbol;
double entryPrice = SymbolInfoDouble(
                       _Symbol, SYMBOL_ASK) - ((spread * 20) 
                       * symbolPoint
                    );
double lotSize = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MIN);
int sl = spread * 50;  //-- pips
int tp = spread * 100; //-- pips
string orderComment = "Pending Orders Manager Sell Stop Order";
OpenSellStop(
   magicNumber, symbol, entryPrice, 
   lotSize, sl, tp, orderComment
);

bool ModifyPendingOrderByTicket(
   ulong orderTicket,
   double newEntryPrice,
   int newSl,
   int newTp
);

Ändert einen schwebenden Auftrag unter Verwendung der angegebenen Parameter.
double symbolPoint = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
int spread = (int)SymbolInfoInteger(_Symbol, SYMBOL_SPREAD);
int totalOpenOders = OrdersTotal();
for(int x = 0; x < totalOpenOders; x++)
  {
   ulong orderTicket = OrderGetTicket(x);
   if(orderTicket > 0)
     {
      //-- Modify a buy stop order
      if(OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_BUY_STOP)
        {
         double newEntryPrice = OrderGetDouble(
                                   ORDER_PRICE_OPEN) + 
                                   ((spread * 40) * symbolPoint
                                );
         int newSl = 0; //-- Do not modify the stop loss level
         int newTp = 0; //-- Don not modify the take profit level
         ModifyPendingOrderByTicket(
            orderTicket, newEntryPrice, newSl, newTp
         );
         break;
        }
     }
  }

bool DeletePendingOrderByTicket(
   ulong orderTicket
);

Löscht einen schwebenden Auftrag auf der Grundlage des angegebenen Parameters Ticketnummer.
for(int x = 0; x < totalOpenOders; x++)
  {
   ulong orderTicket = OrderGetTicket(x);
   if(orderTicket > 0)
     {
      DeletePendingOrderByTicket(orderTicket);
      break;
     }
  }

bool DeleteAllPendingOrders(
   string symbol = ALL_SYMBOLS,
   ulong magicNumber = 0
);

Löscht alle schwebenden Aufträge, die auf den Parametern Symbolname und magische Zahl basieren.
//Deletes all orders in the account
DeleteAllPendingOrders("", 0);

//Deletes all orders belonging to the symbol
DeleteAllPendingOrders(_Symbol, 0);

//Deletes all orders that have a magic number 101
DeleteAllPendingOrders("", 101);

//Deletes all EURUSD orders that have a magic number 101
DeleteAllPendingOrders("EURUSD", 101);

bool DeleteAllPendingOrders()

Löscht einfach alle offenen schwebenden Aufträge im Konto.
//Deletes all orders in the account
DeleteAllPendingOrders();

bool DeleteAllBuyStops(
   string symbol = ALL_SYMBOLS,
   ulong magicNumber = 0
);

Löscht alle BuyStop-Orders, die auf den angegebenen Parametern Symbolname und magische Zahl basieren.
//Deletes all buy stops in the account
DeleteAllBuyStops("", 0);

//Deletes all buy stops belonging to the symbol
DeleteAllBuyStops(_Symbol, 0);

//Deletes all buy stops that have a magic number 101
DeleteAllBuyStops("", 101);

//Deletes all EURUSD buy stops that have a magic number 101
DeleteAllBuyStops("EURUSD", 101);

bool DeleteAllBuyLimits(
   string symbol = ALL_SYMBOLS,
   ulong magicNumber = 0
);

Löscht alle BuyLimit-Orders, die auf den angegebenen Parametern Symbolname und magische Zahl basieren.
//Deletes all buy limits in the account
DeleteAllBuyLimits("", 0);

//Deletes all buy limits belonging to the symbol
DeleteAllBuyLimits(_Symbol, 0);

//Deletes all buy limits that have a magic number 101
DeleteAllBuyLimits("", 101);

//Deletes all GBPUSD buy limits that have a magic number 101
DeleteAllBuyLimits("GBPUSD", 101);

bool DeleteAllSellStops(
   string symbol = ALL_SYMBOLS,
   ulong magicNumber = 0
);

Löscht alle SellStop-Orders, die auf den angegebenen Parametern Symbolname und magische Zahl basieren.
//Deletes all sell stops in the account
DeleteAllSellStops("", 0);

//Deletes all sell stops belonging to the symbol
DeleteAllSellStops(_Symbol, 0);

//Deletes all sell stops that have a magic number 101
DeleteAllSellStops("", 101);

//Deletes all JPYUSD sell stops that have a magic number 101
DeleteAllSellStops("JPYUSD", 101);

bool DeleteAllSellLimits(
   string symbol = ALL_SYMBOLS,
   ulong magicNumber = 0
);

Löscht alle SellLimit-Orders, die auf den angegebenen Parametern Symbolname und magische Zahl basieren.
//Deletes all sell limits in the account
DeleteAllSellLimits("", 0);

//Deletes all sell limits belonging to the symbol
DeleteAllSellLimits(_Symbol, 0);

//Deletes all sell limits that have a magic number 101
DeleteAllSellLimits("", 101);

//Deletes all AUDJPY sell limits that have a magic number 101
DeleteAllSellLimits("AUDJPY", 101);


bool DeleteAllMagicOrders(
   ulong magicNumber
);

Löscht alle schwebenden Aufträge auf der Grundlage des angegebenen Parameters „magische Zahl“.
//-- Deletes all orders open in the account
DeleteAllMagicOrders("", 0);

//-- Deletes all orders that have a magic number 101
DeleteAllMagicOrders(101);

int BuyStopOrdersTotal();

Gibt die Gesamtzahl der offenen BuyStop-Orders zurück.
//Get the total number of open buy stops in the account
BuyStopOrdersTotal();


int BuyLimitOrdersTotal();

Gibt die Gesamtzahl der offenen BuyLimit-Orders zurück.
//Get the total number of open buy limits in the account
BuyLimitOrdersTotal();


int SellStopOrdersTotal();

Gibt die Gesamtzahl der offenen SellStop-Orders zurück.
//Get the total number of open sell stops in the account
SellStopOrdersTotal();


int SellLimitOrdersTotal();

Gibt die Gesamtzahl der offenen SellLimit-Orders zurück.
//Get the total number of open sell limits in the account
SellLimitOrdersTotal();


double OrdersTotalVolume();

Gibt das Gesamtvolumen aller offenen Orders zurück.
//Get the total volume/lot of open orders in the account
OrdersTotalVolume();


double BuyStopOrdersTotalVolume();

Gibt das Gesamtvolumen aller BuyStop-Orders zurück.
//Get the total volume/lot of open buy stops in the account
BuyStopOrdersTotalVolume();


double BuyLimitOrdersTotalVolume();

Gibt das Gesamtvolumen aller BuyLimit-Orders zurück.
//Get the total volume/lot of open buy limits in the account
BuyLimitOrdersTotalVolume();


double SellStopOrdersTotalVolume();

Gibt das Gesamtvolumen aller SellStop-Orders zurück.
//Get the total volume/lot of open sell stops in the account
SellStopOrdersTotalVolume();

double SellLimitOrdersTotalVolume();


Gibt das Gesamtvolumen aller SellLimit-Orders zurück.
//Get the total volume/lot of open sell limits in the account
SellLimitOrdersTotalVolume();

int MagicOrdersTotal(
   ulong magicNumber
);


Gibt die Anzahl der offenen Aufträge zurück, die der angegebenen magischen Zahl entsprechen.
//Get the total open pending orders for magic number 101
MagicOrdersTotal(101);


int MagicBuyStopOrdersTotal(
   ulong magicNumber
);


Gibt die Anzahl der offenen BuyStop-Orders zurück, die der angegebenen magischen Zahl entsprechen.
//Get the total open buy stop orders for magic number 101
MagicBuyStopOrdersTotal(101);


int MagicBuyLimitOrdersTotal(
   ulong magicNumber
);


Gibt die Anzahl der offenen BuyLimit-Orders zurück, die der angegebenen magischen Zahl entsprechen.
//Get the total open buy limit orders for magic number 101
MagicBuyLimitOrdersTotal(101);


int MagicSellStopOrdersTotal(
   ulong magicNumber
);


Gibt die Anzahl der offenen SellStop-Orders zurück, die der angegebenen magischen Zahl entsprechen.
//Get the total open sell stop orders for magic number 101
MagicSellStopOrdersTotal(101);


int MagicSellLimitOrdersTotal(
   ulong magicNumber
);

Gibt die Anzahl der offenen SellLimit-Orders zurück, die der angegebenen magischen Zahl entsprechen.
//Get the total open sell limit orders for magic number 101
MagicSellLimitOrdersTotal(101);


double MagicOrdersTotalVolume(
   ulong magicNumber
);

Gibt das Gesamtvolumen aller offenen Orders zurück, die der angegebenen magischen Zahl entsprechen.
//Get the total volume/lot of all open orders for magic 101
MagicOrdersTotalVolume(101);

double MagicBuyStopOrdersTotalVolume(
   ulong magicNumber
);


Gibt das Gesamtvolumen aller offenen BuyStop-Orders zurück, die der angegebenen, magischen Zahl entsprechen.
//Get the total volume/lot of all buy stop orders for magic 101
MagicBuyStopOrdersTotalVolume(101);

double MagicBuyLimitOrdersTotalVolume(
   ulong magicNumber
);


Gibt das Gesamtvolumen aller offenen BuyLimit-Orders zurück, die der angegebenen magischen Zahl entsprechen.
//Get the total volume/lot of all buy limit orders for magic 101
MagicBuyLimitOrdersTotalVolume(101);

double MagicSellStopOrdersTotalVolume(
   ulong magicNumber
);


Gibt das Gesamtvolumen aller offenen SellStop-Orders zurück, die der angegebenen magischen Zahl entsprechen.
//Get the total volume/lot of all sell stop orders for magic 101
MagicSellStopOrdersTotalVolume(101);

double MagicSellLimitOrdersTotalVolume(
   ulong magicNumber
);


Gibt das Gesamtvolumen aller offenen SellLimit-Orders zurück, die der angegebenen magischen Zahl entsprechen.
//Get the total volume/lot of all sell limit orders for magic 101
MagicSellLimitOrdersTotalVolume(101);

int SymbolOrdersTotal(
   string symbol,
   ulong magicNumber
);

Gibt die Anzahl der offenen Orders zurück, die dem angegebenen Symbol und der magischen Zahl entsprechen.
//Get the total open orders for the symbol
SymbolOrdersTotal(_Symbol, 0);

//Get the total open orders for the symbol and magic 101
SymbolOrdersTotal(_Symbol, 101);


int SymbolBuyStopOrdersTotal(
   string symbol,
   ulong magicNumber
);


Gibt die Anzahl der offenen BuyStop-Orders zurück, die dem angegebenen Symbol und der magischen Zahl entsprechen.
//Get the total buy stop orders for the symbol
SymbolBuyStopOrdersTotal(_Symbol, 0);

//Get the total buy stop orders for the symbol and magic number 101
SymbolBuyStopOrdersTotal(_Symbol, 101);


int SymbolBuyLimitOrdersTotal(
   string symbol,
   ulong magicNumber
);


Gibt die Anzahl der offenen BuyLimit-Orders zurück, die dem angegebenen Symbol und der magischen Zahl entsprechen.
//Get the total buy limit orders for the symbol
SymbolBuyLimitOrdersTotal(_Symbol, 0);

//Get the total buy limit orders for the symbol and magic number 101
SymbolBuyLimitOrdersTotal(_Symbol, 101);


int SymbolSellStopOrdersTotal(
   string symbol,
   ulong magicNumber
);


Gibt die Anzahl der offenen SellStop-Orders zurück, die dem angegebenen Symbol und der magischen Zahl entsprechen.
//Get the total sell stop orders for the symbol
SymbolSellStopOrdersTotal(_Symbol, 0);

//Get the total sell stop orders for the symbol and magic 101
SymbolSellStopOrdersTotal(_Symbol, 101);


int SymbolSellLimitOrdersTotal(
   string symbol,
   ulong magicNumber
);


Gibt die Anzahl der offenen SellLimit-Orders zurück, die dem angegebenen Symbol und der magischen Zahl entsprechen.
//Get the total sell limit orders for the symbol
SymbolSellLimitOrdersTotal(_Symbol, 0);

//Get the total sell limit orders for the symbol and magic 101
SymbolSellLimitOrdersTotal(_Symbol, 101);


double SymbolOrdersTotalVolume(
   string symbol,
   ulong magicNumber
);


Gibt das Gesamtvolumen aller offenen Orders zurück, die dem angegebenen Symbol und der magischen Zahl entsprechen.
//Get the total orders volume/lot for the symbol
SymbolOrdersTotalVolume(_Symbol, 0);

//Get the total orders volume/lot for the symbol and magic 101
SymbolOrdersTotalVolume(_Symbol, 101);


double SymbolBuyStopOrdersTotalVolume(
   string symbol,
   ulong magicNumber
);

Gibt das Gesamtvolumen aller offenen BuyStop-Orders zurück, die dem angegebenen Symbol und der magischen Zahl entsprechen.
//Get the total buy stops volume/lot for the symbol
SymbolBuyStopOrdersTotalVolume(_Symbol, 0);

//Get the total buy stops volume/lot for the symbol and magic 101
SymbolBuyStopOrdersTotalVolume(_Symbol, 101);

double SymbolBuyLimitOrdersTotalVolume(
   string symbol,
   ulong magicNumber
);


Gibt das Gesamtvolumen aller offenen BuyLimit-Orders zurück, die dem angegebenen Symbol und der magischen Zahl entsprechen.
//Get the total buy limits volume/lot for the symbol
SymbolBuyLimitOrdersTotalVolume(_Symbol, 0);

//Get the total buy limits volume/lot for symbol and magic 101
SymbolBuyLimitOrdersTotalVolume(_Symbol, 101);

double SymbolSellStopOrdersTotalVolume(
   string symbol,
   ulong magicNumber
);


Gibt das Gesamtvolumen aller offenen SellStop-Orders zurück, die dem angegebenen Symbol und der magischen Zahl entsprechen.
//Get the total sell stops volume/lot for symbol
SymbolSellStopOrdersTotalVolume(_Symbol, 0);

//Get the total sell stops volume/lot for symbol and magic 101
SymbolSellStopOrdersTotalVolume(_Symbol, 101);

double SymbolSellLimitOrdersTotalVolume(
   string symbol,
   ulong magicNumber
);


Gibt das Gesamtvolumen aller offenen SellLimit-Orders zurück, die dem angegebenen Symbol und der magischen Zahl entsprechen.
//Get the total sell limits volume/lot for symbol
SymbolSellLimitOrdersTotalVolume(_Symbol, 0);

//Get the total sell limits volume/lot for symbol and magic 101
SymbolSellLimitOrdersTotalVolume(_Symbol, 101);

string AccountOrdersStatus(
   bool formatForComment
);


Druckt einen als Zeichenkette formatierten Status aller offenen Orders auf dem Symbolchart oder der Registerkarte Experten in MetaTrader 5.
//Print the status of all open orders 
//formatted for the chart comments
Comment(AccountOrdersStatus(true));

//Print the status of all open orders 
//formatted for the Experts tab
Print(AccountOrdersStatus(false));

//Activate an alert with the status of all 
//open orders formatted for printing
Print(AccountOrdersStatus(false));


string MagicOrdersStatus(
   ulong magicNumber,
   bool formatForComment
);


Druckt einen als Zeichenkette formatierten Status aller offenen Orders, die der angegebenen magischen Zahl entsprechen, auf dem Symboldiagramm oder der Registerkarte Experten in MetaTrader 5.
//Print the status of all open orders matching 
//magic number 101 formatted for the chart comments
Comment(MagicOrdersStatus(101, true));

//Print the status of all open orders matching
//magic number 101 formatted for the Experts tab
Print(MagicOrdersStatus(101, false));

//Activate an alert with the status of all open orders
//matching magic number 101 formatted for printing
Print(MagicOrdersStatus(101, false));


 
string SymbolOrdersStatus(
   string symbol,
   ulong magicNumber,
   bool formatForComment
);

Druckt einen als Zeichenkette formatierten Status aller offenen Orders, die dem angegebenen Symbol und der magischen Zahl entsprechen, auf dem Symboldiagramm oder der Registerkarte Experten im MetaTrader 5.  
//Print the status of all open orders matching
//the symbol and magic number 101 formatted for the chart comments
Comment(SymbolOrdersStatus(_Symbol, 101, true));

//Print the status of all open orders matching
//the symbol and magic number 101 formatted for the Experts tab
Print(SymbolOrdersStatus(_Symbol, 101, false));

//Activate an alert with the status of all open orders
//matching the symbol and magic number 101 formatted for printing
Print(SymbolOrdersStatus(_Symbol, 101, false));

Mit der importierten Bibliothek können Sie nun durch einfache Funktionsaufrufe Daten zum Status schwebender Aufträge öffnen, ändern, löschen oder abrufen. Um dies zu demonstrieren, werden wir im nächsten Abschnitt ein praktisches Handels-Panel mit grafischer Nutzeroberfläche (GUI) für die Verwaltung schwebender Aufträge erstellen.


Wie man ein Pending Orders Panel (GUI) entwickelt, das auf der Pending Orders Manager EX5 Library basiert

In diesem Abschnitt werden wir eine grafische Nutzeroberfläche (GUI) für einen Pending Orders Panel Expert Advisor entwickeln, der die Pending Orders Manager EX5 Bibliothek nutzt, um alle Orders zu öffnen, zu löschen und zu überwachen, die mit einer bestimmten magischen Zahl verbunden sind, die an das Panel gebunden ist. Dieses Beispiel ist eine praktische Demonstration des Imports und der Implementierung der soeben erstellten EX5-Bibliothek in einer realen MQL5-Anwendung.

Das Pending Orders Panel wird die MQL5-Standardbibliothek für Panels und Dialoge nutzen, was es uns ermöglicht, die Codebasis minimal und effizient zu halten. Unten sehen Sie ein Bild der endgültigen GUI des Pending Orders Panel.

MQL5-Panel für schwebende Aufträge (GUI)

Um mit der Erstellung der GUI zu beginnen, erstellen Sie einen neuen Expert Advisor mit dem MQL-Assistenten der MetaEditor-IDE und nennen Sie ihn PendingOrdersPanel.mq5. Da unser Pending Orders Panel Expert Advisor die Bibliothek PendingOrdersManager.ex5 integrieren wird, müssen zunächst die Funktionsprototyp-Beschreibungen der Bibliothek importiert und eingebunden werden, wie zuvor beschrieben. Platzieren Sie den Bibliotheksimportcode direkt unter den #property-Direktiven. Da die Bibliothek zahlreiche Funktionen enthält, importieren wir nur die erforderlichen Funktionsprototypen, die im folgenden Code aufgeführt sind.

#import "Toolkit/PendingOrdersManager.ex5" //-- Opening import directive
//-- Function descriptions for the imported function prototypes

//-- Pending Orders Execution and Modification Functions
bool OpenBuyLimit(ulong magicNumber, string symbol, double entryPrice, double lotSize, int sl, int tp, string orderComment);
bool OpenBuyStop(ulong magicNumber, string symbol, double entryPrice, double lotSize, int sl, int tp, string orderComment);
bool OpenSellLimit(ulong magicNumber, string symbol, double entryPrice, double lotSize, int sl, int tp, string orderComment);
bool OpenSellStop(ulong magicNumber, string symbol, double entryPrice, double lotSize, int sl, int tp, string orderComment);
//--
int MagicOrdersTotal(ulong magicNumber);
int MagicBuyStopOrdersTotal(ulong magicNumber);
int MagicBuyLimitOrdersTotal(ulong magicNumber);
int MagicSellStopOrdersTotal(ulong magicNumber);
int MagicSellLimitOrdersTotal(ulong magicNumber);
//--
bool DeleteAllBuyStops(string symbol, ulong magicNumber);
bool DeleteAllBuyLimits(string symbol, ulong magicNumber);
bool DeleteAllSellStops(string symbol, ulong magicNumber);
bool DeleteAllSellLimits(string symbol, ulong magicNumber);
bool DeleteAllMagicOrders(ulong magicNumber);

#import //--- Closing import directive

Wir erstellen die globalen Variablen, die wir zum Speichern der Auftragseigenschaften verwenden werden.

//-- Global variables
//-----------------------
ulong magicNo = 10101010;
double symbolPoint = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
long symbolDigits = SymbolInfoInteger(_Symbol, SYMBOL_DIGITS);
int spread = (int)SymbolInfoInteger(_Symbol, SYMBOL_SPREAD);
double volumeLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
int sl = (int)spread * 50;
int tp = (int)spread * 100;

Als Nächstes müssen wir einige Konstanten definieren, um alle Eigenschaften der grafischen Objekte zu speichern. So können wir die Werte an einer zentralen Stelle aktualisieren oder ändern, wenn wir das Erscheinungsbild der Auftragstafeln ändern wollen.

//-- Define some values for the main panel
#define MAIN_PANEL_NAME string("Orders Panel - Trading: " + _Symbol + " - Magic No: " + IntegerToString(magicNo))
#define MAIN_PANEL_SUBWINDOW 0
#define MAIN_PANEL_X1 350
#define MAIN_PANEL_Y1 10
#define MAIN_PANEL_WIDTH int(800 + MAIN_PANEL_X1)
#define MAIN_PANEL_X2 MAIN_PANEL_WIDTH

//-- Define the GUI objects general properties
#define GUI_OBJECTS_MARGIN 5
#define GUI_OBJECTS_HEIGHT 40//40
#define GUI_OBJECTS_WIDTH int((MAIN_PANEL_WIDTH) / 7)
#define GUI_OBJECTS_FONT_SIZE 9//10
#define GUI_OBJECTS_HEADER_FONT_SIZE GUI_OBJECTS_FONT_SIZE
//-----
#define MAIN_PANEL_HEIGHT int(((GUI_OBJECTS_HEIGHT + (GUI_OBJECTS_MARGIN * 2)) * 10) + MAIN_PANEL_Y1)
#define MAIN_PANEL_Y2 MAIN_PANEL_HEIGHT

//-- Define the GUI objects colors
#define GUI_OBJECTS_HEADING_COLOR clrNavy

#define GUI_OBJECTS_BUY_BTN_COLOR clrWhite
#define GUI_OBJECTS_BUY_BTN_BG_COLOR clrBlue
#define GUI_OBJECTS_BUY_EDIT_COLOR clrBlue
#define GUI_OBJECTS_BUY_EDIT_BG_COLOR clrAliceBlue

#define GUI_OBJECTS_SELL_BTN_COLOR clrWhite
#define GUI_OBJECTS_SELL_BTN_BG_COLOR clrCrimson
#define GUI_OBJECTS_SELL_EDIT_COLOR clrMaroon
#define GUI_OBJECTS_SELL_EDIT_BG_COLOR clrMistyRose

/*------------------------------------------------------
* Define GUI components for the heading labels ****
*-----------------------------------------------------*/
//-- Define values for the lotVolHeaderLabel
#define VOLUME_LOT_LABEL_NAME "Volume Lot Header Label"
#define VOLUME_LOT_LABEL_SUBWINDOW 0
#define VOLUME_LOT_LABEL_X1 int(GUI_OBJECTS_MARGIN + GUI_OBJECTS_WIDTH)
#define VOLUME_LOT_LABEL_Y1 int(GUI_OBJECTS_MARGIN * 2)
#define VOLUME_LOT_LABEL_TEXT "VOLUME/LOT"


//-- Define values for the openPriceHeaderLabel
#define OPEN_PRICE_LABEL_NAME "Open Price Header Label"
#define OPEN_PRICE_LABEL_SUBWINDOW 0
#define OPEN_PRICE_LABEL_X1 (int(GUI_OBJECTS_WIDTH) * 2)
#define OPEN_PRICE_LABEL_Y1 int(GUI_OBJECTS_MARGIN * 2)
#define OPEN_PRICE_LABEL_TEXT "OPENING PRICE"

//-- Define values for the slHeaderLabel
#define SL_LABEL_NAME "Sl Header Label"
#define SL_LABEL_SUBWINDOW 0
#define SL_LABEL_X1 (int(GUI_OBJECTS_WIDTH) * 3)
#define SL_LABEL_Y1 int(GUI_OBJECTS_MARGIN * 2)
#define SL_LABEL_TEXT "SL (Pips)"

//-- Define values for the tpHeaderLabel
#define TP_LABEL_NAME "Tp Header Label"
#define TP_LABEL_SUBWINDOW 0
#define TP_LABEL_X1 (int(GUI_OBJECTS_WIDTH) * 3.75)
#define TP_LABEL_Y1 int(GUI_OBJECTS_MARGIN * 2)
#define TP_LABEL_TEXT "TP (Pips)"

/*------------------------------------------------------
* Define Buy Stop Order GUI components ****
*-----------------------------------------------------*/
//-- Define values for the buyStopBtn
#define BUY_STOP_BTN_NAME "Buy Stop Button"
#define BUY_STOP_BTN_SUBWINDOW 0
#define BUY_STOP_BTN_X1 GUI_OBJECTS_MARGIN
#define BUY_STOP_BTN_Y1 int(GUI_OBJECTS_MARGIN + GUI_OBJECTS_HEIGHT)
#define BUY_STOP_BTN_TEXT "BUY STOP"

//-- Define values for the buyStopVolumeLotEdit
#define BUY_STOP_VOLUME_LOT_EDIT_NAME "Buy Stop Volume Lot Edit"
#define BUY_STOP_VOLUME_LOT_EDIT_SUBWINDOW 0
#define BUY_STOP_VOLUME_LOT_EDIT_X1 int(GUI_OBJECTS_MARGIN + GUI_OBJECTS_WIDTH)
#define BUY_STOP_VOLUME_LOT_EDIT_Y1 int(GUI_OBJECTS_MARGIN + GUI_OBJECTS_HEIGHT)

//-- Define values for the buyStopOpenPriceEdit
#define BUY_STOP_OPEN_PRICE_EDIT_NAME "Buy Stop Open Price Edit"
#define BUY_STOP_OPEN_PRICE_EDIT_SUBWINDOW 0
#define BUY_STOP_OPEN_PRICE_EDIT_X1 int((GUI_OBJECTS_WIDTH) * 2)
#define BUY_STOP_OPEN_PRICE_EDIT_Y1 int(GUI_OBJECTS_MARGIN + GUI_OBJECTS_HEIGHT)

//-- Define values for the buyStopSlEdit
#define BUY_STOP_SL_EDIT_NAME "Buy Stop SL Edit"
#define BUY_STOP_SL_EDIT_SUBWINDOW 0
#define BUY_STOP_SL_EDIT_X1 int(GUI_OBJECTS_WIDTH * 3)
#define BUY_STOP_SL_EDIT_Y1 int(GUI_OBJECTS_MARGIN + GUI_OBJECTS_HEIGHT)

//-- Define values for the buyStopTpEdit
#define BUY_STOP_TP_EDIT_NAME "Buy Stop TP Edit"
#define BUY_STOP_TP_EDIT_SUBWINDOW 0
#define BUY_STOP_TP_EDIT_X1 int(GUI_OBJECTS_WIDTH * 3.7)
#define BUY_STOP_TP_EDIT_Y1 int(GUI_OBJECTS_MARGIN + GUI_OBJECTS_HEIGHT)

/*------------------------------------------------------
* Define Sell Stop Order GUI components ****
*-----------------------------------------------------*/
//-- Define values for the sellStopBtn
#define SELL_STOP_BTN_NAME "Sell Stop Button"
#define SELL_STOP_BTN_SUBWINDOW 0
#define SELL_STOP_BTN_X1 GUI_OBJECTS_MARGIN
#define SELL_STOP_BTN_Y1 int((GUI_OBJECTS_MARGIN + GUI_OBJECTS_HEIGHT) * 2)
#define SELL_STOP_BTN_TEXT "SELL STOP"

//-- Define values for the sellStopVolumeLotEdit
#define SELL_STOP_VOLUME_LOT_EDIT_NAME "Sell Stop Volume Lot Edit"
#define SELL_STOP_VOLUME_LOT_EDIT_SUBWINDOW 0
#define SELL_STOP_VOLUME_LOT_EDIT_X1 int(GUI_OBJECTS_MARGIN + GUI_OBJECTS_WIDTH)
#define SELL_STOP_VOLUME_LOT_EDIT_Y1 int((GUI_OBJECTS_MARGIN + GUI_OBJECTS_HEIGHT) * 2)

//-- Define values for the sellStopOpenPriceEdit
#define SELL_STOP_OPEN_PRICE_EDIT_NAME "Sell Stop Open Price Edit"
#define SELL_STOP_OPEN_PRICE_EDIT_SUBWINDOW 0
#define SELL_STOP_OPEN_PRICE_EDIT_X1 int((GUI_OBJECTS_WIDTH) * 2)
#define SELL_STOP_OPEN_PRICE_EDIT_Y1 int((GUI_OBJECTS_MARGIN + GUI_OBJECTS_HEIGHT) * 2)

//-- Define values for the sellStopSlEdit
#define SELL_STOP_SL_EDIT_NAME "Sell Stop SL Edit"
#define SELL_STOP_SL_EDIT_SUBWINDOW 0
#define SELL_STOP_SL_EDIT_X1 int(GUI_OBJECTS_WIDTH * 3)
#define SELL_STOP_SL_EDIT_Y1 int((GUI_OBJECTS_MARGIN + GUI_OBJECTS_HEIGHT) * 2)

//-- Define values for the sellStopTpEdit
#define SELL_STOP_TP_EDIT_NAME "Sell Stop TP Edit"
#define SELL_STOP_TP_EDIT_SUBWINDOW 0
#define SELL_STOP_TP_EDIT_X1 int(GUI_OBJECTS_WIDTH * 3.7)
#define SELL_STOP_TP_EDIT_Y1 int((GUI_OBJECTS_MARGIN + GUI_OBJECTS_HEIGHT) * 2)

/*------------------------------------------------------
* Define Buy Limit Order GUI components ****
*-----------------------------------------------------*/
//-- Define values for the buyLimitBtn
#define BUY_LIMIT_BTN_NAME "Buy Limit Button"
#define BUY_LIMIT_BTN_SUBWINDOW 0
#define BUY_LIMIT_BTN_X1 GUI_OBJECTS_MARGIN
#define BUY_LIMIT_BTN_Y1 int((GUI_OBJECTS_MARGIN + GUI_OBJECTS_HEIGHT) * 3)
#define BUY_LIMIT_BTN_TEXT "BUY LIMIT"

//-- Define values for the buyLimitVolumeLotEdit
#define BUY_LIMIT_VOLUME_LOT_EDIT_NAME "Buy Limit Volume Lot Edit"
#define BUY_LIMIT_VOLUME_LOT_EDIT_SUBWINDOW 0
#define BUY_LIMIT_VOLUME_LOT_EDIT_X1 int(GUI_OBJECTS_MARGIN + GUI_OBJECTS_WIDTH)
#define BUY_LIMIT_VOLUME_LOT_EDIT_Y1 int((GUI_OBJECTS_MARGIN + GUI_OBJECTS_HEIGHT) * 3)

//-- Define values for the buySLimitOpenPriceEdit
#define BUY_LIMIT_OPEN_PRICE_EDIT_NAME "Buy Limit Open Price Edit"
#define BUY_LIMIT_OPEN_PRICE_EDIT_SUBWINDOW 0
#define BUY_LIMIT_OPEN_PRICE_EDIT_X1 int((GUI_OBJECTS_WIDTH) * 2)
#define BUY_LIMIT_OPEN_PRICE_EDIT_Y1 int((GUI_OBJECTS_MARGIN + GUI_OBJECTS_HEIGHT) * 3)

//-- Define values for the buyLimitSlEdit
#define BUY_LIMIT_SL_EDIT_NAME "Buy Limit SL Edit"
#define BUY_LIMIT_SL_EDIT_SUBWINDOW 0
#define BUY_LIMIT_SL_EDIT_X1 int(GUI_OBJECTS_WIDTH * 3)
#define BUY_LIMIT_SL_EDIT_Y1 int((GUI_OBJECTS_MARGIN + GUI_OBJECTS_HEIGHT) * 3)

//-- Define values for the buyLimitTpEdit
#define BUY_LIMIT_TP_EDIT_NAME "Buy Limit TP Edit"
#define BUY_LIMIT_TP_EDIT_SUBWINDOW 0
#define BUY_LIMIT_TP_EDIT_X1 int(GUI_OBJECTS_WIDTH * 3.7)
#define BUY_LIMIT_TP_EDIT_Y1 int((GUI_OBJECTS_MARGIN + GUI_OBJECTS_HEIGHT) * 3)

/*------------------------------------------------------
* Define Sell Limit Order GUI components ****
*-----------------------------------------------------*/
//-- Define values for the sellLimitBtn
#define SELL_LIMIT_BTN_NAME "Sell Limit Button"
#define SELL_LIMIT_BTN_SUBWINDOW 0
#define SELL_LIMIT_BTN_X1 GUI_OBJECTS_MARGIN
#define SELL_LIMIT_BTN_Y1 int((GUI_OBJECTS_MARGIN + GUI_OBJECTS_HEIGHT) * 4)
#define SELL_LIMIT_BTN_TEXT "SELL LIMIT"

//-- Define values for the sellLimitVolumeLotEdit
#define SELL_LIMIT_VOLUME_LOT_EDIT_NAME "Sell Limit Volume Lot Edit"
#define SELL_LIMIT_VOLUME_LOT_EDIT_SUBWINDOW 0
#define SELL_LIMIT_VOLUME_LOT_EDIT_X1 int(GUI_OBJECTS_MARGIN + GUI_OBJECTS_WIDTH)
#define SELL_LIMIT_VOLUME_LOT_EDIT_Y1 int((GUI_OBJECTS_MARGIN + GUI_OBJECTS_HEIGHT) * 4)

//-- Define values for the sellLimitOpenPriceEdit
#define SELL_LIMIT_OPEN_PRICE_EDIT_NAME "Sell Limit Open Price Edit"
#define SELL_LIMIT_OPEN_PRICE_EDIT_SUBWINDOW 0
#define SELL_LIMIT_OPEN_PRICE_EDIT_X1 int((GUI_OBJECTS_WIDTH) * 2)
#define SELL_LIMIT_OPEN_PRICE_EDIT_Y1 int((GUI_OBJECTS_MARGIN + GUI_OBJECTS_HEIGHT) * 4)

//-- Define values for the sellLimitSlEdit
#define SELL_LIMIT_SL_EDIT_NAME "Sell Limit SL Edit"
#define SELL_LIMIT_SL_EDIT_SUBWINDOW 0
#define SELL_LIMIT_SL_EDIT_X1 int(GUI_OBJECTS_WIDTH * 3)
#define SELL_LIMIT_SL_EDIT_Y1 int((GUI_OBJECTS_MARGIN + GUI_OBJECTS_HEIGHT) * 4)

//-- Define values for the sellLimitTpEdit
#define SELL_LIMIT_TP_EDIT_NAME "Sell Limit TP Edit"
#define SELL_LIMIT_TP_EDIT_SUBWINDOW 0
#define SELL_LIMIT_TP_EDIT_X1 int(GUI_OBJECTS_WIDTH * 3.7)
#define SELL_LIMIT_TP_EDIT_Y1 int((GUI_OBJECTS_MARGIN + GUI_OBJECTS_HEIGHT) * 4)

/*------------------------------------------------------
* Define Order Status GUI components ****
*-----------------------------------------------------*/
//-- Define values for the orders status
#define STATUS_HEADER_FONT_SIZE int(GUI_OBJECTS_FONT_SIZE)// / 1.1)
#define STATUS_EDIT_FONT_SIZE int(GUI_OBJECTS_FONT_SIZE)// / 1.1)
#define STATUS_EDIT_WIDTH int((MAIN_PANEL_WIDTH / 1.485) - (GUI_OBJECTS_MARGIN * 2))
#define STATUS_EDIT_COLOR clrBlack
#define STATUS_EDIT_BG_COLOR clrLemonChiffon
#define STATUS_EDIT_BORDER_COLOR clrMidnightBlue
#define DELETE_ORDERS_BTN_COLOR clrLightYellow
#define DELETE_BUY_ORDERS_BTN_BG_COLOR clrRoyalBlue
#define DELETE_SELL_ORDERS_BTN_BG_COLOR clrCrimson
#define DELETE_ALL_ORDERS_BTN_BG_COLOR clrMediumVioletRed
#define DELETE_ORDERS_BTN_BORDER_COLOR clrBlack
#define DELETE_ORDERS_BTN_WIDTH int((STATUS_EDIT_WIDTH / 1.93) - (GUI_OBJECTS_MARGIN * 3))
#define DELETE_ORDERS_BTN_FONT_SIZE int((GUI_OBJECTS_FONT_SIZE))// / 1.05)

//-- Define values for the magicOrderStatusLabel
#define MAGIC_ORDER_STATUS_LABEL_NAME "Magic Order Status Label"
#define MAGIC_ORDER_STATUS_LABEL_SUBWINDOW 0
#define MAGIC_ORDER_STATUS_LABEL_X1 int(GUI_OBJECTS_MARGIN * 3)
#define MAGIC_ORDER_STATUS_LABEL_Y1 int((GUI_OBJECTS_HEIGHT * 6) + (GUI_OBJECTS_MARGIN * 2))
#define MAGIC_ORDER_STATUS_LABEL_TEXT string("MAGIC No: " + IntegerToString(magicNo) + " - TOTAL OPEN ORDERS: ")

//-- Define values for the magicOrdersStatusEdit
#define MAGIC_ORDER_STATUS_EDIT_NAME "Magic Order Status Edit"
#define MAGIC_ORDER_STATUS_EDIT_SUBWINDOW 0
#define MAGIC_ORDER_STATUS_EDIT_X1 int(GUI_OBJECTS_MARGIN * 2)
#define MAGIC_ORDER_STATUS_EDIT_Y1 int((MAGIC_ORDER_STATUS_LABEL_Y1) + (GUI_OBJECTS_HEIGHT / 1.7))

//-- Define values for the deleteAllMagicBuyStopsBtn
#define DELETE_ALL_MAGIC_BUY_STOPS_BTN_NAME "Delete All Magic Buy Stops Btn"
#define DELETE_ALL_MAGIC_BUY_STOPS_BTN_SUBWINDOW 0
#define DELETE_ALL_MAGIC_BUY_STOPS_BTN_X1 int(GUI_OBJECTS_MARGIN * 2)
#define DELETE_ALL_MAGIC_BUY_STOPS_BTN_Y1 int((MAGIC_ORDER_STATUS_EDIT_Y1) + (GUI_OBJECTS_HEIGHT + GUI_OBJECTS_MARGIN))
#define DELETE_ALL_MAGIC_BUY_STOPS_BTN_TEXT "DELETE ALL MAGIC BUY STOPS"

//-- Define values for the deleteAllMagicSellStopsBtn
#define DELETE_ALL_MAGIC_SELL_STOPS_BTN_NAME "Delete All Magic Sell Stops Btn"
#define DELETE_ALL_MAGIC_SELL_STOPS_BTN_SUBWINDOW 0
#define DELETE_ALL_MAGIC_SELL_STOPS_BTN_X1 int((GUI_OBJECTS_MARGIN * 3) + DELETE_ORDERS_BTN_WIDTH)
#define DELETE_ALL_MAGIC_SELL_STOPS_BTN_Y1 int((MAGIC_ORDER_STATUS_EDIT_Y1) + (GUI_OBJECTS_HEIGHT + GUI_OBJECTS_MARGIN))
#define DELETE_ALL_MAGIC_SELL_STOPS_BTN_TEXT "DELETE ALL MAGIC SELL STOPS"

//-- Define values for the deleteAllMagicBuyLimitsBtn
#define DELETE_ALL_MAGIC_BUY_LIMITS_BTN_NAME "Delete All Magic Buy Limits Btn"
#define DELETE_ALL_MAGIC_BUY_LIMITS_BTN_SUBWINDOW 0
#define DELETE_ALL_MAGIC_BUY_LIMITS_BTN_X1 int(GUI_OBJECTS_MARGIN * 2)
#define DELETE_ALL_MAGIC_BUY_LIMITS_BTN_Y1 int((DELETE_ALL_MAGIC_BUY_STOPS_BTN_Y1) + (GUI_OBJECTS_HEIGHT + GUI_OBJECTS_MARGIN))
#define DELETE_ALL_MAGIC_BUY_LIMITS_BTN_TEXT "DELETE ALL MAGIC BUY LIMITS"

//-- Define values for the deleteAllMagicSellLimitsBtn
#define DELETE_ALL_MAGIC_SELL_LIMITS_BTN_NAME "Delete All Magic Sell Limits Btn"
#define DELETE_ALL_MAGIC_SELL_LIMITS_BTN_SUBWINDOW 0
#define DELETE_ALL_MAGIC_SELL_LIMITS_BTN_X1 int((GUI_OBJECTS_MARGIN * 3) + DELETE_ORDERS_BTN_WIDTH)
#define DELETE_ALL_MAGIC_SELL_LIMITS_BTN_Y1 DELETE_ALL_MAGIC_BUY_LIMITS_BTN_Y1//int((MAGIC_ORDER_STATUS_EDIT_Y1) + (GUI_OBJECTS_HEIGHT + GUI_OBJECTS_MARGIN))
#define DELETE_ALL_MAGIC_SELL_LIMITS_BTN_TEXT "DELETE ALL MAGIC SELL LIMITS"

//-- Define values for the deleteAllMagicOrdersBtn
#define DELETE_ALL_MAGIC_ORDERS_BTN_NAME "Delete All Magic Orders Btn"
#define DELETE_ALL_MAGIC_ORDERS_BTN_SUBWINDOW 0
#define DELETE_ALL_MAGIC_ORDERS_BTN_X1 int(GUI_OBJECTS_MARGIN * 2)
#define DELETE_ALL_MAGIC_ORDERS_BTN_Y1 int((DELETE_ALL_MAGIC_BUY_LIMITS_BTN_Y1) + (GUI_OBJECTS_HEIGHT + GUI_OBJECTS_MARGIN))
#define DELETE_ALL_MAGIC_ORDERS_BTN_TEXT "DELETE ALL MAGIC PENDING ORDERS"

Wir fügen die MQL5-Standardklassen für Panels und Dialoge zu unserem Code hinzu oder binden Sie sie ein.

//-- Include the MQL5 standard library for panels and dialogs
#include <Controls\Dialog.mqh>
#include <Controls\Button.mqh>
#include <Controls\Label.mqh>
#include <Controls\Edit.mqh>

Da die Panel- und Dialogklassen nun in unserer Datei enthalten und verfügbar sind, können wir ihre Objekte erstellen, um ihre Funktionalität in unserem Code zu erweitern.

//-- Create objects for the included standard classes
CAppDialog mainPanelWindow;

//-- Create the header label components
CLabel lotVolHeaderLabel;
CLabel openPriceHeaderLabel;
CLabel slHeaderLabel;
CLabel tpHeaderLabel;

//-- Create the buy stop GUI components
//--BuyStopBtn
CButton buyStopBtn;
//--BuyStopEdits
CEdit buyStopVolumeLotEdit;
CEdit buyStopOpenPriceEdit;
CEdit buyStopSlEdit;
CEdit buyStopTpEdit;

//-- Create the sell stop GUI components
//--SellStopBtn
CButton sellStopBtn;
//--sellStopEdits
CEdit sellStopVolumeLotEdit;
CEdit sellStopOpenPriceEdit;
CEdit sellStopSlEdit;
CEdit sellStopTpEdit;

//-- Create the buy limit GUI components
//--BuyLimitBtn
CButton buyLimitBtn;
//--BuyLimitEdits
CEdit buyLimitVolumeLotEdit;
CEdit buyLimitOpenPriceEdit;
CEdit buyLimitSlEdit;
CEdit buyLimitTpEdit;

//-- Create the sell limit GUI components
//--sellLimitBtn
CButton sellLimitBtn;
//--sellLimitEdits
CEdit sellLimitVolumeLotEdit;
CEdit sellLimitOpenPriceEdit;
CEdit sellLimitSlEdit;
CEdit sellLimitTpEdit;

//-- Create the order status GUI components
//--magic order status
CLabel magicOrderStatusLabel;
CEdit magicOrdersStatusEdit;
//--Magic orders delete buttons
CButton deleteAllMagicBuyStopsBtn;
CButton deleteAllMagicSellStopsBtn;
CButton deleteAllMagicBuyLimitsBtn;
CButton deleteAllMagicSellLimitsBtn;
CButton deleteAllMagicOrdersBtn;

Wir erstellen die Variablen, die für die Speicherung der Auftragseingangspreise verantwortlich sein werden, sowie einen String, der den Auftragsstatus aller von unserem Expert Advisor eröffneten Aufträge speichert.

//-- Default starting entry prices for different pending orders
double buyStopEntryPrice = SymbolInfoDouble(_Symbol, SYMBOL_ASK) + ((spread * 20) * symbolPoint);
double buyLimitEntryPrice = SymbolInfoDouble(_Symbol, SYMBOL_ASK) - ((spread * 20) * symbolPoint);
double sellStopEntryPrice = SymbolInfoDouble(_Symbol, SYMBOL_ASK) - ((spread * 20) * symbolPoint);
double sellLimitEntryPrice = SymbolInfoDouble(_Symbol, SYMBOL_ASK) + ((spread * 20) * symbolPoint);

//-- String values for the orders status
string magicOrderStatus;

Nachdem der Kopfteil unseres Codes abgeschlossen ist, müssen wir als Nächstes die Funktion erstellen, die für die Erzeugung und das Laden der grafischen Nutzeroberfläche während der Initialisierung des Expert Advisors verantwortlich ist. Wir werden diese Funktion CreateGui() nennen.

void CreateGui()
  {
//-- Create the orders panel
   mainPanelWindow.Create(
      0, MAIN_PANEL_NAME, MAIN_PANEL_SUBWINDOW,
      MAIN_PANEL_X1, MAIN_PANEL_Y1, MAIN_PANEL_X2, MAIN_PANEL_Y2
   );
   /*------------------------------------------------------
   * Header Labels GUI components creation ****
   *-----------------------------------------------------*/
//--Create the lot volume header label
   lotVolHeaderLabel.Create(
      0, VOLUME_LOT_LABEL_NAME, VOLUME_LOT_LABEL_SUBWINDOW,
      VOLUME_LOT_LABEL_X1,
      VOLUME_LOT_LABEL_Y1,
      GUI_OBJECTS_WIDTH,
      GUI_OBJECTS_HEIGHT
   );
   lotVolHeaderLabel.Text(VOLUME_LOT_LABEL_TEXT);
   lotVolHeaderLabel.Color(GUI_OBJECTS_HEADING_COLOR);
   lotVolHeaderLabel.FontSize(GUI_OBJECTS_HEADER_FONT_SIZE);
   mainPanelWindow.Add(lotVolHeaderLabel);

//--Create the open price header label
   openPriceHeaderLabel.Create(
      0, OPEN_PRICE_LABEL_NAME, OPEN_PRICE_LABEL_SUBWINDOW,
      OPEN_PRICE_LABEL_X1, OPEN_PRICE_LABEL_Y1,
      GUI_OBJECTS_WIDTH, GUI_OBJECTS_HEIGHT
   );
   openPriceHeaderLabel.Text(OPEN_PRICE_LABEL_TEXT);
   openPriceHeaderLabel.Color(GUI_OBJECTS_HEADING_COLOR);
   openPriceHeaderLabel.FontSize(GUI_OBJECTS_HEADER_FONT_SIZE);
   mainPanelWindow.Add(openPriceHeaderLabel);

//--Create the sl header label
   slHeaderLabel.Create(
      0, SL_LABEL_NAME, SL_LABEL_SUBWINDOW,
      SL_LABEL_X1, SL_LABEL_Y1,
      int(GUI_OBJECTS_WIDTH / 1.4), GUI_OBJECTS_HEIGHT
   );
   slHeaderLabel.Text(SL_LABEL_TEXT);
   slHeaderLabel.Color(GUI_OBJECTS_HEADING_COLOR);
   slHeaderLabel.FontSize(GUI_OBJECTS_HEADER_FONT_SIZE);
   mainPanelWindow.Add(slHeaderLabel);

//--Create the tp header label
   tpHeaderLabel.Create(
      0, TP_LABEL_NAME, TP_LABEL_SUBWINDOW,
      TP_LABEL_X1, TP_LABEL_Y1,
      int(GUI_OBJECTS_WIDTH / 1.4), GUI_OBJECTS_HEIGHT
   );
   tpHeaderLabel.Text(TP_LABEL_TEXT);
   tpHeaderLabel.Color(GUI_OBJECTS_HEADING_COLOR);
   tpHeaderLabel.FontSize(GUI_OBJECTS_HEADER_FONT_SIZE);
   mainPanelWindow.Add(tpHeaderLabel);

   /*------------------------------------------------------
   * Buy Stop Order GUI components creation ****
   *-----------------------------------------------------*/
//--Create the open buy stop button
   buyStopBtn.Create(
      0, BUY_STOP_BTN_NAME, BUY_STOP_BTN_SUBWINDOW,
      BUY_STOP_BTN_X1, BUY_STOP_BTN_Y1,
      0, 0
   );
   buyStopBtn.Text(BUY_STOP_BTN_TEXT);
   buyStopBtn.Width(GUI_OBJECTS_WIDTH);
   buyStopBtn.Height(GUI_OBJECTS_HEIGHT);
   buyStopBtn.Color(GUI_OBJECTS_BUY_BTN_COLOR);
   buyStopBtn.ColorBackground(GUI_OBJECTS_BUY_BTN_BG_COLOR);
   buyStopBtn.FontSize(GUI_OBJECTS_FONT_SIZE);
   mainPanelWindow.Add(buyStopBtn);

//--Create the buy stop volume lot edit to get the buy stop volume/lot user input
   buyStopVolumeLotEdit.Create(
      0, BUY_STOP_VOLUME_LOT_EDIT_NAME, BUY_STOP_VOLUME_LOT_EDIT_SUBWINDOW,
      BUY_STOP_VOLUME_LOT_EDIT_X1, BUY_STOP_VOLUME_LOT_EDIT_Y1,
      0, 0
   );
   buyStopVolumeLotEdit.Text(DoubleToString(volumeLot));
   buyStopVolumeLotEdit.Width(GUI_OBJECTS_WIDTH);
   buyStopVolumeLotEdit.Height(GUI_OBJECTS_HEIGHT);
   buyStopVolumeLotEdit.Color(GUI_OBJECTS_BUY_EDIT_COLOR);
   buyStopVolumeLotEdit.ColorBackground(GUI_OBJECTS_BUY_EDIT_BG_COLOR);
   buyStopVolumeLotEdit.FontSize(GUI_OBJECTS_FONT_SIZE);
   buyStopVolumeLotEdit.ColorBorder(GUI_OBJECTS_BUY_BTN_BG_COLOR);
   mainPanelWindow.Add(buyStopVolumeLotEdit);

//--Create the buy stop price edit to get the buy stop opening price user input
   buyStopOpenPriceEdit.Create(
      0, BUY_STOP_OPEN_PRICE_EDIT_NAME, BUY_STOP_OPEN_PRICE_EDIT_SUBWINDOW,
      BUY_STOP_OPEN_PRICE_EDIT_X1, BUY_STOP_OPEN_PRICE_EDIT_Y1,
      0, 0
   );
   buyStopOpenPriceEdit.Text(DoubleToString(buyStopEntryPrice, int(symbolDigits)));
   buyStopOpenPriceEdit.Width(GUI_OBJECTS_WIDTH);
   buyStopOpenPriceEdit.Height(GUI_OBJECTS_HEIGHT);
   buyStopOpenPriceEdit.Color(GUI_OBJECTS_BUY_EDIT_COLOR);
   buyStopOpenPriceEdit.ColorBackground(GUI_OBJECTS_BUY_EDIT_BG_COLOR);
   buyStopOpenPriceEdit.FontSize(GUI_OBJECTS_FONT_SIZE);
   buyStopOpenPriceEdit.ColorBorder(GUI_OBJECTS_BUY_BTN_BG_COLOR);
   mainPanelWindow.Add(buyStopOpenPriceEdit);

//--Create the buy stop sl edit to get the buy stop sl user input
   buyStopSlEdit.Create(
      0, BUY_STOP_SL_EDIT_NAME, BUY_STOP_SL_EDIT_SUBWINDOW,
      BUY_STOP_SL_EDIT_X1, BUY_STOP_SL_EDIT_Y1,
      0, 0
   );
   buyStopSlEdit.Text(IntegerToString(sl));
   buyStopSlEdit.Width(int(GUI_OBJECTS_WIDTH / 1.4));
   buyStopSlEdit.Height(GUI_OBJECTS_HEIGHT);
   buyStopSlEdit.Color(GUI_OBJECTS_BUY_EDIT_COLOR);
   buyStopSlEdit.ColorBackground(GUI_OBJECTS_BUY_EDIT_BG_COLOR);
   buyStopSlEdit.FontSize(GUI_OBJECTS_FONT_SIZE);
   buyStopSlEdit.ColorBorder(GUI_OBJECTS_BUY_BTN_BG_COLOR);
   mainPanelWindow.Add(buyStopSlEdit);

//--Create the buy stop tp edit to get the buy stop tp user input
   buyStopTpEdit.Create(
      0, BUY_STOP_TP_EDIT_NAME, BUY_STOP_TP_EDIT_SUBWINDOW,
      BUY_STOP_TP_EDIT_X1, BUY_STOP_TP_EDIT_Y1,
      0, 0
   );
   buyStopTpEdit.Text(IntegerToString(tp));
   buyStopTpEdit.Width(GUI_OBJECTS_WIDTH);
   buyStopTpEdit.Height(GUI_OBJECTS_HEIGHT);
   buyStopTpEdit.Color(GUI_OBJECTS_BUY_EDIT_COLOR);
   buyStopTpEdit.ColorBackground(GUI_OBJECTS_BUY_EDIT_BG_COLOR);
   buyStopTpEdit.FontSize(GUI_OBJECTS_FONT_SIZE);
   buyStopTpEdit.ColorBorder(GUI_OBJECTS_BUY_BTN_BG_COLOR);
   mainPanelWindow.Add(buyStopTpEdit);

   /*------------------------------------------------------
   * Sell Stop Order GUI components creation ****
   *-----------------------------------------------------*/
//--Create the open sell stop button
   sellStopBtn.Create(
      0, SELL_STOP_BTN_NAME, SELL_STOP_BTN_SUBWINDOW,
      SELL_STOP_BTN_X1, SELL_STOP_BTN_Y1,
      0, 0
   );
   sellStopBtn.Text(SELL_STOP_BTN_TEXT);
   sellStopBtn.Width(GUI_OBJECTS_WIDTH);
   sellStopBtn.Height(GUI_OBJECTS_HEIGHT);
   sellStopBtn.Color(GUI_OBJECTS_SELL_BTN_COLOR);
   sellStopBtn.ColorBackground(GUI_OBJECTS_SELL_BTN_BG_COLOR);
   sellStopBtn.FontSize(GUI_OBJECTS_FONT_SIZE);
   mainPanelWindow.Add(sellStopBtn);

//--Create the sell stop volume lot edit to get the sell stop volume/lot user input
   sellStopVolumeLotEdit.Create(
      0, SELL_STOP_VOLUME_LOT_EDIT_NAME, SELL_STOP_VOLUME_LOT_EDIT_SUBWINDOW,
      SELL_STOP_VOLUME_LOT_EDIT_X1, SELL_STOP_VOLUME_LOT_EDIT_Y1,
      0, 0
   );
   sellStopVolumeLotEdit.Text(DoubleToString(volumeLot));
   sellStopVolumeLotEdit.Width(GUI_OBJECTS_WIDTH);
   sellStopVolumeLotEdit.Height(GUI_OBJECTS_HEIGHT);
   sellStopVolumeLotEdit.Color(GUI_OBJECTS_SELL_EDIT_COLOR);
   sellStopVolumeLotEdit.ColorBackground(GUI_OBJECTS_SELL_EDIT_BG_COLOR);
   sellStopVolumeLotEdit.FontSize(GUI_OBJECTS_FONT_SIZE);
   sellStopVolumeLotEdit.ColorBorder(GUI_OBJECTS_SELL_BTN_BG_COLOR);
   mainPanelWindow.Add(sellStopVolumeLotEdit);

//--Create the sell stop price edit to get the sell stop opening price user input
   sellStopOpenPriceEdit.Create(
      0, SELL_STOP_OPEN_PRICE_EDIT_NAME, SELL_STOP_OPEN_PRICE_EDIT_SUBWINDOW,
      SELL_STOP_OPEN_PRICE_EDIT_X1, SELL_STOP_OPEN_PRICE_EDIT_Y1,
      0, 0
   );
   sellStopOpenPriceEdit.Text(DoubleToString(sellStopEntryPrice, int(symbolDigits)));
   sellStopOpenPriceEdit.Width(GUI_OBJECTS_WIDTH);
   sellStopOpenPriceEdit.Height(GUI_OBJECTS_HEIGHT);
   sellStopOpenPriceEdit.Color(GUI_OBJECTS_SELL_EDIT_COLOR);
   sellStopOpenPriceEdit.ColorBackground(GUI_OBJECTS_SELL_EDIT_BG_COLOR);
   sellStopOpenPriceEdit.FontSize(GUI_OBJECTS_FONT_SIZE);
   sellStopOpenPriceEdit.ColorBorder(GUI_OBJECTS_SELL_BTN_BG_COLOR);
   mainPanelWindow.Add(sellStopOpenPriceEdit);

//--Create the sell stop sl edit to get the sell stop sl user input
   sellStopSlEdit.Create(
      0, SELL_STOP_SL_EDIT_NAME, SELL_STOP_SL_EDIT_SUBWINDOW,
      SELL_STOP_SL_EDIT_X1, SELL_STOP_SL_EDIT_Y1,
      0, 0
   );
   sellStopSlEdit.Text(IntegerToString(sl));
   sellStopSlEdit.Width(int(GUI_OBJECTS_WIDTH / 1.4));
   sellStopSlEdit.Height(GUI_OBJECTS_HEIGHT);
   sellStopSlEdit.Color(GUI_OBJECTS_SELL_EDIT_COLOR);
   sellStopSlEdit.ColorBackground(GUI_OBJECTS_SELL_EDIT_BG_COLOR);
   sellStopSlEdit.FontSize(GUI_OBJECTS_FONT_SIZE);
   sellStopSlEdit.ColorBorder(GUI_OBJECTS_SELL_BTN_BG_COLOR);
   mainPanelWindow.Add(sellStopSlEdit);

//--Create the sell stop tp edit to get the sell stop tp user input
   sellStopTpEdit.Create(
      0, SELL_STOP_TP_EDIT_NAME, SELL_STOP_TP_EDIT_SUBWINDOW,
      SELL_STOP_TP_EDIT_X1, SELL_STOP_TP_EDIT_Y1,
      0, 0
   );
   sellStopTpEdit.Text(IntegerToString(tp));
   sellStopTpEdit.Width(GUI_OBJECTS_WIDTH);
   sellStopTpEdit.Height(GUI_OBJECTS_HEIGHT);
   sellStopTpEdit.Color(GUI_OBJECTS_SELL_EDIT_COLOR);
   sellStopTpEdit.ColorBackground(GUI_OBJECTS_SELL_EDIT_BG_COLOR);
   sellStopTpEdit.FontSize(GUI_OBJECTS_FONT_SIZE);
   sellStopTpEdit.ColorBorder(GUI_OBJECTS_SELL_BTN_BG_COLOR);
   mainPanelWindow.Add(sellStopTpEdit);

   /*------------------------------------------------------
   * Buy Limit Order GUI components creation ****
   *-----------------------------------------------------*/
//--Create the open buy limit button
   buyLimitBtn.Create(
      0, BUY_LIMIT_BTN_NAME, BUY_LIMIT_BTN_SUBWINDOW,
      BUY_LIMIT_BTN_X1, BUY_LIMIT_BTN_Y1,
      0, 0
   );
   buyLimitBtn.Text(BUY_LIMIT_BTN_TEXT);
   buyLimitBtn.Width(GUI_OBJECTS_WIDTH);
   buyLimitBtn.Height(GUI_OBJECTS_HEIGHT);
   buyLimitBtn.Color(GUI_OBJECTS_BUY_BTN_COLOR);
   buyLimitBtn.ColorBackground(GUI_OBJECTS_BUY_BTN_BG_COLOR);
   buyLimitBtn.FontSize(GUI_OBJECTS_FONT_SIZE);
   mainPanelWindow.Add(buyLimitBtn);

//--Create the buy limit volume lot edit to get the buy limit volume/lot user input
   buyLimitVolumeLotEdit.Create(
      0, BUY_LIMIT_VOLUME_LOT_EDIT_NAME, BUY_LIMIT_VOLUME_LOT_EDIT_SUBWINDOW,
      BUY_LIMIT_VOLUME_LOT_EDIT_X1, BUY_LIMIT_VOLUME_LOT_EDIT_Y1,
      0, 0
   );
   buyLimitVolumeLotEdit.Text(DoubleToString(volumeLot));
   buyLimitVolumeLotEdit.Width(GUI_OBJECTS_WIDTH);
   buyLimitVolumeLotEdit.Height(GUI_OBJECTS_HEIGHT);
   buyLimitVolumeLotEdit.Color(GUI_OBJECTS_BUY_EDIT_COLOR);
   buyLimitVolumeLotEdit.ColorBackground(GUI_OBJECTS_BUY_EDIT_BG_COLOR);
   buyLimitVolumeLotEdit.FontSize(GUI_OBJECTS_FONT_SIZE);
   buyLimitVolumeLotEdit.ColorBorder(GUI_OBJECTS_BUY_BTN_BG_COLOR);
   mainPanelWindow.Add(buyLimitVolumeLotEdit);

//--Create the buy limit price edit to get the buy limit opening price user input
   buyLimitOpenPriceEdit.Create(
      0, BUY_LIMIT_OPEN_PRICE_EDIT_NAME, BUY_LIMIT_OPEN_PRICE_EDIT_SUBWINDOW,
      BUY_LIMIT_OPEN_PRICE_EDIT_X1, BUY_LIMIT_OPEN_PRICE_EDIT_Y1,
      0, 0
   );
   buyLimitOpenPriceEdit.Text(DoubleToString(buyLimitEntryPrice, int(symbolDigits)));
   buyLimitOpenPriceEdit.Width(GUI_OBJECTS_WIDTH);
   buyLimitOpenPriceEdit.Height(GUI_OBJECTS_HEIGHT);
   buyLimitOpenPriceEdit.Color(GUI_OBJECTS_BUY_EDIT_COLOR);
   buyLimitOpenPriceEdit.ColorBackground(GUI_OBJECTS_BUY_EDIT_BG_COLOR);
   buyLimitOpenPriceEdit.FontSize(GUI_OBJECTS_FONT_SIZE);
   buyLimitOpenPriceEdit.ColorBorder(GUI_OBJECTS_BUY_BTN_BG_COLOR);
   mainPanelWindow.Add(buyLimitOpenPriceEdit);

//--Create the buy limit sl edit to get the buy limit sl user input
   buyLimitSlEdit.Create(
      0, BUY_LIMIT_SL_EDIT_NAME, BUY_LIMIT_SL_EDIT_SUBWINDOW,
      BUY_LIMIT_SL_EDIT_X1, BUY_LIMIT_SL_EDIT_Y1,
      0, 0
   );
   buyLimitSlEdit.Text(IntegerToString(sl));
   buyLimitSlEdit.Width(int(GUI_OBJECTS_WIDTH / 1.4));
   buyLimitSlEdit.Height(GUI_OBJECTS_HEIGHT);
   buyLimitSlEdit.Color(GUI_OBJECTS_BUY_EDIT_COLOR);
   buyLimitSlEdit.ColorBackground(GUI_OBJECTS_BUY_EDIT_BG_COLOR);
   buyLimitSlEdit.FontSize(GUI_OBJECTS_FONT_SIZE);
   buyLimitSlEdit.ColorBorder(GUI_OBJECTS_BUY_BTN_BG_COLOR);
   mainPanelWindow.Add(buyLimitSlEdit);

//--Create the buy limit tp edit to get the buy limit tp user input
   buyLimitTpEdit.Create(
      0, BUY_LIMIT_TP_EDIT_NAME, BUY_LIMIT_TP_EDIT_SUBWINDOW,
      BUY_LIMIT_TP_EDIT_X1, BUY_LIMIT_TP_EDIT_Y1,
      0, 0
   );
   buyLimitTpEdit.Text(IntegerToString(tp));
   buyLimitTpEdit.Width(GUI_OBJECTS_WIDTH);
   buyLimitTpEdit.Height(GUI_OBJECTS_HEIGHT);
   buyLimitTpEdit.Color(GUI_OBJECTS_BUY_EDIT_COLOR);
   buyLimitTpEdit.ColorBackground(GUI_OBJECTS_BUY_EDIT_BG_COLOR);
   buyLimitTpEdit.FontSize(GUI_OBJECTS_FONT_SIZE);
   buyLimitTpEdit.ColorBorder(GUI_OBJECTS_BUY_BTN_BG_COLOR);
   mainPanelWindow.Add(buyLimitTpEdit);

   /*------------------------------------------------------
   * Sell Limit Order GUI components creation ****
   *-----------------------------------------------------*/
//--Create the open sell limit button
   sellLimitBtn.Create(
      0, SELL_LIMIT_BTN_NAME, SELL_LIMIT_BTN_SUBWINDOW,
      SELL_LIMIT_BTN_X1, SELL_LIMIT_BTN_Y1,
      0, 0
   );
   sellLimitBtn.Text(SELL_LIMIT_BTN_TEXT);
   sellLimitBtn.Width(GUI_OBJECTS_WIDTH);
   sellLimitBtn.Height(GUI_OBJECTS_HEIGHT);
   sellLimitBtn.Color(GUI_OBJECTS_SELL_BTN_COLOR);
   sellLimitBtn.ColorBackground(GUI_OBJECTS_SELL_BTN_BG_COLOR);
   sellLimitBtn.FontSize(GUI_OBJECTS_FONT_SIZE);
   mainPanelWindow.Add(sellLimitBtn);

//--Create the sell limit volume lot edit to get the sell limit volume/lot user input
   sellLimitVolumeLotEdit.Create(
      0, SELL_LIMIT_VOLUME_LOT_EDIT_NAME, SELL_LIMIT_VOLUME_LOT_EDIT_SUBWINDOW,
      SELL_LIMIT_VOLUME_LOT_EDIT_X1, SELL_LIMIT_VOLUME_LOT_EDIT_Y1,
      0, 0
   );
   sellLimitVolumeLotEdit.Text(DoubleToString(volumeLot));
   sellLimitVolumeLotEdit.Width(GUI_OBJECTS_WIDTH);
   sellLimitVolumeLotEdit.Height(GUI_OBJECTS_HEIGHT);
   sellLimitVolumeLotEdit.Color(GUI_OBJECTS_SELL_EDIT_COLOR);
   sellLimitVolumeLotEdit.ColorBackground(GUI_OBJECTS_SELL_EDIT_BG_COLOR);
   sellLimitVolumeLotEdit.FontSize(GUI_OBJECTS_FONT_SIZE);
   sellLimitVolumeLotEdit.ColorBorder(GUI_OBJECTS_SELL_BTN_BG_COLOR);
   mainPanelWindow.Add(sellLimitVolumeLotEdit);

//--Create the sell limit price edit to get the sell limit opening price user input
   sellLimitOpenPriceEdit.Create(
      0, SELL_LIMIT_OPEN_PRICE_EDIT_NAME, SELL_LIMIT_OPEN_PRICE_EDIT_SUBWINDOW,
      SELL_LIMIT_OPEN_PRICE_EDIT_X1, SELL_LIMIT_OPEN_PRICE_EDIT_Y1,
      0, 0
   );
   sellLimitOpenPriceEdit.Text(DoubleToString(sellLimitEntryPrice, int(symbolDigits)));
   sellLimitOpenPriceEdit.Width(GUI_OBJECTS_WIDTH);
   sellLimitOpenPriceEdit.Height(GUI_OBJECTS_HEIGHT);
   sellLimitOpenPriceEdit.Color(GUI_OBJECTS_SELL_EDIT_COLOR);
   sellLimitOpenPriceEdit.ColorBackground(GUI_OBJECTS_SELL_EDIT_BG_COLOR);
   sellLimitOpenPriceEdit.FontSize(GUI_OBJECTS_FONT_SIZE);
   sellLimitOpenPriceEdit.ColorBorder(GUI_OBJECTS_SELL_BTN_BG_COLOR);
   mainPanelWindow.Add(sellLimitOpenPriceEdit);

//--Create the sell limit sl edit to get the sell limit sl user input
   sellLimitSlEdit.Create(
      0, SELL_LIMIT_SL_EDIT_NAME, SELL_LIMIT_SL_EDIT_SUBWINDOW,
      SELL_LIMIT_SL_EDIT_X1, SELL_LIMIT_SL_EDIT_Y1,
      0, 0
   );
   sellLimitSlEdit.Text(IntegerToString(sl));
   sellLimitSlEdit.Width(int(GUI_OBJECTS_WIDTH / 1.4));
   sellLimitSlEdit.Height(GUI_OBJECTS_HEIGHT);
   sellLimitSlEdit.Color(GUI_OBJECTS_SELL_EDIT_COLOR);
   sellLimitSlEdit.ColorBackground(GUI_OBJECTS_SELL_EDIT_BG_COLOR);
   sellLimitSlEdit.FontSize(GUI_OBJECTS_FONT_SIZE);
   sellLimitSlEdit.ColorBorder(GUI_OBJECTS_SELL_BTN_BG_COLOR);
   mainPanelWindow.Add(sellLimitSlEdit);

//--Create the sell limit tp edit to get the sell limit tp user input
   sellLimitTpEdit.Create(
      0, SELL_LIMIT_TP_EDIT_NAME, SELL_LIMIT_TP_EDIT_SUBWINDOW,
      SELL_LIMIT_TP_EDIT_X1, SELL_LIMIT_TP_EDIT_Y1,
      0, 0
   );
   sellLimitTpEdit.Text(IntegerToString(tp));
   sellLimitTpEdit.Width(GUI_OBJECTS_WIDTH);
   sellLimitTpEdit.Height(GUI_OBJECTS_HEIGHT);
   sellLimitTpEdit.Color(GUI_OBJECTS_SELL_EDIT_COLOR);
   sellLimitTpEdit.ColorBackground(GUI_OBJECTS_SELL_EDIT_BG_COLOR);
   sellLimitTpEdit.FontSize(GUI_OBJECTS_FONT_SIZE);
   sellLimitTpEdit.ColorBorder(GUI_OBJECTS_SELL_BTN_BG_COLOR);
   mainPanelWindow.Add(sellLimitTpEdit);

   /*-------------------------------------------------------------
   * Status Labels and readonly edits GUI components creation ****
   *------------------------------------------------------------*/
//--Create the order magic status label
   magicOrderStatusLabel.Create(
      0, MAGIC_ORDER_STATUS_LABEL_NAME, MAGIC_ORDER_STATUS_LABEL_SUBWINDOW,
      MAGIC_ORDER_STATUS_LABEL_X1,
      MAGIC_ORDER_STATUS_LABEL_Y1,
      GUI_OBJECTS_WIDTH,
      GUI_OBJECTS_HEIGHT
   );
   magicOrderStatusLabel.Text(MAGIC_ORDER_STATUS_LABEL_TEXT + " - (Total Open Orders: " + (string(MagicOrdersTotal(magicNo))) + ")");
   magicOrderStatusLabel.Color(STATUS_EDIT_COLOR);
   magicOrderStatusLabel.FontSize(STATUS_HEADER_FONT_SIZE);
   mainPanelWindow.Add(magicOrderStatusLabel);

//--Create the magic order status edit to display the magic orders status
   magicOrdersStatusEdit.Create(
      0, MAGIC_ORDER_STATUS_EDIT_NAME, MAGIC_ORDER_STATUS_EDIT_SUBWINDOW,
      MAGIC_ORDER_STATUS_EDIT_X1, MAGIC_ORDER_STATUS_EDIT_Y1,
      0, 0
   );
   magicOrdersStatusEdit.ReadOnly(true);
   magicOrdersStatusEdit.Text(magicOrderStatus);
   magicOrdersStatusEdit.Width(STATUS_EDIT_WIDTH);
   magicOrdersStatusEdit.Height(GUI_OBJECTS_HEIGHT);
   magicOrdersStatusEdit.Color(STATUS_EDIT_COLOR);
   magicOrdersStatusEdit.ColorBackground(STATUS_EDIT_BG_COLOR);
   magicOrdersStatusEdit.FontSize(STATUS_EDIT_FONT_SIZE);
   magicOrdersStatusEdit.ColorBorder(STATUS_EDIT_BORDER_COLOR);
   mainPanelWindow.Add(magicOrdersStatusEdit);

//--Create the delete all magic buy stops button
   deleteAllMagicBuyStopsBtn.Create(
      0, DELETE_ALL_MAGIC_BUY_STOPS_BTN_NAME, DELETE_ALL_MAGIC_BUY_STOPS_BTN_SUBWINDOW,
      DELETE_ALL_MAGIC_BUY_STOPS_BTN_X1, DELETE_ALL_MAGIC_BUY_STOPS_BTN_Y1,
      0, 0
   );
   deleteAllMagicBuyStopsBtn.Text(DELETE_ALL_MAGIC_BUY_STOPS_BTN_TEXT);
   deleteAllMagicBuyStopsBtn.Width(DELETE_ORDERS_BTN_WIDTH);
   deleteAllMagicBuyStopsBtn.Height(GUI_OBJECTS_HEIGHT);
   deleteAllMagicBuyStopsBtn.Color(DELETE_ORDERS_BTN_COLOR);
   deleteAllMagicBuyStopsBtn.ColorBackground(DELETE_BUY_ORDERS_BTN_BG_COLOR);
   deleteAllMagicBuyStopsBtn.ColorBorder(DELETE_ORDERS_BTN_BORDER_COLOR);
   deleteAllMagicBuyStopsBtn.FontSize(DELETE_ORDERS_BTN_FONT_SIZE);
   mainPanelWindow.Add(deleteAllMagicBuyStopsBtn);

//--Create the delete all magic sell stops button
   deleteAllMagicSellStopsBtn.Create(
      0, DELETE_ALL_MAGIC_SELL_STOPS_BTN_NAME, DELETE_ALL_MAGIC_SELL_STOPS_BTN_SUBWINDOW,
      DELETE_ALL_MAGIC_SELL_STOPS_BTN_X1, DELETE_ALL_MAGIC_SELL_STOPS_BTN_Y1,
      0, 0
   );
   deleteAllMagicSellStopsBtn.Text(DELETE_ALL_MAGIC_SELL_STOPS_BTN_TEXT);
   deleteAllMagicSellStopsBtn.Width(DELETE_ORDERS_BTN_WIDTH);
   deleteAllMagicSellStopsBtn.Height(GUI_OBJECTS_HEIGHT);
   deleteAllMagicSellStopsBtn.Color(DELETE_ORDERS_BTN_COLOR);
   deleteAllMagicSellStopsBtn.ColorBackground(DELETE_SELL_ORDERS_BTN_BG_COLOR);
   deleteAllMagicSellStopsBtn.ColorBorder(DELETE_ORDERS_BTN_BORDER_COLOR);
   deleteAllMagicSellStopsBtn.FontSize(DELETE_ORDERS_BTN_FONT_SIZE);
   mainPanelWindow.Add(deleteAllMagicSellStopsBtn);

//--Create the delete all magic buy limits button
   deleteAllMagicBuyLimitsBtn.Create(
      0, DELETE_ALL_MAGIC_BUY_LIMITS_BTN_NAME, DELETE_ALL_MAGIC_BUY_LIMITS_BTN_SUBWINDOW,
      DELETE_ALL_MAGIC_BUY_LIMITS_BTN_X1, DELETE_ALL_MAGIC_BUY_LIMITS_BTN_Y1,
      0, 0
   );
   deleteAllMagicBuyLimitsBtn.Text(DELETE_ALL_MAGIC_BUY_LIMITS_BTN_TEXT);
   deleteAllMagicBuyLimitsBtn.Width(DELETE_ORDERS_BTN_WIDTH);
   deleteAllMagicBuyLimitsBtn.Height(GUI_OBJECTS_HEIGHT);
   deleteAllMagicBuyLimitsBtn.Color(DELETE_ORDERS_BTN_COLOR);
   deleteAllMagicBuyLimitsBtn.ColorBackground(DELETE_BUY_ORDERS_BTN_BG_COLOR);
   deleteAllMagicBuyLimitsBtn.ColorBorder(DELETE_ORDERS_BTN_BORDER_COLOR);
   deleteAllMagicBuyLimitsBtn.FontSize(DELETE_ORDERS_BTN_FONT_SIZE);
   mainPanelWindow.Add(deleteAllMagicBuyLimitsBtn);

//--Create the delete all magic sell limits button
   deleteAllMagicSellLimitsBtn.Create(
      0, DELETE_ALL_MAGIC_SELL_LIMITS_BTN_NAME, DELETE_ALL_MAGIC_SELL_LIMITS_BTN_SUBWINDOW,
      DELETE_ALL_MAGIC_SELL_LIMITS_BTN_X1, DELETE_ALL_MAGIC_SELL_LIMITS_BTN_Y1,
      0, 0
   );
   deleteAllMagicSellLimitsBtn.Text(DELETE_ALL_MAGIC_SELL_LIMITS_BTN_TEXT);
   deleteAllMagicSellLimitsBtn.Width(DELETE_ORDERS_BTN_WIDTH);
   deleteAllMagicSellLimitsBtn.Height(GUI_OBJECTS_HEIGHT);
   deleteAllMagicSellLimitsBtn.Color(DELETE_ORDERS_BTN_COLOR);
   deleteAllMagicSellLimitsBtn.ColorBackground(DELETE_SELL_ORDERS_BTN_BG_COLOR);
   deleteAllMagicSellLimitsBtn.ColorBorder(DELETE_ORDERS_BTN_BORDER_COLOR);
   deleteAllMagicSellLimitsBtn.FontSize(DELETE_ORDERS_BTN_FONT_SIZE);
   mainPanelWindow.Add(deleteAllMagicSellLimitsBtn);

//--Create the delete all magic orders button
   deleteAllMagicOrdersBtn.Create(
      0, DELETE_ALL_MAGIC_ORDERS_BTN_NAME, DELETE_ALL_MAGIC_ORDERS_BTN_SUBWINDOW,
      DELETE_ALL_MAGIC_ORDERS_BTN_X1, DELETE_ALL_MAGIC_ORDERS_BTN_Y1,
      0, 0
   );
   deleteAllMagicOrdersBtn.Text(DELETE_ALL_MAGIC_ORDERS_BTN_TEXT);
   deleteAllMagicOrdersBtn.Width(STATUS_EDIT_WIDTH);
   deleteAllMagicOrdersBtn.Height(GUI_OBJECTS_HEIGHT);
   deleteAllMagicOrdersBtn.Color(DELETE_ORDERS_BTN_COLOR);
   deleteAllMagicOrdersBtn.ColorBackground(DELETE_ALL_ORDERS_BTN_BG_COLOR);
   deleteAllMagicOrdersBtn.ColorBorder(DELETE_ORDERS_BTN_BORDER_COLOR);
   deleteAllMagicOrdersBtn.FontSize(DELETE_ORDERS_BTN_FONT_SIZE);
   mainPanelWindow.Add(deleteAllMagicOrdersBtn);

//--Call the Run() method to load the main panel window
   mainPanelWindow.Run();
  }

Jetzt müssen wir alle Tastendrücke oder Aktivierungen erkennen, indem wir die Funktion OnChartEvent(...) ausfüllen. Diese Funktion dient zur Ereignisbehandlung für alle Nutzerinteraktionen und ist damit die Kernkomponente für die Reaktionsfähigkeit unseres Panels. In diesem Abschnitt werden wir die importierten Prototyp-Funktionen aus der Bibliothek PendingOrdersManager.ex5 aufrufen, die es uns ermöglichen, schwebende Aufträge auf der Grundlage von Nutzereingaben zu verwalten und zu manipulieren. Wenn ein Nutzer beispielsweise auf eine Schaltfläche klickt, um einen neuen schwebenden Auftrag zu erteilen, wird die entsprechende Bibliotheksfunktion ausgelöst, um den Vorgang auszuführen.

Um die Nutzererfahrung mit dem Panel für schwebender Aufträge weiter zu verbessern, werden wir auch ein auditives Feedback integrieren. Verschiedene Töne werden abgespielt, um das Ergebnis einer Aktion zu signalisieren, z. B. ob einen Auftrag erfolgreich aufgegeben wurde oder ob sie aufgrund eines Fehlers fehlgeschlagen ist. Dies ermöglicht Echtzeit-Feedback und eine zusätzliche Ebene der Interaktivität, wodurch das Panel intuitiver und nutzerfreundlicher wird. Durch die Kombination von visuellen und auditiven Hinweisen wird sichergestellt, dass die Nutzer den Status ihrer Aktionen leicht verfolgen und entsprechend reagieren können.

void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//--Detect any clicks or events performed to the orders panel window and make it moveable
   mainPanelWindow.ChartEvent(id, lparam, dparam, sparam);

//--Detect any click events on the chart
   if(id == CHARTEVENT_OBJECT_CLICK)
     {
      //--Detect when the buyStopBtn is clicked and open a new buy stop order
      if(sparam == buyStopBtn.Name())
        {
         Print(__FUNCTION__, " CHARTEVEN_OBJECT_CLICK: ", sparam);
         Print("Opening a new Buy Stop Order with the details below: ");
         Print("Volume: ", buyStopVolumeLotEdit.Text());
         Print("Open Price: ", buyStopOpenPriceEdit.Text());
         Print("Sl (Pips): ", buyStopSlEdit.Text());
         Print("Tp (Pips): ", buyStopTpEdit.Text());
         if(
            OpenBuyStop(
               magicNo, _Symbol, StringToDouble(buyStopOpenPriceEdit.Text()),
               StringToDouble(buyStopVolumeLotEdit.Text()), (uint)StringToInteger(buyStopSlEdit.Text()),
               (uint)StringToInteger(buyStopTpEdit.Text()), "EX5 PendingOrdersManager Panel"
            )
         )
           {
            PlaySound("ok.wav");//-- Order placed ok
           }
         else
           {
            PlaySound("alert2.wav");//-- Order failed
           }
        }

      //--Detect when the sellStopBtn is clicked and open a new sell stop order
      if(sparam == sellStopBtn.Name())
        {
         Print(__FUNCTION__, " CHARTEVEN_OBJECT_CLICK: ", sparam);
         Print("Opening a new Sell Stop Order with the details below: ");
         Print("Volume: ", sellStopVolumeLotEdit.Text());
         Print("Open Price: ", sellStopOpenPriceEdit.Text());
         Print("Sl (Pips): ", sellStopSlEdit.Text());
         Print("Tp (Pips): ", sellStopTpEdit.Text());
         if(
            OpenSellStop(
               magicNo, _Symbol, StringToDouble(sellStopOpenPriceEdit.Text()),
               StringToDouble(sellStopVolumeLotEdit.Text()), (uint)StringToInteger(sellStopSlEdit.Text()),
               (uint)StringToInteger(sellStopTpEdit.Text()), "EX5 PendingOrdersManager Panel"
            )
         )
           {
            PlaySound("ok.wav");//-- Order placed ok
           }
         else
           {
            PlaySound("alert2.wav");//-- Order failed
           }
        }

      //--Detect when the buyLimitBtn is clicked and open a new buy limit order
      if(sparam == buyLimitBtn.Name())
        {
         Print(__FUNCTION__, " CHARTEVEN_OBJECT_CLICK: ", sparam);
         Print("Opening a new Buy Limit Order with the details below: ");
         Print("Volume: ", buyLimitVolumeLotEdit.Text());
         Print("Open Price: ", buyLimitOpenPriceEdit.Text());
         Print("Sl (Pips): ", buyLimitSlEdit.Text());
         Print("Tp (Pips): ", buyLimitTpEdit.Text());
         if(
            OpenBuyLimit(
               magicNo, _Symbol, StringToDouble(buyLimitOpenPriceEdit.Text()),
               StringToDouble(buyLimitVolumeLotEdit.Text()), (uint)StringToInteger(buyLimitSlEdit.Text()),
               (uint)StringToInteger(buyLimitTpEdit.Text()), "EX5 PendingOrdersManager Panel"
            )
         )
           {
            PlaySound("ok.wav");//-- Order placed ok
           }
         else
           {
            PlaySound("alert2.wav");//-- Order failed
           }
        }

      //--Detect when the sellLimitBtn is clicked and open a new sell limit order
      if(sparam == sellLimitBtn.Name())
        {
         Print(__FUNCTION__, " CHARTEVEN_OBJECT_CLICK: ", sparam);
         Print("Opening a new Sell Limit Order with the details below: ");
         Print("Volume: ", sellLimitVolumeLotEdit.Text());
         Print("Open Price: ", sellLimitOpenPriceEdit.Text());
         Print("Sl (Pips): ", sellLimitSlEdit.Text());
         Print("Tp (Pips): ", sellLimitTpEdit.Text());

         if(
            OpenSellLimit(
               magicNo, _Symbol, StringToDouble(sellLimitOpenPriceEdit.Text()),
               StringToDouble(sellLimitVolumeLotEdit.Text()), (uint)StringToInteger(sellLimitSlEdit.Text()),
               (uint)StringToInteger(sellLimitTpEdit.Text()), "EX5 PendingOrdersManager Panel"
            )
         )
           {
            PlaySound("ok.wav");//-- Order placed ok
           }
         else
           {
            PlaySound("alert2.wav");//-- Order failed
           }
        }

      //--Detect when the deleteAllMagicBuyStopsBtn is clicked and delete all the specified orders
      if(sparam == deleteAllMagicBuyStopsBtn.Name() && MagicBuyStopOrdersTotal(magicNo) > 0)
        {
         Print(__FUNCTION__, " CHARTEVEN_OBJECT_CLICK: ", sparam);
         Print("Deleting all the buy stop orders with magic number: ", magicNo);
         if(DeleteAllBuyStops("", magicNo))
           {
            PlaySound("ok.wav");//-- Orders deleted ok
           }
         else
           {
            PlaySound("alert2.wav");//-- Order deleting failed
           }
        }

      //--Detect when the deleteAllMagicSellStopsBtn is clicked and delete all the specified orders
      if(sparam == deleteAllMagicSellStopsBtn.Name() && MagicSellStopOrdersTotal(magicNo) > 0)
        {
         Print(__FUNCTION__, " CHARTEVEN_OBJECT_CLICK: ", sparam);
         Print("Deleting all the sell stop orders with magic number: ", magicNo);
         if(DeleteAllSellStops("", magicNo))
           {
            PlaySound("ok.wav");//-- Orders deleted ok
           }
         else
           {
            PlaySound("alert2.wav");//-- Order deleting failed
           }
        }

      //--Detect when the deleteAllMagicBuyLimitsBtn is clicked and delete all the specified orders
      if(sparam == deleteAllMagicBuyLimitsBtn.Name() && MagicBuyLimitOrdersTotal(magicNo) > 0)
        {
         Print(__FUNCTION__, " CHARTEVEN_OBJECT_CLICK: ", sparam);
         Print("Deleting all the buy limit orders with magic number: ", magicNo);
         if(DeleteAllBuyLimits("", magicNo))
           {
            PlaySound("ok.wav");//-- Orders deleted ok
           }
         else
           {
            PlaySound("alert2.wav");//-- Order deleting failed
           }
        }

      //--Detect when the deleteAllMagicSellLimitsBtn is clicked and delete all the specified orders
      if(sparam == deleteAllMagicSellLimitsBtn.Name() && MagicSellLimitOrdersTotal(magicNo) > 0)
        {
         Print(__FUNCTION__, " CHARTEVEN_OBJECT_CLICK: ", sparam);
         Print("Deleting all the sell limit orders with magic number: ", magicNo);
         if(DeleteAllSellLimits("", magicNo))
           {
            PlaySound("ok.wav");//-- Orders deleted ok
           }
         else
           {
            PlaySound("alert2.wav");//-- Order deleting failed
           }
        }

      //--Detect when the deleteAllMagicOrdersBtn is clicked and delete all the specified orders
      if(sparam == deleteAllMagicOrdersBtn.Name() && MagicOrdersTotal(magicNo) > 0)
        {
         Print(__FUNCTION__, " CHARTEVEN_OBJECT_CLICK: ", sparam);
         Print("Deleting all the open peding orders with magic number: ", magicNo);
         if(DeleteAllMagicOrders(magicNo))
           {
            PlaySound("ok.wav");//-- Orders deleted ok
           }
         else
           {
            PlaySound("alert2.wav");//-- Order deleting failed
           }
        }
     }
  }

Sie werden feststellen, dass der Expert Advisor, sobald er gestartet wurde, automatisch die Felder Auftragsvolumen/Lot, Einstiegskurse, Stop Loss (SL) und Take Profit (TP) mit vordefinierten Werten auf der Grundlage des aktuellen Spreads ausfüllt. Diese Werte geben dem Nutzer einen Ausgangspunkt für die Auftragserteilung, wodurch der Handelsprozess rationalisiert und die manuelle Eingabe minimiert wird. Darüber hinaus sind die Schaltflächen zum Löschen von Aufträgen unterhalb der magischen Auftragsstatus zunächst ausgegraut und deaktiviert, wenn keine schwebenden oder aktiven Aufträge mit der dem Expert Advisor zugewiesenen magischen Nummer gefunden werden. Sobald der Expert Advisor übereinstimmende Aufträge identifiziert, werden die Schaltflächen aktiviert und ändern ihre Farbe, um zu signalisieren, dass sie nun betriebsbereit und bereit sind, Löschbefehle auszuführen.

Orders Panel: mit deaktivierten Schaltflächen zum Löschen von Orders

Wenn der Expert Advisor feststellt, dass Aufträge mit der zugewiesenen magischen Zahl geöffnet sind, werden die Schaltflächen zum Löschen von Aufträgen aktiviert und ändern ihre Farbe, um anzuzeigen, dass sie aktiviert sind und verwendet werden können.

Orders Panel: Zwei aktivierte Schaltflächen zum Löschen von Aufträgen

Orders Panel: Alle aktivierten Schaltflächen zum Löschen von Aufträgen

Um diese Funktion zu implementieren, müssen wir den folgenden Code in die Funktion OnTick() einfügen. So können wir die importierten EX5-Bibliotheksfunktionen nutzen, um die grafische Nutzeroberfläche in Echtzeit zu überwachen und zu aktualisieren und sicherzustellen, dass sie bei jedem eingehenden Tick mit dem Status der Aufträge synchronisiert wird.

void OnTick()
  {
//---
   magicOrderStatus = " Buy Stops: " + (string(MagicBuyStopOrdersTotal(magicNo))) +
                      ", Sell Stops: " + (string(MagicSellStopOrdersTotal(magicNo))) +
                      ", Buy Limits: " + (string(MagicBuyLimitOrdersTotal(magicNo))) +
                      ", Sell Limits: " + (string(MagicSellLimitOrdersTotal(magicNo))) +
                      " ";
   magicOrderStatusLabel.Text(MAGIC_ORDER_STATUS_LABEL_TEXT + (string(MagicOrdersTotal(magicNo))));
   magicOrdersStatusEdit.Text(magicOrderStatus);

//-- Disable and change the background color of the deleteAllMagicBuyStopsBtn depending on the open orders status
   if(MagicBuyStopOrdersTotal(magicNo) == 0)
     {
      deleteAllMagicBuyStopsBtn.Disable();
      deleteAllMagicBuyStopsBtn.ColorBackground(clrLightSlateGray);
     }
   else
     {
      deleteAllMagicBuyStopsBtn.Enable();
      deleteAllMagicBuyStopsBtn.ColorBackground(DELETE_BUY_ORDERS_BTN_BG_COLOR);
     }

//-- Disable and change the background color of the deleteAllMagicSellStopsBtn depending on the open orders status
   if(MagicSellStopOrdersTotal(magicNo) == 0)
     {
      deleteAllMagicSellStopsBtn.Disable();
      deleteAllMagicSellStopsBtn.ColorBackground(clrLightSlateGray);
     }
   else
     {
      deleteAllMagicSellStopsBtn.Enable();
      deleteAllMagicSellStopsBtn.ColorBackground(DELETE_SELL_ORDERS_BTN_BG_COLOR);
     }

//-- Disable and change the background color of the deleteAllMagicBuyLimitsBtn depending on the open orders status
   if(MagicBuyLimitOrdersTotal(magicNo) == 0)
     {
      deleteAllMagicBuyLimitsBtn.Disable();
      deleteAllMagicBuyLimitsBtn.ColorBackground(clrLightSlateGray);
     }
   else
     {
      deleteAllMagicBuyLimitsBtn.Enable();
      deleteAllMagicBuyLimitsBtn.ColorBackground(DELETE_BUY_ORDERS_BTN_BG_COLOR);
     }

//-- Disable and change the background color of the deleteAllMagicSellLimitsBtn depending on the open orders status
   if(MagicSellLimitOrdersTotal(magicNo) == 0)
     {
      deleteAllMagicSellLimitsBtn.Disable();
      deleteAllMagicSellLimitsBtn.ColorBackground(clrLightSlateGray);
     }
   else
     {
      deleteAllMagicSellLimitsBtn.Enable();
      deleteAllMagicSellLimitsBtn.ColorBackground(DELETE_SELL_ORDERS_BTN_BG_COLOR);
     }

//-- Disable and change the background color of the deleteAllMagicOrdersBtn depending on the open orders status
   if(MagicOrdersTotal(magicNo) == 0)
     {
      deleteAllMagicOrdersBtn.Disable();
      deleteAllMagicOrdersBtn.ColorBackground(clrLightSlateGray);
     }
   else
     {
      deleteAllMagicOrdersBtn.Enable();
      deleteAllMagicOrdersBtn.ColorBackground(DELETE_ALL_ORDERS_BTN_BG_COLOR);
     }
  }

Schließlich müssen wir sicherstellen, dass alle Ressourcen ordnungsgemäß freigegeben und bereinigt werden, wenn der Expert Advisor beendet wird. Dazu fügen wir den folgenden Code in die Funktion OnDeinit(...) ein.

void OnDeinit(const int reason)
  {
//---
   //-- Delete and garbage collect the graphical user interface and other graphical objects
   mainPanelWindow.Destroy();

//-- Clear any chart comments
   Comment("");
  }

Die Datei PendingOrdersPanel.mq5 ist am Ende dieses Artikels beigefügt.


Schlussfolgerung

Wir haben eine umfassende EX5-Bibliothek für die Verwaltung schwebender Aufträge erstellt, die zeigt, wie Sie verschiedene Arten schwebender Aufträge öffnen, ändern, löschen, sortieren und filtern können. Diese Bibliothek ist eine nützliche Ressource für jeden MQL5-Entwickler, der ein flexibles und einfach zu bedienendes Werkzeug für die Verwaltung von schwebenden Aufträgen benötigt, das es ihm ermöglicht, mit einem einfachen Funktionsaufruf schnell den Status von Aufträgen abzufragen oder Maßnahmen zu ergreifen.

Die Bibliothek ist vollgepackt mit Funktionen und wird mit einer übersichtlichen Dokumentation und praktischen Beispielen geliefert. Im nächsten Artikel werden wir eine ähnliche Methode anwenden, um eine EX5-Bibliothek zur Verwaltung der Historie zu erstellen, die den Umgang mit Handelsgeschäften und der Auftragshistorie in MQL5 wesentlich erleichtert.

Vielen Dank, dass Sie uns gefolgt sind, und alles Gute für Ihren Handel und Ihre MQL5-Programmierung!

Übersetzt aus dem Englischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/en/articles/15888

Erstellen eines Handelsadministrator-Panels in MQL5 Teil IV: Login-Sicherheitsschicht Erstellen eines Handelsadministrator-Panels in MQL5 Teil IV: Login-Sicherheitsschicht
Stellen Sie sich vor, ein bösartiger Akteur dringt in den Raum des Handelsadministrator ein und verschafft sich Zugang zu den Computern und dem Admin-Panel, über das Millionen von Händlern weltweit wertvolle Informationen erhalten. Ein solches Eindringen könnte katastrophale Folgen haben, z. B. das unbefugte Versenden irreführender Nachrichten oder zufällige Klicks auf Schaltflächen, die unbeabsichtigte Aktionen auslösen. In dieser Diskussion werden wir die Sicherheitsmaßnahmen in MQL5 und die neuen Sicherheitsfunktionen, die wir in unserem Admin-Panel zum Schutz vor diesen Bedrohungen implementiert haben, untersuchen. Durch die Verbesserung unserer Sicherheitsprotokolle wollen wir unsere Kommunikationskanäle schützen und das Vertrauen unserer weltweiten Handelsgemeinschaft erhalten. Weitere Informationen finden Sie in diesem Artikel.
Klassische Strategien neu interpretieren (Teil X): Kann KI den MACD verbessern? Klassische Strategien neu interpretieren (Teil X): Kann KI den MACD verbessern?
Begleiten Sie uns bei der empirischen Analyse des MACD-Indikators, um zu testen, ob die Anwendung von KI auf eine Strategie, die den Indikator mit einbezieht, unsere Prognosegenauigkeit für den EURUSD verbessern würde. Gleichzeitig haben wir geprüft, ob der Indikator selbst leichter vorhersagbar ist als der Preis, und ob der Wert des Indikators das künftige Preisniveau vorhersagt. Wir geben Ihnen die Informationen an die Hand, die Sie benötigen, um zu entscheiden, ob Sie Ihre Zeit in die Integration des MACD in Ihre AI-Handelsstrategien investieren sollten.
Erstellen eines MQL5 Expert Advisors basierend auf der Strategie „Daily Range Breakout“ Erstellen eines MQL5 Expert Advisors basierend auf der Strategie „Daily Range Breakout“
In diesem Artikel erstellen wir einen MQL5 Expert Advisor auf Basis der Daily Range Breakout Strategie. Wir behandeln die wichtigsten Konzepte der Strategie, entwerfen den EA-Blaupause, und implementieren die Breakout-Logik in MQL5. Schließlich werden Techniken für das Backtesting und die Optimierung des EA erforscht, um seine Effektivität zu maximieren.
Nachrichtenhandel leicht gemacht (Teil 4): Leistungsverbesserung Nachrichtenhandel leicht gemacht (Teil 4): Leistungsverbesserung
Dieser Artikel befasst sich mit Methoden zur Verbesserung der Laufzeit des Experten im Strategietester. Der Code wird so geschrieben, dass die Zeiten der Nachrichtenereignisse in stündliche Kategorien unterteilt werden. Der Zugriff auf diese Ereigniszeiten erfolgt innerhalb der angegebenen Stunde. Dadurch wird sichergestellt, dass der EA sowohl in Umgebungen mit hoher als auch mit niedriger Volatilität effizient ereignisgesteuerte Trades verwalten kann.