Русский 中文 Español Deutsch 日本語 Português 한국어 Français Italiano Türkçe
MQL5 Cookbook: Getting Position Properties

MQL5 Cookbook: Getting Position Properties

MetaTrader 5Examples | 4 March 2013, 08:40
22 229 2
Anatoli Kazharski
Anatoli Kazharski

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 Ltd.
Original article: https://www.mql5.com/ru/articles/639

Last comments | Go to discussion (2)
Dean Thomas Whittingham
Dean Thomas Whittingham | 14 Jul 2019 at 06:26

Hi Anatoli,

I only just found these two articles 'cookbook' and am grateful for your efforts.


I have noticed with programs/scripts like this, they do not seem to recognize if there is more than one position on a particular currency pair.


For instance, if I have two positions open on the EURUSD (one sell at 1.2250, and the other sell at 1.2200), then it only recognizes the first one and not the second. I am not sure if this is because something has to tell the program/script that its an account which allows hedging? Do you have any articles that deals with scripts that recognizes multiple positions on the one currency pair?


Many thanks

Dingo

Fernando Jose Velasco Borea
Fernando Jose Velasco Borea | 8 May 2021 at 08:25
Dean Thomas Whittingham:

Hi Anatoli,

I only just found these two articles 'cookbook' and am grateful for your efforts.


I have noticed with programs/scripts like this, they do not seem to recognize if there is more than one position on a particular currency pair.


For instance, if I have two positions open on the EURUSD (one sell at 1.2250, and the other sell at 1.2200), then it only recognizes the first one and not the second. I am not sure if this is because something has to tell the program/script that its an account which allows hedging? Do you have any articles that deals with scripts that recognizes multiple positions on the one currency pair?


Many thanks

Dingo

Hey! 

I know it's been a while since you posted this. Indeed, I think the first method will only pick up the first order in the pos for the given symbol. To read all trades from a specific symbol, you'd need to adapt the second variant to the script (all trades) and just add an if "filter" to where it procedes only if the order symbol is the same as the current given symbol.

Hope it helps.

-Fernando.

MQL5 Programming Basics: Arrays MQL5 Programming Basics: Arrays
Arrays are an integral part of almost any programming language along with variables and functions. The article should be of interest primarily to novice MQL5 programmers, while experienced programmers will have a good opportunity to summarize and systematize their knowledge.
MQL5 Cookbook: Using Different Print Modes MQL5 Cookbook: Using Different Print Modes
This is the first article of the MQL5 Cookbook series. I will start with simple examples to allow those who are taking their first steps in programming to gradually become familiar with the new language. I remember my first efforts at designing and programming trading systems which I may say was quite difficult, given the fact that it was the first programming language in my life. However, it turned out to be easier than I thought and it only took me a few months before I could develop a fairly complex program.
MQL5 Cookbook: Position Properties on the Custom Info Panel MQL5 Cookbook: Position Properties on the Custom Info Panel
This time we will create a simple Expert Advisor that will get position properties on the current symbol and display them on the custom info panel during manual trading. The info panel will be created using graphical objects and displayed information will be refreshed at every tick. This is going to be much more convenient than all the time having to manually run the script described in the previous article of the series called "MQL5 Cookbook: Getting Position Properties".
Calculation of Integral Characteristics of Indicator Emissions Calculation of Integral Characteristics of Indicator Emissions
Indicator emissions are a little-studied area of market research. Primarily, this is due to the difficulty of analysis that is caused by the processing of very large arrays of time-varying data. Existing graphical analysis is too resource intensive and has therefore triggered the development of a parsimonious algorithm that uses time series of emissions. This article demonstrates how visual (intuitive image) analysis can be replaced with the study of integral characteristics of emissions. It can be of interest to both traders and developers of automated trading systems.