Errors, bugs, questions - page 540

 

My Expert Advisor, which is currently participating in the Championship, is performing incorrect actions due to incorrect operation of the standard CTrade library.

I use the PositionClose function to close positions. But along with closing positions, this function itself OPENS trades!

The function is used like this:

//--- Объект класса СTrade
CTrade mytrade;
//--- Объект класса СPositionInfo
CPositionInfo myposition;

//+------------------------------------------------------------------+
//| Проверяет и если нужно, закрывает открытую позицию               |
//+------------------------------------------------------------------+
bool ClosePosition(string ptype,double clp)
  {
   bool R=false, marker=false; int i;
     
      if(myposition.Select(_Symbol)==true)
        {
         if(myposition.Symbol()==_Symbol)
           {
            //--- Делаем попытки закрыть позицию, если позиция не закрылась с первого раза
              for (i=5; i>=1; i--) 
                {R=mytrade.PositionClose(_Symbol,50,5); if (R == true && myposition.Select(_Symbol)==false) break;}
               if(i >= 1) 
                 {//--- запрос успешно выполнен
                  Alert("Открытая позиция была успешно закрыта!!");
                  marker=true;
                 }
               else
                 {
                  Alert("Запрос на закрытие позиции не выполнен - ошибка: ",mytrade.ResultRetcodeDescription());
                 }
            //  }
           }
        }
      return(marker);
     }

PositionClose ends up opening sometimes unnecessary orders.

Here, the Buy trade was closed first and then an extra Sell trade of the same size was opened. Moreover, AccountInfoDouble(ACCOUNT_FREEMARGIN) has not noticed this extra trade. Because it was followed by a trade with larger lot, though there wasn't enough money for it according to the used MM.

I realize that perhaps I'm not using the MQL functions optimally. But the fact that a function in the MQL proprietary library intended for closing trades will open trades by itself does not fit my idea of the acceptable behavior of functions.

 
masharov:

I understand that I may not be using MQL functions optimally. But the fact that a function in the MQL proprietary library intended for closing trades will itself open trades does not fit my idea of the acceptable behavior of functions.

Read the article Trading Events in MetaTrader 5:

Trade events and changes in trading history are reported through independent channels. When sending a Buy request using the OrderSend() function, you can immediately recognize the ticket of the order, which has been created if the request was successfully checked. But at the same time, the order itself may not yet appear in the client terminal, and an attempt to select it using the OrderSelect() function will fail.

Also see the article Orders, Positions and Trades in MetaTrader 5
 

I haven't used the OrderSend function. The function PositionClose from the standard MQL library is used, which is designed to work with orders.

The help for this function does not describe that it can open trades.

Quote from the reference:

PositionClose

Closes a position at the specified symbol.

bool PositionClose(
const string symbol, // symbol
ulong deviation=ULONG_MAX // deviation
)

Parameters

symbol

[in] Name of trade instrument, on which the position should be closed.

deviation=ULONG_MAX

[in] Maximum deviation from the current price (in points).

Returned value

true - if the basic check of structures is successful, otherwise false.

Note

Successful finish of PositionClose(...) method does not always mean successful execution of a trade operation. It is necessary to check the result of a trade request (return code of the trade server) by calling the ResultRetcode() method.

 
masharov:

I have not used the OrderSend function. The PositionClose function from the standard MQL library is used, which is designed to simplify working with orders.

The help for this function does not describe that it can open trades.

Quote from the reference:

PositionClose

Closes a position at the specified symbol.

bool PositionClose(
const string symbol, // symbol
ulong deviation=ULONG_MAX // deviation
)

Parameters

symbol

[in] Name of trade instrument, on which the position should be closed.

deviation=ULONG_MAX

[in] Maximum deviation from the current price (in points).

Returned value

true - if the basic check of structures is successful, otherwise false.

Note

Successful finish of PositionClose(...) method does not always mean successful execution of a trade operation. The result of the trade request execution (the trade server return code) must be checked by calling the ResultRetcode() method.

There is no error in the library function PositionClose(...). But there is one in your code. Here is the quote from the reference.

Успешное окончание работы метода PositionClose(...) не всегда означает успешное совершение торговой операции. 
Необходимо проверять результат выполнения торгового запроса (код возврата торгового сервера) вызовом метода ResultRetcode(). 

I, for example, don't see this check in your code.

 
masharov:

I have not used the OrderSend function. The PositionClose function from the standard MQL library, which is designed to work with orders, is used.

The help for this function does not describe that it can open trades.


And you can look at the implementation of the PositionClose function:

bool CTrade::PositionClose(const string symbol,ulong deviation)
  {
   bool   partial_close=false;
   int    retry_count  =10;
   uint   retcode      =TRADE_RETCODE_REJECT;
//--- check stopped
   if(IsStopped(__FUNCTION__)) return(false);
//--- variables
   string action,result;
//--- clean
   ClearStructures();
   do
     {
      //--- checking
      if(PositionSelect(symbol))
        {
         if((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
           {
            //--- prepare request for close BUY position
            m_request.type =ORDER_TYPE_SELL;
            m_request.price=SymbolInfoDouble(symbol,SYMBOL_BID);
           }
         else
           {
            //--- prepare request for close SELL position
            m_request.type =ORDER_TYPE_BUY;
            m_request.price=SymbolInfoDouble(symbol,SYMBOL_ASK);
           }
        }
      else
        {
         //--- position not found
         m_result.retcode=retcode;
         return(false);
        }
      //--- setting request
      m_request.action      =TRADE_ACTION_DEAL;
      m_request.symbol      =symbol;
      m_request.deviation   =(deviation==ULONG_MAX) ? m_deviation : deviation;
      m_request.type_filling=m_type_filling;
      m_request.volume      =PositionGetDouble(POSITION_VOLUME);
      //--- check volume
      double max_volume=SymbolInfoDouble(symbol,SYMBOL_VOLUME_MAX);
      if(m_request.volume>max_volume)
        {
         m_request.volume=max_volume;
         partial_close=true;
        }
      else
         partial_close=false;
      //--- order check
      if(!OrderCheck(m_request,m_check_result))
        {
         //--- copy return code
         m_result.retcode=m_check_result.retcode;
         if(m_log_level>LOG_LEVEL_NO)
            printf(__FUNCTION__+": %s [%s]",FormatRequest(action,m_request),FormatRequestResult(result,m_request,m_result));
         return(false);
        }
      //--- order send
      if(!OrderSend(m_request,m_result))
        {
         if(--retry_count!=0) continue;
         if(retcode==TRADE_RETCODE_DONE_PARTIAL)
            m_result.retcode=retcode;
         if(m_log_level>LOG_LEVEL_NO)
            printf(__FUNCTION__+": %s [%s]",FormatRequest(action,m_request),FormatRequestResult(result,m_request,m_result));
         return(false);
        }
      retcode=TRADE_RETCODE_DONE_PARTIAL;
      if(partial_close) Sleep(1000);
     }
   while(partial_close);
   if(m_log_level>LOG_LEVEL_ERRORS)
      printf(__FUNCTION__+": %s [%s]",FormatRequest(action,m_request),FormatRequestResult(result,m_request,m_result));
//--- ok
   return(true);
  }
 

Figured I didn't need to study the source code of the standard libraries.

The help does not describe the possibility of opening trades with the PositionClose function. The checks and protections against opening trades with the PositionClose function, which your team developed, should contain itself. I believe that the standard libraries are an ideal code that should serve as a model for others. Therefore, parsing the code of the libraries before using them should not be necessary.

Quote:

The standard MQL5 library is written in MQL5 language and is designed to facilitate writing programs (indicators, scripts, experts) to end users. The library provides easy access to most internal MQL5 functions.

 
masharov:

Figured I didn't need to study the source code of the standard libraries.

The help does not describe the possibility of opening trades with the PositionClose function. The checks and protections against opening trades with the PositionClose function, which your team developed, should contain itself. I believe that the standard libraries are an ideal code that should serve as a model for others. Therefore, parsing the code of libraries before using them should not be required.

Ignorance of the law does not exempt you from responsibility. Where in your code is the check that the position has closed?

            //--- Делаем попытки закрыть позицию, если позиция не закрылась с первого раза
              for (i=5; i>=1; i--) 
                {
                 R=mytrade.PositionClose(_Symbol,50,5); 
                 if (R == true && myposition.Select(_Symbol)==false) break;
                }

Expression

R == true

only indicates that the PositionClose() function was successfully executed, but not that the position was closed:

Note

Successful completion of the PositionClose(...) method does not always mean successful execution of a trade operation. It is necessary to check the result of execution of a trade request (return code of the trade server) by calling the ResultRetcode() method.

The second expression

myposition.Select(_Symbol)==false)

is equivalent to

PositionSelect(_Symbol)==false)

and also gives no guarantee for asynchronous trade operations. A position has already been closed on the trade server and the terminal has not yet received a message about it. So, it turns out that you have created a bug in your code.

In real life, not everything is as smooth as in the tester; there can be small delays between sending a trade request and the result of its execution. Everyone solves this problem himself, for a start it wouldn't hurt to check the return code using ResultRetcode() function , as it is written in the help.

 

Again.

I realize that perhaps I'm not using the MQL functions optimally. But the fact that a function in the MQL proprietary library intended forclosing trades willopen trades itself doesn't fit my idea of the acceptable behavior of functions.

Everything you say applies to closing trades. Yes, the EA does not optimally check closing positions. But that doesn't allow a function designed to close to open trades on its own.

The help says:

PositionClose

Closes the position according to the specified symbol.

No conditions are described that the function can open a trade. The recommendation to check the return code also serves only to additionally check if the trade is closed or not.

 
masharov:

Again.

I understand that I may not be using MQL functions optimally. But the fact that the function in the MQL proprietary library intended forclosing trades willopen trades by itself does not fit my idea of the acceptable behavior of functions.
There is no position closing function, there is only the function for sending a buy or sell request (and what will be the result - opening or closing of a position - is unknown). In your case, because of an algorithmic error, repeated requests are sent without checking if the previous request was executed.
 
Rosh:
There is no position closing function, there is only the function of sending a buy or sell request (and the result - the opening or closing of a position - is unknown). In your case, because of an algorithmic error, repeated requests are sent without checking if the previous request was executed.

The Help has this function

MQL5 Reference / Standard Library / Trading Classes / CTrade / PositionClose

Closes position by specified symbol.

The user should not care about how the function is implemented on the low level. Since this function exists, MetaQuotes has warranted that it will not have any non-standard behavior not described in the help.

The standard MQL5 library is written in MQL5 and is aimed at facilitating the writing of programs (indicators, scripts, and Expert Advisors) by end-users. The library provides easy access to most of the internal MQL5 functions.

Reason: