English Русский 中文 Español 日本語 Português
preview
MQL5 Handels-Toolkit (Teil 2): Erweiterung und Implementierung der Positionsmanagement EX5-Bibliothek

MQL5 Handels-Toolkit (Teil 2): Erweiterung und Implementierung der Positionsmanagement EX5-Bibliothek

MetaTrader 5Beispiele | 19 September 2024, 10:30
220 0
Wanateki Solutions LTD
Kelvin Muturi Muigua

Einführung

Im ersten Artikel haben wir die MQL5-Codebibliotheken im Detail analysiert. Wir haben verschiedene Bibliothekstypen, ihre Vorteile, die Erstellung von EX5-Bibliotheken und die Bestandteile einer EX5-Quellcodedatei (.mq5) behandelt. Damit haben Sie eine solide Grundlage für EX5-Bibliotheken und deren Erstellungsprozess geschaffen. Anschließend haben wir ein praktisches Beispiel für eine EX5-Positionsmanagement-Bibliothek erstellt, um zu zeigen, wie man mit MQL5 exportierbare Funktionen kodiert.

In diesem Artikel werden wir auf dieser Grundlage weiter aufbauen. Wir werden die Positionsmanagement-EX5-Bibliothek erweitern und zwei grundlegende Expert Advisors erstellen. Einer dieser Beispiel-Expert Advisors verwendet ein grafisches Handels- und Informationspanel und demonstriert, wie die Positions Management EX5-Bibliothek importiert und in der Praxis eingesetzt werden kann. Dies dient als praktisches Beispiel für die Erstellung und Integration einer EX5-Bibliothek in Ihren MQL5-Code. Lassen Sie uns zunächst den Prozess des Imports und der Verwendung einer bereits entwickelten und kompilierten .ex5-Binärbibliothek aufschlüsseln.


Wie man eine EX5-Bibliothek importiert und implementiert

Um eine .EX5-Bibliothek zu importieren und in Ihrem MQL5-Code zu verwenden (Expert Advisors, nutzerdefinierte Indikatoren, Skripte oder Dienste), müssen Sie die #import-Direktiven direkt unter den #property-Direktiven im Kopf oder oberen Abschnitt Ihrer Quellcode-Datei einfügen. Um die binär kompilierte Bibliothek einzubinden, beginnen Sie mit der Angabe der #import-Direktive, gefolgt von dem Dateipfad, in dem die Bibliothek gespeichert ist. Standardmäßig sucht MQL5 an zwei Stellen nach Bibliotheken, um Ihnen Zeit zu sparen, wenn Sie sie direkt in Ihrem Code referenzieren. Der erste Ort ist das Verzeichnis „MQL5/Libraries, der standardmäßig für die Speicherung von Bibliotheken vorgesehen ist. Wenn die Bibliothek dort nicht gefunden wird, durchsucht MQL5 den Ordner, in dem sich Ihr MQL-Programm selbst befindet. Wenn Ihre EX5-Bibliothek direkt im Verzeichnis „MQL5/Bibliotheken/“ oder im selben Ordner wie Ihr Quellcode gespeichert ist, geben Sie einfach den Bibliotheksnamen in Anführungszeichen nach der #import-Anweisung an, ohne den Ordnerpfad anzugeben.

Nachdem Sie den Pfad zum Bibliotheksordner angegeben haben, geben wir den Bibliotheksnamen gefolgt von der Erweiterung .ex5 ein. In der nächsten neuen Zeile fügen wir die Definitionen oder Beschreibungen aller exportierten Funktionsprototypen hinzu, die in Ihren Code importiert werden sollen. Schließlich beenden wir den Import-Codeabschnitt mit einer weiteren #import-Anweisung, um ihn abzuschließen.

#import "FilePath/LibraryName.ex5" //-- Opening .EX5 Library import directive

   //-- Function definitions/descriptions prototypes
   int  FunctionPrototype1();
   void FunctionPrototype2(bool y);
   bool FunctionPrototype3(double x);

#import //--- Closing .EX5 Library import directive

Es ist erforderlich, die Datei .ex5 Erweiterung nach dem Bibliotheksnamen anzugeben, wenn die Import-Direktive deklariert wird. Wenn Sie die Erweiterung weglassen, bedeutet dies, dass Sie standardmäßig eine .DLL-Bibliothek importieren.

Sie können auch mehrere .ex5-Bibliotheken in eine einzige MQL5-Datei importieren und implementieren. Die Codestruktur für den Import mehrerer .ex5-Bibliotheken ist ähnlich wie beim Import einer einzelnen Bibliothek, der einzige Unterschied besteht in der Platzierung der abschließenden #import-Anweisungen. Bei mehreren Bibliotheksimporten sollte der abschließenden #import-Direktive der ersten Bibliothek der Name der nächsten zu importierenden .ex5-Bibliothek folgen. Dadurch wird die erste Importrichtlinie geschlossen, während die nächste Importrichtlinie eingeleitet wird, usw. Wenn Sie die letzte Import-Direktive der letzten Bibliothek schließen, achten Sie darauf, dass sie ohne einen Bibliotheksnamen endet.

#import "FilePath/LibraryName.ex5"  //-- Opening .EX5 Library import directive

   //-- Function definitions/descriptions prototypes for the first library here
   int  FunctionPrototype1();
   void FunctionPrototype2(bool y);
   
#import "FilePath/SecondLibraryName.ex5"
   //-- Function definitions/descriptions prototypes for the second library here
   bool  FunctionPrototype();
   string FunctionPrototype2(bool z);

#import //--- Closing .EX5 Library import directive

Wenn Sie mit mehreren Bibliotheken in MQL5 arbeiten, ist es erforderlich, jeder einen eindeutigen Namen zu geben. Es spielt keine Rolle, ob all diese Bibliotheken in verschiedenen Ordnern gespeichert sind, es müssen jedoch eindeutige Namen verwendet werden, damit keine Fehler auftreten.

Jede Bibliothek schafft ihre eigene isolierte Umgebung oder ihren eigenen „Namensraum“ (namespace). Das bedeutet, dass die Funktionen innerhalb einer Bibliothek mit dem Namen dieser Bibliothek verbunden sind. Sie können Funktionen innerhalb einer Bibliothek frei benennen, ohne sich Gedanken über Konflikte zu machen, selbst wenn sie mit eingebauten Funktionsnamen übereinstimmen. Es wird jedoch allgemein empfohlen, der Klarheit halber solche Bezeichnungen zu vermeiden.

Wenn Sie Funktionen mit demselben Namen in verschiedenen Bibliotheken haben, wird das System die Funktion nach bestimmten Regeln priorisieren. Dies verhindert Verwechslungen beim Aufruf von Funktionen mit identischen Namen. Sobald Sie die Funktionsprototypen der Bibliothek erfolgreich importiert haben, können Sie sie nahtlos in Ihren Code integrieren und sie wie jede andere lokale Funktion behandeln, die Sie selbst definiert haben.

Im weiteren Verlauf des Artikels erkläre ich ausführlich, wie EX5-Bibliotheken in der Praxis eingesetzt werden können. Sie werden zwei ausführliche Demonstrationen finden: eine, bei der wir einen auf VIDyA-Handelsstrategien basierenden Expert Advisor programmieren, und eine weitere, bei der eine grafische Nutzeroberfläche (GUI) verwendet wird. Diese Expert Advisors werden unsere maßgeschneiderte Positionsmanagement EX5-Bibliothek integrieren und nutzen. Diese praktischen Beispiele bieten wertvolle Einblicke in die Implementierung von EX5-Bibliotheken in realen Expert Advisors.


Allgemeine Laufzeitfehler bei der Implementierung der EX5-Bibliothek

Das Debuggen von EX5-Bibliotheken kann eine Herausforderung sein, da die meisten Fehler im Zusammenhang mit den importierten Prototyp-Funktionen während der Laufzeit auftreten, wenn die fertig kompilierte MQL5-Anwendung im Handelsterminal geladen wird. Diese Fehler entstehen typischerweise durch die Kodierung des Header-Import-Bibliotheksrichtlinien-Abschnitts mit falschen Werten wie den Pfaden oder Namen der Bibliotheksdateien, Funktionsprototyp-Beschreibungen, Typen, Namen, der vollständigen Liste der Parameter und Rückgabewerte während der Importdeklarationen. Es wird nicht erwartet, dass der Compiler diese Fehler bei der Importdeklaration während der Kompilierung erkennt, da er nicht auf den Quellcode der importierten Bibliothek zugreifen kann, da dieser gekapselt und bereits in ein binäres, ausführbares Modul (.ex5) kompiliert ist.

Jede Quellcodedatei, die diese Fehler enthält, wird erfolgreich kompiliert, aber wenn Sie versuchen, die kompilierte MQL5-Anwendung in das Handelsterminal zu laden, wird sie fehlschlagen und Laufzeitfehler erzeugen. Diese Fehler werden entweder auf der Registerkarte Experten oder auf der Registerkarte Journal des MetaTrader5-Terminals angezeigt. Hier sind die häufigsten Fehler, auf die Sie stoßen können:

Unresolved Import Function Call(cannot find 'Function_Name' in 'Library_Name.ex5')

    • Beschreibung: Dieser Laufzeitfehler tritt auf, wenn Sie versuchen, die MQL5-App in einem MetaTrader5-Chart zu laden und wird auf der Registerkarte Experten angezeigt. Er wird durch falsche Definitionen von Funktionsprototypen oder Beschreibungen, wie Typ, Name oder Parameter, verursacht, die im Abschnitt der Importdirektive der Bibliothek angegeben sind.
    • Auflösung: Vergewissern Sie sich, dass das Import-Code-Segment der Bibliothek ordnungsgemäß mit den richtigen Funktionsprototyp-Definitionen kodiert ist, und kompilieren Sie Ihren Code neu.

Unaufgelöster Import-Funktionsaufruf EX5-Fehler


Cannot Open File 'Library_Name.ex5'(loading of ExpertAdvisor_Name (GBPJPY,M15) failed [0])

    • Beschreibung: Dieser Laufzeitfehler tritt auf, wenn Sie versuchen, die MQL5-App in einem MetaTrader5-Chart zu laden und wird auf der Registerkarte Journal angezeigt. Es wird verursacht, wenn die importierte EX5-Bibliotheksdatei nicht gefunden und geladen werden kann.
    • Auflösung: Vergewissern Sie sich, dass der korrekte Dateipfad zur Bibliothek im Importcode-Segment der Bibliothek angegeben ist, und kompilieren Sie Ihren Code neu.
EX5-Bibliotheksdatei kann nicht geöffnet werden

Während andere Fehler bei der Arbeit mit importierten Bibliotheken in MQL5 auftreten können, sind die oben genannten Laufzeitfehler die häufigsten und für Anfänger am problematischsten. Diese Fehler stellen eine besondere Herausforderung dar, da sie leicht übersehen werden können und nicht darauf ausgelegt sind, vom Compiler während der Kompilierung erkannt zu werden.


Aktualisierung und erneute Bereitstellung von EX5-Bibliotheken

Es ist wichtig, dass Sie bei der Neuverteilung Ihrer EX5-Bibliotheken nach jeder Aktualisierung die richtige Reihenfolge einhalten, um sicherzustellen, dass die neuen Änderungen ordnungsgemäß in die MQL5-Projekte, die die Bibliothek verwenden, integriert werden. Die Kompilierungssequenz ist der wichtigste Schritt bei der Aktualisierung und Neuverteilung von Bibliotheken in MQL5. Um sicherzustellen, dass alle neuen Änderungen und Aktualisierungen in allen Projekten, die die Bibliothek importieren, verwendet werden, führen Sie die folgenden Schritte aus:

  1. Kompilieren Sie die neue EX5-Datei: Beginnen Sie mit der Kompilierung der aktualisierten .mq5 Bibliotheksquellcodedatei, um die neue ausführbare Binärdatei .ex5 zu erstellen.
  2. Importierte Funktionsprototypen aktualisieren: Aktualisieren Sie in allen MQL5-Projekten, die die EX5-Bibliothek verwenden, alle Funktionsprototyp-Importdefinitionen, wenn sie sich durch das neue .ex5-Bibliotheksupdate geändert haben.
  3. Kompilieren Sie die Projekte: Kompilieren Sie alle MQL5-Projekte neu, die die EX5-Bibliothek implementieren.
Wenn Sie diese Reihenfolge einhalten, stellen Sie sicher, dass alle Aktualisierungen in der EX5-Bibliothek reflektiert und in alle Projekte integriert werden, die die Bibliothek importieren.


Die Funktion für ein Trailing-Stop-Loss

Bevor wir unsere Bibliothek für die Verwaltung von Positionen implementieren können, müssen wir sie noch um einige wichtige Funktionen erweitern. Wir beginnen mit dem Hinzufügen eines Moduls oder einer Funktion zur Verwaltung des Trailing-Stop-Loss, da unsere Bibliothek ohne diese wesentliche Funktion nicht vollständig ist. Ein Trailing-Stop-Loss ist ein wichtiger Bestandteil jeder Handelsstrategie, da er, wenn er richtig eingesetzt wird, das Potenzial hat, die Gewinnspannen und die Gesamterfolgsquote eines Systems zu erhöhen.

Die Funktion für das Trailing-Stop-Loss heißt SetTrailingStopLoss() und ist für das Setzen des Trailing-SL einer bestehenden offenen Position verantwortlich, wobei das Ticket der Position als Filtermechanismus verwendet wird. Es nimmt die Ticketnummer einer Position und den gewünschten Trailing-Stop-Loss in Pips (Punkten) als Argumente oder Parameter und versucht, den Stop-Loss der Position auf dem Handelsserver zu aktualisieren, wenn bestimmte Bedingungen erfüllt sind. Diese Funktion sollte kontinuierlich bei jedem Tick aufgerufen werden, um den Trailing-Stop-Loss in Echtzeit zu ändern, da sich der Status der Zielpositionen ständig ändert.

Zunächst wird geprüft, ob der Handel erlaubt ist und ob der angegebene Trailing-Stop-Loss in Pips (Punkten) gültig ist. Es wählt dann die Position aus, ruft alle erforderlichen Symbolinformationen ab und speichert sie, und berechnet den Trailing-Stop-Loss-Kurs. Wenn der berechnete Preis gültig ist, sendet er einen Auftrag an den Handelsserver, um den Stop-Loss zu setzen. Wenn der Auftrag erfolgreich ausgeführt wurde, gibt die Funktion den Wert true zurück, andernfalls false.

Wir beginnen mit der Erstellung der Funktionsdefinition. Unsere Trailing-Stop-Loss-Funktion ist vom Typ bool und hat zwei Parameter:

  1. ulong positionTicket: Dies ist eine eindeutige Kennung für die Position, die wir ändern werden.
  2. int trailingStopLoss: Dies ist das gewünschte Stop-Loss-Niveau in Pips (Punkten) vom aktuellen Kurs der Position.

Das Schlüsselwort export zeigt an, dass diese Bibliotheksfunktion von jeder MQL5-Quellcodedatei oder jedem Projekt, das sie importiert, aufgerufen werden kann.

bool SetTrailingStopLoss(ulong positionTicket, int trailingStopLoss) export
  {
    //-- place the function body here
  }

Wir müssen prüfen, ob der Handel erlaubt ist und ob der Parameter trailingStopLoss größer als Null ist. Ist eine der beiden Bedingungen nicht erfüllt, verlassen wir die Funktion und geben false zurück, um den Vorgang zu beenden.

if(!TradingIsAllowed() || trailingStopLoss == 0)
     {
      return(false); //--- algo trading is disabled or trailing stop loss is invalid, exit function
     }

Als Nächstes bestätigen und wählen wir die Position mit Hilfe des bereitgestellten PositionTickets. Wenn die Positionsauswahl fehlschlägt, wird eine Fehlermeldung ausgegeben und die Funktion beendet.

//--- Confirm and select the position using the provided positionTicket
   ResetLastError(); //--- Reset error cache incase of ticket selection errors
   if(!PositionSelectByTicket(positionTicket))
     {
      //---Position selection failed
      Print("\r\n_______________________________________________________________________________________");
      Print(__FUNCTION__, ": Selecting position with ticket:", positionTicket, " failed. ERROR: ", GetLastError());
      return(false); //-- Exit the function
     }

Anschließend erstellen wir einige Variablen, mit deren Hilfe wir den Trailing-Stop-Loss speichern und validieren können. Wir beginnen mit der Erstellung der Variablen slPriceVariable, um den berechneten Trailing-Stop-Loss-Kurs zu speichern, und speichern dann die Positionseigenschaften wie Symbol, Einstiegskurs, Volumen, aktuellen Stop-Loss-Kurs, aktuellen Take-Profit-Kurs und Positionstyp.

//-- create variable to store the calculated trailing sl prices to send to the trade server
   double slPrice = 0.0;

//--- Position ticket selected, save the position properties
   string positionSymbol = PositionGetString(POSITION_SYMBOL);
   double entryPrice = PositionGetDouble(POSITION_PRICE_OPEN);
   double volume = PositionGetDouble(POSITION_VOLUME);
   double currentPositionSlPrice = PositionGetDouble(POSITION_SL);
   double currentPositionTpPrice = PositionGetDouble(POSITION_TP);
   ENUM_POSITION_TYPE positionType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);

Ebenso speichern wir weiterhin die verschiedenen Symboleigenschaften, die mit der ausgewählten Position verbunden sind. Diese Eigenschaften werden später auch zur Validierung und Berechnung des Trailing-Stop-Loss verwendet.

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

Wir prüfen, ob der angegebene Wert für den Trailing-Stop-Loss kleiner ist als der Handelsstopp des Symbols. Wenn dies der Fall ist, passen wir den Trainling-Stop-Loss so an, dass er dem Stop-Level des Symbols entspricht.

//-- Check if the trailing stop loss is less than the symbol trade stop levels
   if(trailingStopLoss < symbolStopLevel)
     {
      //-- Trailing stop loss is less than the allowed level for the current symbol
      trailingStopLoss = symbolStopLevel; //-- Set it to the symbol stop level by default
     }

Der nächste Schritt besteht in der Berechnung des Trailing-Stop-Loss-Kurses, je nachdem, ob es sich bei der Position um einen Kauf oder Verkauf handelt. Bei Kaufpositionen wird der Stop-Loss-Kurs unterhalb des aktuellen Kurses gesetzt, bei Verkaufspositionen oberhalb des aktuellen Kurses. Wir überprüfen auch, ob der berechnete Stop-Loss-Kurs innerhalb der gültigen Grenzen liegt.

//-- Calculate and store the trailing stop loss price
   if(positionType == POSITION_TYPE_BUY)
     {
      slPrice = positionPriceCurrent - (trailingStopLoss * symbolPoint);

      //-- Check if the proposed slPrice for the trailing stop loss is valid
      if(slPrice < entryPrice || slPrice < currentPositionSlPrice)
        {
         return(false); //-- Exit the function, proposed trailing stop loss price is invalid
        }
     }
   else  //-- SELL POSITION
     {
      slPrice = positionPriceCurrent + (trailingStopLoss * symbolPoint);

      //-- Check if the proposed slPrice for the trailing stop loss is valid
      if(slPrice > entryPrice || slPrice > currentPositionSlPrice)
        {
         return(false); //-- Exit the function, proposed trailing stop loss price is invalid
        }
     }

Bevor wir den Trailing-Stop-Loss setzen, sollten wir die Details der Position in das Protokoll des MetaTrader5 drucken. Dazu gehören das Symbol, der Positionstyp, das Volumen, der Einstiegskurs, der aktuelle Stop-Loss- und Take-Profit-Kurs sowie andere relevante Informationen.

//-- Print position properties before setting the trailing stop loss
   string positionProperties = "--> "  + positionSymbol + " " + EnumToString(positionType) + " Trailing Stop Loss Modification Details" +
                               " <--\r\n";
   positionProperties += "------------------------------------------------------------\r\n";
   positionProperties += "Ticket: " + (string)positionTicket + "\r\n";
   positionProperties += "Volume: " + StringFormat("%G", volume) + "\r\n";
   positionProperties += "Price Open: " + StringFormat("%G", entryPrice) + "\r\n";
   positionProperties += "Current SL: " + StringFormat("%G", currentPositionSlPrice) + "   -> New Trailing SL: " + (string)slPrice + "\r\n";
   positionProperties += "Current TP: " + StringFormat("%G", currentPositionTpPrice) + "\r\n";
   positionProperties += "Comment: " + PositionGetString(POSITION_COMMENT) + "\r\n";
   positionProperties += "Magic Number: " + (string)PositionGetInteger(POSITION_MAGIC) + "\r\n";
   positionProperties += "---";
   Print(positionProperties);

Wir setzen die Strukturen tradeRequest und tradeResult auf Null zurück. Anschließend initialisieren wir die Parameter, die für die Festlegung von Stop-Loss und Take-Profit erforderlich sind.

//-- 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_SLTP; //-- Trade operation type for setting sl and tp
   tradeRequest.position = positionTicket;
   tradeRequest.symbol = positionSymbol;
   tradeRequest.sl = slPrice;
   tradeRequest.tp = currentPositionTpPrice;

Schließlich setzen wir den Fehler-Cache zurück und senden den Auftrag an den Handelsserver, bis er erfolgreich ist oder bis zu 101 Mal wiederholt wird. Wenn der Auftrag erfolgreich ausgeführt wurde, drucken wir eine Erfolgsmeldung, geben true zurück und beenden die Funktion. Wenn die Auftragsanfrage fehlschlägt, behandeln wir den Fehler, geben false zurück und beenden die Funktion.

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

   for(int loop = 0; loop <= 100; loop++) //-- try modifying the sl and tp 101 times untill 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 set the Trailing SL for #%I64d %s %s", positionTicket, positionSymbol, EnumToString(positionType));
            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__, positionSymbol, tradeResult.retcode) || IsStopped())
           {
            PrintFormat("ERROR setting the Trailing SL for #%I64d %s %s", positionTicket, positionSymbol, EnumToString(positionType));
            Print("_______________________________________________________________________________________\r\n\r\n");
            return(false); //-- exit function
            break; //-- exit for loop
           }
        }
     }
   return(false);
  }

Vergewissern Sie sich, dass alle Codesegmente der Funktion SetTrailingStopLoss() in der nachstehenden Reihenfolge vollständig sind:

bool SetTrailingStopLoss(ulong positionTicket, int trailingStopLoss) export
  {
//-- first check if the EA is allowed to trade and the trailing stop loss parameter is more than zero
   if(!TradingIsAllowed() || trailingStopLoss == 0)
     {
      return(false); //--- algo trading is disabled or trailing stop loss is invalid, exit function
     }

//--- Confirm and select the position using the provided positionTicket
   ResetLastError(); //--- Reset error cache incase of ticket selection errors
   if(!PositionSelectByTicket(positionTicket))
     {
      //---Position selection failed
      Print("\r\n_______________________________________________________________________________________");
      Print(__FUNCTION__, ": Selecting position with ticket:", positionTicket, " failed. ERROR: ", GetLastError());
      return(false); //-- Exit the function
     }

//-- create variable to store the calculated trailing sl prices to send to the trade server
   double slPrice = 0.0;

//--- Position ticket selected, save the position properties
   string positionSymbol = PositionGetString(POSITION_SYMBOL);
   double entryPrice = PositionGetDouble(POSITION_PRICE_OPEN);
   double volume = PositionGetDouble(POSITION_VOLUME);
   double currentPositionSlPrice = PositionGetDouble(POSITION_SL);
   double currentPositionTpPrice = PositionGetDouble(POSITION_TP);
   ENUM_POSITION_TYPE positionType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);

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

//-- Check if the trailing stop loss is less than the symbol trade stop levels
   if(trailingStopLoss < symbolStopLevel)
     {
      //-- Trailing stop loss is less than the allowed level for the current symbol
      trailingStopLoss = symbolStopLevel; //-- Set it to the symbol stop level by default
     }

//-- Calculate and store the trailing stop loss price
   if(positionType == POSITION_TYPE_BUY)
     {
      slPrice = positionPriceCurrent - (trailingStopLoss * symbolPoint);

      //-- Check if the proposed slPrice for the trailing stop loss is valid
      if(slPrice < entryPrice || slPrice < currentPositionSlPrice)
        {
         return(false); //-- Exit the function, proposed trailing stop loss price is invalid
        }
     }
   else  //-- SELL POSITION
     {
      slPrice = positionPriceCurrent + (trailingStopLoss * symbolPoint);

      //-- Check if the proposed slPrice for the trailing stop loss is valid
      if(slPrice > entryPrice || slPrice > currentPositionSlPrice)
        {
         return(false); //-- Exit the function, proposed trailing stop loss price is invalid
        }
     }

//-- Print position properties before setting the trailing stop loss
   string positionProperties = "--> "  + positionSymbol + " " + EnumToString(positionType) + " Trailing Stop Loss Modification Details" +
                               " <--\r\n";
   positionProperties += "------------------------------------------------------------\r\n";
   positionProperties += "Ticket: " + (string)positionTicket + "\r\n";
   positionProperties += "Volume: " + StringFormat("%G", volume) + "\r\n";
   positionProperties += "Price Open: " + StringFormat("%G", entryPrice) + "\r\n";
   positionProperties += "Current SL: " + StringFormat("%G", currentPositionSlPrice) + "   -> New Trailing SL: " + (string)slPrice + "\r\n";
   positionProperties += "Current TP: " + StringFormat("%G", currentPositionTpPrice) + "\r\n";
   positionProperties += "Comment: " + PositionGetString(POSITION_COMMENT) + "\r\n";
   positionProperties += "Magic Number: " + (string)PositionGetInteger(POSITION_MAGIC) + "\r\n";
   positionProperties += "---";
   Print(positionProperties);

//-- 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_SLTP; //-- Trade operation type for setting sl and tp
   tradeRequest.position = positionTicket;
   tradeRequest.symbol = positionSymbol;
   tradeRequest.sl = slPrice;
   tradeRequest.tp = currentPositionTpPrice;

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

   for(int loop = 0; loop <= 100; loop++) //-- try modifying the sl and tp 101 times untill 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 set the Trailing SL for #%I64d %s %s", positionTicket, positionSymbol, EnumToString(positionType));
            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__, positionSymbol, tradeResult.retcode) || IsStopped())
           {
            PrintFormat("ERROR setting the Trailing SL for #%I64d %s %s", positionTicket, positionSymbol, EnumToString(positionType));
            Print("_______________________________________________________________________________________\r\n\r\n");
            return(false); //-- exit function
            break; //-- exit for loop
           }
        }
     }
   return(false);
  }



Funktion Alle Positionen schließen

Diese Funktion soll sehr flexibel sein und ist für die Schließung aller offenen Positionen auf der Grundlage bestimmter Parameter zuständig. Wir werden die Funktion CloseAllPositions() nennen. Er sucht nach offenen Positionen, die den angegebenen Argumenten oder Parametern (Symbol und magische Zahl) entsprechen, und versucht, sie alle zu schließen. Wenn der Handel nicht erlaubt ist, wird die Funktion nicht weiter ausgeführt und sofort beendet. Die Funktion durchläuft alle offenen Positionen, filtert sie anhand der angegebenen Kriterien und schließt alle übereinstimmenden Positionen.

Nachdem der Versuch, alle Positionen zu schließen, abgeschlossen ist, wird eine Schleife eingeleitet, um zu bestätigen, dass alle angestrebten Positionen geschlossen wurden, um eventuelle Fehler zu behandeln und um sicherzustellen, dass wir nicht in eine Endlosschleife geraten. Wenn unsere Funktion erfolgreich alle Positionen schließt, wird sie beendet und gibt true zurück; andernfalls gibt sie false zurück.

Beginnen wir mit der Definition der Funktion CloseAllPositions(). Sie gibt einen bool‘schen Wert zurück und akzeptiert zwei Parameter mit Standardwerten:

  1. string symbol: Die Standardeinstellung ist ALL_SYMBOLS.
  2. ulong magicNumber: Dieser Wert ist standardmäßig 0.

bool CloseAllPositions(string symbol = ALL_SYMBOLS, ulong magicNumber = 0) export
  {
//-- Functions body goes here
  }

Wir müssen prüfen, ob der Handel erlaubt ist. Wenn der Handel nicht erlaubt ist, wird die Funktion beendet und false zurückgegeben.

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

Wir erstellen eine neue Variable returnThis vom Typ bool, um den Rückgabewert der Funktion zu speichern, und geben ihr einen Standardwert von false.

bool returnThis = false;

Wir ermitteln und speichern die Gesamtzahl der offenen Positionen und verwenden diesen Wert in einer for-Schleife, die es uns ermöglicht, auf alle offenen Positionen zuzugreifen und sie zu bearbeiten. Bei jeder Iteration speichern wir die ausgewählten Positionseigenschaften und verwenden diese Daten, um Positionen auf der Grundlage des angegebenen Symbols und der magischen Zahl zu filtern. Entspricht die Position nicht den Kriterien, wird mit der nächsten Position fortgefahren. Wenn die Position den Kriterien entspricht, schließen wir die Position mit der Funktion ClosePositionByTicket().

int totalOpenPositions = PositionsTotal();
   for(int x = 0; x < totalOpenPositions; x++)
     {
      //--- Get position properties
      ulong positionTicket = PositionGetTicket(x); //-- Get ticket to select the position
      string selectedSymbol = PositionGetString(POSITION_SYMBOL);
      ulong positionMagicNo = PositionGetInteger(POSITION_MAGIC);

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

      //-- Close the position
      ClosePositionByTicket(positionTicket);
     }

Wir haben nun alle angegebenen offenen Positionen durchlaufen und Beendigungsanforderungen an den Handelsserver gesendet, um sie zu schließen. Bevor wir die Funktion abschließen, müssen wir uns vergewissern, dass alle angestrebten Positionen tatsächlich geschlossen wurden. Dazu verwenden wir eine Schleife, in der die Funktion CloseAllPositions() so lange rekursiv aufgerufen wird, bis alle Positionen, die unseren Kriterien entsprechen, geschlossen sind. Bei jeder Iteration versuchen wir, alle verbleibenden Positionen zu schließen, das Senden des Auftrags für einen kurzen Zeitraum zu unterbrechen, um die Ausführung zu beschleunigen und den Handelsserver nicht zu überlasten, und einen Unterbrechungszähler zu erhöhen, um Endlosschleifen zu vermeiden. Wir prüfen auch auf kritische Fehler und andere Ausstiegsbedingungen (z. B. wenn das Skript angehalten wurde oder die maximale Anzahl der Schleifen überschritten hat). Wenn eine dieser Bedingungen erfüllt ist, werden wir die Schleife verlassen.

int breakerBreaker = 0; //-- Variable that safeguards and makes sure we are not locked in an infinite loop
   while(SymbolPositionsTotal(symbol, magicNumber) > 0)
     {
      breakerBreaker++;
      CloseAllPositions(symbol, magicNumber); //-- We still have some open positions, do a function callback
      Sleep(100); //-- 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 > 101)
        {
         break;
        }
     }

Wir überprüfen erneut, ob alle angestrebten Positionen geschlossen wurden, und speichern diesen Status in der Rückgabevariablen, bevor wir die Funktion abschließen und beenden.

if(SymbolPositionsTotal(symbol, magicNumber) == 0)
     {
      returnThis = true; //-- Save this status for the function return value
     }

   return(returnThis);

Vergewissern Sie sich, dass alle Codesegmente der Funktion CloseAllPositions() in der nachstehenden Reihenfolge vollständig sind:

bool CloseAllPositions(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 positions and close them
   int totalOpenPositions = PositionsTotal();
   for(int x = 0; x < totalOpenPositions; x++)
     {
      //--- Get position properties
      ulong positionTicket = PositionGetTicket(x); //-- Get ticket to select the position
      string selectedSymbol = PositionGetString(POSITION_SYMBOL);
      ulong positionMagicNo = PositionGetInteger(POSITION_MAGIC);

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

      //-- Close the position
      ClosePositionByTicket(positionTicket);
     }

//-- Confirm that we have closed all the positions being targeted
   int breakerBreaker = 0; //-- Variable that safeguards and makes sure we are not locked in an infinite loop
   while(SymbolPositionsTotal(symbol, magicNumber) > 0)
     {
      breakerBreaker++;
      CloseAllPositions(symbol, magicNumber); //-- We still have some open positions, do a function callback
      Sleep(100); //-- 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 > 101)
        {
         break;
        }
     }

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

   return(returnThis);
  }


Die überladene Funktion Close All Positions

Der Einfachheit halber werden wir die Funktion CloseAllPositions() mit einer zweiten Version überladen, die keine Parameter akzeptiert und alle offenen Positionen im Konto schließt, wenn sie aufgerufen wird. Diese Funktion kann exportiert werden und steht dann auch in der Positions Manager EX5 Bibliothek zur Verfügung.

//+------------------------------------------------------------------+
//| CloseAllPositions(): Closes all positions in the account         |
//+------------------------------------------------------------------+
bool CloseAllPositions() export
  {
   return(CloseAllPositions(ALL_SYMBOLS, 0));
  }


Sortieren und Filtern der Funktion zum Schließen von Positionen

Wenn Sie in den MQL5-Entwicklerforen stöbern, werden Sie häufig auf Fragen von MQL5-Anfängern stoßen, die Hilfe bei der Codierung von Algorithmen zum Filtern, Sortieren und Verwalten verschiedener Positionsoperationen suchen, wie z. B. das Schließen oder Ändern bestimmter Positionen auf der Grundlage von Kriterien wie magische Zahl, Gewinn- oder Verluststatus usw. Die folgende Funktionsbibliothek soll diesen Bedarf decken und die effektive Umsetzung dieser Vorgänge erleichtern und beschleunigen.

Die nachstehenden Sortier- und Filterfunktionen für das Schließen von Positionen verfolgen einen ähnlichen Ansatz wie die Funktion CloseAllPositions(), weisen aber jeweils bemerkenswerte Unterschiede auf. Sie verwenden eine rekursive Programmierstrategie, um sicherzustellen, dass alle spezifizierten Positionen geschlossen werden, und enthalten Trace-Protokolle, um alle aufgetretenen Fehler im Protokoll des Expert Advisors für die Endnutzerdiagnose zu drucken und aufzuzeichnen. Ein zusätzlicher Vorteil dieser Funktionen ist ihre hohe Erfolgsquote bei der Erreichung der vorgegebenen Ziele, da sie rekursiv nach behebbaren Fehlern suchen und die angegebenen Handelsaufträge mehrfach senden, um sicherzustellen, dass die Aufträge erfolgreich sind. Um die Funktionsweise der einzelnen Funktionen besser zu verstehen, habe ich ausführliche Code-Kommentare eingefügt, die die Struktur und Organisation der einzelnen Code-Komponenten innerhalb der Funktionen erklären.


Alle Kaufpositionen schließen

Die Funktion CloseAllBuyPositions() ist für die Schließung aller offenen Kaufpositionen verantwortlich, die den angegebenen Funktionsparametern oder Argumenten Symbolname und Magische Zahl entsprechen. Es wird true zurückgegeben, wenn alle spezifizierten Positionen erfolgreich geschlossen wurden, andernfalls false.

bool CloseAllBuyPositions(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 positions and close them
   int totalOpenPositions = PositionsTotal();
   for(int x = 0; x < totalOpenPositions; x++)
     {
      //--- Get position properties
      ulong positionTicket = PositionGetTicket(x); //-- Get ticket to select the position
      string selectedSymbol = PositionGetString(POSITION_SYMBOL);
      ulong positionMagicNo = PositionGetInteger(POSITION_MAGIC);
      ulong positionType = PositionGetInteger(POSITION_TYPE);

      //-- Filter positions by symbol, type and magic number
      if(
         (symbol != ALL_SYMBOLS && symbol != selectedSymbol) || (positionType != POSITION_TYPE_BUY) ||
         (magicNumber != 0 && positionMagicNo != magicNumber)
      )
        {
         continue;
        }

      //-- Close the position
      ClosePositionByTicket(positionTicket);
     }

//-- Confirm that we have closed all the buy positions being targeted
   int breakerBreaker = 0; //-- Variable that safeguards and makes sure we are not locked in an infinite loop
   while(SymbolBuyPositionsTotal(symbol, magicNumber) > 0)
     {
      breakerBreaker++;
      CloseAllBuyPositions(symbol, magicNumber); //-- We still have some open buy positions, do a function callback
      Sleep(100); //-- 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 > 101)
        {
         break;
        }
     }

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

Close All Sell Positions

Die Funktion CloseAllSellPositions() hat die Aufgabe, alle offenen Verkaufspositionen zu schließen, die dem angegebenen Symbolnamen und den Funktionsparametern oder Argumenten der magischen Zahl entsprechen. Es wird true zurückgegeben, wenn alle spezifizierten Positionen erfolgreich geschlossen wurden, andernfalls false.

bool CloseAllSellPositions(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 positions and close them
   int totalOpenPositions = PositionsTotal();
   for(int x = 0; x < totalOpenPositions; x++)
     {
      //--- Get position properties
      ulong positionTicket = PositionGetTicket(x); //-- Get ticket to select the position
      string selectedSymbol = PositionGetString(POSITION_SYMBOL);
      ulong positionMagicNo = PositionGetInteger(POSITION_MAGIC);
      ulong positionType = PositionGetInteger(POSITION_TYPE);

      //-- Filter positions by symbol, type and magic number
      if(
         (symbol != ALL_SYMBOLS && symbol != selectedSymbol) || (positionType != POSITION_TYPE_SELL) ||
         (magicNumber != 0 && positionMagicNo != magicNumber)
      )
        {
         continue;
        }

      //-- Close the position
      ClosePositionByTicket(positionTicket);
     }

//-- Confirm that we have closed all the sell positions being targeted
   int breakerBreaker = 0; //-- Variable that safeguards and makes sure we are not locked in an infinite loop
   while(SymbolSellPositionsTotal(symbol, magicNumber) > 0)
     {
      breakerBreaker++;
      CloseAllSellPositions(symbol, magicNumber); //-- We still have some open sell positions, do a function callback
      Sleep(100); //-- 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 > 101)
        {
         break;
        }
     }

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



Close All Magic Positions

Die Funktion CloseAllMagicPositions() ist für das Schließen aller offenen Positionen zuständig, die mit dem angegebenen Funktionsparameter oder Argument der magischen Zahl übereinstimmen. Es wird true zurückgegeben, wenn alle spezifizierten Positionen erfolgreich geschlossen wurden, andernfalls false.

bool CloseAllMagicPositions(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 positions data
   ulong positionTicket, positionMagicNo;
   string positionSymbol;

//-- Scan for magic number specific positions and close them
   int totalOpenPositions = PositionsTotal();
   for(int x = 0; x < totalOpenPositions; x++)
     {
      //--- Get position properties
      positionTicket = PositionGetTicket(x); //-- Get ticket to select the position
      positionMagicNo = PositionGetInteger(POSITION_MAGIC);
      positionSymbol = PositionGetString(POSITION_SYMBOL);

      //-- Filter positions by magic number
      if(magicNumber == positionMagicNo)
        {
         //-- Close the position
         ClosePositionByTicket(positionTicket);
        }
     }

//-- Confirm that we have closed all the positions being targeted
   int breakerBreaker = 0; //-- Variable that safeguards and makes sure we are not locked in an infinite loop
   while(MagicPositionsTotal(magicNumber) > 0)
     {
      breakerBreaker++;
      CloseAllMagicPositions(magicNumber); //-- We still have some open positions, do a function callback
      Sleep(100); //-- 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__, positionSymbol, GetLastError()) || IsStopped() || breakerBreaker > 101)
        {
         break;
        }
     }

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



Alle profitablen Positionen schließen

Die Funktion CloseAllProfitablePositions() schließt alle profitablen offenen Positionen, die den angegebenen Funktionsparametern oder Argumenten Symbolname und Magische Zahl entsprechen. Es wird true zurückgegeben, wenn alle spezifizierten Positionen erfolgreich geschlossen wurden, andernfalls false.

bool CloseAllProfitablePositions(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
     }

//-- Scan for profitable positions that match the specified symbol and magic number to close them
   int totalOpenPositions = PositionsTotal();
   for(int x = 0; x < totalOpenPositions; x++)
     {
      //--- Get position properties
      ulong positionTicket = PositionGetTicket(x); //-- Get ticket to select the position
      string selectedSymbol = PositionGetString(POSITION_SYMBOL);
      ulong positionMagicNo = PositionGetInteger(POSITION_MAGIC);
      double positionProfit = PositionGetDouble(POSITION_PROFIT);

      //-- Filter positions by symbol, magic number and profit
      if(
         ((symbol != ALL_SYMBOLS && symbol != selectedSymbol) || (magicNumber != 0 && positionMagicNo != magicNumber)) ||
         positionProfit <= 0
      )
        {
         continue;
        }

      //-- Close the position
      ClosePositionByTicket(positionTicket);
     }
   return(true);
  }

___


Alle profitablen Kaufpositionen schließen

Die Funktion CloseAllProfitableBuyPositions() schließt alle profitablen offenen Kaufpositionen, die mit den angegebenen Funktionsparametern oder Argumenten Symbolname und Magische Zahl übereinstimmen. Es wird true zurückgegeben, wenn es alle spezifizierten Positionen erfolgreich geschlossen wurden, andernfalls false.

bool CloseAllProfitableBuyPositions(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
     }

//-- Scan for profitable positions that match the specified symbol and magic number to close them
   int totalOpenPositions = PositionsTotal();
   for(int x = 0; x < totalOpenPositions; x++)
     {
      //--- Get position properties
      ulong positionTicket = PositionGetTicket(x); //-- Get ticket to select the position
      string selectedSymbol = PositionGetString(POSITION_SYMBOL);
      ulong positionMagicNo = PositionGetInteger(POSITION_MAGIC);
      double positionProfit = PositionGetDouble(POSITION_PROFIT);

      //-- Filter positions by symbol, magic number, profit and type
      if(
         ((symbol != ALL_SYMBOLS && symbol != selectedSymbol) || (magicNumber != 0 && positionMagicNo != magicNumber)) ||
         positionProfit <= 0 || PositionGetInteger(POSITION_TYPE) != POSITION_TYPE_BUY
      )
        {
         continue;
        }

      //-- Close the position
      ClosePositionByTicket(positionTicket);
     }
   return(true);
  }


Alle profitablen Verkaufspositionen schließen

Die Funktion CloseAllProfitableSellPositions() schließt alle profitablen offenen Verkaufspositionen, die den angegebenen Funktionsparametern oder Argumenten Symbolname und Magische Zahl entsprechen. Es wird true zurückgegeben, wenn es alle spezifizierten Positionen erfolgreich geschlossen wurden, andernfalls false.

bool CloseAllProfitableSellPositions(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
     }

//-- Scan for profitable positions that match the specified symbol and magic number to close them
   int totalOpenPositions = PositionsTotal();
   for(int x = 0; x < totalOpenPositions; x++)
     {
      //--- Get position properties
      ulong positionTicket = PositionGetTicket(x); //-- Get ticket to select the position
      string selectedSymbol = PositionGetString(POSITION_SYMBOL);
      ulong positionMagicNo = PositionGetInteger(POSITION_MAGIC);
      double positionProfit = PositionGetDouble(POSITION_PROFIT);

      //-- Filter positions by symbol, magic number, profit and type
      if(
         ((symbol != ALL_SYMBOLS && symbol != selectedSymbol) || (magicNumber != 0 && positionMagicNo != magicNumber)) ||
         positionProfit <= 0 || PositionGetInteger(POSITION_TYPE) != POSITION_TYPE_SELL
      )
        {
         continue;
        }

      //-- Close the position
      ClosePositionByTicket(positionTicket);
     }
   return(true);
  }


Close All Loss Positions

Die Funktion CloseAllLossPositions() schließt alle offenen Verlustpositionen, die mit den angegebenen Funktionsparametern oder Argumenten Symbolname und magische Zahl übereinstimmen. Sie gibt true zurück, wenn es alle spezifizierten Positionen erfolgreich geschlossen wurden, und false, wenn das nicht gelang.

bool CloseAllLossPositions(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
     }

//-- Scan for loss positions that match the specified symbol and magic number and close them
   int totalOpenPositions = PositionsTotal();
   for(int x = 0; x < totalOpenPositions; x++)
     {
      //--- Get position properties
      ulong positionTicket = PositionGetTicket(x); //-- Get ticket to select the position
      string selectedSymbol = PositionGetString(POSITION_SYMBOL);
      ulong positionMagicNo = PositionGetInteger(POSITION_MAGIC);
      double positionProfit = PositionGetDouble(POSITION_PROFIT);

      //-- Filter positions by symbol, magic number and profit
      if(
         ((symbol != ALL_SYMBOLS && symbol != selectedSymbol) || (magicNumber != 0 && positionMagicNo != magicNumber)) ||
         positionProfit > 0
      )
        {
         continue;
        }

      //-- Close the position
      ClosePositionByTicket(positionTicket);
     }

   return(true);
  }


Alle Kauf-Positionen mit Verlust schließen

Die Funktion CloseAllLossBuyPositions() schließt alle offenen Verlust-Kaufpositionen, die mit dem angegebenen Symbolnamen und den Funktionsparametern oder Argumenten der magischen Zahl übereinstimmen. Sie gibt true zurück, wenn es alle spezifizierten Positionen erfolgreich geschlossen wurden, und false, wenn das nicht gelang.

bool CloseAllLossBuyPositions(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
     }

//-- Scan for loss positions that match the specified symbol and magic number and close them
   int totalOpenPositions = PositionsTotal();
   for(int x = 0; x < totalOpenPositions; x++)
     {
      //--- Get position properties
      ulong positionTicket = PositionGetTicket(x); //-- Get ticket to select the position
      string selectedSymbol = PositionGetString(POSITION_SYMBOL);
      ulong positionMagicNo = PositionGetInteger(POSITION_MAGIC);
      double positionProfit = PositionGetDouble(POSITION_PROFIT);

      //-- Filter positions by symbol, magic number, profit and type
      if(
         ((symbol != ALL_SYMBOLS && symbol != selectedSymbol) || (magicNumber != 0 && positionMagicNo != magicNumber)) ||
         positionProfit > 0 || PositionGetInteger(POSITION_TYPE) != POSITION_TYPE_BUY
      )
        {
         continue;
        }

      //-- Close the position
      ClosePositionByTicket(positionTicket);
     }

   return(true);
  }


Alle Verkaufspositionen mit Verlust schließen

Die Funktion CloseAllLossSellPositions() schließt alle offenen Verkaufspositionen mit Verlust, die den angegebenen Funktionsparametern oder Argumenten Symbolname und magische Zahl entsprechen. Sie gibt true zurück, wenn es alle spezifizierten Positionen erfolgreich geschlossen wurden, und false, wenn das nicht gelang.

bool CloseAllLossSellPositions(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
     }

//-- Scan for loss positions that match the specified symbol and magic number and close them
   int totalOpenPositions = PositionsTotal();
   for(int x = 0; x < totalOpenPositions; x++)
     {
      //--- Get position properties
      ulong positionTicket = PositionGetTicket(x); //-- Get ticket to select the position
      string selectedSymbol = PositionGetString(POSITION_SYMBOL);
      ulong positionMagicNo = PositionGetInteger(POSITION_MAGIC);
      double positionProfit = PositionGetDouble(POSITION_PROFIT);

      //-- Filter positions by symbol, magic number, profit and type
      if(
         ((symbol != ALL_SYMBOLS && symbol != selectedSymbol) || (magicNumber != 0 && positionMagicNo != magicNumber)) ||
         positionProfit > 0 || PositionGetInteger(POSITION_TYPE) != POSITION_TYPE_SELL
      )
        {
         continue;
        }

      //-- Close the position
      ClosePositionByTicket(positionTicket);
     }

   return(true);
  }  



Position Statusfunktionen

Bei der Entwicklung eines Handelssystems ist es wichtig, den Kontostand anhand von Echtzeitdaten zu den verschiedenen Positionen zu verfolgen. Unabhängig davon, ob Sie eine rasterbasierte Strategie oder eine konservative Preisaktionsstrategie entwickeln, ist ein klarer und einfacher Überblick über alle offenen Positionen entscheidend für den Erfolg Ihres Handelssystems. Es gibt jedoch keine sofort einsatzbereiten Standard-Sprachfunktionen, die diese Informationen liefern. Diese EX5-Bibliothek zielt darauf ab, das Sammeln von Positionsinformationen mit einzeiligen Funktionsaufrufen zu vereinfachen. Die nachstehenden exportierbaren Funktionen geben Ihnen den nötigen Vorsprung, um Positionen zu überwachen und zu entscheiden, ob sie geschlossen oder aufgestockt werden sollen, und bilden damit eine der tragenden Säulen Ihres Handelssystems.


Get Positions Data

Die Funktion GetPositionsData() spielt eine entscheidende Rolle beim Sammeln und Speichern aller erforderlichen Positionsstatusinformationen. Sie speichert diese Daten in globalen Variablen, auf die innerhalb der gesamten Bibliothek leicht zugegriffen werden kann. Diese Variablen sollen bei jedem Tick kontinuierlich aktualisiert werden, damit sie genau und zuverlässig bleiben.

Platzieren Sie die folgenden globalen Variablendeklarationen am Anfang unserer Bibliothek unterhalb der Deklarationen der globalen Variablen für die Datenstrukturen für Handelsoperationen und -ergebnisse.

string accountCurrency = AccountInfoString(ACCOUNT_CURRENCY);

//-- Position status global variables
//-------------------------------------------------------------------------------------------------------------------
int accountBuyPositionsTotal = 0, accountSellPositionsTotal = 0,
    symbolPositionsTotal = 0, symbolBuyPositionsTotal = 0, symbolSellPositionsTotal = 0,
    magicPositionsTotal = 0, magicBuyPositionsTotal = 0, magicSellPositionsTotal = 0;
double accountPositionsVolumeTotal = 0.0, accountBuyPositionsVolumeTotal = 0.0, accountSellPositionsVolumeTotal = 0.0,
       accountBuyPositionsProfit = 0.0, accountSellPositionsProfit = 0.0,
       symbolPositionsVolumeTotal = 0.0, symbolBuyPositionsVolumeTotal = 0.0,
       symbolSellPositionsVolumeTotal = 0.0, symbolPositionsProfit = 0.0,
       symbolBuyPositionsProfit = 0.0, symbolSellPositionsProfit = 0.0,
       magicPositionsVolumeTotal = 0.0, magicBuyPositionsVolumeTotal = 0.0,
       magicSellPositionsVolumeTotal = 0.0, magicPositionsProfit = 0.0,
       magicBuyPositionsProfit = 0.0, magicSellPositionsProfit = 0.0;

Aktualisieren und speichern Sie die Positionsstatusdaten in der unten stehenden Funktion GetPositionsData().

void GetPositionsData(string symbol, ulong magicNumber)
  {
//-- Reset the acount open positions status
   accountBuyPositionsTotal = 0;
   accountSellPositionsTotal = 0;
   accountPositionsVolumeTotal = 0.0;
   accountBuyPositionsVolumeTotal = 0.0;
   accountSellPositionsVolumeTotal = 0.0;
   accountBuyPositionsProfit = 0.0;
   accountSellPositionsProfit = 0.0;

//-- Reset the EA's magic open positions status
   magicPositionsTotal = 0;
   magicBuyPositionsTotal = 0;
   magicSellPositionsTotal = 0;
   magicPositionsVolumeTotal = 0.0;
   magicBuyPositionsVolumeTotal = 0.0;
   magicSellPositionsVolumeTotal = 0.0;
   magicPositionsProfit = 0.0;
   magicBuyPositionsProfit = 0.0;
   magicSellPositionsProfit = 0.0;

//-- Reset the symbol open positions status
   symbolPositionsTotal = 0;
   symbolBuyPositionsTotal = 0;
   symbolSellPositionsTotal = 0;
   symbolPositionsVolumeTotal = 0.0;
   symbolBuyPositionsVolumeTotal = 0.0;
   symbolSellPositionsVolumeTotal = 0.0;
   symbolPositionsProfit = 0.0;
   symbolBuyPositionsProfit = 0.0;
   symbolSellPositionsProfit = 0.0;

//-- Update and save the open positions status with realtime data
   int totalOpenPositions = PositionsTotal();
   if(totalOpenPositions > 0)
     {
      //-- Scan for symbol and magic number specific positions and save their status
      for(int x = 0; x < totalOpenPositions; x++)
        {
         //--- Get position properties
         ulong  positionTicket = PositionGetTicket(x); //-- Get ticket to select the position
         string selectedSymbol = PositionGetString(POSITION_SYMBOL);
         ulong positionMagicNo = PositionGetInteger(POSITION_MAGIC);

         //-- Filter positions by magic number
         if(magicNumber != 0 && positionMagicNo != magicNumber)
           {
            continue;
           }

         //-- Save the account positions status first
         accountPositionsVolumeTotal += PositionGetDouble(POSITION_VOLUME);

         if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
           {
            //-- Account properties
            ++accountBuyPositionsTotal;
            accountBuyPositionsVolumeTotal += PositionGetDouble(POSITION_VOLUME);
            accountBuyPositionsProfit += PositionGetDouble(POSITION_PROFIT);
           }
         else //-- POSITION_TYPE_SELL
           {
            //-- Account properties
            ++accountSellPositionsTotal;
            accountSellPositionsVolumeTotal += PositionGetDouble(POSITION_VOLUME);
            accountSellPositionsProfit += PositionGetDouble(POSITION_PROFIT);
           }

         //-- Filter positions openend by EA and save their status
         if(
            PositionGetInteger(POSITION_REASON) == POSITION_REASON_EXPERT &&
            positionMagicNo == magicNumber
         )
           {
            ++magicPositionsTotal;
            magicPositionsProfit += PositionGetDouble(POSITION_PROFIT);
            magicPositionsVolumeTotal += PositionGetDouble(POSITION_VOLUME);
            if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
              {
               //-- Magic properties
               ++magicBuyPositionsTotal;
               magicBuyPositionsProfit += PositionGetDouble(POSITION_PROFIT);
               magicBuyPositionsVolumeTotal += PositionGetDouble(POSITION_VOLUME);
              }
            else //-- POSITION_TYPE_SELL
              {
               //-- Magic properties
               ++magicSellPositionsTotal;
               magicSellPositionsProfit += PositionGetDouble(POSITION_PROFIT);
               magicSellPositionsVolumeTotal += PositionGetDouble(POSITION_VOLUME);
              }
           }

         //-- Filter positions by symbol
         if(symbol == ALL_SYMBOLS || selectedSymbol == symbol)
           {
            ++symbolPositionsTotal;
            symbolPositionsVolumeTotal += PositionGetDouble(POSITION_VOLUME);
            symbolPositionsProfit += PositionGetDouble(POSITION_PROFIT);
            if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
              {
               ++symbolBuyPositionsTotal;
               symbolBuyPositionsVolumeTotal += PositionGetDouble(POSITION_VOLUME);
               symbolBuyPositionsProfit += PositionGetDouble(POSITION_PROFIT);
              }
            else //-- POSITION_TYPE_SELL
              {
               ++symbolSellPositionsTotal;
               symbolSellPositionsVolumeTotal += PositionGetDouble(POSITION_VOLUME);
               symbolSellPositionsProfit += PositionGetDouble(POSITION_PROFIT);
              }
           }
        }
     }
  }

Um Zugriff auf die verschiedenen Eigenschaften des Positionsstatus zu erhalten, die wir oben in den globalen Variablen erfasst und gespeichert haben, müssen wir einfache exportierbare Funktionen erstellen, auf die von einer externen Codebasis aus zugegriffen werden kann. Wir werden dies durch die Codierung der folgenden Funktionen erreichen.


Buy Positions Total

Gibt einen ganzzahligen Wert für die Gesamtzahl aller offenen Kaufpositionen im Konto zurück.

int BuyPositionsTotal() export
  {
   GetPositionsData(ALL_SYMBOLS, 0);
   return(accountBuyPositionsTotal);
  }

Sell Positions Total

Gibt einen ganzzahligen Wert für die Gesamtzahl aller offenen Verkaufspositionen im Konto zurück.

int SellPositionsTotal() export
  {
   GetPositionsData(ALL_SYMBOLS, 0);
   return(accountSellPositionsTotal);
  }


Positions Total Volume

Gibt einen ‚double‘-Wert des Gesamtvolumens/Lots/der Gesamtmenge aller offenen Positionen im Konto zurück.

double PositionsTotalVolume() export
  {
   GetPositionsData(ALL_SYMBOLS, 0);
   return(accountPositionsVolumeTotal);
  }


Buy Positions Total Volume

Gibt einen ‚double‘-Wert des Gesamtvolumens/Lots/der Gesamtmenge aller offenen Kaufpositionen im Konto zurück.

double BuyPositionsTotalVolume() export
  {
   GetPositionsData(ALL_SYMBOLS, 0);
   return(accountBuyPositionsVolumeTotal);
  }


Sell Positions Total Volume

Gibt einen ‚double‘-Wert des Gesamtvolumens/der Gesamtmenge aller offenen Verkaufspositionen des Kontos zurück.

double SellPositionsTotalVolume() export
  {
   GetPositionsData(ALL_SYMBOLS, 0);
   return(accountSellPositionsVolumeTotal);
  }


Buy Positions Profit

Gibt einen ‚double‘-Wert des Gesamtgewinns aller offenen Kaufpositionen des Kontos zurück.

double BuyPositionsProfit() export
  {
   GetPositionsData(ALL_SYMBOLS, 0);
   return(accountBuyPositionsProfit);
  }


Sell Positions Profit

Gibt einen ‚double‘-Wert des Gesamtgewinns aller offenen Verkaufspositionen des Kontos zurück.

double SellPositionsProfit() export
  {
   GetPositionsData(ALL_SYMBOLS, 0);
   return(accountSellPositionsProfit);
  }


Magic Positions Total

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

int MagicPositionsTotal(ulong magicNumber) export
  {
   GetPositionsData(ALL_SYMBOLS, magicNumber);
   return(magicPositionsTotal);
  }


Magic Buy Positions Total

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

int MagicBuyPositionsTotal(ulong magicNumber) export
  {
   GetPositionsData(ALL_SYMBOLS, magicNumber);
   return(magicBuyPositionsTotal);
  }


Magic Sell Positions Total

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

int MagicSellPositionsTotal(ulong magicNumber) export
  {
   GetPositionsData(ALL_SYMBOLS, magicNumber);
   return(magicSellPositionsTotal);
  }


Magic Positions Total Volume

Gibt einen ‚double‘-Wert des Gesamtvolumens/der Gesamtmenge aller offenen Positionen für die angegebene magische Zahl im Konto zurück.

double MagicPositionsTotalVolume(ulong magicNumber) export
  {
   GetPositionsData(ALL_SYMBOLS, magicNumber);
   return(magicPositionsVolumeTotal);
  }


Magic Buy Positions Total Volume

Gibt einen ‚double‘-Wert des Gesamtvolumens/der Gesamtmenge aller offenen Kaufpositionen für die angegebene magische Zahl im Konto zurück.

double MagicBuyPositionsTotalVolume(ulong magicNumber) export
  {
   GetPositionsData(ALL_SYMBOLS, magicNumber);
   return(magicBuyPositionsVolumeTotal);
  }


Magic Sell Positions Total Volume

Gibt einen ‚double‘-Wert des Gesamtvolumens/der Gesamtmenge aller offenen Verkaufspositionen für die angegebene magische Zahl im Konto zurück.

double MagicSellPositionsTotalVolume(ulong magicNumber) export
  {
   GetPositionsData(ALL_SYMBOLS, magicNumber);
   return(magicSellPositionsVolumeTotal);
  }


Magic Positions Profit

Gibt einen ‚double‘-Wert für den Gesamtgewinn aller offenen Positionen für die angegebene magische Zahl im Konto zurück.

double MagicPositionsProfit(ulong magicNumber) export
  {
   GetPositionsData(ALL_SYMBOLS, magicNumber);
   return(magicPositionsProfit);
  }


Magic Buy Positions Profit

Gibt einen ‚double‘-Wert des Gesamtgewinns aller offenen Kaufpositionen für die angegebene magische Zahl im Konto zurück.

double MagicBuyPositionsProfit(ulong magicNumber) export
  {
   GetPositionsData(ALL_SYMBOLS, magicNumber);
   return(magicBuyPositionsProfit);
  }


Magic Sell Positions Profit

Gibt einen ‚double‘-Wert für den Gesamtgewinn aller offenen Verkaufspositionen für die angegebene magische Zahl im Konto zurück.

double MagicSellPositionsProfit(ulong magicNumber) export
  {
   GetPositionsData(ALL_SYMBOLS, magicNumber);
   return(magicSellPositionsProfit);
  }


Symbol Positions Total

Gibt einen ganzzahligen Wert für die Gesamtzahl aller offenen Positionen für ein bestimmtes Symbol im Konto zurück.

int SymbolPositionsTotal(string symbol, ulong magicNumber) export
  {
   GetPositionsData(symbol, magicNumber);
   return(symbolPositionsTotal);
  }


Symbol Buy Positions Total

Gibt einen ganzzahligen Wert für die Gesamtzahl aller offenen Kaufpositionen für ein bestimmtes Symbol im Konto zurück.

int SymbolBuyPositionsTotal(string symbol, ulong magicNumber) export
  {
   GetPositionsData(symbol, magicNumber);
   return(symbolBuyPositionsTotal);
  }


Symbol Sell Positions Total

Gibt einen ganzzahligen Wert für die Gesamtzahl aller offenen Verkaufspositionen für ein bestimmtes Symbol im Konto zurück.

int SymbolSellPositionsTotal(string symbol, ulong magicNumber) export
  {
   GetPositionsData(symbol, magicNumber);
   return(symbolSellPositionsTotal);
  }


Symbol Positions Total Volume

Gibt einen ‚double‘-Wert des Gesamtvolumens/der Gesamtmenge aller offenen Positionen für ein bestimmtes Symbol im Konto zurück.

double SymbolPositionsTotalVolume(string symbol, ulong magicNumber) export
  {
   GetPositionsData(symbol, magicNumber);
   return(symbolPositionsVolumeTotal);
  }


Symbol Buy Positions Total Volume

Gibt einen ‚double‘-Wert des Gesamtvolumens/der Gesamtmenge aller offenen Kaufpositionen für ein bestimmtes Symbol im Konto zurück.

double SymbolBuyPositionsTotalVolume(string symbol, ulong magicNumber) export
  {
   GetPositionsData(symbol, magicNumber);
   return(symbolBuyPositionsVolumeTotal);
  }


Symbol Sell Positions Total Volume

Gibt einen ‚double‘-Wert des Gesamtvolumens/der Gesamtmenge aller offenen Verkaufspositionen für ein bestimmtes Symbol im Konto zurück.

double SymbolSellPositionsTotalVolume(string symbol, ulong magicNumber) export
  {
   GetPositionsData(symbol, magicNumber);
   return(symbolSellPositionsVolumeTotal);
  }


Symbol Positions Profit

Gibt einen ‚double‘-Wert des Gesamtgewinns aller offenen Positionen für ein bestimmtes Symbol im Konto zurück.

double SymbolPositionsProfit(string symbol, ulong magicNumber) export
  {
   GetPositionsData(symbol, magicNumber);
   return(NormalizeDouble(symbolPositionsProfit, 2));
  }


Symbol Buy Positions Profit

Gibt einen ‚double‘-Wert des Gesamtgewinns aller offenen Kaufpositionen für ein bestimmtes Symbol im Konto zurück.

double SymbolBuyPositionsProfit(string symbol, ulong magicNumber) export
  {
   GetPositionsData(symbol, magicNumber);
   return(NormalizeDouble(symbolBuyPositionsProfit, 2));
  }


Symbol Sell Positions Profit

Gibt einen ‚double‘-Wert des Gesamtgewinns aller offenen Verkaufspositionen für ein bestimmtes Symbol im Konto zurück.

double SymbolSellPositionsProfit(string symbol, ulong magicNumber) export
  {
   GetPositionsData(symbol, magicNumber);
   return(NormalizeDouble(symbolSellPositionsProfit, 2));
  }


Account Positions Status

Gibt eine vorformatierte Zeichenkette mit dem Status der Kontopositionen zurück, die in das Protokoll gedruckt oder in den Chartkommentaren angezeigt werden kann. Die Funktion akzeptiert einen einzigen booleschen Parameter namens formatForComment. Wenn formatForComment true ist, formatiert die Funktion die Daten für die Anzeige im Chartfenster. Ist sie false, werden die Daten für die Anzeige auf der Registerkarte Logs des Expert Advisors formatiert.

string AccountPositionsStatus(bool formatForComment) export
  {
   GetPositionsData(ALL_SYMBOLS, 0); //-- Update the position status variables before we display their data
   string spacer = "";
   if(formatForComment) //-- Add some formating space for the chart comment string
     {
      spacer = "                                        ";
     }
   string accountPositionsStatus = "\r\n" + spacer + "|---------------------------------------------------------------------------\r\n";
   accountPositionsStatus += spacer + "| " + (string)AccountInfoInteger(ACCOUNT_LOGIN) + " - ACCOUNT POSTIONS STATUS \r\n";
   accountPositionsStatus += spacer + "|---------------------------------------------------------------------------\r\n";
   accountPositionsStatus += spacer + "|     Total Open:   " + (string)PositionsTotal() + "\r\n";
   accountPositionsStatus += spacer + "|     Total Volume: " + (string)accountPositionsVolumeTotal + "\r\n";
   accountPositionsStatus += spacer + "|     Total Profit: " +
   (string)(NormalizeDouble(AccountInfoDouble(ACCOUNT_PROFIT), 2)) + accountCurrency + "\r\n";
   accountPositionsStatus += spacer + "|------------------------------------------------------------------\r\n";
   accountPositionsStatus += spacer + "| BUY POSITIONS: \r\n";
   accountPositionsStatus += spacer + "|     Total Open:   " + (string)accountBuyPositionsTotal + "\r\n";
   accountPositionsStatus += spacer + "|     Total Volume: " + (string)accountBuyPositionsVolumeTotal + "\r\n";
   accountPositionsStatus += spacer + "|     Total Profit: " + (string)(NormalizeDouble(accountBuyPositionsProfit, 2)) +
   accountCurrency + "\r\n";
   accountPositionsStatus += spacer + "|------------------------------------------------------------------\r\n";
   accountPositionsStatus += spacer + "| SELL POSITIONS: \r\n";
   accountPositionsStatus += spacer + "|     Total Open:   " + (string)accountSellPositionsTotal + "\r\n";
   accountPositionsStatus += spacer + "|     Total Volume: " + (string)accountSellPositionsVolumeTotal + "\r\n";
   accountPositionsStatus += spacer + "|     Total Profit: " + (string)(NormalizeDouble(accountSellPositionsProfit, 2)) +
   accountCurrency + "\r\n";
   accountPositionsStatus += spacer + "|---------------------------------------------------------------------------\r\n";
   accountPositionsStatus += spacer + "\r\n";
   return(accountPositionsStatus);
  }


Magic Positions Status

Gibt eine vorformatierte Zeichenkette zurück, die den Status der magischen Positionen des Kontos enthält und die in das Protokoll gedruckt oder in den Chart-Kommentaren angezeigt werden kann. Die Funktion nimmt zwei Argumente oder Parameter entgegen. Eine magicNumber ohne Vorzeichen und ein bool‘sches formatForComment. Wenn formatForComment true ist, formatiert die Funktion die Daten für die Anzeige im Chartfenster. Ist sie false, werden die Daten für die Anzeige auf der Registerkarte Logs des Expert Advisors formatiert.

string MagicPositionsStatus(ulong magicNumber, bool formatForComment) export
  {
   GetPositionsData(ALL_SYMBOLS, magicNumber); //-- Update the position status variables before we display their data
   string spacer = "";
   if(formatForComment) //-- Add some formating space for the chart comment string
     {
      spacer = "                                        ";
     }
   string magicPositionsStatus = "\r\n" + spacer + "|---------------------------------------------------------------------------\r\n";
   magicPositionsStatus += spacer + "| " + (string)magicNumber + " - MAGIC POSTIONS STATUS \r\n";
   magicPositionsStatus += spacer + "|---------------------------------------------------------------------------\r\n";
   magicPositionsStatus += spacer + "|     Total Open:   " + (string)magicPositionsTotal + "\r\n";
   magicPositionsStatus += spacer + "|     Total Volume: " + (string)magicPositionsVolumeTotal + "\r\n";
   magicPositionsStatus += spacer + "|     Total Profit: " +
   (string)(NormalizeDouble(magicPositionsProfit, 2)) + accountCurrency + "\r\n";
   magicPositionsStatus += spacer + "|------------------------------------------------------------------\r\n";
   magicPositionsStatus += spacer + "| BUY POSITIONS: \r\n";
   magicPositionsStatus += spacer + "|     Total Open:   " + (string)magicBuyPositionsTotal + "\r\n";
   magicPositionsStatus += spacer + "|     Total Volume: " + (string)magicBuyPositionsVolumeTotal + "\r\n";
   magicPositionsStatus += spacer + "|     Total Profit: " + (string)(NormalizeDouble(magicBuyPositionsProfit, 2)) +
   accountCurrency + "\r\n";
   magicPositionsStatus += spacer + "|------------------------------------------------------------------\r\n";
   magicPositionsStatus += spacer + "| SELL POSITIONS: \r\n";
   magicPositionsStatus += spacer + "|     Total Open:   " + (string)magicSellPositionsTotal + "\r\n";
   magicPositionsStatus += spacer + "|     Total Volume: " + (string)magicSellPositionsVolumeTotal + "\r\n";
   magicPositionsStatus += spacer + "|     Total Profit: " + (string)(NormalizeDouble(magicSellPositionsProfit, 2)) +
   accountCurrency + "\r\n";
   magicPositionsStatus += spacer + "|---------------------------------------------------------------------------\r\n";
   magicPositionsStatus += spacer + "\r\n";
   return(magicPositionsStatus);
  }


Symbol Positions Status

Gibt eine vorformatierte Zeichenkette mit dem Status der Kontosymbolpositionen zurück, die im Protokoll ausgedruckt oder in den Chartkommentaren angezeigt werden kann. Die Funktion nimmt drei Argumente oder Parameter entgegen. Eine Zeichenfolge symbol, unsigned long magicNumber und ein bool formatForComment. Wenn der bool‘sche Wert formatForComment true ist, formatiert die Funktion die Daten für die Anzeige im Chartfenster. Ist sie false, werden die Daten für die Anzeige auf der Registerkarte Logs des Expert Advisors formatiert.

string SymbolPositionsStatus(string symbol, ulong magicNumber, bool formatForComment) export
  {
   GetPositionsData(symbol, magicNumber); //-- Update the position status variables before we display their data
   string spacer = "";
   if(formatForComment) //-- Add some formating space for the chart comment string
     {
      spacer = "                                        ";
     }
   string symbolPositionsStatus = "\r\n" + spacer + "|---------------------------------------------------------------------------\r\n";
   symbolPositionsStatus += spacer + "| " + symbol + " - SYMBOL POSTIONS STATUS \r\n";
   symbolPositionsStatus += spacer + "|---------------------------------------------------------------------------\r\n";
   symbolPositionsStatus += spacer + "|     Total Open:   " + (string)symbolPositionsTotal + "\r\n";
   symbolPositionsStatus += spacer + "|     Total Volume: " + (string)symbolPositionsVolumeTotal + "\r\n";
   symbolPositionsStatus += spacer + "|     Total Profit: " +
   (string)(NormalizeDouble(symbolPositionsProfit, 2)) + accountCurrency + "\r\n";
   symbolPositionsStatus += spacer + "|------------------------------------------------------------------\r\n";
   symbolPositionsStatus += spacer + "| BUY POSITIONS: \r\n";
   symbolPositionsStatus += spacer + "|     Total Open:   " + (string)symbolBuyPositionsTotal + "\r\n";
   symbolPositionsStatus += spacer + "|     Total Volume: " + (string)symbolBuyPositionsVolumeTotal + "\r\n";
   symbolPositionsStatus += spacer + "|     Total Profit: " + (string)(NormalizeDouble(symbolBuyPositionsProfit, 2)) +
   accountCurrency + "\r\n";
   symbolPositionsStatus += spacer + "|------------------------------------------------------------------\r\n";
   symbolPositionsStatus += spacer + "| SELL POSITIONS: \r\n";
   symbolPositionsStatus += spacer + "|     Total Open:   " + (string)symbolSellPositionsTotal + "\r\n";
   symbolPositionsStatus += spacer + "|     Total Volume: " + (string)symbolSellPositionsVolumeTotal + "\r\n";
   symbolPositionsStatus += spacer + "|     Total Profit: " + (string)(NormalizeDouble(symbolSellPositionsProfit, 2)) +
   accountCurrency + "\r\n";
   symbolPositionsStatus += spacer + "|---------------------------------------------------------------------------\r\n";
   symbolPositionsStatus += spacer + "\r\n";
   return(symbolPositionsStatus);
  }



So importieren und implementieren Sie unsere Positionsmanagement EX5-Bibliothek

Wir haben eine umfassende Bibliothek für die Positionsverwaltung EX5 entwickelt, die alle wesentlichen Funktionen für Positionsvorgänge, Statusextraktion und Anzeigemodule enthält. Es ist nun an der Zeit zu dokumentieren und zu erklären, wie man diese Bibliothek effektiv in jedes MQL5-Projekt importiert und nutzt.

Um den Implementierungsprozess zu vereinfachen, werden zunächst alle Funktionen oder Module der Positionsverwaltungsbibliothek zusammen mit einigen realen Codebeispielen beschrieben. Dadurch erhalten die Nutzer der Bibliothek einen schnellen Überblick über die in der Binärdatei PositionsManager.ex5 enthaltenen Komponenten.

Positionen Manager EX5 Bibliothek Dokumentation

Funktion Prototyp Beschreibung Beschreibung Beispiel für einen Anwendungsfall
bool ErrorAdvisor(
   string callingFunc, 
   string symbol, 
   int tradeServerErrorCode
);
Verwaltet Handelsserver- und Laufzeitfehler bei der Bearbeitung von Positionen und Aufträgen. Gibt true zurück, wenn der Fehler behebbar ist und die Handelsanfrage erneut gesendet werden kann, false , wenn der Fehler kritisch ist und das Senden der Anfrage gestoppt werden sollte.
ResetLastError(); //-- Reset and clear the last error
//--------------------------------------------------------------
//-- Insert code to send the order request to the trade server
//--------------------------------------------------------------
string symbol = _Symbol; //Symbol being traded
int retcode = tradeResult.retcode;//Trade Request Structure (MqlTradeRequest)
if(!ErrorAdvisor(__FUNCTION__, symbol, retcode)
  {
//Critical error found
//Order can not be executed. Exit function or log this error
  }
bool TradingIsAllowed();
Überprüft, ob der Expert Advisor vom Nutzer, dem Handelsserver und dem Broker die Erlaubnis erhalten hat, Geschäfte auszuführen. 
if(!TradingIsAllowed())
  {
   //--- algo trading is disabled, exit function
   return(false);
  }

bool OpenBuyPosition(
   ulong magicNumber,
   string symbol,
   double lotSize,
   int sl, int tp,
   string positionComment
);
Eröffnet eine neue Kaufposition, die den angegebenen Parametern entspricht.
ulong magicNo = 123;
string symbol = _Symbol;
double lotSize = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MIN);
int sl = 500; //-- pips
int tp = 1000; //-- pips
string comment = "Buy position";
OpenBuyPosition(magicNo, symbol, lotSize, sl, tp, comment);
bool OpenSellPosition(
   ulong magicNumber,
   string symbol,
   double lotSize,
   int sl,
   int tp,
   string positionComment
);
Eröffnet eine neue Verkaufsposition, die den angegebenen Parametern entspricht.
ulong magicNo = 123;
string symbol = _Symbol;
double lotSize = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MIN);
int sl = 500; //-- pips
int tp = 1000; //-- pips
string comment = "Sell position";
OpenSellPosition(magicNo, symbol, lotSize, sl, tp, comment);
bool SetSlTpByTicket(
   ulong positionTicket,
   int sl,
   int tp
);
Legt den Stop-Loss für eine Position fest, die dem angegebenen Ticket entspricht.
int sl = 500, int tp = 1000; //-- pips
int totalOpenPostions = PositionsTotal();
for(int x = 0; x < totalOpenPostions; x++)
{
   ulong positionTicket = PositionGetTicket(x);
   if(positionTicket > 0)
   {
      SetSlTpByTicket(positionTicket, sl, tp);
   }   
}
bool ClosePositionByTicket(
   ulong positionTicket
);
Schließt eine Position, die mit dem angegebenen Ticket übereinstimmt.
//-- Example to close all open positions
for(int x = 0; x < totalOpenPostions; x++)
{
   ulong positionTicket = PositionGetTicket(x);
   if(positionTicket > 0)
   {
      ClosePositionByTicket(positionTicket);
   }   
}
bool SetTrailingStopLoss(
   ulong positionTicket,
   int trailingStopLoss
);
Setzt einen Trailing-Stop-Loss für eine Position, die dem angegebenen Ticket entspricht. Diese Funktion sollte bei jedem Tick in der Funktion OnTick() ausgeführt werden, um den Trailing-Stop-Loss in Echtzeit zu aktualisieren.
//-- Execute this on every tick
//-- Example to set 500 pips trailing stop loss for all positions
int trailingStopLoss = 500; //-- 500 pips trailing stop loss
for(int x = 0; x < totalOpenPostions; x++)
{
   ulong positionTicket = PositionGetTicket(x);
   if(positionTicket > 0)
   {
      SetTrailingStopLoss(positionTicket, trailingStopLoss);
   }   
}
bool CloseAllPositions(
   string symbol, 
   ulong magicNumber
);
Vielseitige Funktion, die alle offenen Positionen, die den angegebenen Parametern entsprechen, schließt.
//Close all positions
CloseAllPositions("", 0);

//Only close all positions matching a magic number value of 1
CloseAllPositions("", 1);

//Only close all current symbol positions
CloseAllPositions(_Symbol, 0);
bool CloseAllPositions();

Schließt alle offenen Positionen.
//Close all open positions in the account
CloseAllPositions();
 
bool CloseAllBuyPositions(
   string symbol, 
   ulong magicNumber
);
Schließt alle Kaufpositionen, die den angegebenen Parametern entsprechen.
//Close all buy positions for the current symbol
CloseAllBuyPositions(_Symbol, 0);

//Close all buy positions matching magic number 1 for all symbols
CloseAllBuyPositions("", 1);

//Close all buy positions in the account
CloseAllBuyPositions("", 0);
 
bool CloseAllSellPositions(
   string symbol,
   ulong magicNumber
);

Schließt alle Verkaufspositionen, die den angegebenen Parametern entsprechen.  
//Close all sell positions for the current symbol
CloseAllSellPositions(_Symbol, 0);

//Close all sell positions matching magic number 1 for all symbols
CloseAllSellPositions("", 1);

//Close all sell positions in the account
CloseAllSellPositions("", 0);
 
bool CloseAllMagicPositions(
   ulong magicNumber
);
Schließt alle Positionen, die der angegebenen magischen Zahl entsprechen.  
//Close all positions matching magic number 1
CloseAllMagicPositions(1);

//Close all positions in the account
CloseAllMagicPositions(0);
 
bool CloseAllProfitablePositions(
   string symbol,
   ulong magicNumber
);

Schließt alle profitablen Positionen, die den angegebenen Parametern entsprechen.
//Close all profitable positions for the current symbol
CloseAllProfitablePositions(_Symbol, 0);

//Close all profitable positions matching magic number 1 for all symbols
CloseAllProfitablePositions("", 1);

//Close all profitable positions in the account
CloseAllProfitablePositions("", 0);
 
bool CloseAllProfitableBuyPositions(
   string symbol,
   ulong magicNumber
);
Schließt alle profitablen Kaufpositionen, die den angegebenen Parametern entsprechen.
//Close all profitable buy positions for the current symbol
CloseAllProfitableBuyPositions(_Symbol, 0);

//Close all profitable buy positions matching magic number 1 for all symbols
CloseAllProfitableBuyPositions("", 1);

//Close all profitable buy positions in the account
CloseAllProfitableBuyPositions("", 0);
 
bool CloseAllProfitableSellPositions(
   string symbol,
   ulong magicNumber
);
Schließt alle profitablen Verkaufspositionen, die den angegebenen Parametern entsprechen.
//Close all profitable sell positions for the current symbol
CloseAllProfitableSellPositions(_Symbol, 0);

//Close all profitable sell positions matching magic number 1 for all symbols
CloseAllProfitableSellPositions("", 1);

//Close all profitable sell positions in the account
CloseAllProfitableSellPositions("", 0);
 
bool CloseAllLossPositions(
   string symbol,
   ulong magicNumber
);

Schließt alle Verlustpositionen, die den angegebenen Parametern entsprechen.
//Close all loss positions for the current symbol
CloseAllLossPositions(_Symbol, 0);

//Close all loss positions matching magic number 1 for all symbols
CloseAllLossPositions("", 1);

//Close all loss positions in the account
CloseAllLossPositions("", 0);
 
bool CloseAllLossBuyPositions(
   string symbol,
   ulong magicNumber
);
Schließt alle Kaufpositionen mit Verlust, die den angegebenen Parametern entsprechen.
//Close all loss buy positions for the current symbol
CloseAllLossBuyPositions(_Symbol, 0);

//Close all loss buy positions matching magic number 1 for all symbols
CloseAllLossBuyPositions("", 1);

//Close all loss buy positions in the account
CloseAllLossBuyPositions("", 0);

 
bool CloseAllLossSellPositions(
   string symbol,
   ulong magicNumber
);

Schließt alle Verkaufspositionen mit Verlust, die den angegebenen Parametern entsprechen.
//Close all loss sell positions for the current symbol
CloseAllLossSellPositions(_Symbol, 0);

//Close all loss sell positions matching magic number 1 for all symbols
CloseAllLossSellPositions("", 1);

//Close all loss sell positions in the account
CloseAllLossSellPositions("", 0);
 
int BuyPositionsTotal();

Gibt die Anzahl der offenen Kaufpositionen zurück.  
//Get the total number of open buy positions in the account
BuyPositionsTotal();

 
int SellPositionsTotal();

Gibt die Anzahl der offenen Verkaufspositionen zurück.
//Get the total number of open sell positions in the account
SellPositionsTotal();

 
double PositionsTotalVolume();

Gibt das Gesamtvolumen aller offenen Positionen zurück.
//Get the total volume of all open positions in the account
PositionsTotalVolume();

 
double BuyPositionsTotalVolume();
Gibt das Gesamtvolumen aller offenen Kaufpositionen zurück.
//Get the total volume of all open buy positions in the account
BuyPositionsTotalVolume();

 
double SellPositionsTotalVolume();

Gibt das Gesamtvolumen aller offenen Verkaufspositionen zurück.
//Get the total volume of all open sell positions in the account
SellPositionsTotalVolume();

 
double BuyPositionsProfit();
Gibt den Gesamtgewinn aller offenen Kaufpositionen zurück.
//Get the total profit of all open buy positions in the account
BuyPositionsProfit();

 
double SellPositionsProfit();

Gibt den Gesamtgewinn aller offenen Verkaufspositionen zurück.
//Get the total profit of all open sell positions in the account
SellPositionsProfit();

 
int MagicPositionsTotal(
   ulong magicNumber
);

Gibt die Anzahl der offenen Positionen zurück, die der angegebenen magischen Zahl entsprechen.
//Get the total number of open positions matching magic number 1
MagicPositionsTotal(1);
 
int MagicBuyPositionsTotal(
   ulong magicNumber
);

Gibt die Anzahl der offenen Kaufpositionen zurück, die der angegebenen magischen Zahl entsprechen.
//Get the total number of open buy positions matching magic number 1
MagicBuyPositionsTotal(1);
 
int MagicSellPositionsTotal(
   ulong magicNumber
);

Gibt die Anzahl der offenen Verkaufspositionen zurück, die der angegebenen magischen Zahl entsprechen.
//Get the total number of open sell positions matching magic number 1
MagicSellPositionsTotal(1);
 
double MagicPositionsTotalVolume(
   ulong magicNumber
);

Gibt das Gesamtvolumen aller offenen Positionen zurück, die der angegebenen magischen Zahl entsprechen.
//Get the total volume of open positions matching magic number 1
MagicPositionsTotalVolume(1);
 
double MagicBuyPositionsTotalVolume(
   ulong magicNumber
);

Gibt das Gesamtvolumen aller offenen Kaufpositionen zurück, die der angegebenen magischen Zahl entsprechen.
//Get the total volume of open buy positions matching magic number 1
MagicBuyPositionsTotalVolume(1);
 
double MagicSellPositionsTotalVolume(
   ulong magicNumber
);

Gibt das Gesamtvolumen aller offenen Verkaufspositionen zurück, die der angegebenen magischen Zahl entsprechen.
 
//Get the total volume of open sell positions matching magic number 1
MagicSellPositionsTotalVolume(1);
 
double MagicPositionsProfit(
   ulong magicNumber
);

Gibt den Gesamtgewinn aller offenen Positionen zurück, die der angegebenen magischen Zahl entsprechen.
//Get the total profit of open positions matching magic number 1
MagicPositionsProfit(1);
 
double MagicBuyPositionsProfit(
   ulong magicNumber
);
Gibt den Gesamtgewinn aller offenen Kaufpositionen zurück, die der angegebenen magischen Zahl entsprechen.
//Get the total profit of open buy positions matching magic number 1
MagicBuyPositionsProfit(1);
 
double MagicSellPositionsProfit(
   ulong magicNumber
);
Gibt den Gesamtgewinn aller offenen Verkaufspositionen zurück, die der angegebenen magischen Zahl entsprechen.
//Get total profit of sell positions matching magic number 1
MagicSellPositionsProfit(1);

 
int SymbolPositionsTotal(
   string symbol,
   ulong magicNumber
);

Gibt die Gesamtzahl aller offenen Positionen zurück, die dem angegebenen Symbol und der magischen Zahl entsprechen.
//Get total number of positions matching symbol and magic number 1
MagicPositionsTotal(_Symbol, 1);
 
int SymbolBuyPositionsTotal(
   string symbol,
   ulong magicNumber
);
Gibt die Gesamtzahl aller offenen Kaufpositionen zurück, die dem angegebenen Symbol und der magischen Zahl entsprechen.
//Get total number of buy positions matching symbol and magic number 1
SymbolBuyPositionsTotal(_Symbol, 1);

 
int SymbolSellPositionsTotal(
   string symbol,
   ulong magicNumber
);
Gibt die Gesamtzahl aller offenen Verkaufspositionen zurück, die dem angegebenen Symbol und der magischen Zahl entsprechen.
//Get total number of sell positions matching symbol and magic number 1
SymbolSellPositionsTotal(_Symbol, 1);

 
double SymbolPositionsTotalVolume(
   string symbol,
   ulong magicNumber
);

Gibt das Gesamtvolumen aller offenen Positionen zurück, die dem angegebenen Symbol und der magischen Zahl entsprechen.
//Get the volume of positions matching symbol and magic number 1
SymbolPositionsTotalVolume(_Symbol, 1);

 
double SymbolBuyPositionsTotalVolume(
   string symbol,
   ulong magicNumber
);

Gibt das Gesamtvolumen aller offenen Kaufpositionen zurück, die dem angegebenen Symbol und der magischen Zahl entsprechen.
//Get the volume of buy positions matching symbol and magic number 1
SymbolBuyPositionsTotalVolume(_Symbol, 1);
 
double SymbolSellPositionsTotalVolume(
   string symbol,
   ulong magicNumber
);

Gibt das Gesamtvolumen aller offenen Verkaufspositionen zurück, die dem angegebenen Symbol und der magischen Zahl entsprechen.
//Get the volume of sell positions matching symbol and magic number 1
SymbolSellPositionsTotalVolume(_Symbol, 1);
 
double SymbolPositionsProfit(
   string symbol,
   ulong magicNumber
);

Gibt den Gesamtgewinn aller offenen Positionen zurück, die dem angegebenen Symbol und der magischen Zahl entsprechen.
//Get the profit of all positions matching symbol and magic number 1
SymbolPositionsProfit(_Symbol, 1);
 
double SymbolBuyPositionsProfit(
   string symbol,
   ulong magicNumber
);
Gibt den Gesamtgewinn aller offenen Kaufpositionen zurück, die dem angegebenen Symbol und der magischen Zahl entsprechen.
//Get the profit of all buy positions matching symbol and magic number 1
SymbolBuyPositionsProfit(_Symbol, 1);

 
double SymbolSellPositionsProfit(
   string symbol,
   ulong magicNumber
);
Gibt den Gesamtgewinn aller offenen Verkaufspositionen zurück, die dem angegebenen Symbol und der magischen Zahl entsprechen.
//Get the profit of all sell positions matching symbol and magic number 1
SymbolSellPositionsProfit(_Symbol, 1);
 
string AccountPositionsStatus(
   bool formatForComment
);
Druckt einen als Zeichenkette formatierten Status aller offenen Positionen auf dem Symbolchart oder der Registerkarte Experten im MetaTrader5.  
//Print the status of all open positions formatted for the chart comments
AccountPositionsStatus(true);

//Print the status of all open positions formatted for the Experts tab
AccountPositionsStatus(false);
 
string MagicPositionsStatus(
   ulong magicNumber,
   bool formatForComment
);

Druckt einen als Zeichenkette formatierten Status aller offenen Positionen, die mit der angegebenen magischen Zahl übereinstimmen, auf dem Symboldiagramm oder der Registerkarte Experten im MetaTrader5.
//Print the status of all open positions matching
//the magic number 1 formatted for the chart comments
MagicPositionsStatus(1, true);

//Print the status of all open positions matching
//the magic number 1 formatted for the Experts tab
MagicPositionsStatus(1, false);
 
string SymbolPositionsStatus(
   string symbol,
   ulong magicNumber,
   bool formatForComment
);
Druckt einen als Zeichenkette formatierten Status aller offenen Positionen, die mit dem angegebenen Symbol und der magischen Zahl übereinstimmen, auf dem Symboldiagramm oder der Registerkarte Experten im MetaTrader5.
//Print the status of all open positions matching
//the symbol and magic number 1 formatted for the chart comments
SymbolPositionsStatus(_Symbol, 1, true);

//Print the status of all open positions matching
//the symbol and magic number 1 formatted for the Experts tab
SymbolPositionsStatus(_Symbol, 1, false);

Die Integration der Bibliothek in Ihre MQL5-Projekte ist ganz einfach. Befolgen Sie diese beiden Schritte, um PositionsManager.ex5 in Ihren MQL5-Code zu importieren:

  • Schritt 1: Kopieren Sie die ausführbare Bibliotheksdatei PositionsManager.ex5

Platzieren Sie die Datei PositionsManager.ex5 im Verzeichnis MQL5/Bibliotheken/Toolkit. Vergewissern Sie sich, dass Sie diese Datei heruntergeladen und an den angegebenen Ort kopiert haben, falls sie nicht bereits vorhanden ist. Eine Kopie von PositionsManager.ex5 ist am Ende dieses Artikels zu Ihrer Information beigefügt.

  • Schritt 2: Importieren Sie die Beschreibungen der Funktionsprototypen

Fügen Sie die Importdirektiven der Positionsmanager-Bibliothek und ihre Funktionsprototyp-Beschreibungen in den Header-Bereich Ihrer Quellcode-Datei ein. Verwenden Sie das folgende Codesegment, um alle Funktionen oder Module aus der Datei PositionsManager.ex5 Bibliothek zu importieren. Ich habe auch eine leere Expert Advisor-Vorlage (PositionsManager_Imports_Template.mq5) erstellt, die das folgende Codesegment enthält. Sie können gerne selektiv Funktionsbeschreibungen auskommentieren oder entfernen, die Sie für Ihr Projekt nicht benötigen. Die Datei PositionsManager_Imports_Template.mq5 ist ebenfalls am Ende dieses Artikels angehängt.

//+-------------------------------------------------------------------------------------+
//| PositionsManager.ex5 imports template                                               |
//+-------------------------------------------------------------------------------------+
#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();

//-- Position Execution and Modification Functions
bool   OpenBuyPosition(ulong magicNumber, string symbol, double lotSize, int sl, int tp, string positionComment);
bool   OpenSellPosition(ulong magicNumber, string symbol, double lotSize, int sl, int tp, string positionComment);
bool   SetSlTpByTicket(ulong positionTicket, int sl, int tp);
bool   ClosePositionByTicket(ulong positionTicket);
bool   SetTrailingStopLoss(ulong positionTicket, int trailingStopLoss);
bool   CloseAllPositions(string symbol, ulong magicNumber);
bool   CloseAllPositions();
bool   CloseAllBuyPositions(string symbol, ulong magicNumber);
bool   CloseAllSellPositions(string symbol, ulong magicNumber);
bool   CloseAllMagicPositions(ulong magicNumber);
bool   CloseAllProfitablePositions(string symbol, ulong magicNumber);
bool   CloseAllProfitableBuyPositions(string symbol, ulong magicNumber);
bool   CloseAllProfitableSellPositions(string symbol, ulong magicNumber);
bool   CloseAllLossPositions(string symbol, ulong magicNumber);
bool   CloseAllLossBuyPositions(string symbol, ulong magicNumber);
bool   CloseAllLossSellPositions(string symbol, ulong magicNumber);

//-- Position Status Monitoring Functions
int    BuyPositionsTotal();
int    SellPositionsTotal();
double PositionsTotalVolume();
double BuyPositionsTotalVolume();
double SellPositionsTotalVolume();
double BuyPositionsProfit();
double SellPositionsProfit();

//-- Positions Filtered By Magic Number Status Monitoring Functions
int    MagicPositionsTotal(ulong magicNumber);
int    MagicBuyPositionsTotal(ulong magicNumber);
int    MagicSellPositionsTotal(ulong magicNumber);
double MagicPositionsTotalVolume(ulong magicNumber);
double MagicBuyPositionsTotalVolume(ulong magicNumber);
double MagicSellPositionsTotalVolume(ulong magicNumber);
double MagicPositionsProfit(ulong magicNumber);
double MagicBuyPositionsProfit(ulong magicNumber);
double MagicSellPositionsProfit(ulong magicNumber);

//-- Positions Filtered By Symbol and/or Magic Number Status Monitoring Functions
int    SymbolPositionsTotal(string symbol, ulong magicNumber);
int    SymbolBuyPositionsTotal(string symbol, ulong magicNumber);
int    SymbolSellPositionsTotal(string symbol, ulong magicNumber);
double SymbolPositionsTotalVolume(string symbol, ulong magicNumber);
double SymbolBuyPositionsTotalVolume(string symbol, ulong magicNumber);
double SymbolSellPositionsTotalVolume(string symbol, ulong magicNumber);
double SymbolPositionsProfit(string symbol, ulong magicNumber);
double SymbolBuyPositionsProfit(string symbol, ulong magicNumber);
double SymbolSellPositionsProfit(string symbol, ulong magicNumber);

//-- Log and Data Display Functions
string AccountPositionsStatus(bool formatForComment);
string MagicPositionsStatus(ulong magicNumber, bool formatForComment);
string SymbolPositionsStatus(string symbol, ulong magicNumber, bool formatForComment);

#import //--- Closing import directive

Mit der importierten Bibliothek können Sie nun mit einfachen Funktionsaufrufen mühelos Positionsstatusdaten öffnen, schließen, ändern oder abrufen. Um dies zu veranschaulichen, erstellen wir in den folgenden Abschnitten drei grundlegende Expert Advisors.


Entwicklung eines Dual VIDyA Trailing Stop Expert Advisors mit der Positions Manager EX5 Bibliothek

In diesem Abschnitt werden wir einen Expert Advisor für eine Trailing-Stop-Handelsstrategie entwickeln, der auf dem technischen Indikator Variable Index Dynamic Average (VIDyA) basiert. Dies ist ein praktisches Beispiel für die Implementierung der Positions Manager EX5-Bibliothek in einer realen Handelsanwendung.

Die Strategie VIDyA Trailing Stop verwendet ein Paar technischer Indikatoren mit variablem Index und dynamischem Durchschnitt, um Kauf- und Verkaufssignale zu generieren. Da der VIDyA-Indikator als Linie auf dem Chart angezeigt wird, werden wir eine Crossover-Strategie anwenden, um einen neuen Handelseinstieg zu signalisieren. Für eine Crossover-Strategie müssen die Indikatorpaare unterschiedliche Einstellungen haben. Der erste VIDyA-Indikator mit niedrigeren Eingangswerten wird als „schneller VIDyA“ bezeichnet, da er schneller reagiert und Signale erzeugt. Die zweite Variante mit höheren Eingangswerten wird als „langsamer VIDyA“ bezeichnet, da sie langsamer auf Preisänderungen reagiert. Für einen Kauf muss die „schnelle VIDyA“-Linie über der „langsamen VIDyA“-Linie liegen und für einen Verkauf muss die „schnelle VIDyA“-Linie unter der „langsamen VIDyA“-Linie liegen.

Duale VIDyA-Strategie


Erstellen Sie einen neuen Expert Advisor mit dem MetaEditor IDE neue Datei MQL Wizard und nennen es „DualVidyaTrader.mq5“. Da unser Expert Advisor die Bibliothek PositionsManager.ex5 verwenden wird, müssen zunächst die Funktionsprototypbeschreibungen der Bibliothek importiert und eingefügt werden, wie zuvor beschrieben. Platzieren Sie das Codesegment für den Bibliotheksimport unterhalb der #property-Anweisungen. Da die Bibliothek viele Funktionen enthält, werden wir nicht alle importieren oder verwenden; wir importieren nur die Funktionsprototypen, die im folgenden Code aufgeführt sind.

//--- Import the PositionsManager EX5 Library
#import "Toolkit/PositionsManager.ex5" //-- Open the ex5 import directive
//-- Prototype function descriptions of the EX5 PositionsManager library
bool   OpenBuyPosition(ulong magicNumber, string symbol, double lotSize, int sl, int tp, string positionComment);
bool   OpenSellPosition(ulong magicNumber, string symbol, double lotSize, int sl, int tp, string positionComment);
bool   SetTrailingStopLoss(ulong positionTicket, int trailingStopLoss);
int    MagicPositionsTotal(ulong magicNumber);
int    MagicBuyPositionsTotal(ulong magicNumber);
int    MagicSellPositionsTotal(ulong magicNumber);
bool   CloseAllProfitableBuyPositions(string symbol, ulong magicNumber);
bool   CloseAllProfitableSellPositions(string symbol, ulong magicNumber);
string MagicPositionsStatus(ulong magicNumber, bool formatForComment);
#import //-- Close the ex5 import directive

Fügen Sie nach dem Codesegment für den Bibliotheksimport PositionsManager.ex5 die globalen Nutzereingabevariablen wie gezeigt ein.

input group ""
input ulong magicNo = 1234;
input ENUM_TIMEFRAMES timeframe = PERIOD_H1;
input ENUM_APPLIED_PRICE  appliedPrice = PRICE_CLOSE; // Applied VIDyA Price

//-- Fast Vidya user inputs
input group "-- FAST VIDyA INPUTS"
input int fast_cmoPeriod = 5; // Fast Chande Momentum Period
input int fast_maPeriod = 10; // Fast MA Smoothing Period
input int fast_emaShift = 0; // Fast Horizontal Shift

//-- Slow Vidya user inputs
input group "-- SLOW VIDyA INPUTS"
input int slow_cmoPeriod = 9; //  Slow Chande Momentum Period
input int slow_maPeriod = 12; // Slow MA Smoothing Period
input int slow_emaShift = 0; // Slow Horizontal Shift

input group "-- PROFIT MANAGEMENT"
input bool liquidateProfitOnCrossover = false; // Liquidate Profit On VIDyA Signal
input bool enableTrailingStops = true; // Use Trailing Stop Losses

Lassen Sie uns weitere globale Variablen erstellen, um den Stop-Loss, Take-Profit, Trailing-Stop-Loss und Lot- oder Volumenwerte zu speichern.

//-- Get and save the SL, trailingSL and TP values from the spread
int spreadMultiForSl = 1000;
int spreadMultiForTrailingSl = 300;
int spreadMultiForTp = 1000;
int sl = int(SymbolInfoInteger(_Symbol, SYMBOL_SPREAD)) * spreadMultiForSl;
int trailingSl = int(SymbolInfoInteger(_Symbol, SYMBOL_SPREAD)) * spreadMultiForTrailingSl;
int tp = int(SymbolInfoInteger(_Symbol, SYMBOL_SPREAD)) * spreadMultiForTp;

//-- Set the lot or volume to the symbol allowed min value
double lotSize = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);

Legen Sie die Variablen des technischen Indikators VIDyA im globalen Bereich an, um sicherzustellen, dass sie auch von jedem Teil unseres Expert Advisor-Codes aus zugänglich sind.

//-- Vidya indicator variables
double fastVidya[], slowVidya[];
int fastVidyaHandle, slowVidyaHandle;
bool buyOk, sellOk, vidyaBuy, vidyaSell;
string vidyaTrend;

Nach dem Abschnitt über die globalen Variablen erstellen Sie die Initialisierungsfunktion des Expert Advisors, die von der Standardfunktion für die Ereignisbehandlung MQL5 OnInit() aufgerufen wird, die zum ersten Mal beim Start oder der Initialisierung des Expert Advisors ausgeführt wird. Benennen Sie diese Funktion GetInit(). In dieser Funktion führen wir alle Dateninitialisierungen durch, einschließlich der Initialisierung des VIDyA-Indikators und der Handhabung der Start-up-Verarbeitung.

int GetInit()
  {
   int returnVal = 1;

//-- Helps to regulate and prevent openning multiple trades on a single signal trigger
   buyOk = true;
   sellOk = true;

//-- Create the fast iVIDyA indicator handle
   fastVidyaHandle = iVIDyA(_Symbol, timeframe, fast_cmoPeriod, fast_maPeriod, fast_emaShift, appliedPrice);
   if(fastVidyaHandle < 0)
     {
      Print("Error creating fastVidyaHandle = ", INVALID_HANDLE);
      Print("Handle creation: Runtime error = ", GetLastError());
      //-- Close the EA if the handle is not properly loaded
      return(-1);
     }
   ArraySetAsSeries(fastVidya, true); //-- set the vidya array to series access

//-- Create the slow iVIDyA indicator handle
   slowVidyaHandle = iVIDyA(_Symbol, timeframe, slow_cmoPeriod, slow_maPeriod, slow_emaShift, appliedPrice);
   if(slowVidyaHandle < 0)
     {
      Print("Error creating vidyaHandle = ", INVALID_HANDLE);
      Print("Handle creation: Runtime error = ", GetLastError());
      //-- Close the EA if the handle is not properly loaded
      return(-1);
     }
   ArraySetAsSeries(slowVidya, true); //-- set the vidya array to series access

   return(returnVal);
  }

Nach der Initialisierungsfunktion erstellen Sie die Deinitialisierungsfunktion mit dem Namen GetDeinit(). Diese Funktion wird innerhalb der standardmäßigen MQL5 Ereignisbehandlungsfunktion OnDeinit() aufgerufen, um eine systemweite Bereinigung aller von unserem Expert Advisor verwendeten Ressourcen durchzuführen. Dies beinhaltet das Freigeben des VIDyA-Indikators, das Freigeben aller mit den Handle-Arrays des Indikators verbundenen Ressourcen und das Entfernen aller Chart-Kommentare oder Objekte.

void GetDeinit()  //-- De-initialize the robot on shutdown and clean everything up
  {
//-- Delete the vidya handles and de-allocate the memory spaces occupied
   IndicatorRelease(fastVidyaHandle);
   ArrayFree(fastVidya);
   IndicatorRelease(slowVidyaHandle);
   ArrayFree(slowVidya);

//-- Delete and clear all chart displayed messages
   Comment("");
  }

Als Nächstes müssen wir eine nutzerdefinierte Funktion erstellen, um die von unserem Indikatorpaar VIDyA generierten Handelssignale zu erkennen und abzurufen. Diese Funktion wird GetVidya() genannt. Sie wird jedes Mal ausgeführt und aktualisiert, wenn ein neuer Tick eintrifft, um sicherzustellen, dass die Signalerzeugung genau und in Echtzeit erfolgt.

void GetVidya()
  {
//-- Get vidya line directions
   if(CopyBuffer(fastVidyaHandle, 0, 0, 100, fastVidya) <= 0 || CopyBuffer(slowVidyaHandle, 0, 0, 100, slowVidya) <= 0)
     {
      return;
     }

//-- Reset vidya status variables
   vidyaBuy = false;
   vidyaSell = false;
   vidyaTrend = "FLAT";

//-- Scan for vidya crossover buy signal
   if(fastVidya[1] > slowVidya[1])
     {
      //-- Save the vidya signal
      vidyaTrend = "BUY/LONG";
      vidyaBuy = true;
      vidyaSell = false;
     }

//-- Scan for vidya crossover sell signal
   if(fastVidya[1] < slowVidya[1])
     {
      //-- Save the vidya signal
      vidyaTrend = "SELL/SHORT";
      vidyaSell = true;
      vidyaBuy = false;
     }
  }

Nachdem wir nun die Funktion zum Abrufen und Aktualisieren des VIDyA-Signals erstellt haben, wollen wir eine weitere nutzerdefinierte Funktion erstellen, die bei jedem neuen Tick ausgeführt wird, um neue Positionen auf der Grundlage des aktuellen VIDyA-Signals zu scannen und zu eröffnen. Diese Funktion wird ScanForTradeOpportunities() genannt. In dieser Funktion werden die aus der Bibliothek PositionsManager.ex5 importierten Prototyp-Funktionen für das Öffnen und den Status von Positionen aufgerufen und ausgeführt.

void ScanForTradeOpportunities()
  {
//-- Get the VIDyA signal
   GetVidya();

   if(MagicPositionsTotal(magicNo) == 0)
     {
      buyOk = true;
      sellOk = true;
     }

//-- Check for a buy entry when a VIDyA buy signal is found
   if(buyOk && vidyaBuy) //-- Open a new buy position
     {
      if(OpenBuyPosition(magicNo, _Symbol, lotSize, sl, tp, "Vidya_BUY: " + IntegerToString(MagicBuyPositionsTotal(magicNo) + 1)))
        {
         buyOk = false;
         sellOk = true;
        }
      //-- Market has a strong buy trend, close all profitable sell positions
      if(liquidateProfitOnCrossover)
        {
         CloseAllProfitableSellPositions(_Symbol, magicNo);
        }
     }

//-- Check for a sell entry when a VIDyA sell signal is found
   if(sellOk && vidyaSell) //-- Open a new sell position
     {
      if(OpenSellPosition(magicNo, _Symbol, lotSize, sl, tp, "Vidya_SELL: " + IntegerToString(MagicSellPositionsTotal(magicNo) + 1)))
        {
         sellOk = false;
         buyOk = true;
        }
      //-- Market has a strong sell trend, close all profitable buy positions
      if(liquidateProfitOnCrossover)
        {
         CloseAllProfitableBuyPositions(_Symbol, magicNo);
        }
     }
  }

Außerdem müssen wir alle offenen Positionen überprüfen und einen Trainling-Stop-Loss setzen. Das ist ganz einfach, denn unsere Bibliothek PositionsManager.ex5 enthält eine Prototyp-Funktion für den Trailing-Stop-Loss, die uns dabei hilft. Erstellen wir eine neue Funktion mit dem Namen CheckAndSetTrailingSl(), um alle offenen Positionen zu scannen und ihre Tickets zur Verwendung als Parameter in der importierten Prototyp-Funktion SetTrailingStopLoss() abzurufen.

void CheckAndSetTrailingSl()
  {
   int totalOpenPostions = PositionsTotal();
   for(int x = 0; x < totalOpenPostions; x++)
     {
      //--- Get position properties
      ulong  positionTicket = PositionGetTicket(x); //-- Get ticket to select the position
      string selectedSymbol = PositionGetString(POSITION_SYMBOL);
      ulong positionMagicNo = PositionGetInteger(POSITION_MAGIC);
      int positionType = int(PositionGetInteger(POSITION_TYPE));

      //-- modify only the positions we have opened with this EA (magic number)
      if(selectedSymbol != _Symbol && positionMagicNo != magicNo)
        {
         continue;
        }
      //-- Only set the trailing stop loss when the market trend is in the opposing direction of the position type
      if((positionType == POSITION_TYPE_BUY && vidyaBuy) || (positionType == POSITION_TYPE_SELL && vidyaSell))
        {
         continue;
        }
      //--- set the trailing stop loss
      SetTrailingStopLoss(positionTicket, trailingSl); //-- call the imported function from our ex5 library
     }
  }

Nachdem wir nun alle wichtigen Module für unseren Expert Advisor erstellt haben, wollen wir sie in der MQL5-Funktion OnTick() zusammenführen, die bei jedem neuen Tick ausgeführt wird. Ordnen Sie sie in der unten angegebenen Reihenfolge an, um sicherzustellen, dass sie unser Handelssystem systematisch in der richtigen Reihenfolge ausführen.

void OnTick()
  {
//-- Scan and open new positions based on the vidya signal
   ScanForTradeOpportunities();

//-- Check and set the trailing stop
   if(enableTrailingStops)
     {
      CheckAndSetTrailingSl();
     }

//-- Display the vidya trend and positions status for the EA's magicNo
   Comment(
      "\nvidyaTrend: ", vidyaTrend,
      MagicPositionsStatus(magicNo, true)
   );
  }

Vergessen Sie schließlich nicht, die Initialisierungs- und De-Initialisierungsfunktionen in ihre jeweiligen Standard-MQL5-Ereignisbehandlungsfunktionen zu integrieren.

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   if(GetInit() <= 0)
     {
      return(INIT_FAILED);
     }
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   GetDeinit();
  }

Sie können die Quellcode-Datei für den DualVidyaTrader.mq5 Expert Advisor am Ende dieses Artikels aufrufen und herunterladen. Ich habe die vollständige Quellcodedatei beigefügt, um sicherzustellen, dass Sie alle notwendigen Komponenten haben, um die Handelsstrategie zu implementieren und nach Bedarf anzupassen.

Wenn Sie unseren neuen Expert Advisor DualVidyaTrader in MetaTrader 5 kompilieren und laden, werden Sie feststellen, dass auf der Registerkarte „Dependencies“ alle Funktionsprototypen der Bibliothek, die aus PositionsManager.ex5 importiert wurden, zusammen mit dem vollständigen Dateipfad, in dem die EX5-Bibliothek gespeichert ist, aufgeführt sind. Dadurch wird sichergestellt, dass alle erforderlichen Abhängigkeiten korrekt referenziert werden, bevor der Expert Advisor in den Chart geladen wird. Wenn Fehler bei der Referenzierung von Bibliotheken auftreten, wie sie weiter oben im Artikel beschrieben wurden, werden diese in den Registerkarten Experten oder Journal des MetaTrader 5 Toolbox-Fensters protokolliert.

Registerkarte der Dependencies von Dual Vidya


Das Handelspanel PositionsManager unterstützt von der Bibliothek Positions Manager EX5

In diesem zweiten Beispiel erstellen wir ein einfaches Expert Advisor-Handelspanel mit grafischer Nutzeroberfläche (GUI), das ebenfalls auf unserer PositionsManager.ex5-Bibliothek basiert.

Positionsmanager-Panel GUI


Wir erstellen einen neuen Expert Advisor mit der neuen Datei MQL Wizard von MetaEditor IDE und nennen ihn PositionsManagerPanel.mq5. Unter dem Codesegment #property directives importieren wir die Bibliothek PositionsManager.ex5. Importieren wir im Abschnitt Beschreibungen der Importfunktionen nur die folgenden Funktionsprototypen.

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

//--Position Execution and Modification Functions
bool   OpenBuyPosition(ulong magicNumber, string symbol, double lotSize, int sl, int tp, string positionComment);
bool   OpenSellPosition(ulong magicNumber, string symbol, double lotSize, int sl, int tp, string positionComment);
bool   SetSlTpByTicket(ulong positionTicket, int sl, int tp);
bool   ClosePositionByTicket(ulong positionTicket);
bool   SetTrailingStopLoss(ulong positionTicket, int trailingStopLoss);
bool   CloseAllPositions(string symbol, ulong magicNumber);
bool   CloseAllBuyPositions(string symbol, ulong magicNumber);
bool   CloseAllSellPositions(string symbol, ulong magicNumber);
bool   CloseAllMagicPositions(ulong magicNumber);
bool   CloseAllProfitablePositions(string symbol, ulong magicNumber);
bool   CloseAllLossPositions(string symbol, ulong magicNumber);

//--Position Status Monitoring Functions
int    BuyPositionsTotal();
int    SellPositionsTotal();
double PositionsTotalVolume();
double BuyPositionsTotalVolume();
double SellPositionsTotalVolume();
double BuyPositionsProfit();
double SellPositionsProfit();
int    MagicPositionsTotal(ulong magicNumber);
int    MagicBuyPositionsTotal(ulong magicNumber);
int    MagicSellPositionsTotal(ulong magicNumber);
double MagicPositionsTotalVolume(ulong magicNumber);
double MagicBuyPositionsTotalVolume(ulong magicNumber);
double MagicSellPositionsTotalVolume(ulong magicNumber);
double MagicPositionsProfit(ulong magicNumber);
double MagicBuyPositionsProfit(ulong magicNumber);
double MagicSellPositionsProfit(ulong magicNumber);
int    SymbolPositionsTotal(string symbol, ulong magicNumber);
int    SymbolBuyPositionsTotal(string symbol, ulong magicNumber);
int    SymbolSellPositionsTotal(string symbol, ulong magicNumber);
double SymbolPositionsTotalVolume(string symbol, ulong magicNumber);
double SymbolBuyPositionsTotalVolume(string symbol, ulong magicNumber);
double SymbolSellPositionsTotalVolume(string symbol, ulong magicNumber);
double SymbolPositionsProfit(string symbol, ulong magicNumber);
double SymbolBuyPositionsProfit(string symbol, ulong magicNumber);
double SymbolSellPositionsProfit(string symbol, ulong magicNumber);
string AccountPositionsStatus(bool formatForComment);
string MagicPositionsStatus(ulong magicNumber, bool formatForComment);
string SymbolPositionsStatus(string symbol, ulong magicNumber, bool formatForComment);
#import //--- Close import directive

Das PositionsManagerPanel.mq5 wird nur eine Nutzereingabe (magische Zahl) enthalten.

//--User input variables
input ulong magicNo = 101010;

Als Nächstes erstellen wir die globalen Variablen zum Speichern von volumeLot, sl und tp.

//-- Global variables
//-----------------------
//-- Get the current symbol spread and multiply it by a significant number
//-- to simulate user-input SL and TP values
double volumeLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
int sl = (int)SymbolInfoInteger(_Symbol, SYMBOL_SPREAD) * 50;
int tp = (int)SymbolInfoInteger(_Symbol, SYMBOL_SPREAD) * 100;

Lassen Sie uns unser erstes grafisches Objekt erstellen, das als Hintergrund für unsere grafische Nutzeroberfläche dienen wird. Wir werden zu diesem Zweck ein rechteckiges Etikett verwenden. Um dies zu erreichen, erstellen wir eine nutzerdefinierte Funktion namens CreateRectangleLabel().

//+-----------------------------------------------------------------------+
//| CreateRectangleLabel(): Creates a rectangle label on the chart window |
//+-----------------------------------------------------------------------+
void CreateRectangleLabel()
  {
//--- Detect if we have an object named the same as our rectangle label
   if(ObjectFind(0, "mainRectangleLabel") >= 0)
     {
      //--- Delete the specified object if it is not a rectangle label
      if(ObjectGetInteger(0, "mainRectangleLabel", OBJPROP_TYPE) != OBJ_RECTANGLE_LABEL)
        {
         ObjectDelete(0, "mainRectangleLabel");
        }
     }
   else
     {
      //-- Create the mainRectangleLabel
      ObjectCreate(0, "mainRectangleLabel", OBJ_RECTANGLE_LABEL, 0, 0, 0);
     }
//--- Set up the new rectangle label properties
   ObjectSetInteger(0, "mainRectangleLabel", OBJPROP_CORNER, CORNER_LEFT_UPPER);
   ObjectSetInteger(0, "mainRectangleLabel", OBJPROP_XDISTANCE, 240);
   ObjectSetInteger(0, "mainRectangleLabel", OBJPROP_YDISTANCE, 2);
   ObjectSetInteger(0, "mainRectangleLabel", OBJPROP_XSIZE, 460);
   ObjectSetInteger(0, "mainRectangleLabel", OBJPROP_YSIZE, 520);
   ObjectSetInteger(0, "mainRectangleLabel", OBJPROP_BGCOLOR, clrMintCream);
   ObjectSetInteger(0, "mainRectangleLabel", OBJPROP_BACK, false);
   ObjectSetInteger(0, "mainRectangleLabel", OBJPROP_HIDDEN, true);
  }

Wir brauchen auch Kennungen, um Text in unserem Handelsbereich anzuzeigen. Wir werden eine weitere nutzerdefinierte Funktion namens CreateLabel() erstellen, um diese Aufgabe zu erledigen.

//+---------------------------------------------------------+
//| CreateLabel(): Creates a text label on the chart window |
//+---------------------------------------------------------+
void CreateLabel(
   string labelName, int xDistance, int yDistance, int xSize, int ySize,
   string labelText, color textColor, string fontType, int fontSize
)
  {
//--- Detect if we have an object with the same name as our label
   if(ObjectFind(0, labelName) >= 0)
     {
      //--- Delete the specified object if it is not a label
      if(ObjectGetInteger(0, labelName, OBJPROP_TYPE) != OBJ_LABEL)
        {
         ObjectDelete(0, labelName);
        }
     }
   else
     {
      //-- Create the label
      ObjectCreate(0, labelName, OBJ_LABEL, 0, 0, 0);
     }
//--- Set up the new rectangle label properties
   ObjectSetInteger(0, labelName, OBJPROP_CORNER, CORNER_LEFT_UPPER);
   ObjectSetInteger(0, labelName, OBJPROP_XDISTANCE, xDistance);
   ObjectSetInteger(0, labelName, OBJPROP_YDISTANCE, yDistance);
   ObjectSetInteger(0, labelName, OBJPROP_XSIZE, xSize);
   ObjectSetInteger(0, labelName, OBJPROP_YSIZE, ySize);
   ObjectSetString(0, labelName, OBJPROP_TEXT, labelText);
   ObjectSetInteger(0, labelName, OBJPROP_COLOR, textColor);
   ObjectSetString(0, labelName, OBJPROP_FONT, fontType);
   ObjectSetInteger(0, labelName, OBJPROP_FONTSIZE, fontSize);
   ObjectSetInteger(0, labelName, OBJPROP_BACK, false);
   ObjectSetInteger(0, labelName, OBJPROP_HIDDEN, true);
   ObjectSetInteger(0, labelName, OBJPROP_SELECTABLE, false);
   ObjectSetInteger(0, labelName, OBJPROP_SELECTED, false);
  }

Anklickbare oder reaktionsfähige Schaltflächen werden für unser Handels-Panel benötigt, um verschiedene Handelsoperationen durchzuführen. Daher müssen wir eine nutzerdefinierte Funktion für die Erstellung von Schaltflächen erstellen. Rufen wir diese Funktion CreateButton() auf.

//+------------------------------------------------------+
//| CreateButton(): Creates buttons on the chart window  |
//+------------------------------------------------------+
void CreateButton(
   string btnName, int xDistance, int yDistance, int xSize, int ySize, string btnText,
   string tooltip, color textColor, string fontType, int fontSize, color bgColor
)
  {
//--- Detect if we have an object named the same as our button
   if(ObjectFind(0, btnName) >= 0)
     {
      //--- Delete the specified object if it is not a button
      if(ObjectGetInteger(0, btnName, OBJPROP_TYPE) != OBJ_BUTTON)
        {
         ObjectDelete(0, btnName);
        }
     }
   else
     {
      //-- Create the button
      ObjectCreate(0, btnName, OBJ_BUTTON, 0, 0, 0);
     }
//--- Set up the new button properties
   ObjectSetInteger(0, btnName, OBJPROP_CORNER, CORNER_LEFT_UPPER);
   ObjectSetInteger(0, btnName, OBJPROP_XDISTANCE, xDistance);
   ObjectSetInteger(0, btnName, OBJPROP_YDISTANCE, yDistance);
   ObjectSetInteger(0, btnName, OBJPROP_XSIZE, xSize);
   ObjectSetInteger(0, btnName, OBJPROP_YSIZE, ySize);
   ObjectSetString(0, btnName, OBJPROP_TEXT, btnText);
   ObjectSetString(0, btnName, OBJPROP_TOOLTIP, tooltip);
   ObjectSetInteger(0, btnName, OBJPROP_COLOR, textColor);
   ObjectSetString(0, btnName, OBJPROP_FONT, fontType);
   ObjectSetInteger(0, btnName, OBJPROP_FONTSIZE, fontSize);
   ObjectSetInteger(0, btnName, OBJPROP_BGCOLOR, bgColor);
  }

Wir benötigen nun eine weitere nutzerdefinierte Funktion, um alle verschiedenen Chartobjekte und grafischen Komponenten mit Nutzereingaben zu laden, die mit den oben beschriebenen Funktionen erstellt wurden. Rufen wir diese Funktion LoadChartObjects() auf.

//+--------------------------------------------------------------------+
//| LoadChartObjects(): Create and load the buttons and chart objects  |
//| for demonstrating how the imported library functions work          |
//+--------------------------------------------------------------------+
void LoadChartObjects()
  {
//-- Create the rectangle label first
   CreateRectangleLabel();

//-- Create the heading label
   CreateLabel(
      "headingLabel", 250, 10, 440, 60,
      "PositionsManager ex5 Library Demo Trade Panel",
      clrMidnightBlue, "Calibri", 10
   );

//-- Create the second heading label
   CreateLabel(
      "headingLabel2", 250, 30, 440, 60,
      ("Trading " + _Symbol + " with Magic Number: " + (string)magicNo),
      clrBlack, "Consolas", 11
   );

//-- "BUY": Button to call the imported ex5 OpenBuyPosition() function
   CreateButton(
      "OpenBuyPositionBtn", 250, 50, 215, 35, "BUY",
      "OpenBuyPosition() Function", clrMintCream, "Arial Black", 10, clrDodgerBlue
   );

//-- "SELL": Button to call the imported ex5 OpenSellPosition() function
   CreateButton(
      "OpenSellPositionBtn", 475, 50, 215, 35, "SELL",
      "OpenSellPosition() Function", clrMintCream, "Arial Black", 10, clrCrimson
   );

//-- "SetSlTpByTicket": Button to call the imported ex5 SetSlTpByTicket() function
   CreateButton(
      "SetSlTpBtn", 250, 90, 215, 35, "SetSlTpByTicket",
      "SetSlTpByTicket() Function", clrMintCream, "Arial Black", 10, clrDarkSlateGray
   );

//-- "SetTrailingStopLoss": Button to call the imported ex5 SetTrailingStopLoss() function when clicked
   CreateButton(
      "SetTrailingStopLossBtn", 475, 90, 215, 35, "SetTrailingStopLoss",
      "SetTrailingStopLoss Function", clrMintCream, "Arial Black", 10, clrDarkSlateGray
   );

//-- "ClosePositionsByTicket": Button to call the imported ex5 ClosePositionByTicket() function
   CreateButton(
      "ClosePositionsBtn", 250, 130, 215, 35, "ClosePositionsByTicket",
      "ClosePositionByTicket() Function", clrMintCream, "Arial Black", 10, clrMaroon
   );

//-- "CloseAllSymbolPositions": Button to call the imported ex5 CloseAllSymbolPositions() function
   CreateButton(
      "CloseAllPositionsBtn", 475, 130, 215, 35, "CloseAllPositions",
      "CloseAllPositions() Function", clrMintCream, "Arial Black", 10, clrMaroon
   );

//-- "CloseAllBuySymbolPositions": Button to call the imported ex5 CloseAllBuySymbolPositions() function
   CreateButton(
      "CloseAllBuyPositionsBtn", 250, 170, 215, 35, "CloseAllBuyPositions",
      "CloseAllBuyPositions() Function", clrMintCream, "Arial Black", 10, clrBrown
   );

//-- "CloseAllSellSymbolPositions": Button to call the imported ex5 CloseAllSellSymbolPositions() function
   CreateButton(
      "CloseAllSellPositionsBtn", 475, 170, 215, 35, "CloseAllSellPositions",
      "CloseAllSellPositions() Function", clrMintCream, "Arial Black", 10, clrBrown
   );

//-- "CloseAllMagicPositions": Button to call the imported ex5 CloseAllMagicPositions() function
   CreateButton(
      "CloseAllMagicPositionsBtn", 250, 210, 440, 35, "CloseAllMagicPositions",
      "CloseAllMagicPositions() Function", clrMintCream, "Arial Black", 10, C'203,18,55'
   );

//-- "CloseAllProfitablePositions": Button to call the imported ex5 CloseAllMagicPositions() function
   CreateButton(
      "CloseAllProfitablePositionsBtn", 250, 250, 215, 35, "CloseAllProfitablePositions",
      "CloseAllProfitablePositions() Function", clrMintCream, "Arial Black", 10, clrSeaGreen
   );

//-- "CloseAllLossPositions": Button to call the imported ex5 CloseAllLossPositions() function
   CreateButton(
      "CloseAllLossPositionsBtn", 475, 250, 215, 35, "CloseAllLossPositions",
      "CloseAllLossPositions() Function", clrMintCream, "Arial Black", 10, C'179,45,0'
   );

//-- Create the bottomHeadingLabel
   CreateLabel(
      "bottomHeadingLabel", 250, 310, 440, 60,
      (_Symbol + " - (Magic Number: " + (string)magicNo + ") Positions Status"),
      clrBlack, "Calibri", 12
   );

//-- Create totalOpenPositionsLabel
   CreateLabel(
      "totalOpenPositionsLabel", 250, 340, 440, 60,
      ("  Total Open:   " + (string)MagicPositionsTotal(magicNo)),
      clrNavy, "Consolas", 11
   );

//-- Create totalPositionsVolumeLabel
   CreateLabel(
      "totalPositionsVolumeLabel", 250, 360, 440, 60,
      ("  Total Volume: " + (string)NormalizeDouble(MagicPositionsTotalVolume(magicNo), 2)),
      clrNavy, "Consolas", 11
   );

//-- Create the totalPositionsProfitLabel
   CreateLabel(
      "totalPositionsProfitLabel", 250, 380, 100, 60,
      (
         "  Total Profit: " + (string)(NormalizeDouble(MagicPositionsProfit(magicNo), 2)) +
         " " + AccountInfoString(ACCOUNT_CURRENCY)
      ),
      clrNavy, "Consolas", 11
   );

//-- Create the buyPositionsHeadingLabel
   CreateLabel(
      "buyPositionsHeadingLabel", 250, 410, 440, 60,
      ("BUY POSITIONS:"),
      clrBlack, "Calibri", 12
   );

//-- Create the totalBuyPositionsLabel
   CreateLabel(
      "totalBuyPositionsLabel", 250, 430, 440, 60,
      ("  Total Open:   " + (string)MagicBuyPositionsTotal(magicNo)),
      clrNavy, "Consolas", 11
   );

//-- Create the totalBuyPositionsVolumeLabel
   CreateLabel(
      "totalBuyPositionsVolumeLabel", 250, 450, 440, 60,
      ("  Total Volume: " + (string)NormalizeDouble(MagicBuyPositionsTotalVolume(magicNo), 2)),
      clrNavy, "Consolas", 11
   );

//-- Create the totalBuyPositionsProfitLabel
   CreateLabel(
      "totalBuyPositionsProfitLabel", 250, 470, 440, 60,
      (
         "  Total Profit: " + (string)(NormalizeDouble(MagicBuyPositionsProfit(magicNo), 2)) +
         " " + AccountInfoString(ACCOUNT_CURRENCY)
      ),
      clrNavy, "Consolas", 11
   );

//-- Create the sellPositionsHeadingLabel
   CreateLabel(
      "sellPositionsHeadingLabel", 475, 410, 440, 60,
      ("SELL POSITIONS:"),
      clrBlack, "Calibri", 12
   );

//-- Create the totalSellPositionsLabel
   CreateLabel(
      "totalSellPositionsLabel", 475, 430, 440, 60,
      ("  Total Open:   " + (string)MagicSellPositionsTotal(magicNo)),
      clrNavy, "Consolas", 11
   );

//-- Create the totalSellPositionsVolumeLabel
   CreateLabel(
      "totalSellPositionsVolumeLabel", 475, 450, 440, 60,
      ("  Total Volume: " + (string)NormalizeDouble(MagicSellPositionsTotalVolume(magicNo), 2)),
      clrNavy, "Consolas", 11
   );

//-- Create the totalSellPositionsProfitLabel
   CreateLabel(
      "totalSellPositionsProfitLabel", 475, 470, 100, 60,
      (
         "  Total Profit: " + (string)(NormalizeDouble(MagicSellPositionsProfit(magicNo), 2)) +
         " " + AccountInfoString(ACCOUNT_CURRENCY)
      ),
      clrNavy, "Consolas", 11
   );

//--- Redraw the chart to refresh it so that it loads our new chart objects
   ChartRedraw();
//---
  }

Diese nächste nutzerdefinierte Funktion ist für das Aufräumen und Löschen aller Chartobjekte und Daten verantwortlich, wenn der Expert Advisor beendet oder de-initialisiert wird. Nennen wir sie DeleteChartObjects(). Sie wird in der MQL5-Standardfunktion OnDeinit() zur Ereignisbehandlung platziert und ausgeführt.

//+------------------------------------------------------------------------------+
//| DeleteChartObjects(): Delete all the chart objects when the EA is terminated |
//| on De-initialization                                                         |
//+------------------------------------------------------------------------------+
void DeleteChartObjects()
  {
//---
//--- Clean up and delete all the buttons or graphical objects
   ObjectDelete(0, "OpenBuyPositionBtn");
   ObjectDelete(0, "OpenSellPositionBtn");
   ObjectDelete(0, "SetSlTpBtn");
   ObjectDelete(0, "SetTrailingStopLossBtn");
   ObjectDelete(0, "ClosePositionsBtn");
   ObjectDelete(0, "CloseAllPositionsBtn");
   ObjectDelete(0, "CloseAllBuyPositionsBtn");
   ObjectDelete(0, "CloseAllSellPositionsBtn");
   ObjectDelete(0, "CloseAllMagicPositionsBtn");
   ObjectDelete(0, "CloseAllProfitablePositionsBtn");
   ObjectDelete(0, "CloseAllLossPositionsBtn");
   ObjectDelete(0, "mainRectangleLabel");

   ObjectDelete(0, "headingLabel");
   ObjectDelete(0, "headingLabel2");

   ObjectDelete(0, "bottomHeadingLabel");
   ObjectDelete(0, "totalOpenPositionsLabel");
   ObjectDelete(0, "totalPositionsVolumeLabel");
   ObjectDelete(0, "totalPositionsProfitLabel");

   ObjectDelete(0, "buyPositionsHeadingLabel");
   ObjectDelete(0, "totalBuyPositionsLabel");
   ObjectDelete(0, "totalBuyPositionsVolumeLabel");
   ObjectDelete(0, "totalBuyPositionsProfitLabel");

   ObjectDelete(0, "sellPositionsHeadingLabel");
   ObjectDelete(0, "totalSellPositionsLabel");
   ObjectDelete(0, "totalSellPositionsVolumeLabel");
   ObjectDelete(0, "totalSellPositionsProfitLabel");
  }

Nachdem wir nun die Erstellung und Verwaltung der grafischen Objekte abgeschlossen haben, erstellen wir die nutzerdefinierten Funktionen, die einige der importierten Funktionen aus der Bibliothek PositionsManager.ex5 implementieren werden. Die erste Funktion dieser Gruppe, die wir ModifySlTp() nennen, ist für die Änderung des Stop-Loss (sl) und des Take-Profits (tp) aller von diesem Expert Advisor eröffneten Positionen verantwortlich, die mit der vom Nutzer eingegebenen magischen Zahl übereinstimmen. Diese Funktion wird jedes Mal ausgeführt, wenn die Schaltfläche setSLTP im Chart angeklickt wird.

//+-------------------------------------------------------------------------+
// ModifySlTp(): This function demonstrates how to use the imported ex5     |
// bool SetSlTpByTicket(ulong positionTicket, int sl, int tp);              |
// It runs this function when the setSLTP button on the chart is clicked.   |
//+-------------------------------------------------------------------------+
void ModifySlTp()
  {
//-- Get positions that we have openend with the chart buy and sell buttons to test the imported function with
   int totalOpenPostions = PositionsTotal();
//--- Scan open positions
   for(int x = 0; x < totalOpenPostions; x++)
     {
      //--- Get position properties
      ulong  positionTicket = PositionGetTicket(x); //-- Get ticket to select the position
      string selectedSymbol = PositionGetString(POSITION_SYMBOL);
      ulong positionMagicNo = PositionGetInteger(POSITION_MAGIC);

      //-- modify only the positions we have opened with this EA (magic number) using the BUY and SELL buttons on the chart
      if(selectedSymbol != _Symbol && positionMagicNo != magicNo)
        {
         continue;
        }
      //--- modify the sl and tp of the position
      SetSlTpByTicket(positionTicket, sl, tp);//-- call the imported function from our ex5 library
     }
  }

Die nächste Funktion, SetTrailingSl(), ist für die Aktualisierung des Trailing Stop-Loss verantwortlich. Sie wird sowohl ausgeführt, wenn die Schaltfläche SetTrailingStopLoss im Chart angeklickt wird, als auch bei jedem neu eintreffenden Tick in der Ereignisbehandlungsfunktion OnTick().

//+-----------------------------------------------------------------------------------+
// SetTrailingSl(): This function demonstrates how to use the imported ex5            |
// bool SetTrailingStopLoss(ulong positionTicket, int trailingStopLoss);              |
// It runs this function when the SetTrailingStopLoss button on the chart is clicked. |
//+-----------------------------------------------------------------------------------+
void SetTrailingSl()
  {
   int trailingSl = sl;

//-- Get positions that we have openend with the chart buy and sell buttons to test the imported function with
   int totalOpenPostions = PositionsTotal();
//--- Scan open positions
   for(int x = 0; x < totalOpenPostions; x++)
     {
      //--- Get position properties
      ulong  positionTicket = PositionGetTicket(x); //-- Get ticket to select the position
      string selectedSymbol = PositionGetString(POSITION_SYMBOL);
      ulong positionMagicNo = PositionGetInteger(POSITION_MAGIC);

      //-- modify only the positions we have opened with this EA (magic number) using the BUY and SELL buttons on the chart
      if(selectedSymbol != _Symbol && positionMagicNo != magicNo)
        {
         continue;
        }
      //--- set the trailing stop loss
      SetTrailingStopLoss(positionTicket, trailingSl); //-- call the imported function from our ex5 library
     }
  }

Die Funktion ClosePositionWithTicket() ist für das Schließen aller offenen Positionen verantwortlich und wird ausgeführt, wenn die Schaltfläche ClosePositions auf dem Chart gedrückt wird.

//+-----------------------------------------------------------------------------------+
// ClosePositionWithTicket(): This function demonstrates how to use the imported ex5  |
// bool ClosePositionByTicket(ulong positionTicket)                                   |
// It runs this function when the ClosePositions button on the chart is clicked.      |
//+-----------------------------------------------------------------------------------+
void ClosePositionWithTicket()
  {
//-- Get positions that we have openend with the chart buy and sell buttons to test the imported function with
   int totalOpenPostions = PositionsTotal();
//--- Scan open positions
   for(int x = 0; x < totalOpenPostions; x++)
     {
      //--- Get position properties
      ulong  positionTicket = PositionGetTicket(x); //-- Get ticket to select the position
      string selectedSymbol = PositionGetString(POSITION_SYMBOL);
      ulong positionMagicNo = PositionGetInteger(POSITION_MAGIC);

      //-- close only the positions we have opened with this EA (magic number) using the BUY and SELL buttons on the chart
      if(selectedSymbol != _Symbol && positionMagicNo != magicNo)
        {
         continue;
        }

      //--- Close the position
      ClosePositionByTicket(positionTicket);//-- call the imported function from our ex5 library
     }
  }

Die letzte Funktion ist die Standard-MQL5-Funktion OnChartEvent(), die erkennt, wenn unsere verschiedenen Schaltflächen gedrückt werden, und die entsprechenden Aktionen ausführt. Fast alle importierten Positionsmanagement-Funktionen aus der PositionsManager.ex5-Bibliothek werden von dieser Funktion aus aufgerufen und ausgeführt.

//+------------------------------------------------------------------+
//| ChartEvent function to detect when the buttons are clicked       |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//---
//--- Detected a CHARTEVENT_CLICK event
   if(id == CHARTEVENT_OBJECT_CLICK)
     {
      Print(__FUNCTION__, ": ", sparam);

      //--- Buy when OpenBuyPositionBtn button (BUY) is pressed or clicked
      if(sparam == "OpenBuyPositionBtn")
        {
         //-- Call our imported function from the Toolkit/PositionsManager ex5 library
         OpenBuyPosition(magicNo, _Symbol, volumeLot, sl, tp, "ex5 PositionsManager");

         //--- Release and unpress the button
         ObjectSetInteger(0, "OpenBuyPositionBtn", OBJPROP_STATE, false);
        }

      //--- Sell when OpenSellPositionBtn button (SELL) is pressed
      if(sparam == "OpenSellPositionBtn")
        {
         //-- Call our imported function from the Toolkit/PositionsManager ex5 library
         OpenSellPosition(magicNo, _Symbol, volumeLot, sl, tp, "ex5 PositionsManager");
         //OpenSellPosition(magicNo, "NON-EXISTENT-Symbol-Name"/*_Symbol*/, volumeLot, sl, tp, "ex5 PositionsManager");

         //--- Release and unpress the button
         ObjectSetInteger(0, "OpenSellPositionBtn", OBJPROP_STATE, false);
        }

      //--- Modify specified positions SL and TP when SetSlTpBtn button (setSLTP) is pressed
      if(sparam == "SetSlTpBtn")
        {
         ModifySlTp();//-- Modify the SL and TP of the positions generated by the BUY and SELL buttons
         //--- Release and unpress the button
         ObjectSetInteger(0, "SetSlTpBtn", OBJPROP_STATE, false);
        }

      //--- Set the Trailing Stop Loss when SetSlTpBtn button (SetTrailingStopLossBtn) is pressed
      if(sparam == "SetTrailingStopLossBtn")
        {
         SetTrailingSl();//-- Set the Trailing Stop Loss for the positions generated by the BUY and SELL buttons
         //--- Release and unpress the button
         ObjectSetInteger(0, "SetTrailingStopLossBtn", OBJPROP_STATE, false);
        }

      //--- Close specified positions when SetSlTpBtn button (setSLTP) is pressed
      if(sparam == "ClosePositionsBtn")
        {
         ClosePositionWithTicket();//-- Close all the positions generated by the BUY and SELL buttons
         //--- Release and unpress the button
         ObjectSetInteger(0, "ClosePositionsBtn", OBJPROP_STATE, false);
        }

      //--- Close all positions for the current symbol when the CloseAllPositionsBtn button is pressed
      if(sparam == "CloseAllPositionsBtn")
        {
         CloseAllPositions(_Symbol, 0);//-- Close all the open symbol positions
         //--- Release and unpress the button
         ObjectSetInteger(0, "CloseAllPositionsBtn", OBJPROP_STATE, false);
        }

      //--- Close all buy positions for the current symbol when the CloseAllBuyPositionsBtn button is pressed
      if(sparam == "CloseAllBuyPositionsBtn")
        {
         CloseAllBuyPositions(_Symbol, magicNo);//-- Close all the open symbol buy positions
         //--- Release and unpress the button
         ObjectSetInteger(0, "CloseAllBuyPositionsBtn", OBJPROP_STATE, false);
        }

      //--- Close all sell positions for the current symbol when the CloseAllSellPositionsBtn button is pressed
      if(sparam == "CloseAllSellPositionsBtn")
        {
         CloseAllSellPositions(_Symbol, magicNo);//-- Close all the open symbol sell positions
         //--- Release and unpress the button
         ObjectSetInteger(0, "CloseAllSellPositionsBtn", OBJPROP_STATE, false);
        }

      //--- Close all positions with the specified magic number when the CloseAllMagicPositionsBtn button is pressed
      if(sparam == "CloseAllMagicPositionsBtn")
        {
         CloseAllMagicPositions(magicNo);//-- Close all the open positions with the specified magic number
         //--- Release and unpress the button
         ObjectSetInteger(0, "CloseAllMagicPositionsBtn", OBJPROP_STATE, false);
        }

      //--- Close all profitable positions with the specified symbol and magic number when the CloseAllProfitablePositionsBtn button is pressed
      if(sparam == "CloseAllProfitablePositionsBtn")
        {
         CloseAllProfitablePositions(_Symbol, magicNo);//-- Close all the open profitable positions with the specified symbol and magic number
         //--- Release and unpress the button
         ObjectSetInteger(0, "CloseAllProfitablePositionsBtn", OBJPROP_STATE, false);
        }

      //--- Close all loss positions with the specified symbol and magic number when the CloseAllLossPositionsBtn button is pressed
      if(sparam == "CloseAllLossPositionsBtn")
        {
         CloseAllLossPositions(_Symbol, magicNo);//-- Close all the open loss positions with the specified symbol and magic number
         //--- Release and unpress the button
         ObjectSetInteger(0, "CloseAllLossPositionsBtn", OBJPROP_STATE, false);
        }

      //--- Redraw the chart to refresh it
      ChartRedraw();
     }
//---
  }

Bevor wir den Expert Advisor PositionsTradePanel.mq5 ausführen, müssen wir alle erforderlichen Komponenten in die Ereignisbehandlungsfunktionen OnInit(), OnDeinit() und OnTick() einbinden. Beginnen Sie mit dem Laden aller grafischen Objekte während der Initialisierung des Experten mit der Funktion LoadChartObjects() in der Funktion OnInit().

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
//create buttons to demonstrate how the different ex5 library functions work
   LoadChartObjects();
//---
   return(INIT_SUCCEEDED);
  }

Rufen Sie die folgenden Funktionen in der Funktion OnTick() auf und führen Sie sie aus.

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//-- Check for profitable positions and set the trailing stop loss on every new tick
   SetTrailingSl(); //-- Calls the ex5 library function responsible for setting Trailing stops
   LoadChartObjects(); //--- Update chart objects
  }

Fügen Sie die Deinitialisierungsfunktion der Ereignisbehandlung von OnDeinit() hinzu, um alle grafischen und Chart-Objekte zu löschen, wenn der Expert Advisor geschlossen oder beendet wird.

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
//-- Clean up the chart
   DeleteChartObjects();

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

Die vollständige Quellcodedatei für den Expert Advisor PositionsManagerPanel.mq5 finden Sie am Ende dieses Artikels zur genaueren Untersuchung.

Speichern, kompilieren und laden Sie den Expert Advisor PositionsManagerPanel.mq5 in einem beliebigen MetaTrader 5-Chart. Auf der Registerkarte „Dependencies“ sehen Sie alle Funktionsprototypen der Bibliothek, die aus PositionsManager.ex5 importiert wurden, zusammen mit dem vollständigen Dateipfad, unter dem die EX5-Bibliothek gespeichert ist. Sobald es im Chart geladen ist, testen Sie es, indem Sie einige Positionen öffnen und das Protokoll der Registerkarte „Experten“ im Toolbox-Panel des Handelsterminals auf die gedruckten Protokolldaten der Funktionen des Prototyps PositionsManager.ex5 überprüfen.

Positionsmanager-Panel, Registerkarte EX5-Dependencies


Schlussfolgerung

Sie haben nun ein umfassendes Verständnis der MQL5 EX5-Bibliotheken erworben. Wir haben ihre Erstellung, Integration und Implementierung in externe MQL5-Projekte behandelt, einschließlich der Fehlersuche in verschiedenen EX5-Bibliotheken und der Aktualisierung und Neuverteilung. Darüber hinaus haben wir eine leistungsstarke, funktionsreiche EX5 Positionsmanagement-Bibliothek mit ausführlicher Dokumentation und praktischen Anwendungsbeispielen erstellt. Ich habe auch demonstriert, wie diese Bibliothek in zwei verschiedene praktische MQL5 Expert Advisors importiert und implementiert werden kann, um so reale Beispiele für den effektiven Einsatz der EX5-Bibliothek zu liefern. Im nächsten Artikel werden wir einen ähnlichen Ansatz verfolgen, um eine umfassende EX5-Bibliothek für die Verwaltung ausstehender Aufträge zu entwickeln, die die Verarbeitung ausstehender Aufträge in Ihren MQL5-Anwendungen vereinfachen soll. Vielen Dank, dass Sie mir gefolgt sind, und ich wünsche Ihnen viel Erfolg bei Ihren Handels- und Programmieraktivitäten.


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

Klassische Strategien neu interpretieren (Teil II): Bollinger-Bänder Ausbrüche Klassische Strategien neu interpretieren (Teil II): Bollinger-Bänder Ausbrüche
Dieser Artikel untersucht eine Handelsstrategie, die die lineare Diskriminanzanalyse (LDA) mit Bollinger-Bändern integriert und kategorische Zonenvorhersagen für strategische Markteinstiegssignale nutzt.
Datenwissenschaft und ML (Teil 27): Convolutional Neural Networks (CNNs) in MetaTrader 5 Trading Bots — funktioniert das? Datenwissenschaft und ML (Teil 27): Convolutional Neural Networks (CNNs) in MetaTrader 5 Trading Bots — funktioniert das?
Faltende neuronale Netzwerke (Convolutional Neural Networks, CNN) sind für ihre Fähigkeiten bei der Erkennung von Mustern in Bildern und Videos bekannt und werden in den verschiedensten Bereichen eingesetzt. In diesem Artikel untersuchen wir das Potenzial von CNNs zur Erkennung wertvoller Muster auf den Finanzmärkten und zur Erzeugung effektiver Handelssignale für MetaTrader 5-Handelsroboter. Lassen Sie uns herausfinden, wie diese tiefgehende maschinelle Lerntechnik für intelligentere Handelsentscheidungen genutzt werden kann.
Vom Neuling zum Experten: Die wesentliche Reise durch den MQL5-Handel Vom Neuling zum Experten: Die wesentliche Reise durch den MQL5-Handel
Entfalten Sie Ihr Potenzial! Sie sind von Möglichkeiten umgeben. Entdecken Sie die 3 wichtigsten Geheimnisse, um Ihre MQL5-Reise in Gang zu bringen oder auf die nächste Stufe zu heben. Lassen Sie uns in die Diskussion über Tipps und Tricks für Anfänger und Profis gleichermaßen eintauchen.
Selbstoptimierende Expert Advisors mit MQL5 und Python erstellen Selbstoptimierende Expert Advisors mit MQL5 und Python erstellen
In diesem Artikel werden wir erörtern, wie wir Expert Advisors erstellen können, die in der Lage sind, Handelsstrategien auf der Grundlage der vorherrschenden Marktbedingungen eigenständig auszuwählen und zu ändern. Wir werden etwas über Markov-Ketten lernen und wie sie algorithmischen Händler helfen können.