OnTrade

이 함수는 Trade 이벤트가 발생할 때 EA로 호출됩니다. 이 기능은 순서, 위치 및 거래 목록의 변경을 처리하기 위한 것입니다.

void  OnTrade(void);

반환 값

반환값 없음

참고

OnTrade()는 Expert Advisors 전용으로 호출됩니다. 이름과 유형이 동일한 함수를 추가하는 경우에도 지표 및 스크립트에서 사용되지 않습니다.

모든 거래 행위(보류 주문, 오프닝/클로징, 정지, 주문 활성화 등)의 경우, 주문 및 거래 내역 및/또는 포지션 목록과 현재 주문 목록을 적절하게 변경합니다.

주문을 처리할 때 거래 서버는 터미널에 들어오는 Trade 이벤트에 대한 메시지를 보냅니다. 주문 및 거래 내역 관련 데이터를 검색하려면 먼저 HistorySelect()를 사용하여 거래 내역 요청을 수행해야 합니다.

다음과 같은 경우 서버에서 거래 이벤트를 생성합니다:

  • 활성화 주문 변경,
  • 포지션 변경,
  • 딜 변경,
  • 거래 이력 변경.

 

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

 

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

샘플 EA OnTrade() 핸들러 포함

//+------------------------------------------------------------------+
//|                                               OnTrade_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"
 
input    int days=7;            // 며칠간 거래의 뎁스 내역
//--- 거래 이력의 한계를 글로벌 범위로 설정
datetime     start;             // 캐시 내 거래 이력 시작 날짜
datetime     end;               // 캐시 내 거래 이력 종료 날짜
//--- 글로벌 카운터
int          orders;            // 활성 주문 수
int          positions;         // 오픈 포지션 수
int          deals;             // 거래 내역 캐시의 거래 수
int          history_orders;    // 거래 내역 캐시의 주문 수
bool         started=false;     // 역관계의 플래그
 
//+------------------------------------------------------------------+
//| Expert 초기화 함수                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   end=TimeCurrent();
   start=end-days*PeriodSeconds(PERIOD_D1);
   PrintFormat("로드할 기록의 제한: start - %s, end - %s",
               TimeToString(start),TimeToString(end));
   InitCounters();
//---
   return(0);
  }
//+------------------------------------------------------------------+
//|  포지션, 주문 및 거래 카운터의 초기화            |
//+------------------------------------------------------------------+
void InitCounters()
  {
   ResetLastError();
//--- 로드 이력
   bool selected=HistorySelect(start,end);
   if(!selected)
     {
      PrintFormat("%s. Failed to load history from %s to %s to cache. Error code: %d",
                  __FUNCTION__,TimeToString(start),TimeToString(end),GetLastError());
      return;
     }
//--- 현재 값 획득
   orders=OrdersTotal();
   positions=PositionsTotal();
   deals=HistoryDealsTotal();
   history_orders=HistoryOrdersTotal();
   started=true;
   Print("주문, 포지션 및 거래 카운터가 초기화되었습니다");
  }  
//+------------------------------------------------------------------+
//| Expert 틱 함수                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   if(started) SimpleTradeProcessor();
   else InitCounters();
  }
//+------------------------------------------------------------------+
//| 거래 이벤트가 도착하면 호출됩니다                                |
//+------------------------------------------------------------------+
void OnTrade()
  {
   if(started) SimpleTradeProcessor();
   else InitCounters();
  }
//+------------------------------------------------------------------+
//| 거래 및 내역 변경의 처리 예               |
//+------------------------------------------------------------------+
void SimpleTradeProcessor()
  {
   end=TimeCurrent();
   ResetLastError();
//--- 지정된 간격에서 프로그램 캐시로 거래 기록 다운로드
   bool selected=HistorySelect(start,end);
   if(!selected)
     {
      PrintFormat("%s. Failed to load history from %s to %s to cache. Error code: %d",
                  __FUNCTION__,TimeToString(start),TimeToString(end),GetLastError());
      return;
     }
//--- 현재 값 획득
   int curr_orders=OrdersTotal();
   int curr_positions=PositionsTotal();
   int curr_deals=HistoryDealsTotal();
   int curr_history_orders=HistoryOrdersTotal();
//--- 활성 주문 건수가 변경되었는지 점검
   if(curr_orders!=orders)
     {
      //--- 활성 주문 수가 변경되었습니다
      PrintFormat("주문 건수가 변경되었습니다. 이전 값은 %d, 현재 값은 %d",
                  orders,curr_orders);
      //--- 값 업데이트
      orders=curr_orders;
     }
//--- 오픈 포지션 수의 변화
   if(curr_positions!=positions)
     {
      //--- 오픈 포지션 수가 변경되었습니다
      PrintFormat("포지션 수가 변경되었습니다. 이전 값은 %d, 현재 값은 %d",
                  positions,curr_positions);
      //--- 값 업데이트
      positions=curr_positions;
     }
//--- 거래 내역 캐시의 딜 수 변경
   if(curr_deals!=deals)
     {
      //--- 거래 기록 캐시의 딜 수가 변경되었습니다
      PrintFormat("딜 수가 변경되었습니다. 이전 값은 %d, 현재 값은 %d",
                  deals,curr_deals);
      //--- 값 업데이트
      deals=curr_deals;
     }
//--- 거래 기록 캐시의 기록 주문 수 변경
   if(curr_history_orders!=history_orders)
     {
      //--- 거래 기록 캐시의 기록 주문 수가 변경되었습니다
      PrintFormat("기록 내 주문 수가 변경되었습니다. 이전 값은 %d, 현재 값은 %d",
                  history_orders,curr_history_orders);
     //--- 값 업데이트
     history_orders=curr_history_orders;
     }
//--- 캐시에서 요청할 거래 기록의 한도를 변경할 필요가 있는지 확인
   CheckStartDateInTradeHistory();
  }
//+------------------------------------------------------------------+
//|  거래 내역 요청 시작 날짜 변경        |
//+------------------------------------------------------------------+
void CheckStartDateInTradeHistory()
  {
//--- 초기 간격, 지금 당장 작업을 시작할 경우
   datetime curr_start=TimeCurrent()-days*PeriodSeconds(PERIOD_D1);
//--- 거래 내역의 시작 제한이 없어지지 않도록 하십시오
//--- 예정일보다 1일 이상 경과
   if(curr_start-start>PeriodSeconds(PERIOD_D1))
     {
      //--- 캐시에 로드할 기록 시작 날짜를 수정
      start=curr_start;
      PrintFormat("로드할 거래 기록의 새 시작 제한: 시작 => %s",
                  TimeToString(start));
      //--- 이제 업데이트된 간격에 대한 거래 기록을 다시 로드합니다
      HistorySelect(start,end);
      //--- 그 이상의 비교를 위해 딜과 주문 카운터를 수정
      history_orders=HistoryOrdersTotal();
      deals=HistoryDealsTotal();
     }
  }
//+------------------------------------------------------------------+
/* 샘플 결과:
  로드할 기록의 한계: 시작 - 2018.07.16 18:11, 끝 - 2018.07.23 18:11
  주문, 포지션 및 거래 카운터가 성공적으로 초기화되었습니다.
  주문 수가 변경되었습니다. 이전 값 0, 현재 값 1
  주문 수가 변경되었습니다. 이전 값 0, 현재 값 1
  포지션 수가 변경되었습니다. 이전 값 0, 현재 값 1
  딜 수가 변경되었습니다. 이전 값 0, 현재 값 1
  내역의 주문 수가 변경되었습니다. 이전 값 0, 현재 값 1
*/

더 보기

OrderSend, OrderSendAsync, OnTradeTransaction, Client terminal events