OnTradeTransaction

이 함수는 TradeTransaction 이벤트가 발생할 때 EA 단위로 호출됩니다. 이 함수는 거래 요청 실행 결과를 처리하기 위한 것입니다.

void  OnTradeTransaction()
   const MqlTradeTransaction&    trans,     // 거래 트랜잭션 구조
   const MqlTradeRequest&        request,   // 요청 구조
   const MqlTradeResult&         result     // 반응 구조
   );

Parameters

trans

[in]  거래 계정에서 수행된 트랜잭션을 설명하는 MqlTradeTransaction 유형 변수.

request

[in]  거래 요청을 설명하는 MqlTradeRequest 유형 변수. 여기에는 TRADE_TRANSACTION_REQUEST 유형 트랜잭션에 대한 값만 포함됩니다.

result

[in]  트랜잭션으로 이어진 거래 요청의 실행 결과를 포함하는 MqlTradeResult 유형 변수. 여기에는 TRADE_TRANSACTION_REQUEST 유형 트랜잭션에 대한 값만 포함됩니다.

반환 값

반환값 없음

참고

OnTradeTransaction()은 다음과 같은 경우 트레이드 서버가 터미널에 보내는 TradeTransaction 이벤트를 처리하기 위해 호출됩니다:

  • OrderSend()/OrderSendAsync() 함수 및 후속 실행을 사용하여 MQL5 프로그램의 거래 요청 전송;
  • GUI 및 그 후속 실행을 통해 수동으로 거래 요청 전송;
  • 서버에서 보류 중인 명령 및 중지 명령의 활성화;
  • 트레이드 서버 쪽에서 작업을 수행.

 

트랜잭션 유형에 대한 데이터는 유형 필드, trans 변수에 포함됩니다. 트레이드 트랜잭션의 유형은 ENUM_TRADE_TRANSACTION_TYPE 열거값에 설명되어 있습니다:

  • TRADE_TRANSACTION_ORDER_ADD – 새 활성 주문 추가
  • TRADE_TRANSACTION_ORDER_UPDATE – 기존 주문 변경
  • TRADE_TRANSACTION_ORDER_DELETE – 활성 주문 목록에서 주문 삭제
  • TRADE_TRANSACTION_DEAL_ADD – 이력에 딜 추가
  • TRADE_TRANSACTION_DEAL_UPDATE – 이력의 딜 변경
  • TRADE_TRANSACTION_DEAL_DELETE – 이력에서 딜 삭제
  • TRADE_TRANSACTION_HISTORY_ADD – 실행 또는 취소의 결과로 내역에 주문 추가
  • TRADE_TRANSACTION_HISTORY_UPDATE – 주문 이력에서 주문 변경
  • TRADE_TRANSACTION_HISTORY_DELETE – 주문 내역에서 주문 삭제
  • TRADE_TRANSACTION_POSITION – 거래 실행과 무관한 포지션 변경
  • TRADE_TRANSACTION_REQUEST – 거래 요청이 서버에서 처리되었으며 처리 결과가 수신되었음을 알리는 알림.

TRADE_TRANSACTION_REQUEST 타입의 거래를 처리할 때는, OnTradeTransaction() 함수의 두 번째, 세 번째 변수 – 요청결과 – 를 분석하여 추가 정보를 얻어야 합니다.

매수 거래 요청을 전송하면 거래 계정의 연쇄 트레이드 트랜잭션으로 이어집니다. 1) 요청을 처리하도록 수락, 2) 계정에 대해 적절한 구매 주문 작성, 3) 주문이 실행됨, 4) 실행된 주문이 활성 주문 리스트에서 제거, 5) 후속 트랜잭션 기록 추가, 6) 이력에 추가, 7) 새 포지션이 생성됩니다. 이 모든 단계는 트레이드 트랜잭션입니다. 이러한 각 트랜잭션이 터미널에 도착하는 것은 TradeTransaction 이벤트입니다. 이러한 거래의 터미널 도착 우선순위는 보장되지 않습니다. 따라서 거래 알고리즘을 개발할 때 한 그룹의 트랜잭션이 차례로 도착할 것이라고 예상해서는 안 됩니다.

EA의 OnTradeTransaction() 핸들러가 트랜잭션을 처리하면 터미널은 들어오는 거래 트랜잭션을 처리합니다. 따라서 OnTradeTransaction() 작업 과정에서 거래 계정 상태가 변경될 수 있습니다. 예를 들어, MQL5 프로그램이 새 주문 추가를 처리하는 동안 실행하거나 열려 있는 주문 목록에서 삭제하고 기록으로 이동할 수 있습니다. 프로그램에 이러한 모든 이벤트가 통지됩니다.

1024개의 요소들로 이루어진 거래 대기 길이. OnTradeTransaction()이 다른 트랜잭션을 너무 오랫동안 처리하면 이전 트랜잭션이 대기열의 새 트랜잭션으로 대체될 수 있습니다.

OnTrade() 핸들러는 적절한 OnTradeTransaction() 호출 뒤에 호출됩니다. 일반적으로 OnTrade () 및 OnTradeTransaction () 요청 수에는 정확한 상관관계가 없습니다. 한 번의 OnTrade() 호출은 하나 이상의 OnTradeTransaction 호출에 해당합니다.

Trade 이벤트는 하나 또는 여러 거래 요청의 결과로 나타날 수 있습니다. 거래 요청은OrderSend() 또는 OrderSendAsync()을 사용하여 서버로 전송됩니다. 각 요청은 여러 가지 거래 이벤트를 유발할 수 있습니다. "하나의 요청당 하나의 거래 이벤트"라는 문장은 꼭 맞다고 하기 어렵습니다. 이벤트의 처리는 여러 단계로 수행될 수 있으며 각 작업의 주문 상태, 포지션 및 거래 기록이 변경될 수 있기 때문입니다.

샘플 EA OnTradeTransaction() 핸들러 포함

//+------------------------------------------------------------------+
//|                                    OnTradeTransaction_Sample.mq5 |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2000-2024, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property description "TradeTransaction 이벤트의 샘플 리스너"
//+------------------------------------------------------------------+
//| Expert 초기화 함수                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   PrintFormat("LAST PING=%.f ms",
               TerminalInfoInteger(TERMINAL_PING_LAST)/1000.);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert 틱 함수                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
 
  }
//+------------------------------------------------------------------+
//| TradeTransaction 함수                                        |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
//---
   static int counter=0;   // OnTradeTransaction() 호출의 카운터
   static uint lasttime=0; // OnTradeTransaction() 최근 호출 시간
//---
   uint time=GetTickCount();
//--- 마지막 거래가 1초 이상 전에 수행된 경우,
   if(time-lasttime>1000)
     {
      counter=0; // 그러면 이것은 새로운 거래 작업이고 카운터는 재설정될 수 있습니다
      if(IS_DEBUG_MODE)
         Print(" 새 거래 작업");
     }
   lasttime=time;
   counter++;
   Print(counter,". ",__FUNCTION__);
//--- 거래 요청 실행 결과
   ulong            lastOrderID   =trans.order;
   ENUM_ORDER_TYPE  lastOrderType =trans.order_type;
   ENUM_ORDER_STATE lastOrderState=trans.order_state;
//--- 트랜잭션이 수행된 심볼의 이름
   string trans_symbol=trans.symbol;
//--- 트랜잭션 유형
   ENUM_TRADE_TRANSACTION_TYPE  trans_type=trans.type;
   switch(trans.type)
     {
      case  TRADE_TRANSACTION_POSITION:   // 포지션 변경
        {
         ulong pos_ID=trans.position;
         PrintFormat("MqlTradeTransaction: Position  #%I64u %s modified: SL=%.5f TP=%.5f",
                     pos_ID,trans_symbol,trans.price_sl,trans.price_tp);
        }
      break;
      case TRADE_TRANSACTION_REQUEST:     // 거래 요청 전송
         PrintFormat("MqlTradeTransaction: TRADE_TRANSACTION_REQUEST");
         break;
      case TRADE_TRANSACTION_DEAL_ADD:    // 거래 추가
        {
         ulong          lastDealID   =trans.deal;
         ENUM_DEAL_TYPE lastDealType =trans.deal_type;
         double        lastDealVolume=trans.volume;
         //--- 외부 시스템의 거래 ID - 거래소에서 할당한 티켓
         string Exchange_ticket="";
         if(HistoryDealSelect(lastDealID))
            Exchange_ticket=HistoryDealGetString(lastDealID,DEAL_EXTERNAL_ID);
         if(Exchange_ticket!="")
            Exchange_ticket=StringFormat("(Exchange deal=%s)",Exchange_ticket);
 
         PrintFormat("MqlTradeTransaction: %s deal #%I64u %s %s %.2f lot   %s",EnumToString(trans_type),
                     lastDealID,EnumToString(lastDealType),trans_symbol,lastDealVolume,Exchange_ticket);
        }
      break;
      case TRADE_TRANSACTION_HISTORY_ADD// 내역에 주문 추가
        {
         //--- 외부 시스템의 주문 ID - 거래소에서 할당한 티켓
         string Exchange_ticket="";
         if(lastOrderState==ORDER_STATE_FILLED)
           {
            if(HistoryOrderSelect(lastOrderID))
               Exchange_ticket=HistoryOrderGetString(lastOrderID,ORDER_EXTERNAL_ID);
            if(Exchange_ticket!="")
               Exchange_ticket=StringFormat("(Exchange ticket=%s)",Exchange_ticket);
           }
         PrintFormat("MqlTradeTransaction: %s order #%I64u %s %s %s   %s",EnumToString(trans_type),
                     lastOrderID,EnumToString(lastOrderType),trans_symbol,EnumToString(lastOrderState),Exchange_ticket);
        }
      break;
      default// 기타 트랜잭션  
        {
         //--- 외부 시스템의 주문 ID - 거래소에서 할당한 티켓
         string Exchange_ticket="";
         if(lastOrderState==ORDER_STATE_PLACED)
           {
            if(OrderSelect(lastOrderID))
               Exchange_ticket=OrderGetString(ORDER_EXTERNAL_ID);
            if(Exchange_ticket!="")
               Exchange_ticket=StringFormat("Exchange ticket=%s",Exchange_ticket);
           }
         PrintFormat("MqlTradeTransaction: %s order #%I64u %s %s   %s",EnumToString(trans_type),
                     lastOrderID,EnumToString(lastOrderType),EnumToString(lastOrderState),Exchange_ticket);
        }
      break;
     }
//--- 주문 티켓    
   ulong orderID_result=result.order;
   string retcode_result=GetRetcodeID(result.retcode);
   if(orderID_result!=0)
      PrintFormat("MqlTradeResult: order #%d retcode=%s ",orderID_result,retcode_result);
//---   
  }
//+------------------------------------------------------------------+
//| 숫자 응답 코드를 문자열 니모닉으로 변환               |
//+------------------------------------------------------------------+
string GetRetcodeID(int retcode)
  {
   switch(retcode)
     {
      case 10004: return("TRADE_RETCODE_REQUOTE");             break;
      case 10006: return("TRADE_RETCODE_REJECT");              break;
      case 10007: return("TRADE_RETCODE_CANCEL");              break;
      case 10008: return("TRADE_RETCODE_PLACED");              break;
      case 10009: return("TRADE_RETCODE_DONE");                break;
      case 10010: return("TRADE_RETCODE_DONE_PARTIAL");        break;
      case 10011: return("TRADE_RETCODE_ERROR");               break;
      case 10012: return("TRADE_RETCODE_TIMEOUT");             break;
      case 10013: return("TRADE_RETCODE_INVALID");             break;
      case 10014: return("TRADE_RETCODE_INVALID_VOLUME");      break;
      case 10015: return("TRADE_RETCODE_INVALID_PRICE");       break;
      case 10016: return("TRADE_RETCODE_INVALID_STOPS");       break;
      case 10017: return("TRADE_RETCODE_TRADE_DISABLED");      break;
      case 10018: return("TRADE_RETCODE_MARKET_CLOSED");       break;
      case 10019: return("TRADE_RETCODE_NO_MONEY");            break;
      case 10020: return("TRADE_RETCODE_PRICE_CHANGED");       break;
      case 10021: return("TRADE_RETCODE_PRICE_OFF");           break;
      case 10022: return("TRADE_RETCODE_INVALID_EXPIRATION");  break;
      case 10023: return("TRADE_RETCODE_ORDER_CHANGED");       break;
      case 10024: return("TRADE_RETCODE_TOO_MANY_REQUESTS");   break;
      case 10025: return("TRADE_RETCODE_NO_CHANGES");          break;
      case 10026: return("TRADE_RETCODE_SERVER_DISABLES_AT");  break;
      case 10027: return("TRADE_RETCODE_CLIENT_DISABLES_AT");  break;
      case 10028: return("TRADE_RETCODE_LOCKED");              break;
      case 10029: return("TRADE_RETCODE_FROZEN");              break;
      case 10030: return("TRADE_RETCODE_INVALID_FILL");        break;
      case 10031: return("TRADE_RETCODE_CONNECTION");          break;
      case 10032: return("TRADE_RETCODE_ONLY_REAL");           break;
      case 10033: return("TRADE_RETCODE_LIMIT_ORDERS");        break;
      case 10034: return("TRADE_RETCODE_LIMIT_VOLUME");        break;
      case 10035: return("TRADE_RETCODE_INVALID_ORDER");       break;
      case 10036: return("TRADE_RETCODE_POSITION_CLOSED");     break;
      default:
         return("TRADE_RETCODE_UNKNOWN="+IntegerToString(retcode));
         break;
     }
//---
  }

더 보기

OrderSend, OrderSendAsync, OnTradeTransaction, Trade request structure, Trade transaction structure, Trade transaction types, Trade operation types, Client terminal events