English Русский 中文 Español Deutsch 日本語 Português Français Italiano Türkçe
6 단계로 나만의 거래 로봇을 만드세요!

6 단계로 나만의 거래 로봇을 만드세요!

MetaTrader 5 | 5 7월 2021, 11:27
123 0
MetaQuotes
MetaQuotes

MQL5 마법사에 대해 다시 한 번

저희 주변의 세상은 빠르게 변하고 있으며 저희는 이를 따라 잡으려고 노력하고 있습니다. 이에 따라 저희는 새로운 것을 배울 시간이 없으며 이는 인간의 정상적인 태도입니다. 트레이더는 다른 사람들과 마찬가지로 최소한의 노력으로 최대의 결과를 얻고자 합니다. 특히 트레이더를 위해 MetaEditor 5는 멋진 MQL5 마법사를 제공합니다. "light version" 바보들을 위한 MQL5 마법사 (MQL5 마법사 for Dummies) 및 "개발자들 버전 (version from developers)"- MQL5 마법사: 새로운 버전 (MQL5 마법사 : New Version)을 포함하여 마법사를 사용하여 자동 거래 시스템을 만드는 방법을 설명해주는 여러 문서가 있습니다.

모든 게 좋아보입니다 - 거래 로봇은 5 번의 마우스 클릭으로 생성되며, 전략 테스터에서 테스트하고 거래 시스템의 매개 변수를 최적화 할 수 있습니다. 수동으로 다른 작업을 수행해야 합니다. 하지만 문제는 트레이더 / MQL5 개발자가 자신 만의 무언가를 만들고 싶고, 어디서도 설명되지 않은 독특한 무언가를 만들고자하고, 자신의 거래 신호 모듈을 작성하려고 할 때 발생합니다. 트레이더는 MQL5 문서를 열어 표준 라이브러리에 도달한 후 끔찍히 놀라게 되는데...


다섯 가지 끔찍한 클래스

사실, MQL5 마법사는 Expert Advisors 생성을 크게 단순화하지만 먼저 입력으로 사용할 내용을 알아야 합니다. MQL5 마법사를 사용하여 Expert Advisor를 자동으로 만들려면 해당 구성 요소가 전문가의 기본 클래스 섹션의 5 가지 기본 클래스를 준수하는지 확인합니다

다음은 객체 지향 프로그래밍 (OOP)이라고 하는 "위대하고 끔찍한" 접근 방식의 전체적 힘 (whole force)에 관련된 내용입니다. 그러나 두려워하지 마십시오. 요새는 거의 모든 사람들이 많은 기능을 갖춘 휴대폰을 가지고 있으나, 대부분의 사람들은 그 작동 방식을 거의 모르니까요. 이 모든 것을 공부할 필요는 없습니다. CExpertSignal 클래스의 일부 기능만 설명하겠습니다.


이 글에서는 거래 신호 모듈을 만드는 단계를 살펴보고 OOP 나 클래스를 듣지 않고도 이를 수행하는 방법을 살펴볼 것입니다. 하지만 원한다면 조금 더 나아갈 수 있습니다.


1. 밑바닥에서부터 클래스 만들기

저희는 기존의 거래 신호 모듈을 저희의 필요에 맞게 변경하지 않을 것입니다. 따라서 단순히 자체 클래스를 작성하지만 먼저 네비게이터 (Navigator)를 사용하여 MQL5/Include/Expert/에 신호를 저장할 새 폴더를 만듭니다.



생성한 폴더를 마우스 오른쪽 버튼으로 클릭하고 "새 파일"을 선택한 다음 거래 신호 모듈에 대한 새 클래스를 생성합니다.


필드를 채우십시오.

  • 클래스 이름 - 클래스의 이름입니다. 이것은 두 이동 평균의 교차점에서 신호를 생성하기위한 모듈이므로 이름을 MA_Cross로 지정하겠습니다.
  • 기본 이름은 클래스가 파생되는 클래스입니다. 그리고 기본 클래스 CExpertSignal에서 파생해야 합니다.

"마침"을 클릭하면 모듈 초안이 준비됩니다. 지금까지는 모두 동쪽입니다. 컴파일러가 기본 클래스 CExpertSignal을 찾을 위치를 알 수 있도록 결과 파일에 #include 선언만 추가하면됩니다.

#include "..\ExpertSignal.mqh"   // CExpertSignal is in the file ExpertSignal

결과:

//+------------------------------------------------------------------+
//|                                                     MA_Cross.mqh |
//|                        Copyright 2012, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2012, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"

#include "..\ExpertSignal.mqh"   // CExpertSignal is in the file ExpertSignal
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class MA_Cross : public CExpertSignal
  {
private:

public:
                     MA_Cross();
                    ~MA_Cross();
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
MA_Cross::MA_Cross()
  {
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
MA_Cross::~MA_Cross()
  {
  }
//+------------------------------------------------------------------+

결과 클래스를 확인하고 (컴파일 오류가 없어야 함) F7을 클릭합니다. 오류가 없고 계속 진행할 수 있습니다.


2. 모듈 핸들

클래스가 완전히 비어 있고 오류가 없으며 테스트 할 수 있습니다. 이를 기반으로 MQL5 마법사에서 새로운 Expert Advisor를 생성해보겠습니다. 저희는 거래 신호 모듈을 선택하는 단계에 도달하게 되고... 저희 모듈이 거기에 없다는 것을 봅니다.


대체 어디에 있는 걸까요? 클래스가 유용 할 수 있음을 이해하기 위해 MQL5 마법사에 대한 표시를 추가하지 않습니다. 이 문제를 해결해봅시다. 표준 패키지의 모듈을 살펴보면 각 모듈에 파일 시작 부분에 헤더가 포함되어 있음을 알 수 있습니다. 특정 규칙에 따라 컴파일 된 모듈의 핸들입니다. 그리고 규칙은 매우 간단합니다.

예를 들어 AMA 기반 거래 신호 모듈의 소스 코드를 엽니다 (적응 이동 평균 신호의 논리 설명 참조). 그리고 이 모듈을 선택하여 MQL5 마법사를 실행합니다. 비교:

핸들의 마지막 블록은 모듈 매개 변수를 나타내며 첫 번째 줄에는 MQL5 마법사에 표시 할 모듈 이름이 포함됩니다. 보시다시피 복잡한 것은 없습니다. 따라서 각 모듈의 핸들에는 다음 항목이 포함됩니다.

  • Title - MQL5 마법사에 표시되는 모듈 이름입니다.
  • 유형 - 신호 모듈의 버전. 항상 SignalAdvanced 여야 합니다.
  • 이름 - MQL5 마법사에서 선택된 후의 모듈 이름이며 생성된 Expert Advisor의 내부 매개 변수를 설명하기위한 주석에 사용됩니다 (권장 지정됨).
  • ShortName - 생성된 Expert Advisor에서 외부 매개 변수의 자동 이름 지정을 위한 접두사 (Signal_<ShortName>_<ParameterName> 형식).
  • 클래스 - 모듈에 포함 된 이름.
  • 페이지 - 이 모듈에 대한 도움말을 얻기 위한 매개 변수 (표준 제공의 모듈에만 해당).

다음은 Parameter=list_of_values ​​형식의 매개 변수 설명이며, 여기에서 다음이 지정됩니다 (쉼표로 구분).

  1. Expert Advisor를 시작할 때 매개 변수 값을 설정하는 함수의 이름입니다.
  2. 매개 변수 유형은 열거 형일 수 있습니다.
  3. 매개 변수의 기본값, 즉 MQL5 마법사에서 변경하지 않는 경우 매개 변수에 설정 될 값입니다.
  4. MQL5 마법사에서 생성 된 Expert Advisor를 시작할 때 표시되는 매개 변수에 대한 설명입니다.

이제 이 모든 것을 알고 거래 신호 모듈의 핸들을 만들어 보겠습니다. 그래서 저희는 두 이동 평균의 교차점에서 거래 신호를 얻기 위한 모듈을 작성하고 있습니다. 최소 4 개의 외부 매개 변수를 설정해야 합니다.

  • FastPeriod - 빠른 이동 평균 기간
  • FastMethod - 빠른 이동 평균의 평활화 유형
  • SlowPeriod - 느린 이동 평균 기간
  • SlowMethod - 느린 이동 평균의 평활화 유형

각 이동 평균을 계산하기 위해 시프트 및 가격 유형을 추가 할 수도 있지만 근본적으로 아무것도 변경되지 않습니다. 따라서 현재 버전은 다음과 같습니다

// wizard description start
//+------------------------------------------------------------------+
//| Description of the class                                         |
//| Title=Signals at the intersection of two MAs                     |
//| Type=SignalAdvanced                                              |
//| Name=My_MA_Cross                                                 |
//| ShortName=MaCross                                                |
//| Class=MA_Cross                                                   |
//| Page=Not needed                                                  |
//| Parameter=FastPeriod,int,13,Period of fast MA                    |
//| Parameter=FastMethod,ENUM_MA_METHOD,MODE_SMA,Method of fast MA   |
//| Parameter=SlowPeriod,int,21,Period of slow MA                    |
//| Parameter=SlowMethod,ENUM_MA_METHOD,MODE_SMA,Method of slow MA   |
//+------------------------------------------------------------------+
// wizard description end

모듈 핸들이 준비되었으며 여기에서 다음을 설명해드립니다

  1. MQL5 마법사에 표시된 이름 - "두 이동 평균의 교차점에서의 신호".
  2. 거래 신호를 구성하기 위한 4 개의 외부 매개 변수.
    • FastPeriod - 기본값이 13인 빠른 이동 평균 기간입니다.
    • FastMethod - 빠른 이동 평균의 스무딩 유형이며 기본적으로 단순 스무딩입니다.
    • SlowPeriod - 기본값이 21 인 느린 이동 평균 기간입니다.
    • SlowMethod - 느린 이동 평균의 스무딩 유형이며 기본적으로 단순 스무딩입니다.

변경 사항을 저장하고 컴파일하십시오. 오류가 없어야 합니다. MQL5 마법사를 실행하여 확인하십시오. 이제 모듈을 선택할 수 있으며 모든 매개 변수가 표시됩니다!


축하합니다. 거래 신호 모듈이 이제 멋지게 보입니다!


3. 매개 변수 설정 방법

이제 외부 매개 변수로 작업 할 시간입니다. 거래 모듈은 MA_Cross 클래스로 표시되므로 해당 매개 변수는 private 멤버와 동일한 클래스 내에 저장되어야 합니다. 클래스 선언에 네 줄 (매개 변수 수와 동일)을 추가해 보겠습니다. 이미 핸들에 매개 변수를 설명했으며 다음 사항을 알고 있습니다

class MA_Cross : public CExpertSignal
  {
private:
   //--- Configurable module parameters
   int               m_period_fast;    // Period of the fast MA
   int               m_period_slow;    // Period of the slow MA
   ENUM_MA_METHOD    m_method_fast;    // Type of smoothing of the fast MA
   ENUM_MA_METHOD    m_method_slow;    // Type of smoothing of the slow MA

그러나 모듈의 외부 매개 변수 값이 MA_Cross 클래스의 적절한 멤버에 어떻게 표시됩니까? 모두 매우 간단합니다. 클래스에서 같은 이름의 공개 메소드를 선언하기만 하면 됩니다. 즉, public 섹션에 네 줄을 추가하면 됩니다.

class MA_Cross : public CExpertSignal
  {
private:
   //--- Configurable module parameters
   int               m_period_fast;    // Period of the fast MA
   int               m_period_slow;    // Period of the slow MA
   ENUM_MA_METHOD    m_method_fast;    // Type of smoothing of the fast MA
   ENUM_MA_METHOD    m_method_slow;    // Type of smoothing of the slow MA

public:
   //--- Constructor of class
                     MA_Cross();
   //--- Destructor of class
                    ~MA_Cross();
   //--- Methods for setting
   void              FastPeriod(int value)               { m_period_fast=value;        }
   void              FastMethod(ENUM_MA_METHOD value)    { m_method_fast=value;        }
   void              SlowPeriod(int value)               { m_period_slow=value;        }
   void              SlowMethod(ENUM_MA_METHOD value)    { m_method_slow=value;        }
   };

MQL5 마법사를 사용하여 이 모듈을 기반으로 Expert Advisor를 생성하고 차트에서 실행하면 Expert Advisor를 초기화 할 때 이 네 가지 메소드가 자동으로 호출됩니다. 그래서 여기에 간단한 규칙이 있습니다

모듈의 매개 변수 생성 규칙 - 핸들에서 선언 한 각 매개 변수에 대해 해당 값을 저장하기 위해 클래스에 private 멤버를 만들고 값을 설정하기 위한 public 멤버를 만들어야 합니다. 메소드 이름은 매개 변수 이름과 일치해야 합니다.

그리고 마지막 순간은 값 설정 메소드가 호출되지 않은 경우 사용할 매개 변수에 대한 기본값을 설정하는 것입니다. 선언된 각 변수 또는 클래스 멤버는 초기화되어야 합니다. 이 기술을 사용하면 찾기 어려운 많은 오류를 방지 할 수 있습니다.

자동 초기화의 경우 가장 적합한 것은 클래스 생성자입니다. 객체를 만들 때 항상 가장 먼저 호출됩니다. 기본값의 경우 모듈 핸들에 작성된 값을 사용합니다.

class MA_Cross : public CExpertSignal
  {
private:
   //--- Configurable module parameters
   int               m_period_fast;    // Period of the fast MA
   ENUM_MA_METHOD    m_method_fast;     // Type of smoothing of the fast MA
   int               m_period_slow;    // Period of the slow MA
   ENUM_MA_METHOD    m_method_slow;     // Type of smoothing of the slow MA

public:
   //--- Constructor of class
                     MA_Cross(void);
   //--- Destructor of class
                    ~MA_Cross(void);
//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+
MA_Cross::MA_Cross(void) : m_period_fast(13),          // Default period of the fast MA is 3
                           m_method_fast(MODE_SMA),    // Default smoothing method of the fast MA
                           m_period_slow(21),          // Default period of the slow MA is 21
                           m_method_slow(MODE_SMA)     // Default smoothing method of the slow MA
  {
  }

여기서 클래스 멤버는 초기화 목록을 사용하여 초기화됩니다.

보시다시피, 저희는 아직 이동 평균 지표를 사용하지 않았습니다. 모듈의 핸들에 많은 매개 변수가 명시되어 있으므로 간단한 규칙을 발견했습니다. 모듈을 구현하는 클래스에 많은 메소드와 멤버가 있어야 합니다. 복잡할 건 없습니다! 그러나 생성자에서 매개 변수의 기본값을 설정하는 것을 잊지 마십시오.


4. 입력 매개 변수의 정확성 확인

저희는 거래 모듈을 위한 매개 변수를 만들고, 값을 설정하는 방법을 작성했으며, 이제 다음 중요한 단계인 매개 변수의 정확성을 확인해야 합니다. 저희의 경우에는 이동 평균 기간과 계산을 위해 평활화 유형을 확인해야 합니다. 이를 위해 클래스에 자신의 ValidationSettings() 메소드를 작성해야 합니다. 이 메소드는 상위 클래스 CExpertBase에 정의되어 있으며 모든 하위에서 의무적으로 재정의됩니다.

그러나 객체 지향 프로그래밍에 대해 아무것도 모르는 경우에는 기억하십시오. 클래스에서 매개 변수가 필요하지 않고 true 또는 false를 반환하는 ValidationSettings() 함수를 작성해야 합니다.

class MA_Cross : public CExpertSignal
  {
...
   //--- Constructor of class
                     MA_Cross(void);
   //--- Destructor of class
                    ~MA_Cross(void);
   //--- Checking correctness of input data
   bool              ValidationSettings();
...
   };
//+------------------------------------------------------------------+
//| Checks input parameters and returns true if everything is OK     |
//+------------------------------------------------------------------+
bool MA_Cross:: ValidationSettings()
  {
   //--- Call the base class method
   if(!CExpertSignal::ValidationSettings())  return(false);
   //--- Check periods, number of bars for the calculation of the MA >=1
   if(m_period_fast<1 || m_period_slow<1)
     {
      PrintFormat("Incorrect value set for one of the periods! FastPeriod=%d, SlowPeriod=%d",
                  m_period_fast,m_period_slow);
      return false;
     }
//--- Slow MA period must be greater that the fast MA period
   if(m_period_fast>m_period_slow)
     {
      PrintFormat("SlowPeriod=%d must be greater than FastPeriod=%d!",
                  m_period_slow,m_period_fast);
      return false;
     }
//--- Fast MA smoothing type must be one of the four values of the enumeration
   if(m_method_fast!=MODE_SMA && m_method_fast!=MODE_EMA && m_method_fast!=MODE_SMMA && m_method_fast!=MODE_LWMA)
     {
      PrintFormat("Invalid type of smoothing of the fast MA!");
      return false;
     }
//--- Show MA smoothing type must be one of the four values of the enumeration
   if(m_method_slow!=MODE_SMA && m_method_slow!=MODE_EMA && m_method_slow!=MODE_SMMA && m_method_slow!=MODE_LWMA) 
     {
      PrintFormat("Invalid type of smoothing of the slow MA!");
      return false;
     }
//--- All checks are completed, everything is ok
   return true;
  }
보시다시피 MA_Cross 클래스의 공개 부분에서 ValidationSettings() 메소드의 선언을 추가 한 후 다음 형식으로 메소드 본문을 추가했습니다.
bool MA_Cross:: ValidationSettings()

먼저 반환 유형, 클래스 이름, 범위 확인 연산자 ::,이 모든 뒤에 이전에 선언 된 메소드의 이름이 오게 됩니다. 클래스 메소드의 선언 및 설명에서 매개 변수의 이름과 유형이 일치해야 한다는 점을 잊지 마세요. 그러나 컴파일러는 이러한 오류에 대해 경고합니다.

먼저 기본 클래스 메소드를 호출한 다음 입력 매개 변수를 확인합니다.

//--- Call the base class method
   if(!CExpertSignal::ValidationSettings())  return(false);
//--- Our code to check the values of parameters

이 라인을 추가하지 않으면 생성된 Expert Advisor가 거래 신호 모듈을 초기화 할 수 없습니다.


5. 저희의 지표는 어디에 있습니까?

지표에 대한 모든 준비 작업이 완료되었으므로 지표를 사용할 때입니다. 거래 신호의 각 모듈에는 생성된 Expert Advisor를 실행할 때 자동으로 호출되는 InitIndicators() 메소드가 포함되어 있습니다. 이 방법에서는 모듈에 대한 이동 평균 지표를 제공해야 합니다.

먼저 클래스에서 InitIndicators() 메소드를 선언하고 초안을 붙여 넣습니다

public:
   //--- Constructor of class
                     MA_Cross(void);
   //--- Destructor of class
                    ~MA_Cross(void);
   //--- Methods for setting
   void              FastPeriod(int value)               { m_period_fast=value;        }
   void              FastMethod(ENUM_MA_METHOD value)    { m_method_fast=value;        }
   void              SlowPeriod(int value)               { m_period_slow=value;        }
   void              SlowMethod(ENUM_MA_METHOD value)    { m_method_slow=value;        }
   //--- Checking correctness of input data
   bool              ValidationSettings();
   //--- Creating indicators and timeseries for the module of signals
   bool              InitIndicators(CIndicators *indicators);
  };
...
//+------------------------------------------------------------------+
//| Creates indicators                                               |
//| Input:  a pointer to a collection of indicators                  |
//| Output: true if successful, otherwise false                      |
//+------------------------------------------------------------------+
bool MA_Сross::InitIndicators(CIndicators* indicators)
  {
//--- Standard check of the collection of indicators for NULL
   if(indicators==NULL)                           return(false);
//--- Initializing indicators and timeseries in additional filters
   if(!CExpertSignal::InitIndicators(indicators)) return(false);
//--- Creating our MA indicators
   ... Some code here
//--- Reached this part, so the function was successful, return true
   return(true);
  }

따라서 복잡한 것은 없습니다. 메소드를 선언한 다음 ValidationSettings() 메소드를 수행했듯이 메소드 본문을 생성합니다. 무엇보다도 함수 정의에 클래스 이름과 연산자 ::를 삽입하는 것을 잊지 마십시오. 이동 평균을 생성하기 위해 코드에 삽입 할 수있는 초안이 있습니다. 제대로 해봅시다. 각 인디케이터에 대해 클래스에 별도의 함수를 생성하여 성공하면 true를 반환합니다. 이 함수는 어떤 이름도 가질 수 있지만 용도를 반영하도록 하므로 CreateFastMA() 및 CreateSlowMA() 함수를 호출해보겠습니다.

protected:
   //--- Creating MA indicators
   bool              CreateFastMA(CIndicators *indicators);
   bool              CreateSlowMA(CIndicators *indicators);
  };
//+------------------------------------------------------------------+
//| Creates indicators                                               |
//| Input:  a pointer to a collection of indicators                  |
//| Output: true if successful, otherwise false                      |
//+------------------------------------------------------------------+
bool MA_Cross::InitIndicators(CIndicators *indicators)
  {
//--- Standard check of the collection of indicators for NULL
   if(indicators==NULL) return(false);
//--- Initializing indicators and timeseries in additional filters
   if(!CExpertSignal::InitIndicators(indicators)) return(false);
//--- Creating our MA indicators
   if(!CreateFastMA(indicators))                  return(false);
   if(!CreateSlowMA(indicators))                  return(false);
//--- Reached this part, so the function was successful, return true
   return(true);
  }
//+------------------------------------------------------------------+
//| Creates the "Fast MA" indicator                                  |
//+------------------------------------------------------------------+
bool MA_Cross::CreateFastMA(CIndicators *indicators)
  {
... Some code
//--- Reached this part, so the function was successful, return true
   return(true);
  }
//+------------------------------------------------------------------+
//| Creates the "Slow MA" indicator                                  |
//+------------------------------------------------------------------+
bool MA_Cross::CreateSlowMA(CIndicators *indicators)
  {
... Some code
//--- Reached this part, so the function was successful, return true
   return(true);
  }

그게 전부입니다. MA 지표를 생성하고 어떻게 든 이러한 지표의 핸들을 거래 모듈에 통합하는 코드를 작성하면 모듈이 이러한 지표의 값을 사용할 수 있습니다. 이것이 CIndicators 유형의 변수에 대한 포인터가 매개 변수로 전달되는 이유입니다. 다음은 이에 대한 문서에 기록되어 있습니다.

CIndicators는 시계열 및 기술 지표 클래스의 인스턴스를 수집하기 위한 클래스입니다. CIndicators 클래스는 기술 지표 클래스의 인스턴스 생성, 저장 및 관리 (데이터 동기화, 핸들 및 메모리 관리)를 제공합니다.

이것은 저희가 지표를 생성하여 이 컬렉션에 배치해야 함을 의미합니다. CIndicator 폼의 인디케이터와 그 차일드만 컬렉션에 저장할 수 있으므로 이 사실을 사용해야 합니다. 위에서 언급한 하위 항목인 CiCustom을 사용합니다. 각 이동 평균에 대해 클래스의 비공개 부분에 CiCustom 유형의 객체를 선언합니다

class MA_Cross : public CExpertSignal
  {
private:
   CiCustom          m_fast_ma;            // The indicator as an object
   CiCustom          m_slow_ma;            // The indicator as an object
   //--- Configurable module parameters
   int              m_period_fast;   // Period of the fast MA
   ENUM_MA_METHOD    m_method_fast;    // Type of smoothing of the fast MA
   int              m_period_slow;   // Period of the slow MA
   ENUM_MA_METHOD    m_method_slow;    // Type of smoothing of the slow MA

물론 CIndicator에서 파생되는 고유한 인디케이터 클래스를 만들고 MQL5 마법사와 함께 사용하는 데 필요한 모든 메소드를 구현할 수 있습니다. 그러나 이 경우 CiCustom을 사용하여 거래 신호 모듈에서 모든 사용자 정의 인디케이터를 사용하는 방법을 보여드리고자 합니다.

코드에서 보이는 방법은 다음과 같습니다

//+------------------------------------------------------------------+
//| Creates the "Fast MA" indicator                                  |
//+------------------------------------------------------------------+
bool MA_Cross::CreateFastMA(CIndicators *indicators)
  {
//--- Checking the pointer
   if(indicators==NULL) return(false);
//--- Adding an object to the collection
   if(!indicators.Add(GetPointer(m_fast_ma)))
     {
      printf(__FUNCTION__+": Error adding an object of the fast MA");
      return(false);
     }
//--- Setting parameters of the fast MA
   MqlParam parameters[4];
//---
   parameters[0].type=TYPE_STRING;
   parameters[0].string_value="Examples\\Custom Moving Average.ex5";
   parameters[1].type=TYPE_INT;
   parameters[1].integer_value=m_period_fast;      // Period
   parameters[2].type=TYPE_INT;
   parameters[2].integer_value=0;                  // Shift
   parameters[3].type=TYPE_INT;
   parameters[3].integer_value=m_method_fast;      // Averaging method
//--- Object initialization  
   if(!m_fast_ma.Create(m_symbol.Name(),m_period,IND_CUSTOM,4,parameters))
     {
      printf(__FUNCTION__+": Error initializing the object of the fast MA");
      return(false);
     }
//--- Number of buffers
   if(!m_fast_ma.NumBuffers(1)) return(false);
//--- Reached this part, so the function was successful, return true
   return(true);
  }

CreateFastMA() 메소드에서 먼저 인디케이터 컬렉션의 포인터를 확인한 다음 이 컬렉션에 빠른 MA m_fast_ma의 포인터를 추가합니다. 그런 다음 사용자 지정 인디케이터의 매개 변수를 저장하도록 특별히 설계된 MqlParam 구조를 선언하고 값으로 채웁니다.

표준 터미널 배송 팩의 사용자 지정 이동 평균을 사용자 지정 MA 인디케이터로 사용합니다. 인디케이터의 이름은 data_folder/MQL5/Indicators/ 폴더를 기준으로 표시되어야 합니다. 표준 패키지의 Custom Moving Average.mq5 '는 data_folder/MQL5/Indicators/Examples/에 있으므로 예제 폴더를 포함하여 경로를 지정합니다

parameters[0].string_value="Examples\\Custom Moving Average.ex5";

이 지표의 코드를 보면 필요한 모든 데이터를 볼 수 있습니다.

//--- input parameters
input int            InpMAPeriod=13;       // Period
input int            InpMAShift=0;         // Shift
input ENUM_MA_METHOD InpMAMethod=MODE_SMMA;  // Method

구조의 값에는 유형-값 쌍이 포함됩니다

  1. 매개 변수 유형-문자열 (인디케이터 이름 전송)
  2. 사용자 지정 인디케이터의 실행 파일 이름 - "Custom Moving Averages.exe"
  3. 매개 변수 유형 - int (기간 값)
  4. 이동 평균 기간
  5. 매개 변수 유형- int (시프트 값)
  6. 바에서 평균의 수평 이동
  7. 매개 변수 유형 - int (열거 값은 정수임)
  8. 평균화 방법

구조를 채운 후 인디케이터는 모든 필수 매개 변수의 Create() 메소드에 의해 초기화됩니다. 기호 이름 및 계산된 시간 프레임, ENUM_INDICATOR의 인디케이터 유형 열거, 인디케이터 매개 변수의 수 및 매개 변수 값이 있는 MqlParam 구조. 마지막은 NumBuffers() 메소드를 사용하여 인디케이터 버퍼의 수를 지정하는 것입니다.

느린 이동 평균을 만드는 CreateSlowMA() 메소드는 간단합니다. 모듈에서 사용자 지정 인디케이터를 사용할 때 MQL5 마법사가 생성한 Expert Advisor가 테스터에서도 실행된다는 사실을 잊지 마십시오. 따라서 파일 시작 부분에 필요한 인디케이터의 위치를 ​​테스터에게 전달하는 #property tester_indicator 속성을 ​​추가합니다.

#include "..\ExpertSignal.mqh"   // The CExpertSignal class is in the file ExpertSignal
#property tester_indicator "Examples\\Custom Moving Average.ex5"

여러 다른 지표를 사용하는 경우 각각에 대해 이 줄을 추가해야 합니다. 그래서 저희는 지표를 추가했습니다. 편의를 위해 MA 값을 받는 두 가지 방법을 제공하겠습니다

   //--- Checking correctness of input data
   bool              ValidationSettings(void);
   //--- Creating indicators and timeseries for the module of signals
   bool              InitIndicators(CIndicators *indicators);
   //--- Access to indicator data
   double            FastMA(const int index)             const { return(m_fast_ma.GetData(0,index)); }
   double            SlowMA(const int index)             const { return(m_slow_ma.GetData(0,index)); }

보시다시피 메소드는 매우 간단합니다. SIndicator 부모 클래스의 GetData() 메소드를 사용했습니다. 이 메소드는 지정된 위치의 지정된 인디케이터 버퍼에서 값을 반환합니다.

표준 패키지의 클래식 인디케이터로 작업하기 위한 클래스가 필요한 경우 인디케이터 작업을 위한 클래스 섹션에서 사용할 수 있습니다. 마지막 단계로 진행할 준비가 되었습니다.


6. LongCondition 및 ShortCondition 메소드 정의

모든 것이 저희 모듈을 작동시키고 거래 신호를 생성할 준비가 되었습니다. 이 기능은 CExpertSignal:의 각 하위 항목에서 설명해야 하는 두 가지 방법으로 제공됩니다.

  • LongCondition()은 구매 조건을 확인하고 Long 신호의 강도를 0에서 100까지 반환합니다.
  • ShortCondition() - 는 판매 조건을 확인 하고 의 강점을 반환합니다. 짧은0에서 100까지 신호.

함수가 null 값을 반환하면 거래 신호가 없음을 의미합니다. 신호에 대한 조건이있는 경우 신호의 강도를 추정하고 100을 초과하지 않는 값을 반환 할 수 있습니다. 신호 강도를 평가하면 여러 모듈 및 시장 모델을 기반으로 거래 시스템을 유연하게 구축 할 수 있습니다. 이에 대한 자세한 내용은 MQL5 마법사: 새 버전을 참조하십시오.

거래 신호의 간단한 모듈을 작성하고 있기 때문에 매수 및 매도 신호가 동등하게 평가된다는 데 동의 할 수 있습니다 (100). 클래스 선언에 필요한 메소드를 추가합시다.

   ...
   bool              InitIndicators(CIndicators *indicators);
   //--- Access to data of the indicators
   double            FastMA(const int index)             const { return(m_fast_ma.GetData(0,index)); }
   double            SlowMA(const int index)             const { return(m_slow_ma.GetData(0,index)); }
   //--- Checking buy and sell conditions
   virtual int       LongCondition();
   virtual int       ShortCondition();

또한 함수에 대한 설명을 작성해 보겠습니다. 이것은 매수 신호가 확인되는 방법입니다 (매도 신호와 모두 동일합니다).

//+------------------------------------------------------------------+
//| Returns the strength of the buy signal                           |
//+------------------------------------------------------------------+
int MA_Cross::LongCondition()
  {
   int signal=0;
//--- For operation with ticks idx=0, for operation with formed bars idx=1
   int idx=StartIndex();
//--- Values of MAs at the last formed bar
   double last_fast_value=FastMA(idx);
   double last_slow_value=SlowMA(idx);
//--- Values of MAs at the last but one formed bar
   double prev_fast_value=FastMA(idx+1);
   double prev_slow_value=SlowMA(idx+1);
//---If the fast MA crossed the slow MA from bottom upwards on the last two closed bars
   if((last_fast_value>last_slow_value) && (prev_fast_value<prev_slow_value))
     {
      signal=100; // There is a signal to buy
     }
//--- Return the signal value
   return(signal);
  }

부모 클래스 CExpertBase의 StartIndex() 함수에 의해 반환된 값이 할당되는 idx 변수를 선언했습니다. Expert Advisor가 모든 틱에 대해 작동하도록 설계된 경우 StartIndex() 함수는 0을 반환합니다. 이 경우 분석은 현재 바에서 시작됩니다. Expert Advisor가 시가로 작동하도록 설계된 경우 StartIndex()는 1을 반환하고 마지막으로 형성된 바에서 분석이 시작됩니다.

기본적으로 StartIndex()는 1 을 반환합니다. 즉, MQL5 마법사에 의해 생성된 Expert Advisor는 새로운 바를 만들고 현재 바를 형성하는 동안 들어오는 틱을 무시합니다.

이 모드를 활성화하는 방법과 사용 방법은 나중에 마무리 스트로크에서 설명합니다.

모듈을 사용할 준비가 되었으므로 이 모듈을 기반으로 MQL5 마법사에서 거래 로봇을 생성해 보겠습니다.


테스터에서 Expert Advisor 확인하기

모듈의 효율성을 테스트하기 위해 MQL5 마법사에서 이를 기반으로 Expert Advisor를 생성하고 차트에서 실행해보겠습니다. 나타난 시작 창의 "입력" 탭에는 MA_Cross 모듈의 매개 변수가 포함되어 있습니다.

다른 모든 매개 변수도 MQL5 마법사에 의해 추가되었으며 선택한 자금 관리 모듈 및 위치 유지 관리 모듈 (Trailing Stop)을 기반으로 EA를 생성합니다. 따라서 저희는 거래 신호 모듈을 작성하고 준비된 솔루션을 받았습니다. 이것이 MQL5 마법사 사용의 주요 이점입니다! 

이제 MetaTrader 5 전략 테스터에서 거래 로봇을 테스트 해봅시다. 주요 매개 변수의 빠른 최적화를 실행해보겠습니다.

이러한 입력 매개 변수 설정에서는 전체 최적화를 위해 50만 번 이상의 패스가 필요합니다. 따라서 빠른 최적화 (유전 알고리즘)를 선택하고 추가로 MQL5 클라우드 네트워크를 활용하여 최적화를 가속화합니다. 최적화는 10분 만에 완료되었으며 결과를 얻었습니다.


보시다시피, MQL5에서 거래 로봇을 생성하고 입력 매개 변수를 최적화하는 것은 위치 관리 서비스 로직을 작성하고 최상의 알고리즘을 디버깅 및 검색하는 데 필요한 시간보다 훨씬 더 적게 소요되었습니다. 


마무리 스트로크

이 항목을 건너 뛰거나 거래 신호 모듈을 작성하는 기술에 완전히 익숙해지면 나중에 다시 돌아갈 수 있습니다.

MQL5 마법사에서 생성된 Expert Advisor의 소스 코드를 열면 false 값이 있는 전역 변수 Expert_EveryTick을 찾을 수 있습니다. 이 변수를 기반으로 StartIndex() 함수는 해당 값을 반환합니다. 실행해야 할 모드를 Expert Advisor에게 전달합니다.

//+------------------------------------------------------------------+
//|                                                 TestMA_Cross.mq5 |
//|                        Copyright 2012, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2012, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
//+------------------------------------------------------------------+
//| Include                                                          |
//+------------------------------------------------------------------+
#include <Expert\Expert.mqh>
//--- available signals
#include <Expert\MySignals\MA_Cross.mqh>
//--- available trailing
#include <Expert\Trailing\TrailingNone.mqh>
//--- available money management
#include <Expert\Money\MoneyFixedLot.mqh>
//+------------------------------------------------------------------+
//| Inputs                                                           |
//+------------------------------------------------------------------+
//--- inputs for expert
input string         Expert_Title             ="TestMA_Cross";  // Document name
ulong               Expert_MagicNumber       =22655;          // Expert Advisor ID
bool                  Expert_EveryTick             =false;          // Work of the EA inside the bar
//--- inputs for main signal
input int            Signal_ThresholdOpen     =10;             // Signal threshold value to open [0...100]
input int            Signal_ThresholdClose    =10;             // Signal threshold value to close [0...100]

Expert_EveryTick을 true로 설정하고 코드를 컴파일하면 거래 로봇은 들어오는 각 틱을 분석하여 현재 불완전한 바의 값을 결정합니다. 작동 방식을 이해하는 경우에만 이를 수행하십시오. 모든 거래 시스템이 바 안에서 작동하도록 설계된 것은 아닙니다.

Expert_EveryTick 매개 변수에 input 키워드를 추가 할 수도 있습니다. 그러면 EA 시작시 차트 또는 테스터에서 설정할 수 있는 새로운 전문가 어드바이저의 입력 매개 변수가 생깁니다.

input bool          Expert_EveryTick         =false;          // Work of the EA inside the bar

이제 저희가 한 일을 요약 할 시간입니다.


거래 신호 모듈을 생성하는 6 단계

MQL5를 마스터했다면 더 이상 Expert Advisor를 처음부터 작성할 필요가 없습니다. 거래 신호 모듈을 생성하고 이 모듈을 기반으로 추적 및 거래량 관리 모듈이 활성화된 거래 로봇을 자동으로 생성합니다. OOP에 익숙하지 않거나 거래 클래스의 구조에 대해 자세히 알아보고 싶지 않은 경우에도 6 단계를 거치면 됩니다.

  1. 별도의 폴더 MQL5/Include/MySignals/에서 MQL5 마법사를 사용하여 새 클래스를 만듭니다. 거래 신호 모듈이 여기에 저장됩니다.
  2. 매개 변수, 유형 및 기본값을 설명하는 모듈 핸들을 만듭니다.
  3. 클래스에서 모듈 매개 변수를 선언하고 생성자에서 초기화를 위한 메소드를 추가합니다.
  4. 입력 매개 변수를 확인하고 CExpertSignal 기본 클래스의 ValidationSettings()를 호출하는 것을 잊지 마십시오.
  5. indicator-objects를 만들고 사전 정의된 초기화 메소드 InitIndicators()를 추가합니다.
  6. LongCondition() 및 ShortCondition() 메소드에서 거래 신호의 조건을 식별합니다.

각 단계는 간단하며 MQL5 프로그래밍에 대한 기술이 거의 필요하지 않습니다. 지침에 따라 모듈을 한 번만 작성하면 되며, 거래 아이디어에 대한 추가 검증은 코딩과 디버깅에 지체한 시간 없이 한 시간 이상 걸리지 않습니다. 


단순한 것에서 복잡한 것까지

MQL5 마법사를 사용하여 만든 거래 로봇에 의해 구현된 거래 전략은 사용하는 거래 신호 모듈만큼 복잡하다는 것을 기억하십시오. 그러나 출입에 대한 일련의 규칙을 기반으로 복잡한 거래 시스템을 구축하기 전에 여러 간단한 시스템으로 분할하고 각각을 개별적으로 확인하십시오.

간단한 모듈을 기반으로 미리 만들어진 거래 신호 모듈을 사용하여 복잡한 거래 전략을 만들 수 있지만 이것은 다른 글의 주제입니다!

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

파일 첨부됨 |
testma_cross.mq5 (7.14 KB)
ma_cross.mqh (11.57 KB)
MetaTrader 5 - 상상 이상! MetaTrader 5 - 상상 이상!
MetaTrader 5 클라이언트 터미널은 처음부터 개발되었으며 물론 이전 제품을 훨씬 능가합니다. 새로운 거래 플랫폼은 모든 금융 시장에서 거래할 수 있는 무한한 기회를 제공합니다. 또한 그 기능은 더욱 유용한 기능과 편리함을 제공하기 위해 계속 확장되고 있습니다. 따라서 MetaTrader 5의 수많은 장점을 모두 나열하는 것은 매우 어렵습니다. 우리는 그것들을 하나의 기사로 간략하게 설명하려고했는데 그 결과에 놀랐습니다. 기사가 간단하지 않습니다!
세마포어 인디케이터를 사용하는 간단한 거래 시스템 세마포어 인디케이터를 사용하는 간단한 거래 시스템
복잡한 거래 시스템을 철저히 살펴보면 일련의 간단한 거래 신호를 기반으로 한다는 것을 알 수 있습니다. 따라서 초보 개발자가 복잡한 알고리즘 작성을 즉시 시작할 필요가 없습니다. 이 글은 거래를 수행하기 위해 세마포어 인디케이터를 사용하는 거래 시스템의 예를 제공합니다.
MetaTrader 5 Tester에서의 전략 시각화 MetaTrader 5 Tester에서의 전략 시각화
우리 모두는 "백 번 듣는 것보다 한 번 보는 것이 낫다"라는 말에 대해 알고 있습니다. 파리나 베네치아에 관한 다양한 책은 읽을 수 있지만, 이런 이미지만으로 이 멋진 도시에서 즐기는 저녁 산책의 느낌에 대해 알 수 없을 것입니다. 시각화의 이점은 시장에서의 작업 (예: 지표를 사용한 차트의 가격 분석, 물론 전략 테스트의 시각화)을 포함하여 우리 삶의 모든 측면에서 쉽게 예상 할 수 있다는 데 있습니다. 이 문서에는 MetaTrader 5 전략 테스터의 모든 시각화 기능에 대한 설명이 포함되어 있습니다.
다중 시간대 및 다중 통화 패널 구축을 위한 객체 지향 접근 방식 다중 시간대 및 다중 통화 패널 구축을 위한 객체 지향 접근 방식
이 글에서는 MetaTrader 5 용 다중 시간 프레임 및 다중 통화 패널을 생성하는데 객체 지향 프로그래밍을 사용하는 방법을 설명합니다. 주요 목표는 패널 자체의 코드를 수정할 필요 없이 가격, 가격 변동, 지표 값 또는 맞춤형 구매/판매 조건과 같은 다양한 종류의 데이터를 표시하는 데 사용할 수 있는 범용 패널을 구축하는 것입니다.