CloseOrders by FIFO Rules

 


I made this code for close from the first to the last ticket according to the FIFO rule:

void CloseShort(){
   int FirstOrderTicket=0;
   int LastOrderTicket=0;
   for(int i=OrdersTotal()-1;i>=0;i--){
      if(OrderSelect(0,SELECT_BY_POS,MODE_TRADES)){
         if(OrderType()==OP_SELL){FirstOrderTicket=OrderTicket();}
         }
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)){
         if(OrderType()==OP_SELL){LastOrderTicket=OrderTicket();}
         }
      }
   for(int s=FirstOrderTicket;s<=LastOrderTicket;s++){
      if(OrderSelect(s,SELECT_BY_TICKET,MODE_TRADES)){
         if(OrderType()==OP_SELL&&OrderSymbol()==Symbol()){
            (ORDERCLOSE)

The first Loop counting from the last gets FirstOrderTicket=POS(0) and the LastOrderTicket.

Then the second loop starts from FirstOrderTicket to the LastOrderTicket to close open orders, but the strategy tester is giving this fail:

2019.05.09 16:49:47.314 2019.04.24 01:51:00  NewGrid EURUSD,M1: unknown ticket 1 for OrderClose function

Anyone can help? Thanks in advance.

 
In the presence of multiple orders (one EA multiple charts, multiple EAs, manual trading,) while you are waiting for the current operation (closing, deleting, modifying) to complete, any number of other operations on other orders could have concurrently happened and changed the position indexing:
  1. For non-FIFO (US brokers,) (or the EA only opens one order per symbol,) you can simply count down in a position loop, and you won't miss orders. Get in the habit of always counting down.
              Loops and Closing or Deleting Orders - MQL4 and MetaTrader 4 - MQL4 programming forum
    For FIFO (US brokers,) and you (potentially) process multiple orders per symbol, you must count up and on a successful operation, reprocess all positions (set index to -1 before continuing.)
  2. and check OrderSelect in case earlier positions were deleted.
              What are Function return values ? How do I use them ? - MQL4 and MetaTrader 4 - MQL4 programming forum
              Common Errors in MQL4 Programs and How to Avoid Them - MQL4 Articles
  3. and if you (potentially) process multiple orders, must call RefreshRates() after server calls if you want to use, on the next order / server call, the Predefined Variables (Bid/Ask) or (be direction independent and use) OrderClosePrice().
 
William Roeder:
In the presence of multiple orders (one EA multiple charts, multiple EAs, manual trading,) while you are waiting for the current operation (closing, deleting, modifying) to complete, any number of other operations on other orders could have concurrently happened and changed the position indexing:
  1. For non-FIFO (US brokers,) (or the EA only opens one order per symbol,) you can simply count down in a position loop, and you won't miss orders. Get in the habit of always counting down.
              Loops and Closing or Deleting Orders - MQL4 and MetaTrader 4 - MQL4 programming forum
    For FIFO (US brokers,) and you (potentially) process multiple orders per symbol, you must count up and on a successful operation, reprocess all positions (set index to -1 before continuing.)
  2. and check OrderSelect in case earlier positions were deleted.
              What are Function return values ? How do I use them ? - MQL4 and MetaTrader 4 - MQL4 programming forum
              Common Errors in MQL4 Programs and How to Avoid Them - MQL4 Articles
  3. and if you (potentially) process multiple orders, must call RefreshRates() after server calls if you want to use, on the next order / server call, the Predefined Variables (Bid/Ask) or (be direction independent and use) OrderClosePrice().
Can you post an example about reprocess positions and set index to -1? Would be very helpful.
 
David Diez:
Can you post an example about reprocess positions and set index to -1? Would be very helpful.
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void Close_AllOrders()
  {
/*-----------------------------------------------------------------------------------------------*/
//Close Orders according to FIFO Rule
   for(i=0; i<OrdersTotal(); i++)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
         if(OrderSymbol()==Symbol())
           {
            if(OrderType()==OP_BUY)
              {
               Close_Result=OrderClose(OrderTicket(),OrderLots(),Bid,0,clrNONE);
               if(Close_Result) i--;
              }
            if(OrderType()==OP_SELL)
              {
               Close_Result=OrderClose(OrderTicket(),OrderLots(),Ask,0,clrNONE);
               if(Close_Result) i--;
              }
           }
     }
/*-----------------------------------------------------------------------------------------------*/
//Error Check
   int Error=GetLastError();
   if(Error>=3)
     {
      Alert("Close_AllOrders() ..Error  : "+ErrorDescription(GetLastError()));
      Print("Close_AllOrders() ..Error  : "+ErrorDescription(GetLastError()));
     }
/*-----------------------------------------------------------------------------------------------*/
   return;
  }
 
Donald Gibson:

Think this will work, thank you.

 
Donald Gibson:
if(Close_Result) i--;
Wrong. While the order was closing, any number of other orders could have also closed. What part of " successful operation, reprocess all positions (set index to -1 before continuing.) " was unclear?
 

William Roeder
:

Wrong. While the order was closing, any number of other orders could have also closed. What part of " successful operation, reprocess all positions (set index to -1 before continuing.) " was unclear?
   for(int b=0;b<OrdersTotal();b++){
      if(OrderSelect(b,SELECT_BY_TICKET,MODE_TRADES)){
         if(OrderType()==OP_BUY&&OrderSymbol()==Symbol()){
            if(OrderProfit()>=0){
               if(!OrderClose(OrderTicket(),OrderLots(),Bid,3,clrGold)){
                  Print("OrderClose error ",GetLastError());
                  RefreshRates();
                  return;
                  }

               else{b=-1;} <-- YOU MEAN THIS?
 

The easiest way is to use recursion. Like whoder says, any number of things can happen between order functions

int closeShortFifoTrades() {
   int ticket = WRONG_VALUE;
   int result = 0;
   for (int i=0; OrderSelect(i, SELECT_BY_POS); i++) 
      if (OrderType() == OP_SELL && (ticket == WRONG_VALUE || OrderTicket() < ticket))
         ticket = OrderTicket();
   bool close = (
      ticket != WRONG_VALUE
      && OrderSelect(ticket, SELECT_BY_TICKET)
      && OrderClose(ticket, OrderLots(), OrderClosePrice(), 10)
   );
   if (close)
      return closeShortFifoTrades() + 1;
   return result;
}
 
nicholi shen:

The easiest way is to use recursion. Like whoder says, any number of things can happen between order functions

Thank you for your reply.
 
The code by Donald Simpson works.
 
David Diez: The code by Donald Simpson works.

Not if orders on other charts also close (by TP, SL, close or delete,) while OrderClose has not yet returned.

I provided links, read them.
          How to separate (and close) (Market) Sell orders and Buy orders separately? - Liquidity - MQL4 and MetaTrader 4 - MQL4 programming forum - Page 2

Reason: