Check if Previous Order is Closed

 

Hello All, I'm sure the answer is buried deep within this forum and I have attempted to look just didn't find anything I might be able to use. Well any ways. Here is what I am trying to do.

Basically once an order is closed I want the take profit booleans to be set back to false that way the current trade is able to use them. Currently only the first trade that the EA looks at is working which is a fourth of the battle I suppose since I haven't even began to code if the EA is looking at multiple orders per pair. 

let me drop the code in and see if anyone can assist. Also I want to note this part of a bigger EA and this portion just handles the take profit or stop loss, a trade manager if you will.

int ticket,total;
int TP1    = 500;
int TP2    = 1000;
int TP3    = 1500;
double SLoss;
//These are the booleans for TakeProfit1-3 currently set to false.
bool TP1h=false,TP2h=false,TP3h=false,nTPset=true;

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void TradeManager(int input1)
  {
   /* */
//Gather Open Orders

   total = OrdersTotal();
// Print("Outside for loop");
   for(int i=total-1; i>=0; i--)
     {
      double bTP1h  = OrderOpenPrice() + (TP1*Point);
      double bTP2h  = OrderOpenPrice() + (TP2*Point);
      double bTP3h  = OrderOpenPrice() + (1300*Point);
      double sTP1h  = OrderOpenPrice() - (TP1*Point);
      double sTP2h  = OrderOpenPrice() - (TP2*Point);
      double sTP3h  = OrderOpenPrice() - (1300*Point);
      
      if(!OrderSelect(i, SELECT_BY_POS))
        {
         Print("Error in OrderSelect. Error code=",GetLastError());
        }

      int type   = OrderType();

      switch(type)
        {
         //Set stops and take profits
         case OP_BUY       :
            //Print("inside Buy Switch for loop");
            if(OrderStopLoss()==0 && OrderTakeProfit()==0 && nTPset)
              {

               SLoss = NormalizeDouble(OrderOpenPrice() - input1*Point,Digits);
               if(!OrderModify(OrderTicket(),OrderOpenPrice(),SLoss,OrderOpenPrice() + TP3*Point,0,0))
                 {
                  Print("Inside Buy IF statment");
                  //Print("Error in OrderModify. Error code=",GetLastError());
                 }
               nTPset=false;
              }
            if(Ask >= bTP1h && TP1h==false)
              {
//As Price rise and reaches any of the Take Profit it will set the bool to true
               TP1h=true;
               SLoss = NormalizeDouble(OrderOpenPrice(),Digits);
               if(!OrderModify(OrderTicket(),OrderOpenPrice(),SLoss,OrderTakeProfit(),0,0))
                 {
                  Print("Inside Buy Take Profit 1 IF statment");
                  //Print("Error in OrderModify. Error code=",GetLastError());
                 }
              }
            if(Ask >= bTP2h && TP2h==false)
              {
               TP2h=true;
               SLoss = NormalizeDouble(bTP1h,Digits);
               if(!OrderModify(OrderTicket(),OrderOpenPrice(),SLoss,OrderTakeProfit(),0,0))
                 {
                  // Print("Error in OrderModify. Error code=",GetLastError());
                 }
              }
            if(Ask >= bTP3h && TP3h==false)
              {
               TP3h=true;
               SLoss = NormalizeDouble(bTP2h,Digits);
               if(!OrderModify(OrderTicket(),OrderOpenPrice(),SLoss,OrderTakeProfit(),0,0))
                 {
                  //  Print("Error in OrderModify. Error code=",GetLastError());
                 }
              }
//Now my question is once this order is closed how do I set the booleans back to false to be used again for the next order
            break;
         case OP_BUYLIMIT  :
            if(OrderStopLoss()==0 && OrderTakeProfit()==0 && nTPset)
              {
               SLoss = NormalizeDouble(OrderOpenPrice() - input1*Point,Digits);
               if(!OrderModify(OrderTicket(),OrderOpenPrice(),SLoss,OrderOpenPrice() + TP3*Point,0,0))
                 {
                  // Print("Error in OrderModify. Error code=",GetLastError());
                 }
               nTPset=false;
              }
            break;
         case OP_BUYSTOP   :
            if(OrderStopLoss()==0 && OrderTakeProfit()==0 && nTPset)
              {
               SLoss = NormalizeDouble(OrderOpenPrice() - input1*Point,Digits);
               if(!OrderModify(OrderTicket(),OrderOpenPrice(),SLoss,OrderOpenPrice() + TP3*Point,0,0))
                 {
                  //   Print("Error in OrderModify. Error code=",GetLastError());
                 }
               nTPset=false;
              }
            break;
         case OP_SELL      :
            if(OrderStopLoss()==0 && OrderTakeProfit()==0  && nTPset)
              {
               SLoss = NormalizeDouble(OrderOpenPrice() + input1*Point,Digits);
               if(!OrderModify(OrderTicket(),OrderOpenPrice(),SLoss,OrderOpenPrice() - TP3*Point,0,0))
                 {
                  //Print("Error in OrderModify. Error code=",GetLastError());
                 }
               nTPset=false;
              }
            if(Bid < sTP1h)
              {
               SLoss = NormalizeDouble(OrderOpenPrice(),Digits);
               if(!OrderModify(OrderTicket(),OrderOpenPrice(),SLoss,OrderTakeProfit(),0,0))
                 {
                  //   Print("Error in OrderModify. Error code=",GetLastError());
                 }
              }
            if(Bid < sTP2h)
              {
               SLoss = NormalizeDouble(sTP1h,Digits);
               if(!OrderModify(OrderTicket(),OrderOpenPrice(),SLoss,OrderTakeProfit(),0,0))
                 {
                  //    Print("Error in OrderModify. Error code=",GetLastError());
                 }
              }
            if(Bid < sTP3h)
              {
               SLoss = NormalizeDouble(sTP2h,Digits);
               if(!OrderModify(OrderTicket(),OrderOpenPrice(),SLoss,OrderTakeProfit(),0,0))
                 {
                  //  Print("Error in OrderModify. Error code=",GetLastError());
                 }
              }
            break;
         case OP_SELLLIMIT :
            if(OrderStopLoss()==0 && OrderTakeProfit()==0 && nTPset)
              {
               SLoss = NormalizeDouble(OrderOpenPrice() + input1*Point,Digits);
               if(!OrderModify(OrderTicket(),OrderOpenPrice(),SLoss,OrderOpenPrice() - TP3*Point,0,0))
                 {
                  //    Print("Error in OrderModify. Error code=",GetLastError());
                 }
               nTPset=false;
              }
            break;
         case OP_SELLSTOP  :
            if(OrderStopLoss()==0 && OrderTakeProfit()==0 && nTPset)
              {
               SLoss = NormalizeDouble(OrderOpenPrice() + input1*Point,Digits);
               if(!OrderModify(OrderTicket(),OrderOpenPrice(),SLoss,OrderOpenPrice() - TP3*Point,0,0))
                 {
                  //  Print("Error in OrderModify. Error code=",GetLastError());
                 }
               nTPset=false;
              }
            break;
        }

   Comment(
      "Buy Take Profit 1 :",bTP1h,"\n"
      "Ask Price:",Ask,"\n");

     }



  }
 
I have spents hours combing this site and yes there are some very complicated coding that goes over my head that I may be able to use. Honestly if someone could just point me in the right direction, I know its a logic issue, where do I put the orderselect if statement. I suppose I could just create a test ea and see if I can pull up the previous order number and go from there. Hmm I will try something..  
 
Joe Ramirez:
I have spents hours combing this site and yes there are some very complicated coding that goes over my head that I may be able to use. Honestly if someone could just point me in the right direction, I know its a logic issue, where do I put the orderselect if statement. I suppose I could just create a test ea and see if I can pull up the previous order number and go from there. Hmm I will try something..  

First of all, these lines:

if(!OrderSelect(i, SELECT_BY_POS))
        {
         Print("Error in OrderSelect. Error code=",GetLastError());
         break;
        }

should go before this block:

      double bTP1h  = OrderOpenPrice() + (TP1*Point);
      double bTP2h  = OrderOpenPrice() + (TP2*Point);
      double bTP3h  = OrderOpenPrice() + (1300*Point);
      double sTP1h  = OrderOpenPrice() - (TP1*Point);
      double sTP2h  = OrderOpenPrice() - (TP2*Point);
      double sTP3h  = OrderOpenPrice() - (1300*Point);

Then you need to check for OrderSymbol() and OrderMagicNumber() if you think your EA will run on multiple orders/pairs in the future.

Once rectified, this same loop can be used to check for whether all orders have been closed, by using an integer counter - whenever an OrderSelect(), OrderSymbol() and OrderMagicNumber() succeeds, add one to the counter. This way, after the for loop, if that counter remains zero, you can reset your 3 flags.

 
  total = OrdersTotal();
// Print("Outside for loop");
   for(int i=total-1; i>=0; i--)
     {
      double bTP1h  = OrderOpenPrice() + (TP1*Point);
  1. Magic number only allows an EA to identify its trades from all others. Using OrdersTotal/OrdersHistoryTotal (MT4) or PositionsTotal (MT5), directly and/or no Magic number filtering on your OrderSelect / Position select loop means your code is incompatible with every EA (including itself on other charts and manual trading.)
              Symbol Doesn't equal Ordersymbol when another currency is added to another seperate chart . - MQL4 programming forum
              PositionClose is not working - MQL5 programming forum
              MagicNumber: "Magic" Identifier of the Order - MQL4 Articles

  2. You can not use any Trade Functions unless you select an order first.
 
Seng Joo Thio:

First of all, these lines:

should go before this block:

Then you need to check for OrderSymbol() and OrderMagicNumber() if you think your EA will run on multiple orders/pairs in the future.

Once rectified, this same loop can be used to check for whether all orders have been closed, by using an integer counter - whenever an OrderSelect(), OrderSymbol() and OrderMagicNumber() succeeds, add one to the counter. This way, after the for loop, if that counter remains zero, you can reset your 3 flags.

Thanks for your reply, I see that you added a break in the if statement I have. Basically its saying if the statement is false to break out the for loop?

As for the double variables, I moved them inside the loop after noticing they wouldn't change after the first order was closed, never thought there position would cause interference, I suppose it would prevent them from pulling unnecessary data if the previous statement is false and breaks out the loop.

I did manage to create a smaller module just for checking previous orders, using OrdersTotalHistory rather than OrdersTotal, which is what I think my issue was when looking to see if the previous order is closed.

Now from what I understand I should look to see if the ordersclosetime equals 0, if it does than the order is still open. 

As for the multiple orders and different pairs thats for later, but I do want to thank you for taking the time to look at the code. 

 
William Roeder:
  1. Magic number only allows an EA to identify its trades from all others. Using OrdersTotal/OrdersHistoryTotal (MT4) or PositionsTotal (MT5), directly and/or no Magic number filtering on your OrderSelect / Position select loop means your code is incompatible with every EA (including itself on other charts and manual trading.)
              Symbol Doesn't equal Ordersymbol when another currency is added to another seperate chart . - MQL4 programming forum
              PositionClose is not working - MQL5 programming forum
              MagicNumber: "Magic" Identifier of the Order - MQL4 Articles

  2. You can not use any Trade Functions unless you select an order first.

Would simply moving the variables below the orderselect if statement be sufficient. like so.

for(int i=total-1; i>=0; i--)
     {
      
      if(!OrderSelect(i, SELECT_BY_POS))
        {
         Print("Error in OrderSelect. Error code=",GetLastError());
         break;
        }

        double bTP1h  = OrderOpenPrice() + (TP1*Point);
 
Joe Ramirez:

Thanks for your reply, I see that you added a break in the if statement I have. Basically its saying if the statement is false to break out the for loop? 

Yes, because if it's false, something is very wrong, and you should check the returned error code before proceeding.

Joe Ramirez:

As for the double variables, I moved them inside the loop after noticing they wouldn't change after the first order was closed, never thought there position would cause interference, I suppose it would prevent them from pulling unnecessary data if the previous statement is false and breaks out the loop. 

Functions like OrderOpenPrice() will return the open price of an order previously selected by OrderSelect(), so it makes sense to have OrderSelect() a priori.

Joe Ramirez:

I did manage to create a smaller module just for checking previous orders, using OrdersTotalHistory rather than OrdersTotal, which is what I think my issue was when looking to see if the previous order is closed.

Now from what I understand I should look to see if the ordersclosetime equals 0, if it does than the order is still open.  

That is one way, and will be useful if you want to extract certain information (e.g. close price).

Otherwise, as I've mentioned (which you probably missed), an easier way is to ride on your existing 'for' loop. You just have to add an integer counter that adds 1 whenever an order of interest is found ("interest" depends on whether you consider multiple symbols/magic numbers). This way, after the loop, if this counter is 0 and the 'for' loop did not exit due to any error, all your orders must have been closed and you can reset your bool flags there and then.

 
Seng Joo Thio:

Yes, because if it's false, something is very wrong, and you should check the returned error code before proceeding.

Functions like OrderOpenPrice() will return the open price of an order previously selected by OrderSelect(), so it makes sense to have OrderSelect() a priori.

That is one way, and will be useful if you want to extract certain information (e.g. close price).

Otherwise, as I've mentioned (which you probably missed), an easier way is to ride on your existing 'for' loop. You just have to add an integer counter that adds 1 whenever an order of interest is found ("interest" depends on whether you consider multiple symbols/magic numbers). This way, after the loop, if this counter is 0 and the 'for' loop did not exit due to any error, all your orders must have been closed and you can reset your bool flags there and then.

First I do want to thank you again for your feedback it is greatly appreciated. I really enjoy coding and everything I have learned is self-taught so I know for a fact the structure or logic is sometimes loss due to lack of experience. 

As for missing what you mentioned, No I didnt. I just didnt know how to write it in code thus continued working on what I did know such as using OrdersHistoryTotal(). The reason for me creating another module is really just to have a smaller function specific for looking at the previous order and determine if I could detect if it was closed. Once I was able to get that to work I would add the code not the module to the current piece I am working on. 

Now let me see if I can understand what you mean by still using OrdersTotal which originally when I started this didnt know that is was just looking at current pending/open orders. I'm going to write it out below to see if I can make sense of it.

total = OrdersTotal();


   for(int i=total-1; i>=0; i--)
     {

        if(!OrderSelect(i, SELECT_BY_POS))
        {
         Print("Error in OrderSelect. Error code=",GetLastError());
        }

        if(OrderMagicNumber() != MagicNumber || OrderSymbol() != Symbol() ) continue; 

        if (OrderSymbol() == Symbol())
         { 
                if(total==0) // Meaning if total of open/pending orders equals 0 then all orders are closed
                {
                bool1=false;
                bool2=false;
                bool3=false;
                }
                
        
         }

     }

Something like this?

Below is what i have written for OrdersHistoryTotal() a lot of what I do is trial and error. Now this works as intended the print statement will print once the previous order is closed.. 

previousOrders = OrdersHistoryTotal();


   for(int i=previousOrders; i>=0; i--)
     {

      
      //Print("The Current Order Number is ",i);
      //Print("The Previous Order Number is ",previousOrder);
      if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY))
        {
         //Print("The Previous Order Number is ",previousOrder);
         if(OrderCloseTime()!=0)
           {
           Print("The Previous Order Number is ",i+1," Order has closed");
           Print("The Previous Order Close Price is ",OrderClosePrice());
           break;
           }
        }

     }
 
Joe Ramirez:

First I do want to thank you again for your feedback it is greatly appreciated. I really enjoy coding and everything I have learned is self-taught so I know for a fact the structure or logic is sometimes loss due to lack of experience. 

As for missing what you mentioned, No I didnt. I just didnt know how to write it in code thus continued working on what I did know such as using OrdersHistoryTotal(). The reason for me creating another module is really just to have a smaller function specific for looking at the previous order and determine if I could detect if it was closed. Once I was able to get that to work I would add the code not the module to the current piece I am working on. 

Now let me see if I can understand what you mean by still using OrdersTotal which originally when I started this didnt know that is was just looking at current pending/open orders. I'm going to write it out below to see if I can make sense of it.

Something like this?

Below is what i have written for OrdersHistoryTotal() a lot of what I do is trial and error. Now this works as intended the print statement will print once the previous order is closed.. 

Here's the way:

   int counter = 0;
   total = OrdersTotal();
   for(int i=total-1; i>=0; i--)
     {
        if(!OrderSelect(i, SELECT_BY_POS))
        {
         Print("Error in OrderSelect. Error code=",GetLastError());
         break;
        }

        if(OrderMagicNumber() != MagicNumber || OrderSymbol() != Symbol() ) continue; 

        if (OrderType()==OP_BUY || OrderType()==OP_SELL) // Here you need to include order types that, if exist, will not require you to reset the bools.
           counter++;

        // Do your usual stuff in your earlier post.
        
     }
   if (counter==0)
     {
      bool1=false;
      bool2=false;
      bool3=false;
     }
  }

As for your solution that made use of OrderHistoryTotal(), you need to handle the scenario where you already have multiple closed orders - when that happens, you'll get false indication that you have no currently open order.

 

You sir! are a freaking genius! I was able to modify the code as you have indicated, and its working like it should, both buy and sell orders trail price like expected. 

Thank you very much. I just need a little direction and you did just that. Greatly appreciate your assistance.

 
How can we write a function in the expert section of MetaTrader 5 to determine if a closed trade was closed with a profit or a loss?
For example, I want to open a buy trade every day at exactly 20:30 broker time on the 5-minute time frame, with a take profit of 400 points and a stop loss of 200 points. When the trade is closed, if it was closed with the take profit, draw a thick blue horizontal line at the time and price of the closing. If it was closed with the stop loss, draw a thick yellow horizontal line at the time and price of the closing.