OrderClose() issue mql4

 

Hi everyone

I try to close some orders (buy/sell) with OrderClose()

My code is this:

void CloseBuyOrder()
  {
   for(int i = OrdersTotal()-1; i >= 0 ; i--)
     {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
        {
         if(OrderSymbol() == Symbol())
            if(OrderMagicNumber() == magicnumber)
               if(OrderType() == OP_BUY)
                  while(!OrderClose(OrderTicket(), OrderLots(), Bid, slippage, clrYellow))
                    {
                     int err = GetLastError();
                     Print("Error in OrderClose. Error code= ",err, ErrorDescription(err));
                    }
        }
     }
  }

void CloseSellOrder()
  {
   for(int i = OrdersTotal()-1; i >= 0 ; i--)
     {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
        {
         if(OrderSymbol() == Symbol())
            if(OrderMagicNumber() == magicnumber)
               if(OrderType() == OP_SELL)
                  while(!OrderClose(OrderTicket(), OrderLots(), Ask, slippage, clrYellow))
                    {
                     int err = GetLastError();
                     Print("Error in OrderClose. Error code= ",err, ErrorDescription(err));
                    }
        }
     }
  }

I call functions like this:

CloseBuyOrder();
RefreshRates();
CloseSellOrder();

As you can see firstly i try to close buy orders (that it work clearly)

but in next when i try to close sell orders i got invalid price error

Do you know whats wrong?

 
yas:

Hi everyone

I try to close some orders (buy/sell) with OrderClose()

My code is this:

I call functions like this:

As you can see firstly i try to close buy orders (that it work clearly)

but in next when i try to close sell orders i got invalid price error

Do you know whats wrong?

 Pass the normalized price

NormalizeDouble(Bid, Digits())
NormalizeDouble(Ask, Digits())

Call RefreshRates() before every OrderClose()

// #1 Update prices (Bid/Ask)
RefreshRates();
// #2 Normalize the price
double price = NormalizeDouble(Bid, Digits());
// #3 Attempt to close
OrderClose(...)


while(!OrderClose(OrderTicket(), OrderLots(), Ask, slippage, clrYellow))

Don't use an infinite loop. You risk getting looped. Use the for() operator to limit the maximum number of iterations

 
Vladislav Boyko #:

 Pass the normalized price


Call RefreshRates() before every OrderClose()


Don't use an infinite loop. You risk getting looped. Use the for() operator to limit the maximum number of iterations

thank you a lot i got it

 
yas #:

thank you a lot i got it

Simple example

bool orderClose(int ticket, int type, double volume, int attempts = 3)
  {
   for(int i = 1; i <= attempts; i++)
     {
      RefreshRates();
      double price = type == 0 ? NormalizeDouble(Bid, Digits()) : NormalizeDouble(Ask, Digits());
      ResetLastError();
      if(OrderClose(ticket, volume, price, 999))
         return(true);
      PrintFormat("OrderClose error %i. Ticket %i", GetLastError(), ticket);
     }
   return(false);
  }
 
If use OrderClosePrice() you can forget about the direction of the closing trade 
 
  1. Each server call takes time. When it finishes, your predefined variables will be wrong. RefreshRates after each call.
  2. Or, stop using Bid/Ask and use OrderClosePrice() to be direction independent.
  3. Prices you get from the terminal (Bid/Ask) are already normalized.
 
William Roeder #:
  1. RefreshRates after each call.

Is the "before" option much worse? Not only calling the server can take time. I prefer to update prices immediately before use (in trading functions).

William Roeder #:
  1. Or, stop using Bid/Ask and use OrderClosePrice() to be direction independent.

I collect orders in an array. Like this:

struct STRUCT_ORDER
  {
   double price;
   double stopLoss;
   double takeProfit;
   double volume;
   int ticket;
   int type;
  };

STRUCT_ORDER orders[];

Do you think "OrderSelect() +  OrderClosePrice()" is better than "RefreshRates() + ternary_operator"?

 
Vladislav Boyko #:

Is the "before" option much worse? Not only calling the server can take time. I prefer to update prices immediately before use (in trading functions).

For example, you wait until the trade flow is free before closing the order

 
  1. Vladislav Boyko #:

    Is the "before" option much worse? Not only calling the server can take time. I prefer to update prices immediately before use (in trading functions).

    Do you think "OrderSelect() +  OrderClosePrice()" is better than "RefreshRates() + ternary_operator"?

    On the first call, the refresh does nothing. After the last call, your code goes on; does the remaining code use any predefined variables and now require a refresh also? Are you sure?

  2. Only blocking calls take time, what other calls do you have?

  3. OCP does not require a refresh and a test. Simplify.

 
William Roeder #:
On the first call, the refresh does nothing. After the last call, your code goes on; does the remaining code use any predefined variables and now require a refresh also? Are you sure?

    If I need the value of a predefined variable to be actual, then I call RefreshRates() before using the predefined variable. I understand you, thanks.

    William Roeder #:
    Only blocking calls take time, what other calls do you have?

      Usually I also do this check:

      bool orderClose(int ticket, int type, double volume, int attempts = 3)
        {
         for(int i = 1; i <= attempts; i++)
           {
            if(isTradeAllowed() < 0)
               return(false);
            RefreshRates();
            double price = type == 0 ? NormalizeDouble(Bid, Digits()) : NormalizeDouble(Ask, Digits());
            ResetLastError();
            if(OrderClose(ticket, volume, price, 999))
               return(true);
            PrintFormat("OrderClose error %i. Ticket %i", GetLastError(), ticket);
           }
         return(false);
        }
      
      int isTradeAllowed(uint MaxWaiting_sec = 10)
        {
         if(!IsTradeAllowed())
           {
            uint StartWaitingTime = GetTickCount();
            Print("Trade flow is busy! Waiting...");
            while(true)
              {
               if(IsStopped())
                 {
                  Print("The expert has been stopped by the user!"); 
                  return(-1); 
                 }
               if(GetTickCount() - StartWaitingTime > MaxWaiting_sec * 1000)
                 {
                  Print(StringConcatenate("Waiting limit exceeded (", MaxWaiting_sec, " sec.)!"));
                  return(-2);
                 }
               if(IsTradeAllowed())
                 {
                  Print("Trade flow is free!");
                  return(0);
                 }
               Sleep(100);
              }
           }
         return(1);
        }
      William Roeder #:
      OCP does not require a refresh and a test. Simplify.

        Unless you have analyzed the order history before. In this case, the OCP will contain the price of the closed order from the history. I find it much easier to use a bid/ask (+ RefreshRates()) than it is to consider cases like this. Or re-select an order whose properties are already known.


        I'm just interested in your opinion. Thank you for your responses

         
        Vladislav Boyko #: Unless you have analyzed the order history before. In this case, the OCP will contain the price of the closed order from the history.

        This post is not about history. It is about closing using Bid/Ask vs. OCP.