MetaTrader 5 herunterladen

MQL5 Cookbook: Wie man Position-Eigenschaften bekommt

27 Juni 2016, 15:49
Anatoli Kazharski
0
454

Einleitung

Der vorangegangene Beitrag mit dem Titel "MQL5 Cookbook: Wie man unterschiedliche Print-Modi verwendet" beschrieb, wie man schnell ein Script schreiben und die benötigte Informationen mit Hilfe dreier unterschiedlicher Modi drucken kann. Jetzt werden wir ein Script erzeugen, das alle Position-Eigenschaften abruft und dem Anwender anzeigt.

Dies müssen wir so implementieren, damit der Anwender die entsprechende Option in den externen Parametern des Scripts wie folgt auswählen kann: entweder die Position-Eigenschaften nur auf einem (aktuelles) Symbol abrufen oder alle offenen Positions (falls vorhanden) auf allen Symbolen nacheinander durchgehen. Die benötigte Information wird diesmal direkt im Dialogfenster angezeigt, was sehr bequem ist. Einige von Ihnen werden diese Methode auch weitaus nützlicher finden.


Das Script schreiben

Der Anfang des Programms ist mehr oder weniger genauso, wie im vorangegangenen Beitrag beschrieben (vgl. Code unten). Wir beginnen mit den Programmeigenschaften. Ihnen folgt die Zeile mit der #define Direktive, und dann weisen wir den Programmnamen der Variable SCRIPT_NAME mit Hilfe der MQLInfoString() Funktion und der MQL5_PROGRAM_NAME Konstante zu, die sie spezifiziert.. Mehr Informationen zu allen möglichen Werten der MQLInfoString() Funktionen finden Sie in den MQL5 Referenzhinweisen.

Wir machen mit der Aufzählung der Modi weiter. Wenn Sie für jeden Identifikator eine Anmerkung schreiben, wird der Text dieser Anmerkung in der Dropdown-Liste in den externen Parametern angezeigt. Wir implementieren zwei Optionen:

  • Aktuelles Symbol - zur Anzeige der Position-Eigenschaften nur auf dem aktuellen Symbol und
  • Alle Symbole - zur Anzeige der Position-Eigenschaften auf allen Symbolen.

Zur Auswahl des entsprechenden Modus wird nur ein externer Parameter (Modus) verwendet. Die Anmerkung, die dem externen Parameter folgt, wird ebenfalls im Fenster der externen Parameter angezeigt. Dadurch können wir Parameternamen erzeugen, die mehr Sinn machen. Derzeit wären natürlich hinsichtlich des Codes kürzere Variablennamen bequemer.

#property copyright   "Copyright 2012, http://tol64.blogspot.com"
#property link        "http://tol64.blogspot.com"
#property description "email: hello.tol64@gmail.com"
#property version     "1.0"
#property script_show_inputs
//---
#define SCRIPT_NAME MQLInfoString(MQL_PROGRAM_NAME) // Script name
//---
// ENUMERATION OF MODES
enum ENUM_SYMBOLS_MODE
  {
   CURRENT_SYMBOL =0,                     // Current symbol
   ALL_SYMBOLS    =1                      // All symbols
  };
//---
// INPUT PARAMETERS
input ENUM_SYMBOLS_MODE mode=CURRENT_SYMBOL;     // Mode

Der Code geht mit globalen Variablen weiter. Damit auf die globalen Variablen von jedem Teil des Scripts aus zugegriffen werden kann, sollten sie außerhalb der Funktionen platziert werden (meist ganz zu Anfang des Programms).

// GLOBAL VARIABLES
long                 pos_magic=0;         // Magic number
string               pos_symbol="";       // Symbol
string               pos_comment="";      // Comment
double               pos_swap=0.0;        // Swap
double               pos_commission=0.0;  // Commission
double               pos_price=0.0;       // Current price of the position
double               pos_cprice=0.0;      // Current price of the position
double               pos_profit=0.0;      // Profit/Loss of the position
double               pos_volume=0.0;      // Position volume
double               pos_sl=0.0;          // Stop Loss of the position
double               pos_tp=0.0;          // Take Profit of the position
datetime             pos_time=NULL;       // Position opening time
long                 pos_id=0;            // Position identifier
ENUM_POSITION_TYPE   pos_type=NULL;       // Position type
//---

In der Hauptprogrammfunktion rufen wir nur eine benutzerdefinierte Funktion auf: PrintPositionProperties() - sie führt alle notwendigen Vorgänge aus:

//+------------------------------------------------------------------+
//| MAIN FUNCTION                                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   PrintPositionProperties();
  }

Die Struktur dieser benutzerdefinierten Funktion PrintPositionProperties() sehen wir uns jetzt Schritt für Schritt mal an. Zuerst bauen wir die Grundlage für unsere zukünftige Arbeit. Sie ist sehr einfach und sieht nach ihrer Implementierung so aus:

//+------------------------------------------------------------------+
//| OPENING A DIALOG BOX WITH SYMBOL DATA                            |
//+------------------------------------------------------------------+
void PrintPositionProperties()
  {
   int err=0; // Variable for handling errors
//---
// If you need to get position properties on the current symbol only
   if(mode==CURRENT_SYMBOL)
     {
 
     }
//---
// If you need to get position properties on all symbols
   if(mode==ALL_SYMBOLS)
     {
 
     }
  }

Wir haben nur zwei Zweige und eine lokale Variable 'err', die zur Verarbeitung von Fehlern verantwortlich ist und zu Beginn der Funktion deklariert wird. Für jede der Optionen müssen wir nun Szenarien für Anwendungsfälle schreiben. Beginnen wir mit dem ersten: "Wenn man nur für das aktuelle Symbol die Position-Eigenschaften möchte".

Das ist ebenfalls sehr leicht. Zunächst müssen wir prüfen, ob es auf dem aktuellen Symbol eine Position gibt. Dies geschieht mit Hilfe der PositionSelect() Funktion, die in MQL5 vorhanden ist und den Symbolnamen als den einzigen Parameter hernimmt. Zur Übertragung des Namens des aktuellen Symbols müssen wir entweder mit der Symbol() Funktion oder der vorab definierten Variable _Symbol arbeiten, die bereits den Namen des aktuellen Symbols enthält. Wenn es auf diesem Symbol eine Position gibt, liefert die PositionSelect() Funktion ein positives Ergebnis. Gibt es keine Position oder ist ein Fehler aufgetreten, liefert sie ein negatives Ergebnis.

Unten sehen Sie den Code mit detaillierten Anmerkungen für die erste Option:

//---
      // If a position exists, then...
      if(PositionSelect(_Symbol))
        {
         // ...get its properties
         GetPositionProperties();
         //---
         // Open a dialog box to display all the data we obtained
         MessageBox("Symbol        : "+pos_symbol+"\n"+
                    "Comment       : "+pos_comment+"\n"+
                    "Magic Number  : "+IntegerToString(pos_magic)+"\n"+
                    "Price Open    : "+DoubleToString(pos_price,_Digits)+"\n"+
                    "Current Price : "+DoubleToString(pos_cprice,_Digits)+"\n"+
                    "Stop Loss     : "+DoubleToString(pos_sl,_Digits)+"\n"+
                    "Take Profit   : "+DoubleToString(pos_tp,_Digits)+"\n"+
                    "Type          : "+PositionTypeToString(pos_type)+"\n"+
                    "Volume        : "+DoubleToString(pos_volume,2)+"\n"+
                    "Commission    : "+DoubleToString(pos_commission,2)+"\n"+
                    "Swap          : "+DoubleToString(pos_swap,2)+"\n"+
                    "Profit        : "+DoubleToString(pos_profit,2)+"\n"+
                    "Time          : "+TimeToString(pos_time)+"\n"+
                    "Identifier    : "+IntegerToString(pos_id)+"",
                    //---
                    "Message Box",MB_ICONASTERISK);
         //---
         return;
        }
      // If there is no position or an error has occurred, report it
      else
        {
         err=GetLastError(); // Get the code of the last registered error
         //---
         if(err>0) // If there is an error
           {
            // Print the relevant message
            MessageBox("Error ("+IntegerToString(err)+") when selecting a position ("+_Symbol+") !\n\n"+
                       "It is possible that there is no position on this symbol. If this is not the case, please try again.",
                       "Error",
                       MB_ICONWARNING);
            //---
            return; // Exit the function
           }
        }
      //---

Im Code oben können wir zwei weitere benutzerdefinierte Funktionen erkennen:- GetPositionProperties() und PositionTypeToString(). Da wir ja Position-Eigenschaften an verschiedenen Punkten im gesamten Programm bekommen müssen, ist es ratsam, eine separate Funktion zu erzeugen, um die Menge an Code zu reduzieren und ihn dadurch besser lesbar zu machen. Unten steht der Code dieser Funktion. Vergessen Sie nicht, in den MQL5 Referenzhinweisen nach weiteren Informationen zu den MQL5 Funktionen und Identifikatoren zu suchen, die in GetPositionProperties() verwendet werden.

//+------------------------------------------------------------------+
//| GETTING SYMBOL PROPERTIES                                        |
//+------------------------------------------------------------------+
void GetPositionProperties()
  {
   pos_symbol     =PositionGetString(POSITION_SYMBOL);
   pos_comment    =PositionGetString(POSITION_COMMENT);
   pos_magic      =PositionGetInteger(POSITION_MAGIC);
   pos_price      =PositionGetDouble(POSITION_PRICE_OPEN);
   pos_cprice     =PositionGetDouble(POSITION_PRICE_CURRENT);
   pos_sl         =PositionGetDouble(POSITION_SL);
   pos_tp         =PositionGetDouble(POSITION_TP);
   pos_type       =(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
   pos_volume     =PositionGetDouble(POSITION_VOLUME);
   pos_commission =PositionGetDouble(POSITION_COMMISSION);
   pos_swap       =PositionGetDouble(POSITION_SWAP);
   pos_profit     =PositionGetDouble(POSITION_PROFIT);
   pos_time       =(datetime)PositionGetInteger(POSITION_TIME);
   pos_id         =PositionGetInteger(POSITION_IDENTIFIER);
  }

Die benutzerdefinierte Funktion PositionTypeToString() wandelt den Position-Typ, der als eine ganze Zahl geliefert wird, in einen String um, um das Format lesen zu können, so wie im Code unten gezeigt:

//+------------------------------------------------------------------+
//| CONVERTING POSITION TYPE TO A STRING                             |
//+------------------------------------------------------------------+
string PositionTypeToString(int position_type)
  {
   string str="";
//---
   if(position_type==0) { str="buy";  }
   if(position_type==1) { str="sell"; }
//---
   return(str);
  }

Der Code für die erste Option, wodurch wir die Position-Eigenschaften auf nur dem aktuellen Symbol sehen können, ist damit fertig. Er kann sogar direkt getestet werden, wenn Sie die in diesem Beitrag beschriebenen Schritte befolgt haben. Öffnen Sie in MetaTrader 5 mit Hilfe der Standard-Tools eine Position. Dazu drücken Sie F9 und das Fenster 'Order' geht auf, wo Sie alle nötigen Optionen zum setzen der Position-Eigenschaften befinden, bevor sie eröffnet wird:

Abb. 1 Das 'Order'-Fenster im MetaTrader 5 Client-Terminal.

Abb. 1 Das 'Order'-Fenster im MetaTrader 5 Client-Terminal.

Sind alle Eigenschaften eingestellt, wählen Sie entweder Kaufen oder Verkaufen und lassen das Script ablaufen. Dazu einfach per Doppelklick aktivieren oder in das Chart hineinziehen. Ein Script-Fenster geht auf. Der erforderliche Wert (Aktuelles Symbol) im Parameter 'Modus' ist bereits standardmäßig eingestellt. Durch Klicken auf 'OK' geht ein Dialogfenster auf und zeigt alle Position-Eigenschaften auf dem aktuellen Symbol:

Abb. 2 Dialogfenster mit den Position-Eigenschaften auf dem aktuellen Symbol.

Abb. 2 Dialogfenster mit den Position-Eigenschaften auf dem aktuellen Symbol.

Sollte sich auf dem aktuellen Symbol keine Position befinden, wird Ihnen das mit einem Warn-Fenster angezeigt:

Abb. 3 Warn-Fenster.

Abb. 3 Warn-Fenster.

Sieht so aus, als funktioniert alles wie geplant und so wie im Code implementiert.

Sehen wir uns nun den Programmcode an, der verwendet wird, wenn Sie die Eigenschaften aller offenen Positions sehen möchten. Der Code mit detaillierten Anmerkungen steht unten:

//---
      int digits=0; // Number of decimal places
      int mb_res=-1; // Variable with the option selected in the dialog box
      int pos_total=PositionsTotal(); // Number of open positions in the terminal
      //---
      // View properties of all positions in a loop one by one
      for(int i=0; i<pos_total; i++)
        {
         ResetLastError(); // Reset the last error
         //---
         pos_symbol=PositionGetSymbol(i); // Get the symbol name
         digits=(int)SymbolInfoInteger(pos_symbol,SYMBOL_DIGITS); // Get the number of digits in the price
         //---
         // If a position on this symbol exists, then...
         if(PositionSelect(pos_symbol))
           {
            // ...get its properties
            GetPositionProperties();
            //---
            // Open a dialog box to display all position properties obtained
            mb_res=MessageBox("Total Positions/Current: "+IntegerToString(pos_total)+"/"+IntegerToString(i+1)+"\n"+
                              "---------------------------------\n"+
                              "Symbol: "        +pos_symbol+"\n"+
                              "Comment: "       +pos_comment+"\n"+
                              "Magic Number: "  +IntegerToString(pos_magic)+"\n"+
                              "Price Open: "    +DoubleToString(pos_price,digits)+"\n"+
                              "Current Price: " +DoubleToString(pos_cprice,digits)+"\n"+
                              "Stop Loss: "     +DoubleToString(pos_sl,digits)+"\n"+
                              "Take Profit: "   +DoubleToString(pos_tp,digits)+"\n"+
                              "Type: "          +PositionTypeToString(pos_type)+"\n"+
                              "Volume: "        +DoubleToString(pos_volume,2)+"\n"+
                              "Commission: "    +DoubleToString(pos_commission,2)+"\n"+
                              "Swap: "          +DoubleToString(pos_swap,2)+"\n"+
                              "Profit: "        +DoubleToString(pos_profit,2)+"\n"+
                              "Time: "          +TimeToString(pos_time)+"\n"+
                              "Identifier: "    +IntegerToString(pos_id)+"",
                              //---
                              "Message Box",MB_CANCELTRYCONTINUE|MB_ICONASTERISK);
            //---
            if(mb_res==IDCANCEL) // If you have clicked Cancel or Close
              { Print("The program ("+SCRIPT_NAME+") has been terminated by the user!"); return; } // Exit the function
            //---
            // If you have clicked Retry   
            if(mb_res==IDTRYAGAIN) { i--; } // Reset the counter to retry
           }
         else // If there is no position or an error has occurred, report it
           {
            err=GetLastError(); // Get the code of the last registered error
            //---
            if(err>0) // If there is an error
              {
               // Print the relevant message
               MessageBox("Error ("+IntegerToString(err)+") when selecting a position ("+pos_symbol+") !\n\n"+
                          "It is possible that there is no position on this symbol. If this is not the case, please try again.",
                          "Error",
                          MB_ICONWARNING);
              }
           }
        }
      //---

Nun müssen wir diese Option nur noch testen. Dazu öffnen wir beispielsweise Positions auf zwei Symbolen (AUDUSD und EURUSD). Sobald wir das Script starten, wählen wir in der Dropdown-Liste im externen Parameter den Modus 'Alle Symbole' und klicken 'OK'. Ein Dialogfenster geht auf - wie unten gezeigt:

Abb. 4 Dialogfenster mit den Position-Eigenschaften für die zweite Option.

Abb. 4 Dialogfenster mit den Position-Eigenschaften für die zweite Option.


Fazit

Wie Sie in der obigen Abbildung erkennen können, gibt es in dem Dialogfenster drei Schaltflächen. Wenn Sie 'Nochmal versuchen' anklicken, wird der Schleifenzähler zurückgesetzt und die Position-Eigenschaften auf dem aktuell im Dialogfenster angezeigten Symbol aktualisiert. Wenn Sie 'Weiter' anklicken, geht das Programm zum nächsten Symbol weiter. Wenn Sie 'Abbrechen' anklicken, wird das Programm beendet.

Hier sei darauf hingewiesen, dass die erste Zeile oberhalb der Liste mit Position-Eigenschaften Informationen zur Gesamtzahl aller offenen Positions (Positions gesamt) sowie die aktuelle Zahl des Position-Zählers (Aktuelle) enthält.

Das war's. Gerne dürfen Sie die unten angehängte Quellcode-Datei herunterladen, die im MetaEditor erstellt werden muss.

Übersetzt aus dem Russischen von MetaQuotes Software Corp.
Originalartikel: https://www.mql5.com/ru/articles/639

Beigefügte Dateien |
MQL5 Cookbook: Position-Eigenschaften auf dem Angepassten Info-Panel MQL5 Cookbook: Position-Eigenschaften auf dem Angepassten Info-Panel

Diesmal erzeugen wir einen einfachen Expert Advisor, der die Position-Eigenschaften auf dem aktuellen Symbol abruft und sie im angepassten Info-Panel während manuell durchgeführtem Handel anzeigt. Das Info-Panel wird mit Hilfe graphischer Objekte erstellt, und die angezeigte Information wird bei jeder Kursschwankung (Tick) aktualisiert. Das ist weitaus bequemer als ständig das im vorangegangenen Beitrag der Reihe "MQL5 Cookbook: Wie man Position-Eigenschaften abruft", beschriebene Script manuell laufen lassen zu müssen.

MQL5 Cookbook: Position-Eigenschaften im MetaTrader 5 Strategietester analysieren MQL5 Cookbook: Position-Eigenschaften im MetaTrader 5 Strategietester analysieren

Wir präsentieren hier eine veränderte Version des Expert Advisors aus dem vorangegangenen Beitrag "MQL5 Cookbook: Position-Eigenschaften auf dem Angepassten Info-Panel". Einige der Themen, die wir ansprechen werden, sind: Daten von Bars bekommen, nach neuen Bar-Ereignissen auf dem aktuellen Symbol suchen, eine Handelsklasse der Standard-Library in eine Datei aufnehmen, eine Suchfunktion für Handelssignale und eine Funktion zur Ausführung von Handelsoperationen erzeugen sowie Handelsereignisse in der OnTrade() Funktion festlegen.

MQL5 Cookbook: Verschiedene Print-Modi nutzen MQL5 Cookbook: Verschiedene Print-Modi nutzen

Dies ist der erste Beitrag der MQL5 Cookbook-Reihe. Ich beginne mit einfachen Beispielen, damit auch diejenigen, die gerade ihren ersten Erfahrungen im Programmieren machen, mit der neuen Sprache vertraut werden. Ich kann mich noch gut an meine ersten Anstrengungen beim Entwurf und Programmieren von Handelssystemen erinnern, die sich extrem schwierig gestalteten. Das lag schlichtweg an der Tatsache, dass dies die erste Programmiersprache meines Lebens war. Doch schon bald stellte sich das Ganze als wesentlich leichter heraus als gedacht - und nach wenigen Monaten konnte ich ziemlich komplexes Programm entwickeln.

MQL5 Market feiert sein Einjähriges MQL5 Market feiert sein Einjähriges

Ein Jahr ist vergangen, seit die Verkäufe im MQL5 Market begonnen haben. Wir blicken zurück auf ein Jahr harter Arbeit, die sich gelohnt hat: der neue Service ist zum größten Platz für Handelsroboter und technische Indikatoren für die MetaTrader 5 Plattform geworden.