Download MetaTrader 5

MQL5 Cookbook: Getting Position Properties

4 March 2013, 08:40
Anatoli Kazharski
0
5 516

Introduction

The previous article called "MQL5 Cookbook: Using Different Print Modes" showed us how we can quickly write a script and print the required information using three different modes. Let us now create a script that will get and display all position properties to the user.

We need to implement it in such a way so as to allow the user to select the appropriate option in the external parameters of the script, as follows: to either only get position properties on one (current) symbol or to run across all open positions (if any) one by one on all symbols. This time, we will view the required information right in the dialog box which is quite convenient and some of you might find this method more useful.


Writing a Script

The beginning of the program is more or less the same as in the previous article (see the code below). We start with the program properties. They are followed by the line with the #define directive and we then assign the program name to the SCRIPT_NAME variable using the MQLInfoString() function and the MQL5_PROGRAM_NAME constant it specifies. More information on all possible values of the MQLInfoString() function can be found in MQL5 Reference.

We continue with enumeration of the modes. If you write a comment for every identifier, the text of such comment will be displayed in the drop-down list in the external parameters. We will implement two options:

  • Current symbol - to display position properties on the current symbol only, and
  • All symbols - to display position properties on all symbols.

There is going to be only one external parameter (mode) to be used to select the appropriate mode. The comment following the external parameter will also be displayed in the window of external parameters. This will allow us to create more meaningful parameter names. At the same time shorter names of variables would be more convenient in terms of code.

#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

The code continues with global variables. In order for global variables to be accessed from any part of the script, they should be placed outside of the functions (usually at the very beginning of the program).

// 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 the main program function, we will call only one user-defined function, PrintPositionProperties(), that will perform all required operations:

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

Let us now take a look at the structure of the user-defined PrintPositionProperties() function step by step. We will first form the base for our further work. It is very simple and when implemented looks as follows:

//+------------------------------------------------------------------+
//| 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)
     {
 
     }
  }

We only have two branches and a local variable err which is responsible for handling errors and is declared at the beginning of the function. Now we need to write use case scenarios for each of the options. Let us start with the first one, i.e. "If you need to get position properties on the current symbol only".

It is very simple. First of all, we need to check if there is a position on the current symbol. This can be done by the PositionSelect() function available in MQL5 which takes the symbol name as the only parameter. To pass the current symbol name we need to either use the Symbol() function or the predefined variable _Symbol that already contains the current symbol name. The PositionSelect() function will return a positive result, if a position on that symbol exists, or a negative result, if there is no position or an error has occurred.

The code with detailed comments for the first option is provided below:

//---
      // 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
           }
        }
      //---

In the code above, we can see two more user-defined functions - GetPositionProperties() and PositionTypeToString(). Since we will have to get position properties in various points throughout the program, it will be good to create a separate function in order to reduce the amount of code and thus make it more readable. Below is the code of this function. Be sure to check MQL5 Reference for additional information on the MQL5 functions and identifiers used in GetPositionProperties().

//+------------------------------------------------------------------+
//| 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);
  }

The user-defined PositionTypeToString() function converts position type returned as an integer to a string to read format, as shown in the code below:

//+------------------------------------------------------------------+
//| 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);
  }

So the code for the first option whereby we can view position properties only on the current symbol is ready. It can even be tested right now if you have followed all steps described in the article. Open a position in MetaTrader 5 using standard tools. For this purpose, press F9 and the Order window will open where you can find all necessary options to set position properties before it opens:

Fig. 1. The Order window in the MetaTrader 5 client terminal.

Fig. 1. The Order window in the MetaTrader 5 client terminal.

When all properties have been set, select either Sell or Buy and run the script by double-clicking or dragging it onto the chart. A script window will open. The required value (Current symbol) of the Mode parameter has already been set by default. A click on the OK button will open a dialog box displaying all position properties on the current symbol:

Fig. 2. Dialog box with position properties on the current symbol.

Fig. 2. Dialog box with position properties on the current symbol.

Otherwise, if there is no position on the current symbol, an alert box will appear:

Fig. 3. Alert box.

Fig. 3. Alert box.

Everything seems to be working as planned and as implemented in the code.

Let us now review the program code that is going to be used if you choose to view all open position properties. The code with detailed comments is shown below:

//---
      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);
              }
           }
        }
      //---

Now we only need to test this option. Let us, for example, open positions on two symbols (AUDUSD and EURUSD). Once we run the script, select the All symbols mode in the drop-down list in the external parameters and click OK, a dialog box will open as shown below:

Fig. 4. Dialog box with position properties for the second option.

Fig. 4. Dialog box with position properties for the second option.


Conclusion

As you can see in the figure above, there are three buttons in the dialog box. If you click Retry, the loop counter will be reset and position properties for the symbol currently displayed in the dialog box will be refreshed. If you click Continue, the program will proceed to the next symbol. The Cancel button serves to terminate the program.

It should also be noted that the first line above the list of position properties contains information on the total number of open positions (Total Positions) and current number of the position counter (Current).

That's about it. Feel free to download the source code file attached below which will need to be compiled in MetaEditor.

Translated from Russian by MetaQuotes Software Corp.
Original article: https://www.mql5.com/ru/articles/639

Attached files |
Step on New Rails: Custom Indicators in MQL5 Step on New Rails: Custom Indicators in MQL5

I will not list all of the new possibilities and features of the new terminal and language. They are numerous, and some novelties are worth the discussion in a separate article. Also there is no code here, written with object-oriented programming, it is a too serous topic to be simply mentioned in a context as additional advantages for developers. In this article we will consider the indicators, their structure, drawing, types and their programming details, as compared to MQL4. I hope that this article will be useful both for beginners and experienced developers, maybe some of them will find something new.

Here Comes the New MetaTrader 5 and MQL5 Here Comes the New MetaTrader 5 and MQL5

This is just a brief review of MetaTrader 5. I can't describe all the system's new features for such a short time period - the testing started on 2009.09.09. This is a symbolical date, and I am sure it will be a lucky number. A few days have passed since I got the beta version of the MetaTrader 5 terminal and MQL5. I haven't managed to try all its features, but I am already impressed.

False trigger protection for Trading Robot False trigger protection for Trading Robot

Profitability of trading systems is defined not only by logic and precision of analyzing the financial instrument dynamics, but also by the quality of the performance algorithm of this logic. False trigger is typical for low quality performance of the main logic of a trading robot. Ways of solving the specified problem are considered in this article.

Using text files for storing input parameters of Expert Advisors, indicators and scripts Using text files for storing input parameters of Expert Advisors, indicators and scripts

The article describes the application of text files for storing dynamic objects, arrays and other variables used as properties of Expert Advisors, indicators and scripts. The files serve as a convenient addition to the functionality of standard tools offered by MQL languages.