FORTS: OnTradeTransaction() 반환 코드 - 페이지 9

 
Михаил :

당신은 이해하지 못했습니다.

이 서버는 20초 동안 주문 상태 PLASED를 보내지 않았습니다.

나는 서버 개발자를 의미했습니다.
 
Михаил :

ORDER_STATE_STARTED 주문 상태가 "동결"되는 OBVIOUS 터미널 오류가 있습니다.  

드디어 알아냈어?

교환은 이 주문에 대해 정확히 무엇을 말 합니까? 빨리 게시 되었습니까? 그렇다면 상태를 업데이트하지 않는 서버 또는 MT 터미널의 오류가 분명합니다. 이것으로 이미 서비스 데스크에 갈 수 있습니다.

 

Service Desk에서 Mikhail과 문제를 논의한 결과:

분명히 주문 시스템이 작동하는 방식과 배치되는 의미를 설명해야 합니다.

그래서:

1. 요청을 보낸다

buy limit 5.00 SNGR-3.16 at 35501

2. MT5 서버는 이 요청(파라미터, 사전 거래 등)을 확인합니다. 문제가 있는 경우 요청에 대한 응답으로 해당 오류 코드를 받게 됩니다.

그런 다음 티켓(#24025010)을 할당하여 새 주문을 시작합니다. 주문 상태는 시작됨으로 설정됩니다. 거래소에서 주문할 때 MT5의 주문ID와 거래소의 주문을 연결하기 위해서는 주문 티켓을 내려놓아야 합니다.
시작된 상태의 새 주문 추가에 대한 트랜잭션이 터미널로 전송됩니다. 이는 OnTradeTransaction에서 추적할 수 있습니다.

3. 다음으로, 거래 서버(게이트웨이를 통해)가 귀하의 요청을 거래소에 보냅니다. 요청이 성공적으로 전송되면 배치된 응답이 귀하의 요청에 전송됩니다.
"요청이 전송되었음을", 작업 결과는 비동기적으로 실행됩니다. 교환이 얼마나 오래 응답할지 미리 알 수 없습니다.

따라서 이 순간에 로그에 항목이 표시됩니다.

2015.11.26 10:48:23.726 Trades  'xxxxxx': buy limit 5.00 SNGR-3.16 at 35501 placed for execution in 7 ms

4. 얼마 후 거래소는 시스템에 주문을 하고 식별자를 할당한 다음 게이트웨이와 MT5 서버에 이를 알립니다.
거래소에서 주문한 경우 거래소의 주문 식별자가 MT5의 주문에 할당되고 주문 상태 가 시작됨 => 배치됨에서 변경됩니다.
어떤 이유로 교환이 주문을 거부하는 경우 주문이 취소됩니다.

이 모든 것은 OnTradeTransaction으로 들어오는 트랜잭션의 간단한 로깅으로 추적할 수 있습니다.

===================================================== ===============================

무슨 일이야:

1. 주문 요청을 보냅니다 - 단락 1-3 참조.

2. 그리고 MT5에 이미 주문이 있지만 아직 거래소에 있지 않은 순간에 이 주문을 철회하도록 요청합니다.
그러나 이 주문은 초기 상태(시작됨)이고 주문의 존재가 정의되지 않았기 때문에 주문 취소를 거부합니다.
이 경우 동작이 정의되지 않았기 때문입니다.

Expert Advisor의 논리에서 적절한 검사 수정을 수행해야 합니다.


Z.Y. 또 다른 것은 1초 이내에

 2015.11 . 26 10 : 48 : 24.583 Trades   ' xxxxxx' : failed cancel order # 24025010 buy limit 5.00 SNGR- 3.16 at 35501.00000 [Invalid request]
(특히 20초) 주문을 했어야 했습니다. 우리는 그것을 분류하고 있습니다. 우리는 잠재적인 문제 중 하나를 발견했습니다. 우리는 그것을 고치고 있습니다.
 
MQ Alexander :
설명 감사합니다! 이것을 문서에 추가하십시오!
 
MQ Alexander :

Service Desk에서 Mikhail과 문제를 논의한 결과:

분명히 주문 시스템이 작동하는 방식과 배치가 의미하는 바를 설명해야 합니다.

그래서:

1. 요청을 보낸다


2. MT5 서버는 이 요청(파라미터, 사전 거래 등)을 확인합니다. 문제가 있는 경우 요청에 대한 응답으로 해당 오류 코드를 받게 됩니다.

그런 다음 티켓(#24025010)을 할당하여 새 주문을 시작합니다. 주문 상태는 시작됨으로 설정됩니다. 거래소에서 주문할 때 MT5의 주문ID와 거래소의 주문을 연결하기 위해서는 주문 티켓을 내려놓아야 합니다.
시작 상태에서 새 주문을 추가하는 것에 대한 트랜잭션이 터미널로 전송됩니다. 이는 OnTradeTransaction에서 추적할 수 있습니다.

3. 다음으로, 거래 서버(게이트웨이를 통해)가 귀하의 요청을 거래소에 보냅니다. 요청이 성공적으로 전송되면 배치된 응답이 귀하의 요청에 전송됩니다.
"요청이 전송되었음을", 작업 결과는 비동기적으로 실행됩니다. 교환이 얼마나 오래 응답할지 미리 알 수 없습니다.

따라서 이 순간에 로그에 항목이 표시됩니다.

4. 얼마 후 거래소는 시스템에 주문을 하고 식별자를 할당한 다음 게이트웨이와 MT5 서버에 이를 알립니다.
거래소에서 주문한 경우 거래소의 주문 식별자가 MT5의 주문에 할당되고 주문 상태 가 시작됨 => 배치됨에서 변경됩니다.
어떤 이유로 교환이 주문을 거부하는 경우 주문이 취소됩니다.

이 모든 것은 OnTradeTransaction에 오는 트랜잭션의 간단한 로깅으로 추적할 수 있습니다.

===================================================== ===============================

무슨 일이야:

1. 주문 요청을 보냅니다 - 단락 1-3 참조.

2. 그리고 MT5에 이미 주문이 있지만 아직 거래소에 있지 않은 순간에 이 주문을 철회하도록 요청합니다.
그러나 이 주문은 초기 상태(시작됨)이고 주문의 존재가 정의되지 않았기 때문에 주문 취소를 거부합니다.
이 경우 동작이 정의되지 않았기 때문입니다.

Expert Advisor의 논리에서 적절한 검사 수정을 수행해야 합니다.


Z.Y. 또 다른 것은 1초 이내에

(특히 20초) 주문을 했어야 했습니다. 우리는 그것을 분류하고 있습니다. 우리는 잠재적인 문제 중 하나를 발견했습니다. 우리는 그것을 고치고 있습니다.
주문 "시작됨" 상태가 "배치됨" 상태로 변경되는 시점이 명확하지 않습니다. 이것은 귀하의 설명의 단락 3에 따라, 귀하의 설명의 단락 4에 따라, 또는 두 경우 모두에서 단락 3과 4에 따라 발생합니까?
 
Yury Kirillov :
주문 "시작됨" 상태가 "배치됨" 상태로 변경되는 시점이 명확하지 않습니다. 이것은 귀하의 설명의 단락 3에 따라, 귀하의 설명의 단락 4에 따라, 또는 두 경우 모두에서 단락 3과 4에 따라 발생합니까?
MQ 알렉산더 :

4. 얼마 후 거래소는 시스템에 주문을 하고 식별자를 할당한 다음 게이트웨이와 MT5 서버에 이를 알립니다.
거래소에서 주문한 경우 거래소의 주문 식별자가 MT5의 주문에 할당되고 주문 상태시작됨 => 배치됨에서 변경됩니다.

 
MQ Alexander :

3. 다음으로, 거래 서버(게이트웨이를 통해)가 귀하의 요청을 거래소에 보냅니다. 요청이 성공적으로 전송되면 배치된 응답이 귀하의 요청에 전송됩니다.

"요청이 전송되었음을", 작업 결과는 비동기적으로 실행됩니다. 교환이 얼마나 오래 응답할지 미리 알 수 없습니다.

따라서 이 순간에 로그에 항목이 표시됩니다.

2015.11.26 10:48:23.726 Trades  'xxxxxx': buy limit 5.00 SNGR-3.16 at 35501 placed for execution in 7 ms

4. 얼마 후 거래소는 시스템에 주문을 하고 식별자를 할당한 다음 게이트웨이와 MT5 서버에 이를 알립니다.
거래소에서 주문한 경우 거래소의 주문 식별자가 MT5의 주문에 할당되고 주문 상태시작됨 => 배치됨에서 변경됩니다.

여기에 혼란의 또 다른 이유가 있습니다. 로그에는 주문이 이미 접수되었다고 나와 있지만 사실 상태는 아직 변경되지 않았습니다.

"보내짐"과 같이 쓰고 "배치됨"이 아니라 주문이 실제로 교환에 의해 수락되지 않습니까?

 

그것은 다음과 같이 밝혀졌습니다.

주문에 대한 작업을 수행하기 전(또는 후에),

매번 상태를 "볼" 필요가 있습니다(생각하지 않은 경우 수정):

 enum ENUM_ORD_REAL_STATE
{
  ORD_NOT_SPECIFIED         = 0 , //Состояние ордера не определено
  ORD_NONE_CANCELED         = 1 , //Ордера нет, отменён пользователем
  ORD_NONE_PARTIAL_CANCELED = 2 , //Ордера нет, исполнился частично (не был залит вторым объёмом)
  ORD_NONE_PARTIAL          = 3 , //Ордера нет, исполнился частично
  ORD_NONE_EXPIRED          = 4 , //Ордера нет, удалён по сроку
  ORD_NONE_FILLED           = 5 , //Ордера нет, исполнился полностью
  ORD_NONE_REJECTED         = 6 , //Ордера нет, отклонён брокером(биржей)
  ORD_BUSY                  = 7 , //Ордер находится в переходном состоянии
  ORD_EXIST                 = 8 , //Ордер выставлен на биржу, возможны действия над ним
  ORD_EXIST_PARTIAL         = 9    //Ордер выставлен на биржу, частично исполнился, возможны действия над ним
};
//
ENUM_ORD_REAL_STATE CheckOrderState( const ulong ticket )
{
   if ( ticket > 0 )
  {
     if ( HistoryOrderSelect ( ticket ) ) //Только не существующий ордер может находится в истории
    {
       ENUM_ORDER_STATE ord_state = ENUM_ORDER_STATE ( HistoryOrderGetInteger ( ticket, ORDER_STATE ) );
       double init_volume = HistoryOrderGetDouble ( ticket, ORDER_VOLUME_INITIAL );
       double cur_volume = HistoryOrderGetDouble ( ticket, ORDER_VOLUME_CURRENT );
//---      
       switch ( ord_state )
      {
                                                           
         case ORDER_STATE_CANCELED :       if ( init_volume == init_volume )
                                         {
                                           return ( ORD_NONE_CANCELED );
                                         }
                                         else
                                         {
                                           return ( ORD_NONE_PARTIAL_CANCELED );
                                         }  
                                         break ;
                                         
         case ORDER_STATE_PARTIAL :         return ( ORD_NONE_PARTIAL );
                                         break ;
                                         
         case ORDER_STATE_EXPIRED :         return ( ORD_NONE_EXPIRED );
                                         break ;
                                                                              
         case ORDER_STATE_FILLED :         return ( ORD_NONE_FILLED );
                                         break ;
                                         
         case ORDER_STATE_REJECTED :       return ( ORD_NONE_REJECTED );
                                         break ;   
 
       
      }
    }
     else
     if ( OrderSelect ( ticket ) ) 
    {
       ENUM_ORDER_STATE ord_state = ENUM_ORDER_STATE ( OrderGetInteger ( ORDER_STATE ) );
//---      
       switch ( ord_state )
      {
         case ORDER_STATE_STARTED :
         case ORDER_STATE_REQUEST_ADD :
         case ORDER_STATE_REQUEST_MODIFY :
         case ORDER_STATE_REQUEST_CANCEL : return ( ORD_BUSY );
                                         break ; 
 
         case ORDER_STATE_PARTIAL :         return ( ORD_EXIST_PARTIAL );
                                         break ;
                                          
         case ORDER_STATE_PLACED :         return ( ORD_EXIST );
                                         break ;
      }
    }
  }
   return ( ORD_NOT_SPECIFIED );
}
 
Михаил :

그것은 다음과 같이 밝혀졌습니다.

주문에 대한 작업을 수행하기 전(또는 후에),

매번 상태를 "볼" 필요가 있습니다(생각하지 않은 경우 수정):

옳지 않아,

HistoryOrderSelect ( 티켓 )의 기록을 살펴보면 HistoryOrderGetInteger() , HistoryOrderGetDouble( ) 을 사용해야 합니다 .

 
Sergey Chalyshev :

옳지 않아,

HistoryOrderSelect ( 티켓 )의 기록을 살펴보면 HistoryOrderGetInteger() , HistoryOrderGetDouble( ) 을 사용해야 합니다 .

맞습니다, 오타입니다 :)

감사합니다 수정했습니다...

사유: