English Русский 中文 Español Deutsch 日本語 Português Français Italiano Türkçe
MQL5 쿡북: TradeTransaction 이벤트 프로세싱

MQL5 쿡북: TradeTransaction 이벤트 프로세싱

MetaTrader 5 | 12 10월 2021, 15:12
148 0
Denis Kirichenko
Denis Kirichenko

개요

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

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

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


1. TradeTransaction 이벤트

우선 TradeTransaction에 대해 알려진 정보를 한번 확인해 보죠.

TradeTransaction 이벤트는 거래 계좌에 대한 특정 오퍼레이션의 결과입니다. 오퍼레이션은 여러가지 거래 단계로 이루어집니다. 예를 들어 시장 주문을 통해 포지션을 오픈하는 오퍼레이션은 다음의 단계로 구성되죠.

  1. 거래 요청
  2. 거래 요청 확인
  3. 서버측에 거래 요청 전송
  4. 서버측으로부터 거래 주문 실행 응답 수신

위와 같은 시퀀스는 EA 코드 내 문자열에 나타난 터미널과 서버 간의 로직만을 보여주죠. TradeTransaction 트레이드 이벤트의 관점에서 보면, 시장 내 포지션 오픈은 다음의 단계로 구성됩니다.

  1. MQL5 프로그램이 서버측으로부터 완료된 요청 결과 수신
  2. 고유 티켓을 가진 주문 요청을 오픈 오더 목록에 포함
  3. 실행 후 오픈 오더 목록에서 해당 주문 삭제
  4. 계좌 기록으로 삭제된 주문이 이동
  5. 계좌 거래 기록에는 주문 실행 결과에 대한 정보 또한 포함됩니다.

따라서 포지션 오픈에는 다섯 번의 OnTradeTransaction() 핸들러 호출이 필요하죠.

우선 함수 헤더를 살펴본 후 전체 프로그램 코드에 대해 이야기해 볼게요. 세 개의 입력 매개 변수가 있네요.

void  OnTradeTransaction(
   const MqlTradeTransaction&    trans,        // structure of the trade transaction
   const MqlTradeRequest&        request,      // structure of the request
   const MqlTradeResult&         result        // structure of the response
   );
-->

이미 해당 변수들에 대한 관련 자료가 나와 있습니다. 거래 트랜잭션 구조 매개 변수는 현재 호출이 실행되는 동안 핸들러가 수신하는 정보의 캐스트와 같습니다.

거래 트랜잭션 유형에 대해서도 설명할게요. 앞으로 많이 마주치게 될 겁니다.

MQL5에서는 ENUM_TRADE_TRANSACTION_TYPE이 거래 트랜잭션 유형을 나타내는 특수 열거형입니다. 거래 트랜잭션 유형을 알기 위해서는 MqlTradeTransaction형 정수형 변수를 참조하면 됩니다.

struct MqlTradeTransaction
  {
   ulong                         deal;             // Ticket of the deal
   ulong                         order;            // Ticket of the order
   string                        symbol;           // Trade symbol
   ENUM_TRADE_TRANSACTION_TYPE   type;             // Type of the trade transaction
   ENUM_ORDER_TYPE               order_type;       // Type of the order
   ENUM_ORDER_STATE              order_state;      // Status of the order
   ENUM_DEAL_TYPE                deal_type;        // Type of the deal
   ENUM_ORDER_TYPE_TIME          time_type;        // Order expiration type
   datetime                      time_expiration;  // Order expiration time
   double                        price;            // Price 
   double                        price_trigger;    // Price that triggers the Stop Limit order
   double                        price_sl;         // Level of Stop Loss
   double                        price_tp;         // Level of Take Profit
   double                        volume;           // Volume in lots
  };
-->

해당 구조의 네 번재 필드가 우리가 찾고 있는 열거형이 되죠.


2. 포지션 프로세싱

포지션과 관련된 모든 거래 오퍼레이션은 OnTradeTransaction() 핸들러를 다섯 번 호출합니다. 해당 오퍼레이션에는 다음이 포함되죠.

  • 포지션 오픈
  • 포지션
  • 포지션 반전
  • 포지션 랏 추가
  • 포지션 부분 청산

포지션 수정만이 유일하게 TradeTransaction 이벤트 핸들러를 두 번 호출합니다.

어떤 거래 유형이 어떤 거래 오퍼레이션을 담당하는지 알 수 없으므로 실험을 통해 직접 알아보겠습니다.

이에 앞서 TradeTransaction 이벤트 핸들러를 포함하는 EA 템플릿을 생성할 겁니다. 제 템플릿은 TradeProcessor.mq5라고 이름 붙였습니다. 로그 내 구조 필드 값에 대한 정보를 표시하는 기능을 추가했는데요. 이 값들이 이벤트 핸들러의 매개 변수로 이용될 겁니다. 전체 기록을 분석하는 데는 시간이 많이 걸리지만 이벤트에 대한 이해도를 높일 수 있을 겁니다.

MetaTrader5 터미널에서 차트를 하나 선택하고 디버깅 모드로 EA를 실행합니다.

수동으로 포지션을 오픈하고 코드를 살펴봅니다. 첫 번째 호출은 다음과 같이 나타납니다(그림 1).

그림 1. TRADE_TRANSACTION_REQUEST 필드 타입

그림 1. TRADE_TRANSACTION_REQUEST 필드 타입

로그에 다음의 기록이 저장됩니다.

IO      0       17:37:53.233    TradeProcessor (EURUSD,H1)      ---===Transaction===---
NK      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Ticket of the deal: 0
RR      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Type of the deal: DEAL_TYPE_BUY
DE      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Ticket of the order: 0
JS      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Status of the order: ORDER_STATE_STARTED
JN      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Type of the order: ORDER_TYPE_BUY
FD      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Price: 0.0000
FN      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Level of Stop Loss: 0.0000
HF      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Level of Take Profit: 0.0000
FQ      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Price that triggers the Stop Limit order: 0.0000
RR      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Trade symbol: 
HD      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Pending order expiration time: 1970.01.01 00:00
GS      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Order expiration type: ORDER_TIME_GTC
DN      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Type of the trade transaction TRADE_TRANSACTION_REQUEST
FK      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Volume in lots: 0.00
-->

해당 블록에서는 트랜잭션 유형과 관련된 기록만 필요합니다. 해당 유형은 (TRADE_TRANSACTION_REQUEST) 요청에 포함되죠.

요청에 대한 정보는 '요청' 블록에서 얻을 수 있습니다.

QG      0       17:37:53.233    TradeProcessor (EURUSD,H1)      ---===Request===--- HL      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Type of the trade operation: TRADE_ACTION_DEAL EE      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Comment to the order: JP      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Deviation from the requested price: 0 GS      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Order expiration time: 1970.01.01 00:00 LF      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Magic number of the EA: 0 FM      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Ticket of the order: 22535869 EJ      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Price: 1.3137 QR      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Stop Loss level of the order: 0.0000 IJ      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Take Profit level of the order: 0.0000 KK      0       17:37:53.233    TradeProcessor (EURUSD,H1)      StopLimit level of the order: 0.0000 FS      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Trade symbol: EURUSD RD      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Type of the order: ORDER_TYPE_BUY

-->

요청 실행 결과에 대한 정보는 '응답' 블록에서 얻을 수 있죠.

KG      0       17:37:53.233    TradeProcessor (EURUSD,H1)      ---===Response===---
JR      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Code of the operation result: 10009
GD      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Ticket of the deal: 15258202
NR      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Ticket of the order: 22535869
EF      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Volume of the deal: 0.11
MN      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Price of the deal: 1.3137
HJ      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Bid: 1.3135
PM      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Ask: 1.3137
OG      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Comment to the operation: 
RQ      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Request ID: 1
-->

요청과 응답의 구조와 같은 핸들러의 기타 매개 변수를 분석하면 요청 및 첫 번째 호출에 대한 추가 정보를 얻게 됩니다.

두 번째 호출은 오픈 오더 목록에 해당 주문을 추가합니다(그림 2).

그림 2. TRADE_TRANSACTION_ORDER_ADD 필드 타입

그림 2. TRADE_TRANSACTION_ORDER_ADD 필드 타입

해당 로그에서는 '트랜잭션' 블록만 보면 되는데요.

MJ      0       17:41:12.280    TradeProcessor (EURUSD,H1)      ---===Transaction===---
JN      0       17:41:12.280    TradeProcessor (EURUSD,H1)      Ticket of the deal: 0
FG      0       17:41:12.280    TradeProcessor (EURUSD,H1)      Type of the deal: DEAL_TYPE_BUY
LM      0       17:41:12.280    TradeProcessor (EURUSD,H1)      Ticket of the order: 22535869
LI      0       17:41:12.280    TradeProcessor (EURUSD,H1)      Status of the order: ORDER_STATE_STARTED
LP      0       17:41:12.280    TradeProcessor (EURUSD,H1)      Type of the order: ORDER_TYPE_BUY
QN      0       17:41:12.280    TradeProcessor (EURUSD,H1)      Price: 1.3137
PD      0       17:41:12.280    TradeProcessor (EURUSD,H1)      Level of Stop Loss: 0.0000
NL      0       17:41:12.280    TradeProcessor (EURUSD,H1)      Level of Take Profit: 0.0000
PG      0       17:41:12.280    TradeProcessor (EURUSD,H1)      Price that triggers the Stop Limit order: 0.0000
DL      0       17:41:12.280    TradeProcessor (EURUSD,H1)      Trade symbol: EURUSD
JK      0       17:41:12.280    TradeProcessor (EURUSD,H1)      Pending order expiration time: 1970.01.01 00:00
QD      0       17:41:12.280    TradeProcessor (EURUSD,H1)      Order expiration type: ORDER_TIME_GTC
IQ      0       17:41:12.280    TradeProcessor (EURUSD,H1)      Type of the trade transaction: TRADE_TRANSACTION_ORDER_ADD
PL      0       17:41:12.280    TradeProcessor (EURUSD,H1)      Volume in lots: 0.11
-->

보시다시피 해당 주문에는 이미 티켓과 기타 매개 변수(심볼, 가격 및 볼륨)이 부여되었으며 오픈 오더 목록에 포함되어 있죠.

이벤트 핸들러의 세 번째 호출은 오픈 오더 목록에서 해당 주문을 삭제합니다(그림 3).

그림 3. TRADE_TRANSACTION_ORDER_DELETE 필드 타입

그림 3. TRADE_TRANSACTION_ORDER_DELETE 필드 타입

해당 로그에서는 '트랜잭션' 블록만 보면 되는데요.

PF      0       17:52:36.722    TradeProcessor (EURUSD,H1)      ---===Transaction===---
OE      0       17:52:36.722    TradeProcessor (EURUSD,H1)      Ticket of the deal: 0
KL      0       17:52:36.722    TradeProcessor (EURUSD,H1)      Type of the deal: DEAL_TYPE_BUY
EH      0       17:52:36.722    TradeProcessor (EURUSD,H1)      Ticket of the order: 22535869
QM      0       17:52:36.722    TradeProcessor (EURUSD,H1)      Status of the order: ORDER_STATE_STARTED
QK      0       17:52:36.722    TradeProcessor (EURUSD,H1)      Type of the order: ORDER_TYPE_BUY
HS      0       17:52:36.722    TradeProcessor (EURUSD,H1)      Price: 1.3137
MH      0       17:52:36.722    TradeProcessor (EURUSD,H1)      Level of Stop Loss: 0.0000
OP      0       17:52:36.722    TradeProcessor (EURUSD,H1)      Level of Take Profit: 0.0000
EJ      0       17:52:36.722    TradeProcessor (EURUSD,H1)      Price that triggers the Stop Limit order: 0.0000
IH      0       17:52:36.722    TradeProcessor (EURUSD,H1)      Trade symbol: EURUSD
KP      0       17:52:36.722    TradeProcessor (EURUSD,H1)      Pending order expiration time: 1970.01.01 00:00
LO      0       17:52:36.722    TradeProcessor (EURUSD,H1)      Order expiration type: ORDER_TIME_GTC
HG      0       17:52:36.722    TradeProcessor (EURUSD,H1)      Type of the trade transaction: TRADE_TRANSACTION_ORDER_DELETE
CG      0       17:52:36.722    TradeProcessor (EURUSD,H1)      Volume in lots: 0.11
-->

트랜잭션 형식 이외에는 새로운 정보가 없거든요.

과거 기록에 새로운 주문이 나타나는 경우 네 번째 핸들러 호출이 실행됩니다(그림 4).

그림 4. TRADE_TRANSACTION_HISTORY_ADD 필드 타입

그림 4. TRADE_TRANSACTION_HISTORY_ADD 필드 타입

필요한 정보는 '트랜잭션' 블록에서 얻을 수 있습니다.

QO      0       17:57:32.234    TradeProcessor (EURUSD,H1)      ---===Transaction==---
RJ      0       17:57:32.234    TradeProcessor (EURUSD,H1)      Ticket of the deal: 0
NS      0       17:57:32.234    TradeProcessor (EURUSD,H1)      Type of the deal: DEAL_TYPE_BUY
DQ      0       17:57:32.234    TradeProcessor (EURUSD,H1)      Ticket of the order: 22535869
EH      0       17:57:32.234    TradeProcessor (EURUSD,H1)      Status of the order: ORDER_STATE_FILLED
RL      0       17:57:32.234    TradeProcessor (EURUSD,H1)      Type of the order: ORDER_TYPE_BUY
KJ      0       17:57:32.234    TradeProcessor (EURUSD,H1)      Price: 1.3137
NO      0       17:57:32.234    TradeProcessor (EURUSD,H1)      Level of Stop Loss: 0.0000
PI      0       17:57:32.234    TradeProcessor (EURUSD,H1)      Level of Take Profit: 0.0000
FS      0       17:57:32.234    TradeProcessor (EURUSD,H1)      Price that triggers the Stop Limit order: 0.0000
JS      0       17:57:32.234    TradeProcessor (EURUSD,H1)      Trade symbol: EURUSD
LG      0       17:57:32.234    TradeProcessor (EURUSD,H1)      Pending order expiration time: 1970.01.01 00:00
KP      0       17:57:32.234    TradeProcessor (EURUSD,H1)      Order expiration type: ORDER_TIME_GTC
OL      0       17:57:32.234    TradeProcessor (EURUSD,H1)      Type of the trade transaction: TRADE_TRANSACTION_HISTORY_ADD
JH      0       17:57:32.234    TradeProcessor (EURUSD,H1)      Volume in lots: 0.00
-->

이제 주문이 실행됐음을 확인할 수 있죠.

마지막으로 다섯 번째 호출은 과거 기록에 거래가 추가되는 경우 발생합니다(그림 5).

그림 5. TRADE_TRANSACTION_DEAL_ADD 필드 타입

그림 5. TRADE_TRANSACTION_DEAL_ADD 필드 타입

이번에도 '트랜잭션' 블록만 보면 됩니다.

OE      0       17:59:40.718    TradeProcessor (EURUSD,H1)      ---===Transaction===---
MS      0       17:59:40.718    TradeProcessor (EURUSD,H1)      Ticket of the deal: 15258202
RJ      0       17:59:40.718    TradeProcessor (EURUSD,H1)      Type of the deal: DEAL_TYPE_BUY
HN      0       17:59:40.718    TradeProcessor (EURUSD,H1)      Ticket of the order: 22535869
LK      0       17:59:40.718    TradeProcessor (EURUSD,H1)      Status of the order: ORDER_STATE_STARTED
LE      0       17:59:40.718    TradeProcessor (EURUSD,H1)      Type of the order: ORDER_TYPE_BUY
MM      0       17:59:40.718    TradeProcessor (EURUSD,H1)      Price: 1.3137
PF      0       17:59:40.718    TradeProcessor (EURUSD,H1)      Level of Stop Loss: 0.0000
NN      0       17:59:40.718    TradeProcessor (EURUSD,H1)      Level of Take Profit: 0.0000
PI      0       17:59:40.718    TradeProcessor (EURUSD,H1)      Price that triggers the Stop Limit order: 0.0000
DJ      0       17:59:40.718    TradeProcessor (EURUSD,H1)      Trade symbol: EURUSD
JM      0       17:59:40.718    TradeProcessor (EURUSD,H1)      Pending order expiration time: 1970.01.01 00:00
QI      0       17:59:40.718    TradeProcessor (EURUSD,H1)      Order expiration type: ORDER_TIME_GTC
CK      0       17:59:40.718    TradeProcessor (EURUSD,H1)      Type of the trade transaction: TRADE_TRANSACTION_DEAL_ADD
RQ      0       17:59:40.718    TradeProcessor (EURUSD,H1)      Volume in lots: 0.11
-->

거래 티켓이 중요한 문자열이죠.

트랜잭션 구조를 보여드릴게요. 포지션에는 두 개의 트랜잭션이 있습니다. 첫 번째는 그림 6과 같이 나타납니다.

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

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


모든 거래 오퍼레이션은 해당 구조에 따라 발생하는 포지션 프로세싱과 연결되어 있습니다. 포지션 수정 오퍼레이션은 예외입니다. 마지막 오퍼레이션은 다음의 두 트랜잭션 프로세싱을 포함합니다(그림 7).

그림 7. 두 번재 트랜잭션 프로세스 구조

그림 7. 두 번재 트랜잭션 프로세스 구조

포지션 수정은 주문 기록에서 찾을 수 없습니다.

포지션에 대해서는 이 정도면 됐습니다.



3. 대기 주문 프로세싱

대기 주문 오퍼레이션 트랜잭션은 보다 간단합니다. 동시에 주문에 대한 트랜잭션 형식 조합이 더 다양하게 나타나죠.

주문을 수정하려면 핸들러를 두 번 호출해야 합니다. 포지션 수정과 비슷하죠. 주문을 걸고 삭제하는 데에는 세 번의 호출이 필요합니다. TradeTransaction 이벤트는 주문 삭제 또는 실행 시 네 번 발생하죠.

이제 대기 주문을 만들어 볼 겁니다. 다시 한번 MetaTrader5 터미널에서 차트를 하나 선택한 후 디버깅 모드로 EA를 실행합니다.

핸들러의 첫 번재 호출은 요청과 연결되어 있습니다(그림 8).

그림 8. TRADE_TRANSACTION_REQUEST 필드 타입

그림 8. TRADE_TRANSACTION_REQUEST 필드 타입

다음과 같은 내용의 로그가 나타납니다.

IO      0       18:13:33.195    TradeProcessor (EURUSD,H1)      ---===Transaction===---
NK      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Ticket of the deal: 0
RR      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Type of the deal: DEAL_TYPE_BUY
DE      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Ticket of the order: 0
JS      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Status of the order: ORDER_STATE_STARTED
JN      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Type of the order: ORDER_TYPE_BUY
FD      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Price: 0.0000
FN      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Level of Stop Loss: 0.0000
HF      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Level of Take Profit: 0.0000
FQ      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Price that triggers the Stop Limit order: 0.0000
RR      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Trade symbol: 
HD      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Pending order expiration time: 1970.01.01 00:00
GS      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Order expiration type: ORDER_TIME_GTC
DN      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Type of the trade transaction: TRADE_TRANSACTION_REQUEST
FK      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Volume in lots: 0.00
NS      0       18:13:33.195    TradeProcessor (EURUSD,H1)      

QG      0       18:13:33.195    TradeProcessor (EURUSD,H1)      ---===Request==---
IQ      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Type of the trade operation: TRADE_ACTION_PENDING
OE      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Order comment: 
PQ      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Deviation from the requested price: 0
QS      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Order expiration time: 1970.01.01 00:00
FI      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Magic number of the EA: 0
CM      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Ticket of the order: 22535983
PK      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Price: 1.6500
KR      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Stop Loss level of the order: 0.0000
OI      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Take Profit level of the order: 0.0000
QK      0       18:13:33.195    TradeProcessor (EURUSD,H1)      StopLimit level of the order: 0.0000
QQ      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Trade symbol: GBPUSD
RD      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Type of the order: ORDER_TYPE_BUY_LIMIT
LS      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Order execution type: ORDER_FILLING_RETURN
MN      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Order expiration type: ORDER_TIME_GTC
IK      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Volume in lots: 0.14
NS      0       18:13:33.195    TradeProcessor (EURUSD,H1)      
CD      0       18:13:33.195    TradeProcessor (EURUSD,H1)      ---===Response===---
RQ      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Code of the operation result: 10009
JI      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Ticket of the deal: 0
GM      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Ticket of the order: 22535983
LF      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Volume of the deal: 0.14
JN      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Price of the deal: 0.0000
MK      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Bid: 0.0000
CM      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Ask: 0.0000
IG      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Comment to the operation: 
DQ      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Request ID: 1
-->

핸들러의 두 번째 호출은 오픈 오더 리스트에 해당 주문을 추가시킵니다(그림 9).

그림 9. TRADE_TRANSACTION_ORDER_ADDED 필드 타입

그림 9. TRADE_TRANSACTION_ORDER_ADDED 필드 타입

해당 로그에서는 '트랜잭션' 블록만 확인하면 되는데요.

HJ      0       18:17:02.886    TradeProcessor (EURUSD,H1)      ---===Transaction===---
GQ      0       18:17:02.886    TradeProcessor (EURUSD,H1)      Ticket of the deal: 0
CH      0       18:17:02.886    TradeProcessor (EURUSD,H1)      Type of the deal: DEAL_TYPE_BUY
RL      0       18:17:02.886    TradeProcessor (EURUSD,H1)      Ticket of the order: 22535983
II      0       18:17:02.886    TradeProcessor (EURUSD,H1)      Status of the order: ORDER_STATE_STARTED
OG      0       18:17:02.886    TradeProcessor (EURUSD,H1)      Type of the order: ORDER_TYPE_BUY_LIMIT
GL      0       18:17:02.886    TradeProcessor (EURUSD,H1)      Price: 1.6500
IE      0       18:17:02.886    TradeProcessor (EURUSD,H1)      Level of Stop Loss: 0.0000
CO      0       18:17:02.886    TradeProcessor (EURUSD,H1)      Level of Take Profit: 0.0000
IF      0       18:17:02.886    TradeProcessor (EURUSD,H1)      Price that triggers the Stop Limit order: 0.0000
PL      0       18:17:02.886    TradeProcessor (EURUSD,H1)      Trade symbol: GBPUSD
OL      0       18:17:02.886    TradeProcessor (EURUSD,H1)      Pending order expiration time: 1970.01.01 00:00
HJ      0       18:17:02.886    TradeProcessor (EURUSD,H1)      Order expiration type: ORDER_TIME_GTC
LF      0       18:17:02.886    TradeProcessor (EURUSD,H1)      Type of the trade transaction: TRADE_TRANSACTION_ORDER_ADD
FR      0       18:17:02.886    TradeProcessor (EURUSD,H1)      Volume in lots: 0.14
-->

핸들러의 세 번째 호출은 실행된 주문에 맞게 데이터를 업데이트합니다(그림 10).

주문 상태는 ORDER_STATE_PLACED 값을 수신하죠.

그림 10. TRADE_TRANSACTION_ORDER_UPDATE 필드 타입

그림 10. TRADE_TRANSACTION_ORDER_UPDATE 필드 타입

해당 로그에서도 '트랜잭션' 블록만 확인하면 됩니다.

HS      0       18:21:27.004    TradeProcessor (EURUSD,H1)      ---===Transaction==---
GF      0       18:21:27.004    TradeProcessor (EURUSD,H1)      Ticket of the deal: 0
CO      0       18:21:27.004    TradeProcessor (EURUSD,H1)      Type of the deal: DEAL_TYPE_BUY
RE      0       18:21:27.004    TradeProcessor (EURUSD,H1)      Ticket of the order: 22535983
KM      0       18:21:27.004    TradeProcessor (EURUSD,H1)      Status of the order: ORDER_STATE_PLACED
QH      0       18:21:27.004    TradeProcessor (EURUSD,H1)      Type of the order: ORDER_TYPE_BUY_LIMIT
EG      0       18:21:27.004    TradeProcessor (EURUSD,H1)      Price: 1.6500
GL      0       18:21:27.004    TradeProcessor (EURUSD,H1)      Level of Stop Loss: 0.0000
ED      0       18:21:27.004    TradeProcessor (EURUSD,H1)      Level of Take Profit: 0.0000
GO      0       18:21:27.004    TradeProcessor (EURUSD,H1)      Price that triggers the Stop Limit order: 0.0000
RE      0       18:21:27.004    TradeProcessor (EURUSD,H1)      Trade symbol: GBPUSD
QS      0       18:21:27.004    TradeProcessor (EURUSD,H1)      Pending order expiration time: 1970.01.01 00:00
JS      0       18:21:27.004    TradeProcessor (EURUSD,H1)      Order expiration type: ORDER_TIME_GTC
RD      0       18:21:27.004    TradeProcessor (EURUSD,H1)      Type of the trade transaction: TRADE_TRANSACTION_ORDER_UPDATE
JK      0       18:21:27.004    TradeProcessor (EURUSD,H1)      Volume in lots: 0.14
-->

여기서는 주문의 상태를 나타내는 문자열이 가장 중요한데요.

포지션 프로세싱과는 달리 대기 주문 프로세싱은 구조로 나타내기 힘듭니다. 대기 주문과 연결된 각 거래 오퍼레이션이 거래 트랜잭션 형식에 따라 다르게 나타나기 때문이죠.

대기 주문을 넣는 데에는 세 번의 트랜잭션이 필요합니다(그림 11).

그림 11. 대기 주문 프로세싱 트랜잭션

그림 11. 대기 주문 프로세싱 트랜잭션

대기 주문 수정은 두 개의 트랜잭션을 발생시키죠(그림 12).

그림 12. 대기 주문 수정 프로세싱 트랜잭션

그림 12. 대기 주문 수정 프로세싱 트랜잭션


대기 주문이 삭제될 경우, OnTradeTransaction() 핸들러는 네 번 호출됩니다(그림 13).

그림 13. 대기 주문 삭제 프로세싱 트랜잭션

그림 13. 대기 주문 삭제 프로세싱 트랜잭션

대기 주문 삭제는 다음의 구조로 나타낼 수 있습니다(그림 14).

그림 14. 대기 주문 삭제 프로세싱 트랜잭션

그림 14. 대기 주문 삭제 프로세싱 트랜잭션


대기 주문을 트리거하는 최근 거래 오퍼레이션은 네 가지의 트랜잭션을 발생시킵니다(그림 15).

그림 15. 대기 주문 실행 프로세싱 트랜잭션

그림 15. 대기 주문 실행 프로세싱 트랜잭션

모든 트랜잭션 조합에 대한 로그를 살펴보지는 않겠습니다. 필요한 경우 코드를 실행해서 확인해 보세요.


4. 범용 핸들러

최종 사용자의 입장에서 TradeTransaction 이벤트 프로그램을 확인해 봅시다. 최종 사용자는 아마 주문 및 포지션 모두에 완벽하게 적용되는 프로그램을 원할 겁니다. 따라서 개발자는 OnTradeTransaction() 코드가 전체 트랜잭션 및 그 조합을 식별할 수 있도록 만들어야 하죠. 그리고 트랜잭션 프로세싱 완료 후에는 어떤 오퍼레이션이 실행되었는지도 나타낼 수 있어야 합니다.

아래는 시퀀셜 프로세싱이 적용된 예제입니다. 개발자에 따르면 다음의 사항을 주의해야 한다네요.

터미널에서 수동으로 전송된 거래 요청 또는 OrderSend()/OrderSendAsync() 함수로 전송된 거래 요청은 거래 서버측에 여러 개의 연속적인 트랜잭션을 발생시킬 수 있습니다. 해당 트랜잭션의 터미널에 대한 우선 순위가 보장되지 않으므로 거래 알고리즘이 특정 트랜잭션 그룹이 순서대로 도착할 것이라는 예측을 기반으로 해서는 안됩니다. 또한, 서버에서 터미널로 전송되는 과정에서 트랜잭션이 사라질 수도 있습니다.

따라서 보다 이상적인 프로그램을 만드려면 위의 예제를 수정해 트랜잭션 프로세싱과 트랜잭션 수신 속도가 서로 독립적이게 만들면 됩니다.

일반적인 경우 포지션과 주문은 동일한 트랜잭션 유형을 갖습니다. 트랜잭션 유형은 총 11가지가 있는데요. 그 중 네 가지만이 터미널 거래에 적용됩니다.

  • TRADE_TRANSACTION_DEAL_UPDATE
  • TRADE_TRANSACTION_DEAL_DELETE
  • TRADE_TRANSACTION_HISTORY_UPDATE
  • TRADE_TRANSACTION_HISTORY_DELETE

본문에서는 위의 유형에 대해서는 따로 다루지 않겠습니다. 위의 트랜잭션 유형은 서버측의 기능을 개선하기 위해 고안되었습니다. 사실 저도 처음 보는 유형입니다.

위의 네 가지를 제외하면 OnTradeTransaction()에서 프로세싱되는 트랜잭션 유형 7개가 남습니다.

핸들러 내에서는 현재 트랜잭션 형식을 정의하는 세그먼트가 아주 중요합니다.

//--- ========== Types of transaction [START]
   switch(trans_type)
     {
      //--- 1) if it is a request
      case TRADE_TRANSACTION_REQUEST:
        {

         //---
         break;
        }
      //--- 2) if it is an addition of a new open order
      case TRADE_TRANSACTION_ORDER_ADD:
        {

         //---
         break;
        }
      //--- 3) if it is a deletion of an order from the list of open ones
      case TRADE_TRANSACTION_ORDER_DELETE:
        {

         //---     
         break;
        }
      //--- 4) if it is an addition of a new order to the history
      case TRADE_TRANSACTION_HISTORY_ADD:
        {

         //---     
         break;
        }
      //--- 5) if it is an addition of a deal to history
      case TRADE_TRANSACTION_DEAL_ADD:
        {

         //---
         break;
        }
      //--- 6) if it is a modification of a position 
      case TRADE_TRANSACTION_POSITION:
        {

         //---
         break;
        }
      //--- 7) if it is a modification of an open order
      case TRADE_TRANSACTION_ORDER_UPDATE:
        {

         //---
         break;
        }
     }
//--- ========== Types of transactions [END]
-->

현재 트랜잭션 유형을 이용해 프로세스되는 거래 오퍼레이션을 정의해 보겠습니다. 포지션과 주문 중 무엇이 대상인지 알기 위해 거래 오퍼레이션 타입 저장을 요청 프로세싱 케이스 모듈이 대리하도록 합니다.

모듈은 다음과 같이 나타날 겁니다.

//--- 1) if it is a request
      case TRADE_TRANSACTION_REQUEST:
        {
         //---
         last_action=request.action;
         string action_str;

         //--- what is the request for?
         switch(last_action)
           {
            //--- а) on market
            case TRADE_ACTION_DEAL:
              {
               action_str="place a market order";
               trade_obj=TRADE_OBJ_POSITION;
               break;
              }
            //--- б) place a pending order
            case TRADE_ACTION_PENDING:
              {
               action_str="place a pending order";
               trade_obj=TRADE_OBJ_ORDER;
               break;
              }
            //--- в) modify position
            case TRADE_ACTION_SLTP:
              {
               trade_obj=TRADE_OBJ_POSITION;
               //---
               StringConcatenate(action_str,request.symbol,": modify the levels of Stop Loss",
                                 " and Take Profit");

               //---
               break;
              }
            //--- г) modify order
            case TRADE_ACTION_MODIFY:
              {
               action_str="modify parameters of the pending order";
               trade_obj=TRADE_OBJ_ORDER;
               break;
              }
            //--- д) delete order
            case TRADE_ACTION_REMOVE:
              {
               action_str="delete pending order";
               trade_obj=TRADE_OBJ_ORDER;
               break;
              }
           }
         //---
         if(InpIsLogging)
            Print("Request received: "+action_str);

         //---
         break;
        }
-->

이 경우 변수 몇 가지를 쉽게 수정할 수 있는데요.

static ENUM_TRADE_REQUEST_ACTIONS last_action; // market operation at the first pass
-->

last_action 변수에 이벤트 핸들러 실행 이유가 저장됩니다.

static ENUM_TRADE_OBJ trade_obj;               // specifies the trade object at the first pass
-->

trade_obj는 프로세싱 대상이 포지션인지 주문인지 구분하죠. 이를 위해 ENUM_TRADE_OBJ 열거형을 생성합니다.

그리고 나서 TRADE_TRANSACTION_ORDER_ADD 형식의 트랜잭션을 프로세싱할 모듈로 이동합니다.

//--- 2) if it is an addition of a new open order
      case TRADE_TRANSACTION_ORDER_ADD:
        {
         if(InpIsLogging)
           {
            if(trade_obj==TRADE_OBJ_POSITION)
               Print("Open a new market order: "+
                     EnumToString(trans.order_type));
            //---
            else if(trade_obj==TRADE_OBJ_ORDER)
               Print("Place a new pending order: "+
                     EnumToString(trans.order_type));
           }
         //---
         break;
        }
-->

꽤 간단한 모듈이죠. 포지션이 프로세스 되었기 때문에 현재 로그에 '새로운 시장 주문 오픈'이 나타날 겁니다. 아니면 '새로운 대기 주문 설정'이 나타나죠. 해당 블록에는 정보 외에 새로운 액션은 나타나지 않습니다.

이제 TRADE_TRANSACTION_ORDER_DELETE 형식을 담당하는 세 번째 모듈을 살펴보죠.

//--- 3) if it is a deletion of an order from the list of open ones
      case TRADE_TRANSACTION_ORDER_DELETE:
        {
         if(InpIsLogging)
            PrintFormat("Order deleted from the list of open ones: #%d, "+
                        EnumToString(trans.order_type),trans.order);
         //---     
         break;
        }
-->

해당 모듈도 정보를 전달하는 역할만을 담당합니다.

네 번째 케이스 모듈은 TRADE_TRANSACTION_HISTORY_ADD 형식을 프로세싱합니다.

//--- 4) if it is an addition of a new order to the history
      case TRADE_TRANSACTION_HISTORY_ADD:
        {
         if(InpIsLogging)
            PrintFormat("Order added to the history: #%d, "+
                        EnumToString(trans.order_type),trans.order);

         //--- if a pending order is being processed
         if(trade_obj==TRADE_OBJ_ORDER)
           {
            //--- if it is the third pass
            if(gTransCnt==2)
              {
               //--- if the order was canceled, check the deals
               datetime now=TimeCurrent();

               //--- request the history of orders and deals
               HistorySelect(now-PeriodSeconds(PERIOD_H1),now);

               //--- attempt to find a deal for the order
               CDealInfo myDealInfo;
               int all_deals=HistoryDealsTotal();
               //---
               bool is_found=false;
               for(int deal_idx=all_deals;deal_idx>=0;deal_idx--)
                  if(myDealInfo.SelectByIndex(deal_idx))
                     if(myDealInfo.Order()==trans.order)
                        is_found=true;

               //--- if the deal was not found
               if(!is_found)
                 {
                  is_to_reset_cnt=true;
                  //---
                  PrintFormat("Order canceled: #%d",trans.order);
                 }
              }
            //--- if it is the fourth pass
            if(gTransCnt==3)
              {
               is_to_reset_cnt=true;
               PrintFormat("Order deleted: #%d",trans.order);
              }
           }
         //---     
         break;
        }
-->

거래의 기록 저장 외에도 해당 모듈은 대기 주문에 대한 프로세싱 여부를 확인합니다. 우리 예제의 경우 현재 호출된 핸들러에 해당하는 숫자를 알아야 합니다. 대기 주문이 취소된 경우, 이같은 형식의 트랜잭션은 세 번째 호출에서 나타납니다. 대기 주문이 삭제된 경우 네 번째 호출에서 나타날 수 있죠.

세 번째 호출을 확인하는 문자열을 통해 거래 기록을 다시 한번 참조합니다. 현재 주문에 대한 거래가 없는 경우, 해당 주문이 취소된 것으로 간주합니다.

다섯 번째 케이스 모듈은 TRADE_TRANSACTION_DEAL_ADD 형식을 프로세싱합니다. 문자열 크기 기준 프로그램 내 가장 큰 블록이죠.

해당 블록에서는 거래 성사 여부가 확인됩니다. 티켓을 이용하여 거래 프로퍼티에 액세스할 수 있습니다. 거래 타입은 포지션이 오픈되었는지, 청산되었는지 등에 대한 정보를 제공합니다. 대기 주문 트리거에 대한 정보 또한 찾을 수 있습니다. 유일하게 대기 주문이 TradeTransaction이벤트 핸들러와 관련된 거래를 발생시킬 수 있는 경우죠.

//--- 5) if it is an addition of a deal to history
      case TRADE_TRANSACTION_DEAL_ADD:
        {
         is_to_reset_cnt=true;
         //---
         ulong deal_ticket=trans.deal;
         ENUM_DEAL_TYPE deal_type=trans.deal_type;
         //---
         if(InpIsLogging)
            PrintFormat("Deal added to history: #%d, "+EnumToString(deal_type),deal_ticket);

         if(deal_ticket>0)
           {
            datetime now=TimeCurrent();

            //--- request the history of orders and deals
            HistorySelect(now-PeriodSeconds(PERIOD_H1),now);

            //--- select a deal by the ticket
            if(HistoryDealSelect(deal_ticket))
              {
               //--- check the deal
               CDealInfo myDealInfo;
               myDealInfo.Ticket(deal_ticket);
               long order=myDealInfo.Order();

               //--- parameters of the deal
               ENUM_DEAL_ENTRY  deal_entry=myDealInfo.Entry();
               double deal_vol=0.;
               //---
               if(myDealInfo.InfoDouble(DEAL_VOLUME,deal_vol))
                  if(myDealInfo.InfoString(DEAL_SYMBOL,deal_symbol))
                    {
                     //--- position
                     CPositionInfo myPos;
                     double pos_vol=WRONG_VALUE;
                     //---
                     if(myPos.Select(deal_symbol))
                        pos_vol=myPos.Volume();

                     //--- if the market was entered
                     if(deal_entry==DEAL_ENTRY_IN)
                       {
                        //--- 1) opening of a position
                        if(deal_vol==pos_vol)
                           PrintFormat("\n%s: new position opened",deal_symbol);

                        //--- 2) addition to the open position        
                        else if(deal_vol<pos_vol)
                           PrintFormat("\n%s: addition to the current position",deal_symbol);
                       }

                     //--- if the market was exited
                     else if(deal_entry==DEAL_ENTRY_OUT)
                       {
                        if(deal_vol>0.0)
                          {
                           //--- 1) closure of a position
                           if(pos_vol==WRONG_VALUE)
                              PrintFormat("\n%s: position closed",deal_symbol);

                           //--- 2) partial closure of the open position        
                           else if(pos_vol>0.0)
                              PrintFormat("\n%s: partial closing of the current position",deal_symbol);
                          }
                       }

                     //--- if position was reversed
                     else if(deal_entry==DEAL_ENTRY_INOUT)
                       {
                        if(deal_vol>0.0)
                           if(pos_vol>0.0)
                              PrintFormat("\n%s: position reversal",deal_symbol);
                       }
                    }

               //--- order activation
               if(trade_obj==TRADE_OBJ_ORDER)
                  PrintFormat("Pending order activation: %d",order);
              }
           }

         //---
         break;
        }
-->

TRADE_TRANSACTION_POSITION 형식의 트랜잭션은 아주 독특한데요. 포지션이 수정되는 경우에만 프로세싱됩니다.

//--- 6) if it is a modification of a position
      case TRADE_TRANSACTION_POSITION:
        {
         is_to_reset_cnt=true;
         //---
         PrintFormat("Modification of a position: %s",deal_symbol);
         //---
         if(InpIsLogging)
           {
            PrintFormat("New price of stop loss: %0."+
                        IntegerToString(_Digits)+"f",trans.price_sl);
            PrintFormat("New price of take profit: %0."+
                        IntegerToString(_Digits)+"f",trans.price_tp);
           }

         //---
         break;
        }
-->

마지막 케이스 모듈은 TRADE_TRANSACTION_ORDER_UPDATE 형식 프로세싱을 통해 활성화됩니다.

대기 주문에 대한 작업이 실행되는 경우에만 나타나죠. 대기 주문과 관련된 모든 거래 오퍼레이션 실행 시 실행됩니다.

//--- 7) if it is a modification of an open order
      case TRADE_TRANSACTION_ORDER_UPDATE:
        {

         //--- if it was the first pass
         if(gTransCnt==0)
           {
            trade_obj=TRADE_OBJ_ORDER;
            PrintFormat("Canceling the order: #%d",trans.order);
           }
         //--- if it was the second pass
         if(gTransCnt==1)
           {
            //--- if it is an order modification
            if(last_action==TRADE_ACTION_MODIFY)
              {
               PrintFormat("Pending order modified: #%d",trans.order);
               //--- clear counter
               is_to_reset_cnt=true;
              }
            //--- if it is deletion of the order
            if(last_action==TRADE_ACTION_REMOVE)
              {
               PrintFormat("Delete pending order: #%d",trans.order);

              }
           }
         //--- if it was the third pass
         if(gTransCnt==2)
           {
            PrintFormat("A new pending order was placed: #%d, "+
                        EnumToString(trans.order_type),trans.order);
            //--- clear counter
            is_to_reset_cnt=true;
           }

         //---
         break;
        }
-->

한번 정리해 보죠. 해당 타입이 OnTradeTransaction()의 첫 번째 호출 시 나타났다면, 주문이 취소되었거나 실행된 겁니다.

두 번째 호출 시 나타났다면, 주문은 취소되었거나 수정된 거죠. 정확한 주문 결과를 확인하려면 정적 변수인 last_action을 참조해 직전 거래 오퍼레이션에 대한 정보를 얻습니다.

이벤트 핸들러의 세 번째 호출 시 이런 형식이 나타날 수 있죠. 세 번째 호출이 대기 주문 설정 프로시저를 완성하게 됩니다.

불리언 변수 is_to_reset_cnt 또한 해당 코드에서 이용됩니다. OnTradeTransaction() 핸들러 호출 카운터 삭제 플래그 역할을 하죠.

TradeTransaction 이벤트 프로세싱에 대해 알아 보았습니다. 핸들로 호출 초기에 시간을 조금 주는 게 좋을 것 같습니다. 거래 또는 주문 기록이 딜레이되지 않도록 말입니다.


결론

여러가지 거래 오퍼레이션을 다루는 법과 터미널에서 일어나는 이벤트에 관한 정보를 얻는 방법을 알아봤습니다.

이벤트 기반 프로그래밍의 최대 장점은 프로그램이 거래 오퍼레이션에 대한 단계적인 구현 정보를 수신할 수 있다는 거죠. 제 생각에 이 방법은 터미널 간 거래 카피에 이용할 수 있을 것 같아요.


MetaQuotes 소프트웨어 사를 통해 러시아어가 번역됨.
원본 기고글: https://www.mql5.com/ru/articles/1111

파일 첨부됨 |
tradeprocessor.mq5 (31.35 KB)
MQL5 쿡북: 커스텀 차트 이벤트 핸들링 MQL5 쿡북: 커스텀 차트 이벤트 핸들링
본문은 MQL5 환경에서의 커스텀 차트 이벤트 시스템 디자인 및 개발을 다루고 있습니다. 이벤트 분류 예제 및 이벤트 클래스 코드와 커스텀 이벤트 핸들러 클래스 코드가 포함되어 있습니다.
3세대 신경망: 심층 신경망 3세대 신경망: 심층 신경망
본문은 머신러닝의 새로운 관점에 대해 다룹니다. 딥러닝, 정확히 말하면 심층 신경망에 대한 글이죠. 2세대 신경망도 간략하게 살펴볼 겁니다. 연결 구조, 종류, 학습 메소드 및 규칙, 단점을 다룬 후 3세대 신경망 개발의 역사, 종류, 특성 및 학습 메소드에 대해 알아보겠습니다. 실제 데이터를 이용한 적층 오토인코더를 이용한 심층 신경망 구축 및 학습 실험도 할 겁니다. 인풋 데이터 선택부터 편차 메트릭까지 자세히 다룰 겁니다. 본문의 마지막 부분에서는 MQL4/R 기반 인디케이터가 탑재된 EA를 이용해 심층 신경망을 구현해 보도록 하겠습니다.
랜덤 포레스트로 추세 예측하기 랜덤 포레스트로 추세 예측하기
본문은 Rattle 패키지를 이용한 외환 시장 내 롱 또는 숏 포지션 예측 패턴 자동 검색에 대해 다룹니다. 모든 투자자에게 도움이 될만 한 글입니다.
MetaTrader 시그널 서비스 및 소셜트레이딩 이야기 MetaTrader 시그널 서비스 및 소셜트레이딩 이야기
시그널 서비스 개선을 위해 항상 노력하고 있습니다. 메커니즘을 업그레이드하고, 새로운 기능을 추가하고, 문제를 수정하죠. 2012년의 MetaTrader 시그널 서비스와 현재의 MetaTrader 시그널 서비스는 완전히 다른 서비스나 마찬가지입니다. 현재는 MetaTrader 클라이언트 터미널 버전에 따라 서버가 제공되는 가상 클라우드 호스팅 서비스를 제공하고 있습니다.