How to use PositionGetDouble(POSITION_VOLUME) correctly? - page 2

 
Cosmas Moses:

there is several way to solve this problem , mine might differ from other . 

Here my code ;

Thank you for sharing your code Cosmas. It is easy to understand. However, I can not use your code because you use the magic number to filter all orders.

I am using CTrade PositionOpen(), Buy() and Sell(). These functions don't have a field to set the magic number, so my orders and trades don't have this.

 
Vladimir Karputov:

Example loop to traverse all positions in the code Example: Calculate Positions and Pending Orders:

Cycle by the current symbol (the current symbol is the symbol on which the EA works -> m_symbol ) and by the specified Magic number ( InpMagic )

Thank you for sharing your code Vladimir. Using PositionsTotal() in the for-loop and counting down seems the way to go for me. I assume that at each pass of the loop one position gets closed and thus PositionsTotal() becomes one less.

I have only one EA running and will not do manual trading so I don't need to filter by magic number as all trades are coming from this one EA.

 
WindmillMQL :

Thank you for sharing your code Vladimir. Using PositionsTotal() in the for-loop and counting down seems the way to go for me. I assume that at each pass of the loop one position gets closed and thus PositionsTotal() becomes one less.

I have only one EA running and will not do manual trading so I don't need to filter by magic number as all trades are coming from this one EA.

You are wrong. There is always a magic number! Take my example and print out the Magic number field, example:

//+------------------------------------------------------------------+
//| Calculate all positions Buy and Sell                             |
//+------------------------------------------------------------------+
void CalculateAllPositions(int &count_buys,int &count_sells)
  {
   count_buys=0;
   count_sells=0;

   for(int i=PositionsTotal()-1; i>=0; i--)
      if(m_position.SelectByIndex(i)) // selects the position by index for further access to its properties
         //if(m_position.Symbol()==m_symbol.Name() && m_position.Magic()==InpMagic)
           {
            if(m_position.PositionType()==POSITION_TYPE_BUY)
               {
                Print(m_position.Symbol()," BUY ",DoubleToString(m_position.Volume(),2)," Magic number ",m_position.Magic());
                count_buys++;
               }

            if(m_position.PositionType()==POSITION_TYPE_SELL)
               {
                Print(m_position.Symbol()," SELL ",DoubleToString(m_position.Volume(),2)," Magic number ",m_position.Magic());
                count_sells++;
               }
           }
//---
   return;
  }
 
WindmillMQL:

My EA places multiple trades in a row, thus adding to an open position. Let's take an example:

First trade: open a sell position of 0.01 lot EURUSD

Second trade, some time later: open a sell position of 0.01 lot EURUSD

Third position, some time after the second trade: open a sell position of 0.02 lot EURUSD

Now, again some time later, I want to know the total size of the open EURUSD position.

The code that I'm using is:


However, this results in size = 0.01 lot, where I expect a value of 0.04 lot.

What code should I use to get the total open EURUSD position size?

Eventually I solved this with the following code. For each of the open positions it checks whether it matches the Symbol() of the chart the EA is attached to. Then it calculates the total long and short positions, and calculates the net position.

double isNetPositionSize(bool ShowAlert){
   double LongSize = 0;
   double ShortSize = 0;
   for(int i = 0; i < PositionsTotal(); i++){
      PositionGetTicket(i);
      int x = StringCompare(Symbol(),PositionGetString(POSITION_SYMBOL),false);
      if(x == 0){
         double size = PositionGetDouble(POSITION_VOLUME);
         if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) 
            LongSize = LongSize + size;
         if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL) 
            ShortSize = ShortSize + size;
      }
   }
   if(ShowAlert) Alert (TimeLocal()," ",Symbol()," Debug. ShortSize: ",ShortSize," LongSize: ",LongSize);
   return (LongSize - ShortSize);
}
 
WindmillMQL:

Eventually I solved this with the following code. For each of the open positions it checks whether it matches the Symbol() of the chart the EA is attached to. Then it calculates the total long and short positions, and calculates the net position.

This is good but you shouldn't compare the strings, and instead you should get the actual position's symbol using PositionInfoString. Better yet, use CPositionInfo...

#include <trade/trade.mqh>

double netPosition(string symbol) {
   CPositionInfo pos;
   double net_volume = 0.0;
   for (int i=PositionsTotal()-1; i>=0; --i)
      if (pos.SelectByIndex(i) && pos.Symbol() == symbol)
         net_volume += pos.PositionType() == POSITION_TYPE_BUY ? pos.Volume() : -pos.Volume();
   return net_volume;
}
 
nicholi shen:

This is good but you shouldn't compare the strings, and instead you should get the actual position's symbol using PositionInfoString. Better yet, use CPositionInfo...

Thank you for pointing me to CPositionInfo; I was not aware of its existence. It looks like that this class provides the same functionality as what I have been using. For example: "pos.Volume()" gives the same result as "PositionGetDouble(POSITION_VOLUME)". The only benefit seems to be that it needs less letters to type in your code.

To be honest, I don't see a major difference between your suggestion and my implementation. Both are comparing strings but in a different way.

You seem to compare strings by using "pos.Symbol() == symbol".

I am comparing strings by using "StringCompare(Symbol(),PositionGetString(POSITION_SYMBOL),false)".

StringCompare() has the benefit that it can be done non case sensitive. I fear that your suggestion does not do that.

 
WindmillMQL :

Thank you for pointing me to CPositionInfo; I was not aware of its existence. It looks like that this class provides the same functionality as what I have been using. For example: "pos.Volume()" gives the same result as "PositionGetDouble(POSITION_VOLUME)". The only benefit seems to be that it needs less letters to type in your code.

To be honest, I don't see a major difference between your suggestion and my implementation. Both are comparing strings but in a different way.

You seem to compare strings by using "pos.Symbol() == symbol".

I am comparing strings by using "StringCompare(Symbol(),PositionGetString( POSITION_SYMBOL ),false)".

StringCompare() has the benefit that it can be done non case sensitive. I fear that your suggestion does not do that.

I gave you an example a long time ago: ( Example loop to traverse all positions in the code Example: Calculate Positions and Pending Orders :) and if you looked at it, you would see the use of the CPositionInfo class

How to start with MQL5
How to start with MQL5
  • 2020.03.12
  • www.mql5.com
This thread discusses MQL5 code examples. There will be examples of how to get data from indicators, how to program advisors...
 
WindmillMQL:

Thank you for pointing me to CPositionInfo; I was not aware of its existence. It looks like that this class provides the same functionality as what I have been using. For example: "pos.Volume()" gives the same result as "PositionGetDouble(POSITION_VOLUME)". The only benefit seems to be that it needs less letters to type in your code.

To be honest, I don't see a major difference between your suggestion and my implementation. Both are comparing strings but in a different way.

You seem to compare strings by using "pos.Symbol() == symbol".

I am comparing strings by using "StringCompare(Symbol(),PositionGetString(POSITION_SYMBOL),false)".

StringCompare() has the benefit that it can be done non case sensitive. I fear that your suggestion does not do that.

Many brokers include duplicate symbols (with slightly modified symbol names) for different reasons. Always check that the position symbol is an exact string match to (including case) the symbol on the chart. In those regards, a call to string compare is redundant. 

Reason: