기고글 토론 "MQL5에서의 이벤트 기반 아키텍처: Expert Advisor를 완전한 기능을 갖춘 트레이딩 시스템으로 전환하는 방법"

 

새로운 기고글 MQL5에서의 이벤트 기반 아키텍처: Expert Advisor를 완전한 기능을 갖춘 트레이딩 시스템으로 전환하는 방법 가 게재되었습니다:

이 글은 MQL5의 이벤트 기반 아키텍처에 대해 중점적으로 다룹니다. 구체적으로는 단일 구조의 OnTick 모델에서 분산 처리로 전환하는 과정에 대해 설명합니다. 미리 정의된 이벤트와 사용자 정의 이벤트, 서비스 및 프로그램 간의 메시징은 물론 아키텍처적인 오류에 대해서도 살펴보겠습니다. 예시는 지표와 EA 간의 상호 작용을 어떻게 구성하여 부하를 줄이고 가독성을 향상시키며 유지 관리를 간소화하는지 보여줄 것입니다.

MQL5로 EA를 개발할 때 많은 사람들은 가장 분명한 솔루션으로 시작합니다: 모든 로직을 OnTick 메서드에 넣는다는 것입니다. 이렇게 시작하는 게 확실히 쉽습니다. 하지만 이러한 접근 방식에는 숨겨진 비용이 있습니다. 프로젝트가 커짐에 따라 매매 규칙, 조건 확인, 주문 처리, 데이터 업데이트, 인터페이스, 계산 및 로깅이 모두 하나의 핸들러에 묶입니다. 결과적으로 코드는 더 이상 감당하기 어려운 상태로 비대해 지게 되고 사실상 순전히 운에 의해서만 유지되는 지경에 이르게 됩니다. 한 곳에서 변경이 있으면 시스템의 전혀 다른 부분에 영향을 미치기 시작합니다. 시각화 패널을 수정했더니 갑자기 매매 시나리오가 제대로 작동하지 않게 됩니다. 진입 필터를 변경하면 백그라운드 검사에서 오류가 발생합니다. 그러한 EA는 금세 취약한 단일 구조로 되 버리며 개발자의 자신감보다 빠르게 코드는 복잡해집니다.

MetaTrader 5는 단순히 시세 정보를 제공하는 플랫폼이 아닙니다. 그 이상의 역할을 하며 이벤트에 기반을 두고 있습니다. 터미널은 틱, 타이머 신호, 사용자 작업, 매매 상태 변화 및 시장 심도 이벤트를 지속적으로 수신합니다. 이러한 메시지는 별도로 처리되어야 합니다. 이를 위해 MQL5는 각각 고유한 책임 영역을 가진 여러 핸들러를 제공합니다. OnTick은 시장 업데이트를 담당합니다. OnTimer — 주기적 및 백그라운드 작업을 담당합니다. OnChartEvent — GUI 및 사용자 동작에 대한 반응을 담당합니다. 논리가 목적에 따라 배분되면 코드가 더 이상 복잡해지지 않게 되고 각각의 모듈이 제 역할을 수행하며 이웃 모듈과 간섭하지 않는 잘 구성된 엔지니어링 시스템을 닮아가기 시작합니다.

MQL5 이벤트

이 글에서는 모든 것을 OnTick 안에 두는 모델에서 좀더 성숙한 이벤트 아키텍처로 전환하는 방법을 살펴보겠습니다. 미리 정의된 핸들러와 사용자 지정 이벤트 그리고 차트에 연결되지 않은 서비스들의 역할을 살펴보겠습니다. 또한 실제 작업이 시작되기도 전에 아키텍처를 망가뜨리는 일반적인 오류들에 대해서도 좀 더 자세히 살펴보겠습니다. 핵심은 간단합니다. MQL5를 본래 목적대로 사용하면 트레이딩 로봇 뿐만 아니라 완전한 기능을 갖춘 애플리케이션 시스템까지 구축할 수 있다는 것입니다.


작성자: MetaQuotes

 
버퍼가 없는 지표를 사용하여 어드바이저에서 작업하는 것—아마도 좋은 예시가 될 것입니다.
 
//+------------------------------------------------------------------+
//| 거래 함수                                                   |
//+------------------------------------------------------------------+
void OnTrade()
  {
   Sleep(0);
//---
  }
//+------------------------------------------------------------------+
//| TradeTransaction 함수                                        |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction& trans,
                        const MqlTradeRequest& request,
                        const MqlTradeResult& result)
  {
   Sleep(0);
//---
  }
왜요?
 
            if(!cTrade.PositionClose(cPosition.Ticket()))
              {
               PrintFormat("Error close Sell position: %d", GetLastError());
               return;
              }
아마도 cTrade에는 오류 발생 시를 대비한 처리 코드가 포함되어 있는 것 같습니다.
 
fxsaber #:
버퍼가 없는 지표를 사용하여 어드바이저에서 작업하는 것—아마도 예시로 삼기에 적합할 것입니다.


이 예제에서는 심볼 데이터가 엄격하게 갱신됩니다(MQL_TESTER를 사용하는 것이 좋습니다).

void OnTick()
  {
//---
   if(BuySignal)
     {
      cSymbol.Refresh();
      cSymbol.RefreshRates();


하지만 이벤트와 틱을 통해 계산된 신호의 최신성 여부에 대한 검증이 이루어지지 않습니다. 그리고 이것이 실제 문제입니다.


비동기식 OrderSend를 통해 이 문제를 완화할 수는 있지만, 완전히 해결할 수는 없습니다. 따라서 이러한 예시에서도 ChartEvent 이벤트 내에서 이벤트가 발생한 틱의 데이터를 추가로 전달해야 합니다.

 
정말 좋네요. MQL5 프로그램 의 ‘서비스’ 유형은 너무 과소평가되고 있어요.
 
정말 좋은 예시네요, 감사합니다.