MQL5: Get the amount of deals since the postions was (re)opened

 

Hi guys,

I am moving from MT4 to MT5 and am rewriting my libraries. Because of the new concept of having only one postion per currency pair I have a problem.
I want to identify how many deals have been made since the postion was reopened.

So for example if I do the following trades on any currency pair:

Lotsize 0.1 Buy
Lotsize 0.2 Buy
Lotsize 0.3 Sell (The position was closed here)
Lotsize 0.1 Buy
Lotsize 0.2 Buy

I would like to find out that here the amount of (open) deals are 2 (!!).

If I use HistoryDealsTotal() I get 5 back.

I don't want to iterate through the whole deals histrory to get that information because of performance reasons and I also don't want to store this informtion in runtime variables because the EA might be stopped / started again and this information needs to be prevserved. I also don't want to use global variables (.ini)

Is there another clean and well performing option?

Thanks,
Wolfgang

 
rgereal:

Hi guys,

I am moving from MT4 to MT5 and am rewriting my libraries. Because of the new concept of having only one postion per currency pair I have a problem.
I want to identify how many deals have been made since the postion was reopened.

So for example if I do the following trades on any currency pair:

Lotsize 0.1 Buy
Lotsize 0.2 Buy
Lotsize 0.3 Sell (The position was closed here)
Lotsize 0.1 Buy
Lotsize 0.2 Buy

I would like to find out that here the amount of (open) deals are 2 (!!).

If I use HistoryDealsTotal() I get 5 back.

I don't want to iterate through the whole deals histrory to get that information because of performance reasons and I also don't want to store this informtion in runtime variables because the EA might be stopped / started again and this information needs to be prevserved. I also don't want to use global variables (.ini)

Is there another clean and well performing option?

Thanks,
Wolfgang

just passed my mind that you can comment each deal with the relevant information at execution time.

For instance:

Lotsize 0.1 Buy - comment the deal with "1st deal"
Lotsize 0.2 Buy - comment the deal with "2nd deal"
Lotsize 0.3 Sell (The position was closed here)
Lotsize 0.1 Buy - comment the deal with "1st deal"
Lotsize 0.2 Buy - comment the deal with "2nd deal"

now you just have to read the last deal from history and you have what you need in the comment. 

 
rgereal:

Hi guys,

I am moving from MT4 to MT5 and am rewriting my libraries. Because of the new concept of having only one postion per currency pair I have a problem.
I want to identify how many deals have been made since the postion was reopened.

So for example if I do the following trades on any currency pair:

Lotsize 0.1 Buy
Lotsize 0.2 Buy
Lotsize 0.3 Sell (The position was closed here)
Lotsize 0.1 Buy
Lotsize 0.2 Buy

I would like to find out that here the amount of (open) deals are 2 (!!).

If I use HistoryDealsTotal() I get 5 back.

I don't want to iterate through the whole deals histrory to get that information because of performance reasons and I also don't want to store this informtion in runtime variables because the EA might be stopped / started again and this information needs to be prevserved. I also don't want to use global variables (.ini)

Is there another clean and well performing option?

Thanks,
Wolfgang

A big bold blue text is a link - click that please.

Even if you have to go through the deal history, I think you should not be worry because MT5 always go through historical data in fast speed and also there are ways to make the iteration more efficient.

1 . You don't have to go through historical in every tick, just iterate when there changes in total number of historical data.

int Deals_Total; //--- this variable must be declared globally

if (Deals_Total != HistoryDealsTotal() )
   {
   Deals_Total= HistoryDealsTotal();
   //--- iterate here

   }

 2. You can iterate starting from a specific time in historical data that you select using HistorySelect . By using this function, at the first iteration in history, like it or not - we have to iterate the entire history, but once we get the deal time that close other position (in your case is sell deal that close buy position), we have to save the deal time into variable and use it for the next iteration. On the next iteration, we will NOT iterate the entire history, but only from that saved deal time to current time.

So we can add the code above into this code below

int      Deals_Total; //--- this variable must be declared globally
datetime  Start_Time;  //--- this variable must be declared globally

if (Deals_Total != HistoryDealsTotal() )
   {
   Deals_Total = HistoryDealsTotal();
   HistorySelect (Start_Time, TimeCurrent() );  //--- only iterate from start time to current time :)

   //--- iterate here

   }

3. Don't worry about globally declared variable (no I'm not talking about MT5's Global Variables of the Terminal ). In EA, globally declared variable will not lose it's value if we open EA property, except if you change it in OnInit().

Try this EA, attach this EA to a chart, then open the EA property (press F7), you may change the input or not (and you may want to do some other experiment with this) but whatever it is, the value of variable my_double and my_count is NOT lost.

input string Some_Input="whatever";
double my_double = 0.0;
bool Alert_Once;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   if (my_double == 0.0)
     Print ("First time running.");
     else
     Print ("NOT the first time running."); 
   
   if (Alert_Once == true)Alert_Once = false;
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
  //---
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
 { 
  static int my_count;
 
  my_count ++;
 
  if (my_double == 0.0)
    {
    my_double =12345.678901;
    Print ("Set value to my double ", my_double);
    }

  if (Alert_Once == false)
    {
    Print ("",my_count," my double is ", my_double);
    Alert_Once = true;
    }
  
  return;
 }
//+------------------------------------------------------------------+

4. About using comment. It's a bad idea using comment as an identifier for our trades, (and btw, we have to iterate through the history to find the matching comment). Broker can delete our trade comment and replace it with their own comment. This is the only way for broker to communicate with us in real trading time. For example, if we get margin call and broker close some of our positions, broker will make comment on that closed position to tell us why our position is closed, and so therefore they practically delete our trade comment.

5. My advice is, save that ticket number (of deal, or order, or that position), in globally declared variable, so we can use it in the future. And you should have some code to iterate through history, just in case something happen, like your MT is closed by accident - not your fault, just some accident :(

That's all ;D 

 

 

Since there is only one open position of a symbol in mt5, can we use PositionGetInteger(POSITION_IDENTIFIER) to get the position ID first,

then use HistorySelectByPosition(position_id)  to retrieve the history of deals and orders having the specified position identifier.

then use HistoryDealsTotal() to get the numbers of deals which compose this position?

    long position_id;
    if(PositionSelect(symbol))
      {
        position_id = PositionGetInteger(POSITION_IDENTIFIER);
      }
    else
      return;        
    HistorySelectByPosition(position_id);
    int deals = HistoryDealsTotal();  

Am i right?

 
luenbo:

 

Since there is only one open position of a symbol in mt5, can we use PositionGetInteger(POSITION_IDENTIFIER) to get the position ID first,

then use HistorySelectByPosition(position_id)  to retrieve the history of deals and orders having the specified position identifier.

then use HistoryDealsTotal() to get the numbers of deals which compose this position?

Am i right?

You know what : You are right, luenbo !. rgereal, luenbo's code is better, so use it.

Why I didn't think of that ? What was I thinking back then, anyway ?

Good one luenbo !

 

Thank you guys for all your input. I implemented a slightly modified version now which iterates through the currently open or "just closed" orders in order to identify how many are open.

I iterate in reverse order (new to old) and stop when I hit an entry that is not of type ENUM_DEAL_ENTRY::DEAL_ENTRY_IN.

The items counted so far are my currently open orders for that symbol.


int TradingRobot::MarketOrdersOpen(string PositionSymbol)
{
    PositionSelect(PositionSymbol);
    double PositionVolume = PositionGetDouble(POSITION_VOLUME);
    if (PositionVolume==0) return 0;
    
    long PositionID = PositionGetInteger(POSITION_IDENTIFIER);
    
    if (HistorySelectByPosition(PositionID))
    {
        int OrdersOpen=0;
        
        for(int i=HistoryDealsTotal()-1;i>=0;i--)
        {
            ulong DealTicket = HistoryDealGetTicket(i);
            ENUM_DEAL_TYPE DealType = HistoryDealGetInteger(DealTicket,DEAL_TYPE);
            ENUM_DEAL_ENTRY DealEntry = HistoryDealGetInteger(DealTicket,DEAL_ENTRY);
            
            if (DealEntry==ENUM_DEAL_ENTRY::DEAL_ENTRY_IN)
            {
                OrdersOpen++;
            }
            else
            {
                return OrdersOpen;
            }
         }
         return OrdersOpen;
    }
    else
    {
        return 0;
    }
}



Reason: