OrdersTotal(). Is last trade risk free?

 

Hello there,

I am playing around a bit with an EA to allow proper pyramiding. I want to find if the last opened trade of a given type is risk-free.

The thing is that I don't know the chronological order in which OrdersTotal() returns trades, the behavior of the EA seems no to change much.

Which code snippet is correct? This one?

/**
* Returns if the last opened order of this type is already risk-free.
* If there are no trades opened, true is returned.
*
* @param    int    Type
* @param    int    Magic
* @return   bool
*/
bool IsLastOrderRiskFree(int Type, int Magic)
{
   for(int i = OrdersTotal() - 1; i >= 0; i--)
   {
      OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
      if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic && OrderType() == Type)
      {
         if(Type == OP_BUY && OrderStopLoss() >= OrderOpenPrice() + (MarketInfo(Symbol(), MODE_SPREAD) * DecimalPip)) return(true);
         if(Type == OP_SELL && OrderStopLoss() <= OrderOpenPrice() - (MarketInfo(Symbol(), MODE_SPREAD) * DecimalPip)) return(true);
         return(false);
      }
   }
   return(true);
}

Or this one?

/**
* Returns if the last opened order of this type is already risk-free.
* If there are no trades opened, true is returned.
*
* @param    int    Type
* @param    int    Magic
* @return   bool
*/
bool IsLastOrderRiskFree(int Type, int Magic)
{
   for (int i = 0; i < OrdersTotal(); i++)
   {
      OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
      if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic && OrderType() == Type)
      {
         if(Type == OP_BUY && OrderStopLoss() >= OrderOpenPrice() + (MarketInfo(Symbol(), MODE_SPREAD) * DecimalPip)) return(true);
         if(Type == OP_SELL && OrderStopLoss() <= OrderOpenPrice() - (MarketInfo(Symbol(), MODE_SPREAD) * DecimalPip)) return(true);
         return(false);
      }
   }
   return(true);
}
Best regards,
 
flaab:

Hello there,

I am playing around a bit with an EA to allow proper pyramiding. I want to find if the last opened trade of a given type is risk-free.

The thing is that I don't know the chronological order in which OrdersTotal() returns trades, the behavior of the EA seems no to change much.

Which code snippet is correct? This one?

Or this one?

Best regards,

Hi flaab,

If the value of OrdersTotal() don't change very often - like in scalping EA, I say both of them can be use. However, if I may, this is the correct way of writing OrderSelect().

This is because the return of OrderSelect is either true or false and we must using it.

if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == true  //-->> if OrderSelect's return is true ...
    && OrderSymbol() == Symbol()                        //-->> ... AND if this is chart Symbol ...
    && OrderMagicNumber() == Magic                      //-->> ... AND this is our magic number ...
    && OrderType() == Type)                             //-->> ... AND this is the OrderType we're looking for ...
    {
                                                        //-->> ... then rock n roll
    }

:D

 
onewithzachy:

Hi flaab,

If the value of OrdersTotal() don't change very often - like in scalping EA, I say both of them can be use. However, if I may, this is the correct way of writing OrderSelect().

This is because the return of OrderSelect is either true or false and we must using it.

:D

Hi there,

But in order to get the LAST opened trade, how shoud I iterate the orders? Decreasing or increasing?

 
flaab:

Hi there,

But in order to get the LAST opened trade, how shoud I iterate the orders? Decreasing or increasing?

Hi flaab,

I prefer increasing one. This is the OrdersTotal() calculation of my scalping EA, the EA is a loser one. When I attach it to a lot of symbol, it open a lot of trades, however I had a problem, that the number of OrdersTotal() change in the middle of iteration. So I have to sort that out and this works well.

  int total = OrdersTotal(), gap;
  for(int i = 0; i < total; i++)     //-->> we count from zero to OrdersTotal()
     {
     //--- your code ...
     //--- ... goes here
     
     if (OrdersTotal() != total)     //-->> number of orders has change ...
       {
       gap = OrdersTotal() - total;  //-->> ... how many "change" ...
       if (gap < 0) gap = - gap;
       i = i - gap;                  //-->> ... we have to restart the iteration
       if (i < 0) i = -1             //-->> ... iteration less than 0, will be add by i++
       total = OrdersTotal();
       }
     }

:D


[Edit : My apology flaab, I didn't read your question carefully. In order to get LAST opened trade, either we have to record/save the last open time or the last ticket number (because ticket number is always increasing). However I prefer the last opened time. Something like this]

ticket = OrderSend (...);
if (ticket > 0)
  {
  if (OrderSelect (ticket, SELECT_BY_TICKET) == true)
     Open_Time = OrderOpenTime();
  }
  else
  {
  Print ("Failed to open position with err "+GetLastError());
  }
 

onewithzachy:

If the value of OrdersTotal() don't change very often - like in scalping EA, I say both of them can be use. However, if I may, this is the correct way of writing OrderSelect().

This is because the return of OrderSelect is either true or false and we must using it.

  1. If all you're doing is counting, etc. The OrdersTotal() will not be changing. If you do any long time functions in the loop like opening/closing/modifying then it can change.
  2. If you are closing orders, then you MUST count down AND check the orderSelect return code.
  3. if (OrderSelect (ticket, SELECT_BY_TICKET) == true)
    You would never code if ( (2+2 == 4) == True) would you? Of course not. if (boolValue) or if (!boolValue) is sufficient. Drop the "== true" it's unnecessary.
flaab:

The thing is that I don't know the chronological order in which OrdersTotal() returns trades, the behavior of the EA seems no to change much.

Which code snippet is correct? This one?

You function name is IsLastOrderRiskFree. Counting down and stopping at the first acceptable one is the Last order.
 
WHRoeder:
  1. If all you're doing is counting, etc. The OrdersTotal() will not be changing. If you do any long time functions in the loop like opening/closing/modifying then it can change.
  2. If you are closing orders, then you MUST count down AND check the orderSelect return code.
  3. You would never code if ( (2+2 == 4) == True) would you? Of course not. if (boolValue) or if (!boolValue) is sufficient. Drop the "== true" it's unnecessary.
You function name is IsLastOrderRiskFree. Counting down and stopping at the first acceptable one is the Last order.

1. Value of OrdersTotal() may change in the middle of iteration coz other EAs may open/close/delete their positions.

2. Agree, but I'm not closing orders.

3. I'm full aware that Flaab is no rookie in MQL4 programming. However there's plenty of forumer around here that write OrderSelect() like first code. It harm no one/nothing to write "== true". It's unnecessary to comment on " "== true" it's unnecessary ".

for (int i = 0; i < OrdersTotal(); i++)
   {
      OrderSelect(i, SELECT_BY_POS, MODE_TRADES);  
      if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic && OrderType() == Type)
      {

4. You said "Counting down and stopping at the first acceptable one is the Last order." Please define "first acceptable one" ?.

:D

 
  1. I did not say to put a untested order select The link is posted (tried to post) confirms to ALWAYS test your return codes.
  2. First acceptable one as already published
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == true  
        && OrderSymbol() == Symbol()  
        && OrderMagicNumber() == Magic
        && OrderType() == Type)    
  3. "== true" is unnecessary. Like in
    bool isUpTrend = fastMA > slowMA;
    if (isUpTrend == true)
    But if you use self documenting boolean names, the code is clearer withOUT it. Experience has shown that if you make an invalid boolean tests with good names, you'll see it and correct it.
 

1. Okay.

2. This is what flaab said in first post "I want to find if the last opened trade of a given type is risk-free." . The thing is, I don't know how many trades this EA open. If there's more than one with same Magic Number, same type, same symbol, then flaab must go for the biggest ticket or biggest open time, so his code is not sufficient to get the last one.

3. I have to write that way for the rookie.

Thanks for your comments WHRoeder

:D

 
Thanks a lot mates.
 

How Can one restrict a number of open position par pair?

 
int MaxOpensPerPair = 10;
string pairs[5];
int paircount[5];
pairs[0] = "EUR/USD";
pairs[1] = "USD/CHF";
pairs[2] = "GBP/USD";
pairs[3] = "USD/JPY";
pairs[4] = "EUR/GPB";
// do an OrderSelect() loop to identify all the relevent open orders of each pair and count them into an array
for(int i=0; i<OrdersTotal(); i++)
{if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
 {if(OrderMagicNumber() == Magic)
  {for(int p=0; p<5; p++)
   {if(OrderSymbol() == pairs[p])
    {paircount[p]++ ; // count all the open trades of each pair;
}}}}}
//check if any pairs can be traded
for(i=0; i<5; i++)
{if(paircount[i]<MaxOpensPerPair)
 { //do trade stuff for that pair
}} 
// untested.
Reason: