기고글 토론 "MQL5 쿡북: TradeTransaction 이벤트 프로세싱"

 

새로운 기고글 MQL5 쿡북: TradeTransaction 이벤트 프로세싱 가 게재되었습니다:

MQL5에서 거래 이벤트를 컨트롤하는 방법을 소개하겠습니다. 해당 주제와 관련해 이미 몇 가지 아티클이 게시되어 있습니다. 'OnTrade() 함수를 이용한 EA 거래 이벤트 프로세싱'도 그 중 하나인데요. 이미 다른 분들이 이용한 방법 대신 새로운 핸들러인 OnTradeTransaction()을 사용하겠습니다.

다음 사항에 주의하셨으면 합니다. MQL5 현재 버전은 클라이언트 터미널 내 14개의 이벤트 핸들러를 포함합니다. 추가적으로, 개발자는 EventChartCustom()을 이용해 커스텀 이벤트를 생성할 수 있으며 OnChartEvent()로 생성된 이벤트를 프로세싱할 수 있습니다. 하지만 이벤트 기반 프로그래밍(EDP)에 대해서는 아직 자료가 없는데요. MQL5의 모든 프로그램이 EDP 원칙을 따르는 걸 생각해 보면 조금 이상한 일입니다. EA 템플릿이 'EA 이벤트 핸들러'라는 옵션까지 제공하는데 말입니다.

어쨌든 MQL5에서 EDP 메커니즘이 사용되는 건 분명합니다. 두 부분으로 구성된 프로그램 블록이 있습니다. 이벤트 선택 및 프로세싱이죠. 클라이언트 터미널의 이벤트를 다루는 경우 개발자는 두 번째 부분인 이벤트 핸들러에 대한 컨트롤만을 갖게 됩니다. 몇몇 이벤트의 경우 예외도 물론 있습니다. 타이머와 커스텀 이벤트가 여기에 해당되죠. 해당 이벤트의 경우 개발자에게 완전한 컨트롤이 주어집니다.

그림 6. 첫 번째 트랜잭션 프로세스 구조

그림 6. 첫 번째 트랜잭션 프로세스 구조

작성자: Denis Kirichenko

 

내 경험상 비동기 모드에서 프로그래밍 할 때 TradeTransaction을 사용해야 할 필요성이 실제로 발생한다고 말할 수 있습니다. 이 기사에서이 모드에 대해 한 마디도 언급하지 않는 것은 유감입니다.

추신 : 나는 또한 "어떤 MQL 레시피"라고 생각했습니다. - 아나톨리 기사의 상표 제목이었습니다. 그러나 이제는 그렇지 않다는 것이 밝혀졌습니다 (

 

C-4, 의견 주셔서 감사합니다.

C-4:

제 경험상 비동기 모드에서 프로그래밍 할 때 TradeTransaction을 사용해야 할 필요성이 실제로 발생한다고 말할 수 있습니다. 이 기사에이 모드에 대해 한 마디도 언급하지 않은 것은 유감입니다 ...

TradeTransaction 핸들러를 사용해야 하는 이유는 여러 가지가 있을 수 있습니다. 이것은 흥미로운 주제이며 경험 많은 동료들도이 문제에 대해 언급하기를 바랍니다 ...

추신 : 나는 또한 "MQL 레시피"라고 생각했습니다. - 아나톨리의 기사의 브랜드 이름이었습니다. 그리고 이제는 그렇지 않다는 것이 밝혀졌습니다 (

예, 저는 Anatoly가이 기사 시리즈의 발명가라는 것을 인정합니다. 나는 그것을 좋아했기 때문에 겸손하게주기에 합류했습니다 :-))))

아나톨리가 신경 쓰지 않기를 바랍니다....

 
이 글에서는 아직 부분 주문 체결(ORD_STATE_PARTIAL) 문제를 다룰 시간이 없었습니다. TradeTransaction 핸들러가 몇 번 호출되나요?
 
denkir:
이 글에서는 아직 부분 주문 체결(ORD_STATE_PARTIAL) 문제를 다룰 시간이 없었습니다. 질문: TradeTransaction 핸들러는 몇 번 호출되나요?

모르겠습니다. 논리적으로 핸들러는 전체 실행과 같은 횟수만큼 트리거되어야 합니다. 주문 실행은 개별 이벤트가 아니며 MT는 주문이 부분적으로 실행될지 아니면 완전히 실행될지 알 수 없기 때문입니다.

안타깝게도 이벤트의 전달은 보장되지 않으며 이벤트 자체는 실시간으로만 작동하므로 적용이 제한적입니다. 그러나 비동기 시스템이나 거래 복사기와 같이 상태 추적을 기반으로 하는 시스템에는 매우 유용합니다. 이벤트 덕분에 온타이머 이벤트 대기와 관련된 루핑 및 추가 브레이크 없이 알고리즘을 구축할 수 있습니다.

 
denkir:

...

아나톨리가 신경 쓰지 않기를 바랍니다 ...

아니, 물론 그는 신경 쓰지 않습니다. ) 특히 이후 ...

C-4:

...

추신 나는 또한 "MQL 레시피"라고 생각했습니다. - 아나톨리의 기사의 브랜드 이름이었습니다. 이제 그렇지 않다는 것이 밝혀졌습니다 (

... "MQL5 레시피"라는 레이블은 MQ 편집진이 제안 했으므로 누구나 사용할 수 있습니다. 가장 중요한 것은 더 많은 다양한 기사를 갖는 것입니다.

 
참조 매뉴얼에는 일관성이 보장되지 않는다고 분명히 명시되어 있습니다! 과거 데이터를 보면 일관성이 상당히 다릅니다.
 
이 글에 감사드립니다. 매우 유용합니다.
 
시스템이 작동하려면 어떻게 해야 하나요?
 
훌륭한 글입니다! 나는 여기서 많은 것을 배웠습니다, 축하합니다.
 
VikMorroHun #:
이 글에 감사드립니다. 매우 유용합니다.

안녕하세요,

제 상황은 아주 간단한 것 같습니다: 보류중인 주문(Sell_Stop)을 설정하고 a) 보류중인 주문이 체결되고 최종적으로 b) 오픈 포지션이 손절 또는 이익 목표에 의해 청산된 경우에 대응할 수 있기를 원합니다.

제가 올바르게 이해했나요?

  1. 보류 주문이 체결되었을 때 OnTradeTransaction()의 "요청" 매개변수가 다음과 같은 "마법" 필드를 소유하고 있음에도 불구하고 포지션 목록에서 요청해야만 매직넘버를 얻을 수 있습니다:
             if(!PositionSelectByTicket(trans.position)) {Print(__LINE__," PositionSelectByTicket FAILED ",err());}
             else {      
                OpnPos[sz].mag  = PositionGetInteger(POSITION_MAGIC);
             }   
    

  2. 매도 포지션이 개설되었는지 또는 청산되었는지 알 수 없는 방식으로 다양한 거래 유형:
    void OnTradeTransaction(const MqlTradeTransaction& trans,
                            const MqlTradeRequest& request,
                            const MqlTradeResult& result)
      {
    //---
    
    //--- 
       static int counter=0;   // 온트레이드트랜스잭션() 호출 카운터 
       static uint lasttime=0; // 온트레이드트랜잭션() 마지막 호출 시간 
    //--- 
       uint time=GetTickCount(); 
    //--- 마지막 트랜잭션이 1초 이상 전에 수행된 경우, 
       if(time-lasttime>1000) 
         { 
          counter=0; // 그러면 이것은 새로운 거래 작업이며 카운터를 재설정할 수 있습니다. 
          if(IS_DEBUG_MODE) 
             Print(__LINE__," "," New trade operation dTime",time-lasttime); 
         } 
       Print(__LINE__," ",counter," ",DoubleToString((double(lasttime=time)/1000.0,2)
                ," Tr.Type: ",EnumToString(trans.type)," DL.Type: ",EnumToString(trans.deal_type)
                ," RQ.Type: ",EnumToString(request.type)," RQ.Fill: ",EnumToString(request.type_filling)
             ); 
    01:00:40에 포지션을 개설하고 10:04:40에 포지션을 청산한 경우 다음과 같은 출력이 생성됩니다:
    01:00:40   322 0 81952.76 Tr.Type: TRADE_TRANSACTION_DEAL_ADD DL.Type: DEAL_TYPE_SELL RQ.Type: ORDER_TYPE_BUY RQ.Fill: ORDER_FILLING_FOK // open sell position
    10:04:40   322 0 81970.73 Tr.Type: TRADE_TRANSACTION_DEAL_ADD DL.Type: DEAL_TYPE_BUY  RQ.Type: ORDER_TYPE_BUY RQ.Fill: ORDER_FILLING_FOK // close sell position
    
    01:00:40   322 0 81955.30 Tr.Type: TRADE_TRANSACTION_ORDER_DELETE DL.Type: DEAL_TYPE_BUY RQ.Type: ORDER_TYPE_BUY RQ.Fill: ORDER_FILLING_FOK // open sell position
    10:04:40   322 0 81980.91 Tr.Type: TRADE_TRANSACTION_ORDER_DELETE DL.Type: DEAL_TYPE_BUY RQ.Type: ORDER_TYPE_BUY RQ.Fill: ORDER_FILLING_FOK // close sell position
    
    01:00:40   322 0 81965.14 Tr.Type: TRADE_TRANSACTION_HISTORY_ADD DL.Type: DEAL_TYPE_BUY RQ.Type: ORDER_TYPE_BUY RQ.Fill: ORDER_FILLING_FOK // open sell position
    10:04:40   322 0 81982.69 Tr.Type: TRADE_TRANSACTION_HISTORY_ADD DL.Type: DEAL_TYPE_BUY RQ.Type: ORDER_TYPE_BUY DL.Type: ORDER_FILLING_FOK // close sell position
    
    01:00:59   322 0 81968.50 Tr.Type: TRADE_TRANSACTION_REQUEST     DL.Type: DEAL_TYPE_BUY RQ.Type: ORDER_TYPE_SELL RQ.Fill: ORDER_FILLING_FOK // open sell position
    
    콜은 거의 동일하게 보이는데 어떻게 그럴까요? 1:00에 매도 포지션이 개설되었는데 왜 12개의 ..TYPE_BUY가 있고 2개의 TYPE_SELL만 있나요?
    매도 스탑이 트리거되어 매도(포지션)가 되는 경우 요청.type = ORDER_TYPE_BUY의 의미는 무엇이고 왜 그런가요? BUY는 어디에서 발생하나요?
매도 또는 매수 포지션이 청산되었는지를 모른 채 OnTradeTransaction()의 수단(파라미터)으로 손절 또는 이익 목표가 청산되었는지 확인하는 우아한 방법을 알고 계신가요?