0
votes

I have an EA with closes a trade on button click

//void CloseCurrentTrade(). It's called after successfull OrderSelect
int orderType = OrderType();
double price;
if (orderType == OP_BUY)
    price = return MarketInfo(OrderSymbol(), MODE_BID);
else if (orderType == OP_SELL)
    price = return MarketInfo(OrderSymbol(), MODE_ASK);
else
    return;
int slippage = 20;
bool closed = OrderClose(OrderTicket(), OrderLots(), price, slippage);
if (closed)
    return;
int lastError = GetLastError();

Sometimes it closes the trade and sometimes it returns error #129 (Invalid price). I can't figure out why. Most of the cases people just misuse bid/ask or don't have enouth slippage. I've try to use slippage up to 200, still the same error. Some EA's just try to close it several times (and it looks like a hack for me), but it does not help as well. There are some mentions that you need to call RefreshRates() before bid/ask, but documentaion says that you don't need to do that for MarketInfo.

I've run out of ideas what it could be. Why it can happen and how to avoid that? I'm testing it on FXCM Demo (if it is the case).

2
You can use OrderClosePrice() instead of bid or ask. The best way seems to try to close the ticket several times, if failed - Sleep(25) and RefreshRates() after that. - Daniel Kniaz
OrderClosePrice() is equial to Bid/Ask I'm using when it fails - sibvic

2 Answers

2
votes

First make sure that you've selected the order properly, and try to use OrderClosePrice where possible(this will eliminate the need for checking the OP_SELL/OP_BUY)

//+------------------------------------------------------------------+
//| Close the latest order for this current symbol                   |
//+------------------------------------------------------------------+
void CloseCurrentTrade()
  {
   for(int i=OrdersTotal()-1;i>=0;i--)
     {
      if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;
      if(OrderSymbol()!=Symbol()) continue;
      if(OrderMagicNumber()!=MagicNum) continue; // if there is no magic number set, then no need for this(manual orders)
      if(OrderType()>OP_SELL) continue;

      if(!OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),Slippage))
         Print("Error in Closing the Order, Error : ",ErrorDescription(GetLastError()));

      break; // assuming you want to close the latest trade only, exit the order closing loop
     }
  }

Also note that your broker might have restrictions on how far the closing price must be from the Order Opened price and other levels(sl/tp), in order to close an order. Refer here

0
votes

Print and compare Ask/Bid && price when closed!=true. Beware that MarketInfo mode data is stored at Ask/Bid predefined variables already, so you can eliminate that if you OrderSelect in current symbol.