오류, 버그, 질문 - 페이지 540

 

현재 챔피언십에 참가하고 있는 My Expert Advisor가 CTrade 표준 라이브러리의 잘못된 작동으로 인해 잘못된 동작을 수행합니다.

PositionClose 함수를 사용하여 위치를 닫습니다. 그러나 포지션 청산과 함께 이 기능 자체가 거래를 엽니다!

함수는 다음과 같이 사용됩니다.

 //--- Объект класса С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는 때때로 추가 주문을 엽니다.

여기서 매수 거래가 먼저 마감된 다음 동일한 볼륨의 추가 매도 거래가 열렸습니다. 게다가 AccountInfoDouble(ACCOUNT_FREEEMARGIN)은 이 추가 거래를 인지하지 못했습니다. 사용 된 MM에 따르면이를위한 자금은 충분하지 않았지만 추가로 열린 거래를 고려하면 증가 된 많은 거래가 다음에 열렸기 때문에 충분하지 않았습니다.

MQL 기능을 최적으로 사용하고 있지 않을 수 있음을 알고 있습니다. 그러나 거래를 성사시키도록 설계된 독점 MQL 라이브러리의 기능이 거래 자체를 개시 한다는 사실은 기능의 허용 가능한 동작에 대한 제 생각 맞지 않습니다.

 
masharov :

MQL 기능을 최적으로 사용하고 있지 않을 수 있음을 알고 있습니다. 그러나 거래를 성사시키도록 설계된 독점 MQL 라이브러리의 기능이 거래 자체를 개시 한다는 사실은 기능의 허용 가능한 동작에 대한 제 생각 맞지 않습니다.

MetaTrader 5의 거래 이벤트 기사 읽기:

거래 이벤트 및 거래 내역의 변경 사항은 독립적인 채널을 통해 보고됩니다. OrderSend() 함수로 구매 요청을 보내면 요청 확인 성공 시 생성된 주문 티켓을 즉시 확인할 수 있습니다. 그러나 동시에 주문 자체가 아직 클라이언트 터미널에 나타나지 않을 수 있으며 OrderSelect() 함수를 사용하여 주문을 선택하려는 시도는 실패합니다.

MetaTrader 5의 주문, 위치 및 거래 기사
 

OrderSend 기능을 사용하지 않았습니다. PositionClose 함수는 주문 작업을 위해 설계된 표준 MQL 라이브러리에서 사용됩니다.

이 기능에 대한 도움말은 거래를 열 수 있다고 설명하지 않습니다.

도움말 인용:

위치닫기

지정된 기호의 위치를 닫습니다.

bool 위치 닫기 (
상수 문자열 기호 , // 기호
울롱 편차=ULONG_MAX // 일탈
)

옵션

기호

【인】 포지션이 마감되어야 하는 거래 상품의 이름.

편차=ULONG_MAX

【인】 현재 가격과의 최대 편차(단위: 포인트)입니다.

반환 값

true - 구조의 기본 검사가 성공한 경우, 그렇지 않으면 false입니다.

메모

PositionClose(...) 메서드의 성공적인 완료가 항상 거래 작업의 성공적인 실행을 의미하지는 않습니다. ResultRetcode() 메서드를 호출하여 거래 요청(거래 서버 반환 코드) 실행 결과를 확인해야 합니다.

 
masharov :

OrderSend 기능을 사용하지 않았습니다. 주문 작업을 단순화하도록 설계된 표준 MQL 라이브러리의 PositionClose 함수가 사용됩니다.

이 기능에 대한 도움말은 거래를 열 수 있다고 설명하지 않습니다.

도움말 인용:

위치닫기

지정된 기호의 위치를 닫습니다.

bool 위치 닫기 (
상수 문자열 기호 , // 기호
울롱 편차=ULONG_MAX // 일탈
)

옵션

기호

【인】 포지션이 마감되어야 하는 거래 상품의 이름.

편차=ULONG_MAX

【인】 현재 가격과의 최대 편차(단위: 포인트)입니다.

반환 값

true - 구조의 기본 검사가 성공한 경우, 그렇지 않으면 false입니다.

메모

PositionClose(...) 메서드의 성공적인 완료가 항상 거래 작업의 성공적인 실행을 의미하지는 않습니다. ResultRetcode() 메서드를 호출하여 거래 요청(거래 서버 반환 코드) 실행 결과를 확인해야 합니다.

PositionClose(...) 라이브러리 함수에는 오류가 없습니다. 그리고 여기 당신이 가지고 있는 코드가 있습니다. 여기 당신 자신이 도움말에서 인용했습니다.

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

예를 들어, 귀하의 코드에는 이 체크가 표시되지 않습니다.

 
masharov :

OrderSend 기능을 사용하지 않았습니다. PositionClose 함수는 주문 작업을 위해 설계된 표준 MQL 라이브러리 에서 사용됩니다.

이 기능에 대한 도움말은 거래를 열 수 있다고 설명하지 않습니다.


그리고 PositionClose 함수의 구현을 살펴봅니다.

 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 );
  }
 

표준 라이브러리 의 소스 코드를 공부할 필요가 없다고 생각했습니다.

도움말은 PositionClose 기능을 사용하여 거래를 열 가능성에 대해 설명하지 않습니다. 팀에서 개발한 PositionClose 기능에는 거래 시작에 대한 확인 및 보호 기능이 포함되어야 합니다. 나는 표준 라이브러리가 다른 사람들의 모델이 되기에 이상적인 코드라고 믿습니다. 따라서 라이브러리 코드를 사용하기 전에 디스어셈블할 필요가 없습니다.

인용문:

MQL5 표준 라이브러리는 MQL5 언어로 작성되었으며 최종 사용자를 위한 프로그램(지표, 스크립트, Expert Advisors) 작성을 용이하게 하도록 설계되었습니다. 라이브러리는 대부분의 내부 MQL5 기능에 대한 편리한 액세스를 제공합니다.

 
masharov :

표준 라이브러리 의 소스 코드를 공부할 필요가 없다고 생각했습니다.

도움말은 PositionClose 기능을 사용하여 거래를 열 가능성에 대해 설명하지 않습니다. 팀에서 개발한 PositionClose 기능에는 거래 시작에 대한 확인 및 보호 기능이 포함되어야 합니다. 나는 표준 라이브러리가 다른 사람들의 모델이 되기에 이상적인 코드라고 믿습니다. 따라서 라이브러리 코드를 사용하기 전에 디스어셈블할 필요가 없습니다.

법에 대한 무지는 변명의 여지가 없습니다. 코드에서 포지션이 마감되었는지 확인하는 위치는 어디입니까?

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

표현

R == true

PositionClose() 함수의 성공적인 실행에 대해서만 말하고 위치를 닫는 것에 대해서는 말하지 않습니다.

메모

PositionClose(...) 메서드의 성공적인 완료가 항상 거래 작업의 성공적인 실행을 의미하지는 않습니다. ResultRetcode() 메서드를 호출하여 거래 요청(거래 서버 반환 코드) 실행 결과를 확인해야 합니다.

그리고 두 번째 표현

myposition.Select( _Symbol )== false )

에 해당

 PositionSelect ( _Symbol )== false )

또한 비동기 거래 작업을 보장하지 않습니다. 포지션은 이미 거래 서버에서 마감되었으며 이에 대한 메시지는 아직 터미널에 도달하지 않았습니다. 따라서 코드에서 자신의 손으로 버그를 만든 것으로 나타났습니다.

인생에서 모든 것이 테스터만큼 순조로운 것은 아니며 거래 요청을 보내고 실행 결과 사이에 약간의 지연도 있습니다. 모두가 이 문제를 스스로 해결합니다. 처음 에는 도움말에 나와 있는 대로 ResultRetcode() 함수를 사용하여 반환 코드를 확인하는 것이 나쁘지 않을 것입니다.

 

반복합니다.

MQL 기능을 최적으로 사용하고 있지 않을 수 있음을 알고 있습니다. 그러나 거래를 성사시키도록 설계된 독점 MQL 라이브러리의 기능이 거래 자체를 개시 한다는 사실은 기능의 허용 가능한 동작에 대한 제 생각 맞지 않습니다.

당신이 말하는 모든 것은 거래 마감에 관한 것입니다. 예, EA는 포지션 마감 을 최적으로 확인하지 않습니다. 그러나 이것은 청산을 위한 기능이 자체적으로 열린 거래를 허용하지 않습니다.

도움말은 다음과 같이 말합니다.

위치닫기

지정된 기호의 위치를 닫습니다.

기능이 거래를 열 수 있다는 조건이 설명되어 있지 않습니다. 반환 코드를 확인하라는 권장 사항은 거래가 마감되었는지 여부를 추가 확인하는 용도로만 제공됩니다.

 
masharov :

반복합니다.

MQL 기능을 최적으로 사용하고 있지 않을 수 있음을 알고 있습니다. 그러나 거래를 성사시키도록 설계된 독점 MQL 라이브러리의 기능이 거래 자체를 개시 한다는 사실은 기능의 허용 가능한 동작에 대한 제 생각 맞지 않습니다.
포지션 청산 기능은 없으며 매수 또는 매도 요청을 보내는 기능만 있습니다(포지션 개설 또는 청산 결과는 알 수 없음). 귀하의 경우 알고리즘 오류로 인해 이전 요청의 실행을 확인하지 않고 반복 요청이 전송됩니다.
 
Rosh :
포지션 청산 기능은 없으며 매수 또는 매도 요청을 보내는 기능만 있습니다(포지션 개설 또는 청산 결과는 알 수 없음). 귀하의 경우 알고리즘 오류로 인해 이전 요청의 실행을 확인하지 않고 반복 요청이 전송됩니다.

도움말에 그런 기능이 있습니다.

MQL5 참조 / 표준 라이브러리 / 트레이드 클래스 / CTrade / PositionClose

지정된 기호의 위치를 닫습니다.

사용자의 낮은 수준에서 기능이 구현되는 방법은 걱정할 필요가 없습니다. 그런 기능이 있기 때문에 MetaQuotes는 도움말에 설명되지 않은 비표준 동작이 없을 것이라고 보장합니다.

MQL5 표준 라이브러리는 MQL5 언어로 작성되었으며 최종 사용자를 위한 프로그램(지표, 스크립트, Expert Advisors) 작성을 용이하게 하도록 설계되었습니다. 라이브러리는 대부분의 내부 MQL5 기능에 대한 편리한 액세스를 제공합니다.

사유: