OrderClose() - error 138

 

Hi there,

i have an issue with OrderClose() command generating error code 138

This seems to work OK, that is: No 138 errors

void OnTick()
  {
   if(iTime(symb,timecheck,0)>start_current_bar)                           
     {
      <catching some technical indicators>

      ri="Cash";
      for(int r=OrdersTotal(); r>=1; r--)                 here we check for positions using SELECT_BY_POS which works well
        {
         if(OrderSelect(r-1,SELECT_BY_POS))
           {
            if(OrderSymbol()==symb && OrderMagicNumber()==magic)
              {
               if(OrderType()==OP_BUY)                                 
                 {
                  ticket_long=OrderTicket();
                  ri="Long";
                  pr_open=OrderOpenPrice();
                 }
               if(OrderType()==OP_SELL)                             
                 {
                  ticket_short=OrderTicket();
                  ri="Short";
                  pr_open=OrderOpenPrice();
                 }
              }
           }
        }

      if(ri=="Long" and some condition based on technical indictors and order open price)
        {
         if(OrderClose(ticket_long,lots,OrderClosePrice(),100,clrGreen)==TRUE) 
            ri="Cash";
        }

      if(ri=="Short" and some other condition based on technical indictors and order open price)
        {
         if(OrderClose(ticket_short,lots,OrderClosePrice(),100,clrRed)==TRUE)
            ri="Cash";
        }

      if(ri=="Cash")
        {
         if(some condition based on technical indictors)       
            ticket_long=OrderSend(symb,OP_BUY,lots,Ask,100,low-0.2*(Ask-low),0,comment,magic,0,clrGreen);                                                  
         if(some other condition based on technical indictors)   
            ticket_short=OrderSend(symb,OP_SELL,lots,Bid,100,high+0.2*(high-Bid),0,comment,magic,0,clrGreen);                                              


         start_current_bar=iTime(symb,timecheck,0);                       
        }
     }
  }

But  when the look up is done by Ticket (see below), which i find more efficient, i get the 138 error.

Also, i get is sometimes, not all the time.

I'm sure i'm overlooking something, but what?

(note that a long and short can never be open at the same time - it's either/or)

void OnTick()
  {
   if(iTime(symb,timecheck,0)>start_current_bar)                           
     {
      <catching some technical indicators>

      ri="Cash";

      if(OrderSelect(ticket_long,SELECT_BY_TICKET))       //here we use SELECT_BY_TICKET which brings (and causes?) error 138
         {
          if(OrderCloseTime()==0)
             {
              ri="Long";
              pr_open=OrderOpenPrice();
             }
         }
      if(OrderSelect(ticket_short,SELECT_BY_TICKET))                            
         {                       
          if(OrderCloseTime()==0)
             {
              ri="Short";
              pr_open=OrderOpenPrice();
             }
         }


      if(ri=="Long" and some condition based on technical indictors and order open price)
        {
         if(OrderClose(ticket_long,lots,OrderClosePrice(),100,clrGreen)==TRUE) 
            ri="Cash";
        }

      if(ri=="Short" and some other condition based on technical indictors and order open price)
        {
         if(OrderClose(ticket_short,lots,OrderClosePrice(),100,clrRed)==TRUE)
            ri="Cash";
        }

      if(ri=="Cash")
        {
         if(some condition based on technical indictors)       
            ticket_long=OrderSend(symb,OP_BUY,lots,Ask,100,low-0.2*(Ask-low),0,comment,magic,0,clrGreen);                                                  
         if(some other condition based on technical indictors)   
            ticket_short=OrderSend(symb,OP_SELL,lots,Bid,100,high+0.2*(high-Bid),0,comment,magic,0,clrGreen);                                              


         start_current_bar=iTime(symb,timecheck,0);                       
        }
     }
  }
OOP in MQL5 by Example: Processing Warning and Error Codes
OOP in MQL5 by Example: Processing Warning and Error Codes
  • www.mql5.com
The article describes an example of creating a class for working with the trade server return codes and all the errors that occur during the MQL-program run. Read the article, and you will learn how to work with classes and objects in MQL5. At the same time, this is a convenient tool for handling errors; and you can further change this tool according to your specific needs.
 

It may help to first search the forum for similar situations ... https://www.mql5.com/en/search#!keyword=OrderClose%20error%20138

The forum is filled with posts asking about the "requote" error. It has been asked many times and answered even more times.

 

Here are some I've answered before:

Forum on trading, automated trading systems and testing trading strategies

re quote in mt5

Fernando Carreiro, 2022.04.22 15:08

First you should research what a "re-quote" is. You should learn what execution policies are and the difference between "Instant" and "Market" execution policies.

You should also learn about maximum deviation (slippage) and how to set it in your order placement. You should also decide how you should handle re-quotes according to your trading strategy.

And then finally, once you understand all that, then you can go back to your MQL code and apply that logic to it.

Forum on trading, automated trading systems and testing trading strategies

Avoid Slippage without Pending Orders.

Fernando Carreiro, 2021.07.26 22:56

As I have already explained, for "Market Execution" policy, the opening price is ignored and you will get whatever price is available at the time.

With "Instant Execution" policy, then the price is important and if it deviates too far away from the current price, you will get a "requote" error.

Remember that Buy orders open at the Ask price and close at the Bid price, and Sell orders open at the Bid price and close at the Ask price.

EDIT: Also read the following:

Forum on trading, automated trading systems and testing trading strategies

Getting Error Code 138 in Backtesting

Fernando Carreiro, 2022.02.19 09:34

Did you search the forum for other threads and posts about OrderSend Error 138? You would have found many, many threads and posts on it!

Did you make the effort to look at the MQL4 documentation to see what Error 138 means? It means there was a "requote"!

Do you know what a "requote" is? Did you search the web for the meaning of a "Requote"? It means that the price you are requesting is not accepted by the broker at that time.

The reason is that you are trying to buy at the bid price, but the market will only allow you to buy it at the ask price.

Why do you not know this? Because you did not read the documentation: Requirements and Limitations in Making Trades

The rules are that you enter a Buy at the market Ask price and exit at the Bid price. For a Sell you enter at the market Bid price and exit at the Ask price.

 
Fernando Carreiro #:

Here are some I've answered before:

Thanks Fernando,

I actually did read them and i should have mentioned that.
While i'm at it, is should have also mentioned i get the error with backtesting.

My bewilderment is caused by the fact that while using the EXACT SAME OrderClose() parameters, i DO get errors when ticket has been selected using SELECT_BY_TICKET and that i do NOT get get them when selecting the ticket using SELECT_BY_POS.

AFAIK this issue in not in the posts i read on Error 138, nor did i figure this could be a RefreshRates() issue, given the error goes away by changing the selection method and that i'm not using Bid or Ask, but OrderClosePrice() instead.

 

I suspect that your problem is this

if(OrderSelect(ticket_long,SELECT_BY_TICKET))       //here we use SELECT_BY_TICKET which brings (and causes?) error 138
         {
          if(OrderCloseTime()==0)
             {
              ri="Long";
              pr_open=OrderOpenPrice();
             }
         }

Now, supposing this order is not closed yet, ri="Long" correct?

Then you follow with this code

      if(OrderSelect(ticket_short,SELECT_BY_TICKET))                            
         {                       
          if(OrderCloseTime()==0)
             {
              ri="Short";
              pr_open=OrderOpenPrice();
             }
         }

and let's say that this order has closed already. ri still equals "Long". Correct?

So as it stands, ri="Long" but you have selected the closed short order.

So when you move on to

if(ri=="Long" and some condition based on technical indictors and order open price)
        {
         if(OrderClose(ticket_long,lots,OrderClosePrice(),100,clrGreen)==TRUE) 
            ri="Cash";
        }

You are trying to close the long with the price that the short order was closed at.

You should re-select the order first.

if(ri=="Long" and some condition based on technical indictors and order open price)
        {
         //Reselect the long order here.
         if(OrderClose(ticket_long,lots,OrderClosePrice(),100,clrGreen)==TRUE) 
            ri="Cash";
        }
 
        if(OrderClose(ticket_long,lots,OrderClosePrice(),100,clrGreen)==TRUE) 

You have exited the select loop. If the first order position (0) was not processed, say different symb or magic, OrderClosePrice is not related to ticket_xxx.

Drop your ri variable and move that code into the loop.

 

Excellent! Thank you guys.
will correct the (now very obvious!) mistake..

PS: I falsely assumed that OrderClosePrice() was not related to any Order (ie OrderSelect) anymore. After all, the selected order hasn't been closed at that point, so arguably there is no OrderClosePrice() to begin with, or so i reasoned. I thought the OrderClosePrice() was some neat way to not have to use Ask or Bid, which triggers an extra lookup. Kind of like a NULL.
Obviously i was wrong.
Documentation on MQL5: Trade Functions / OrderSelect
Documentation on MQL5: Trade Functions / OrderSelect
  • www.mql5.com
OrderSelect - Trade Functions - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5
 
Route206 #:

Excellent! Thank you guys.
will correct the (now very obvious!) mistake..

PS: I falsely assumed that OrderClosePrice() was not related to any Order (ie OrderSelect) anymore. After all, the selected order hasn't been closed at that point, so arguably there is no OrderClosePrice() to begin with, or so i reasoned. I thought the OrderClosePrice() was some neat way to not have to use Ask or Bid, which triggers an extra lookup. Kind of like a NULL.
Obviously i was wrong.

You must always study the documentation, don't assume anything.

I know that the documentation is often not very clear, but in this case it leaves no doubt whatsoever.

OrderClosePrice

Returns close price of the currently selected order.

double  OrderClosePrice();

Returned value

The close price of currently selected order.

Note

The order must be previously selected by the OrderSelect() function.

Example:

  if(OrderSelect(10,SELECT_BY_POS,MODE_HISTORY)==true)
    {
     datetime ctm=OrderOpenTime();
     if(ctm>0) Print("Open time for the order 10 ", ctm);
     ctm=OrderCloseTime();
     if(ctm>0) Print("Close time for the order 10 ", ctm);
    }
  else
    Print("OrderSelect failed error code is",GetLastError());



 

Yes - so much is clear now.

Begs the questions why "0"  can not be used for OrderClose() as after all ,the OrderClosePrice() for a not yet closed order is "0", right?

 
Route206 #:

Yes - so much is clear now.

Begs the questions why "0"  can not be used for OrderClose() as after all ,the OrderClosePrice() for a not yet closed order is "0", right?

Wrong.

 

Aaah- that was the missing piece.
Kept on thinking OrderClosePrice() was only 'filled' after an actual OrderClose.
Never actually checked that as i did just now.

Thanks!
Reason: