포지션 중심적 MetaTrader5 환경에서 주문 추적을 위해 가상 주문 매니저 활용하기

Paul | 5 7월, 2021


1. 들어가며

MetaTrader 4에서 MetaTrader 5 오면서 가장 크게 변한 것 중 하나는 오픈 트레이드를 포지션으로 관리한다는 점입니다. 언제든지 각 심볼마다 하나의 포지션을 열 수 있으며 브로커가 주문을 처리할 때마다 이 포지션의 크기가 위아래로 조정됩니다. 이는 미국에 도입된 NFA 2-43(b) FIFO 규칙을 준수하며, 선물, 상품 및 CFD와 같은 다른 많은 기업에서의 트레이딩 규제에도 부합합니다..

두 개의 EA가 같은 심볼 하나에 대해 각기 반대 방향으로 주문을 넣는 경우가 차이의 대표적 예시입니다.   이는 두 개의 EA가 스캘퍼나 추세 추종자와 같이 다른 타임프레임을 기준으로 작업하는 두개의 EA가 있는 경우 꽤나 흔한 상황일 수 있습니다.  MetaTrader 4에서는, 공개 거래 목록에는 마진이 0인 매수 혹은 매도 공개 주문이 표시됩니다. MetaTrader 5에서는 포지션을 아예 개방하지 않습니다.

EA 코드 자체를 들여다보세요, 아래에 보이듯 자주 쓰이던 MQL4 OpenOrders()나 비슷한 유형의 함수는 MQL5로 이식되면 제대로 작동하지 않을 것입니다.

int OpenOrders()  // MetaTrader 4 code to count total open orders for this EA
{
  int nOpenOrders=0;
  for (int i=OrdersTotal()-1; i>=0; i--)
  {
    OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
    if (OrderMagicNumber()==magic)
      if (OrderType()==OP_BUY || OrderType()==OP_SELL)
        if (OrderSymbol()==Symbol())
          nOpenOrders++;
  }
  return(nOpenOrders);
}

따라서 MetaTrader 5 포지션 중심 환경은 MetaTrader 4에서 사용되는 주문 처리 접근 방식에 익숙한 프로그래머에게 낯선 과제를 안겨줍니다. MetaTrader 4의 단순한 주문 관리 기능은 여러 개의 주문이 하나의 심볼로 거래되거나 하나의 EA로부터 여러 개의 주문이 하나의 심볼로 병합될 수 있을 때 MetaTrader 5에서 더욱 복잡해집니다.


2. MetaTrader 5에서 포지션을 다루는 방법  

MetaTrader 5의 포지션 중심 환경을 다루는 방법엔 매매 전략의 복잡성에 따라 여러가지가 있습니다.

첫째, MetaTrader 5의 보류 주문 처리는 MetaTrader 4와 유사하므로 보류 중인 주문에 대해서만 작성된 MQL5 코드는 MQL4 코드로부터 비교적 간단한 마이그레이션이 될 수 있습니다.

2.1 알기쉬운 EA; 계정 1개당 1 심볼에 1 EA

가장 단순한 접근 방법은 계정 하나당 심볼 하나에 하나의 EA만 매매할 수 있도록 제한을 두는 것입니다  “알기쉬운 EA”란 이 경우 한번에 하나의 주문만 하는 것을 의미하며 꽤나 흔한 방법이지만 피라미딩이나 그리드 트레이딩 같은 방법을 배제하는 면이 있습니다  알기쉬운 EA들은 MQL5에서도 MQL4에 쓰던 것과 비슷한 느낌으로 쓰일 수 있습니다. include\trade\trade.mqh 에 있는 CTrade 라이브러리 래퍼를 쓰는 것도 방법입니다.

2.2 복잡한 EA; 계정 1개당 1 심볼에 1 EA

하나의 기호에 대해 둘 이상의 오픈 포지션이 필요할 수 있는 피라미딩이 그리드 트레이딩와 같은 전략을 가지고 있는 복잡한 EA의 경우, EA에 추가된 비교적 단순한 주문 추적 코드만이 전략을 관리하는 데 필요한 전부일 수 있습니다.   이것은 해당 EA가 같은 심볼에 작업하는 다른 EA와 포지션을 절대 공유하지 않을 때에만 가능합니다.

2.3 계정 1개당 1 심볼에 다수의 EA

이는 가장 복잡한 거래 및 코딩 요구 사항을 제시하며 가상 주문 매니저(Virtual Order Manager, VOM) 라이브러리를 개발한 이유입니다.  이 라이브러리는 다른 EA와 완전히 친화적인 강력한 EA 코드의 개발을 크게 간소화하기 위한 것입니다.

이 문서의 나머지 파트에서 가상 주문 매니저 라이브러리를 더욱 자세히 알아보겠습니다.


3. 가상 주문 매니저 (Virtual Order Manager)의 장단점과 목표 설정 

VOM에는 4개의 주요 디자인 목표가 있습니다:

  1. 사회성: VOM 매매 함수를 올바르게 사용하여 짜인 EA들은 다른 EA의 행동으로부터 독립적입니다.
  2. 내구성: 에러, 서버-클라이언트 연결 중단, 불완전한 주문 등의 특이 상황을 우아하게 해결하는 능력.
  3. 사용용이성: 잘 정리된 문서와 간단한 매매 함수 제공
  4. 전략 테스터를 쓸 수 있는 능력

목표들은 다음과 같이 구현되었습니다:

VOM식 접근은 MQL5 EA에게 다음의 가능성을 열어줍니다:

또한 VOM 접근 방식의 부작용은 가상 손절매, 이익실현 및 보류 주문이 본질적으로 "스텔스" 동작(즉, 브로커 서버에서 볼 수 없음)을 보인다는 점에 유의해야 합니다.   일부는 브로커들이 역지정가 사냥에 참여하는 것을 방지하기 위해 손절매 레벨을 숨겨야한다고 생각합니다..

VOM에도 마찬가지로 약점이 있습니다.  PC 관련 또는 인터넷 연결 장애가 발생했을 때 보호 서버 정지에 의존할 가능성이 있기 때문에 자본 리스크가 증가한다는 점.   또한 뉴스 이벤트와 같이 변동성이 큰 시기에는 가상 미결 주문, 손절 또는 이익 실현이 서버 기반에 해당하는 경우에 비해 훨씬 더 높을 수 있습니다.  VOM EA가 짧은 시간 내에 높은 안정성의 가상 데스크톱에서 브로커 서버로 전환될 경우 이러한 단점의 영향을 최소화할 수 있습니다.


4. 실전 VOM 활용 - 단순 EA

더 깊게 들어가기 전에 어떻게 VOM EA를 짜야하는가 보여줄 시간입니다.  지금부터 우리는 배포 패키지에 들어있는 EA 템플릿을 가지고 MA 크로스 EA를 짤 것입니다.  우리는 MA 간 전략에서 악명 높은 문제인 사이드웨이 시장에서의 무의미한 거래를 줄일 수 있는 프랙탈 이동평균을 사용할 것이다. 이 EA는 단순한 예로 제공되는 것이며 실시간 트레이딩에 권장되지 않는다는 점을 강조하고싶습니다. 백테스트는 수익성이 높지만 거래 횟수가 낮다는 것은 결과가 통계적으로 유의하지 않음을 의미합니다.

이 EA는 experts\Virtual Order Manager\VOM EAs 에서 찾을 수 있습니다.

//+------------------------------------------------------------------+
//|                                           FraMA Cross EA VOM.mq5 |
//+------------------------------------------------------------------+
#property copyright "Paul Hampton-Smith"
#property link      "http://paulsfxrandomwalk.blogspot.com"
#property version   "1.00"

// this is the only include required.  It points to the parent folder
#include "..\VirtualOrderManager.mqh"

input double   Lots=0.1;
input int      Fast_MA_Period=2;
input int      Slow_MA_Period=58;
/* 
Because the broker is 3/5 digit, stoplosses and takeprofits should be x10.  
It seems likely that all brokers offering MetaTrader 5 will be 3/5 digit brokers, 
but if this turns out to be incorrect it will not be a major task to add 
digit size detection. */
input int      Stop_Loss=5000;
input int      Take_Profit=0;
/*
We can also change the level of logging.  LOG_VERBOSE is the most prolific 
log level.  Once an EA has been fully debugged the level can be reduced to 
LOG_MAJOR.  Log files are written under the files\EAlogs folder and are 
automatically deleted after 30 days.  */
input ENUM_LOG_LEVEL Log_Level=LOG_VERBOSE;

// The following global variables will store the handles and values for the MAs 
double g_FastFrAMA[];
double g_SlowFrAMA[];
int g_hFastFrAMA;
int g_hSlowFrAMA;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   LogFile.LogLevel(Log_Level);

// Need to include this line in all EAs using CVirtualOrderManager  
   VOM.Initialise();
   Comment(VOM.m_OpenOrders.SummaryList());

   g_hFastFrAMA = iFrAMA(_Symbol,_Period,Fast_MA_Period,0,PRICE_CLOSE);
   g_hSlowFrAMA = iFrAMA(_Symbol,_Period,Slow_MA_Period,0,PRICE_CLOSE);
   ArraySetAsSeries(g_FastFrAMA,true);
   ArraySetAsSeries(g_SlowFrAMA,true);

   return(0);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
// Need to include this line in all EAs using CVirtualOrderManager  
   VOM.OnTick();
   Comment(VOM.m_OpenOrders.SummaryList());

// We now obtain copies of the most recent two FrAMA values in the 
// g_FastFrAMA and  g_SlowFrAMA arrays.  
   if(CopyBuffer(g_hFastFrAMA,0,Shift,2,g_FastFrAMA)!=2) || 
      CopyBuffer(g_hSlowFrAMA,0,Shift,2,g_SlowFrAMA)!=2)
     {
      Print("Not enough history loaded");
      return;
     }

// And now we detect a cross of the fast FrAMA over the slow FrAMA,
// close any opposite orders and Buy a single new one
   if(g_FastFrAMA[0]>g_SlowFrAMA[0] && g_FastFrAMA[1]<=g_SlowFrAMA[1])
     {
      VOM.CloseAllOrders(_Symbol,VIRTUAL_ORDER_TYPE_SELL);
      if(VOM.OpenedOrdersInSameBar()<1 && VOM.OpenOrders()==0)
        {
         VOM.Buy(_Symbol,Lots,Stop_Loss,Take_Profit);
        }
     }

// Opposite for Sell
   if(g_FastFrAMA[0]<g_SlowFrAMA[0] && g_FastFrAMA[1]>=g_SlowFrAMA[1])
     {
      VOM.CloseAllOrders(_Symbol,VIRTUAL_ORDER_TYPE_BUY);
      if(VOM.OpenedOrdersInSameBar()<1 && VOM.OpenOrders()==0)
        {
         VOM.Sell(_Symbol,Lots,Stop_Loss,Take_Profit);
        }
     }
  }
//+------------------------------------------------------------------+

그리고 Strategy Tester이 릴리즈 되었으니 백테스트 역시 가능합니다, 아래의 1번 그림을 참조해주십시오:

 1번 그림. FrAMA Cross EA 백테스트

1번 그림. FrAMA Cross EA 백테스트

로그 섹션은 2번 그림에 나와있습니다:

 2번 그림. 전략 테스트 로그

2번 그림. 전략 테스트 로그

 

5. VOM 구조

4번 그림은 여러 VOM EA가 어떻게 설정되어있는지 보여줍니다:

3번 그림. 복수의 VOM EA들

3번 그림. 복수의 VOM EA들

그리고 VOM 내부를 보면 주요 구성 요소들은 아래의 4번 그림처럼 되어있습니다:

4번 그림. VOM 내부 스트럭쳐

4번 그림. VOM 내부 스트럭쳐

 4번 그림의 요소 설명:

VOM을 쓰는 Expert Advisor들은 아래의 5번 그림에서처럼 라이브러리를 이용합니다:

 5번 그림. VOM 라이브러리와 EA 상호작용

 5번 그림. VOM 라이브러리와 EA 상호작용


6. 재앙 방호 손절에 대하여

MetaTrader 4 EA에서 가상 역지정은 꽤나 흔했습니다.  클라이언트 측에서만 손절이 유지되는 경우, 매매의 출구 레벨을 브로커는 볼 수 없었으며, 이는 종종 일부 브로커가 역지정가 사냥에 참여한다는 믿음에서 구현된 전략입니다.  가상 중지 자체로는 중지 조치를 취하기 위해 브로커와 클라이언트 간의 연결이 항상 유지되어야 하므로 거래 위험이 크게 증가합니다.

VOM은 서버 기반 역지정가를 가장 엄밀한 가상 역지정가에서 설정가능한 일정 거리를 두고 유지함으로서 해당 리스크를 관리합니다.  이것은 재앙 방호 손절 (Disaster protection stoploss, DPSL)라고 불리는데 이는 일반적으로 인터넷 연결이 끊기거나 PC 장애가 발생할 때처럼 잠시 동안만 브로커와 클라이언트 연결이 끊기는 경우에만 작업이 수행되기 때문입니다.   가상 주문이 개폐되고 서버의 포지션으로 변환되므로 다음 순서에 따라 DPSL을 올바른 수준으로 유지 관리하는 것이 다소 복잡할 수 있습니다. .

가상 주문
행동
개방
가격
가성 SL 포지션
서버 내
손절
서버 내
코멘트
0.1 랏 매수 #1 2.00000 1.99000 0.1 랏 매수 1.98500 DPSL은 가상 SL #1 에서 50 pips 밑
0.1 랏 매수 #2 2.00000 1.99500 0.2 랏 매수 1.99000 가상 주문 #2이 더 엄밀한 SL을 가지므로 DPSL
은 가상 SL #2 보다 50 pips 밑까지 엄밀해집니다.
#2 청산     0.1 랏 매수 1.98500 덜 엄밀한 DPSL로 복귀
0.1 랏 매도 #3 2.00000 2.00500 none none 가상주문 #1 #3 각각 취소
서버에서
#1 청산     0.1 랏 매도 2.01000 가상주문 #3은 개방된 채이며 DPSL은
이제 가상 SL #3 보다 50 pips 위

7. 가상 주문 매니저 테스트하기

이 크기의 프로젝트는 철저하게 테스트하는 데 시간이 걸리기 때문에, 차트의 명령 버튼으로 가상 주문을 쉽게 생성, 수정, 삭제 및 닫을 수 있도록 EA VirtualOrderManaerTester.mq5를 작성했습니다.  

아래 6번 그림은 M5 창에서 0.1LOT의 가상 구매 주문과 EURUSD에 대해 H4 창에서 열린 다른 0.1LOT의 가상 구매 주문이며, 서버 상태는 0.2LOT의 한 포지션를 정확하게 보여줍니다. 전체 포지션은 롱이기 때문에 더욱 엄밀해진 20.0 pip stop 아래에서 재앙 방호 손절을 볼 수 있습니다.

6번 그림. EA 2개가 같은 방향을 가리킴

6번 그림. EA 2개가 같은 방향을 가리킴

7번 그림에서 서로 반대방향의 가상 주문을 가진 두개의 EA들을 볼 수 있고, 브로커에는 어떠한 포지션도 열려있지 않은 것을 볼 수 있습니다:

7번 그림. 서로 반대방향의 가상 주문을 가진 두개의 EA들과 아무 포지션도 없는 브로커

7번 그림. 서로 반대방향의 가상 주문을 가진 두개의 EA들과 아무 포지션도 없는 브로커


8. 모든 VOM 개방 주문의 아주 간단한 표시

각 VOM EA는 자기 주문만 볼 수 있으므로, 모든 VOM의 개방 주문을 수집하는 매우 간단한 EA를 작성했습니다. 표시하는 법은 매우 간단하며, 시간이 허락하면 명령 버튼을 사용하여 각 주문에 필요한 수정, 삭제 또는 닫기 작업을 수행할 수 있습니다. 그 EA는VOM_OrderDisplay.mq5 배포 팩에 들어있습니다.


9. 마치며

이 문서를 쓰는 시점에서, VOM 코드는 MetaTrader 5와 마찬가지로 베타 버전이며, VOM 개념이 대중화되었는지 아니면 그냥 MQL5 프로그래밍의 특이성으로 남을지는 나중이 되어봐야 알 것 같습니다.

섹션 3의 디자인 목표로 돌아가 우리가 어떻게 했는지 한 번 봅시다

  1. 사회성: VOM 매매 함수를 올바르게 사용하여 짜인 EA들은 다른 EA의 행동으로부터 독립적입니다.
    • 결과 - VOM 접근법은 이 목표를 달성했습니다
  2. 내구성: 에러, 서버-클라이언트 연결 중단, 불완전한 주문 등의 특이 상황을 우아하게 해결하는 능력.
    • 결과 - 약간 내구적이긴 하지만 실제 매매 상황이 발생하고 분석되면 더 개선될 여지가 있습니다 
  3. 사용용이성: 잘 정리된 문서와 간단한 매매 함수 제공
    • 결과 - 배포 패키지에서 볼 수 있다시피 .chm 도움말 파일이 포함되었습니다
  4. 전략 테스터를 쓸 수 있는 능력
    • 결과 -최근 공개된 전략 테스터의 초기 테스트에 따르면 VOM 접근 방식은 테스트 속도를 상당히 늦추지만 VOM가 올바르게 백테스트를 수행하는 것으로 나타납니다. 처리량 개선을 위한 일부 작업이 필요할 수 있습니다.  

향후 몇 가지 변경이 바람직할 수 있습니다.

  • 다른 복잡한 소프트웨어 개발과 마찬가지로 코드에 버그가 남아 있을 수 있습니다.
  • MetaTrader 5 베타 빌드가 릴리즈 될 때 마다 호환성을 유지하기 위해 VOM도 변경되어야할 수도 있습니다
  • VomGetLastError() 및 VomErrorDescription() 함수
  • 파일에서 설정을 읽어오는 기능
  • 여러 타입의 트레일링 스탑


10. 배포 팩 안에 들어있는 파일들

VOM 패키지는 다수의 .mqh 파일로 제공되며, 이 파일은 Experts\Virtual Order Manager 폴더에 설치되어야 합니다.

  • ChartObjectsTradeLines.mqh - CEntryPriceLine, CStopLossLine, CTakeProfitLine
  • StringUtilities.mqh - ErrorDescription() 같은 글로벌 enum 기술자
  • Log.mqh - CLog
  • GlobalVirtualStopList.mqh - CGlobalVirtualStopList
  • SimpleChartObject.mqh - CButton, CLabel and CEdit
  • VirtualOrder.mqh - CVirtualOrder
  • GlobalVariable.mqh - CGlobalVariable
  • VirtualOrderArray.mqh - CVirtualOrderArray
  • VirtualOrderManager.mqh - CVirtualOrderManager
  • VirtualOrderManagerConfig.mqh - CConfig
  • VirtualOrderManagerEnums.mqh - VOM용으로 설정된 다양한 enum
  • VOM_manual.mqh - 매뉴얼의 이 페이지
  • VOM_doc.chm***

다섯개의 EA mq5 파일이 Experts\Virtual Order Manager\VOM EAs 에 포함되어있습니다:

  • VOM_template_EA.mq5 - 나만의 EA를 만들기 위해 이걸 복사해서 Experts\Virtual Order Manage\VOM EAs 안에 넣으세요.
  • VirtualOrderManagerTester.mq5
  • Support_Resistance_EA_VOM.mq5
  • FrAMA_Cross_EA_VOM.mq5
  • VOM_OrderDisplay.mq5 

***VOM_doc.chm 파일은 언락해야할 수도 있습니다: