거래 로봇을 무료로 다운로드 하는 법을 시청해보세요
당사를 Twitter에서 찾아주십시오!
당사 팬 페이지에 가입하십시오
스크립트가 흥미로우신가요?
그렇다면 링크 to it -
하셔서 다른 이들이 평가할 수 있도록 해보세요
스크립트가 마음에 드시나요? MetaTrader 5 터미널에서 시도해보십시오
Experts

MACD 샘플 - MetaTrader 5용 expert

게시자:
MetaQuotes
조회수:
332
평가:
(51)
게시됨:
2022.01.10 11:43
macd_sample.mq5 (17.98 KB) 조회
이 코드를 기반으로 한 로봇이나 지표가 필요하신가요? 프리랜스로 주문하세요 프리랜스로 이동

MACD 샘플 EA는 MetaTrader5 클라이언트 터미널의 스탠다드 팩에 포함되어 있으며 MACD 지표를 사용하여 거래하는 EA의 예시입니다.

MACD Sample.mq5 Expert Advisor의 파일은 terminal_data_folder\MQL5\Experts\Examples\MACD\"에 있습니다. 이 Expert Advisor는 EA 개발에서 객체 지향 접근 방식의 한 예입니다.

Expert Advisor의 구조와 작동 방식을 살펴보겠습니다.


1 EA Properties

1.1. EA 속성

//+------------------------------------------------------------------+
//|                                                  MACD Sample.mq5 |
//|                   Copyright 2009-2013, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright   "Copyright 2009-2013, MetaQuotes Software Corp."
#property link        "https://www.mql5.com"
#property version     "5.20"
#property description "expert가 정상적으로 동작하는지 확인 것이 중요합니다"
#property description "입력 관련 세팅에 아무 문제가 없어야 합니다"
#property description "이 경우 변수(Lots, TakeProfit, TrailingStop)를 말합니다"
#property description "2*trend_period bars 이상의 차트에서 TakeProfit를 확인합니다"

처음 5개 행은 주석을 포함하고 다음 7개 행은 전처리기 지시문 #property를 사용하여 MQL5 프로그램의 속성(저작권, 링크, 버전, 설명)을 설정합니다.

Expert Advisor를 실행하면 이들은 모두 "공통" 탭에 표시됩니다.

MACD 샘플 Expert Advisor

그림 1 MACD 샘플 EA의 공통 변수

1.2. Include Files

다음으로, #include 지시문은 표준 라이브러리의 트레이드 클래스를 포함하는 파일을 포함하도록 컴파일러에 지시합니다.

  • Trade.mqh (CTrade - 트레이드 클래스);
  • SymbolInfo.mqh(CSymbolInfo - 거래 상품의 속성과 관련한 작업을 위한 클래스)
  • PositionInfo.mqh(CPositionInfo- 진입한 포지션의 속성과 관련한 작업을 위한 클래스);
  • AccountInfo.mqh(CA계정정보 - 거래 계정의 속성과 관련한 작업을 위한 클래스).
//--- include files 
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
#include <Trade\PositionInfo.mqh>
#include <Trade\AccountInfo.mqh>

적합한 클래스의 인스턴스는 CExpert 클래스의 멤버 변수로 사용됩니다(섹션 3).

1.3. Inputs

그런 다음 유형, 이름, 기본값 및 주석으로 이동합니다. 이들의 역할은 그림2. 에 나와 있습니다. 2.

//--- Expert Advisor 입력 패러미터
input double InpLots          =0.1; // 랏(Lots)
input int    InpTakeProfit    =50;  // Take Profit (pips 기준)
input int    InpTrailingStop  =30;  // Trailing Stop Level (pips 기준)
input int    InpMACDOpenLevel =3;   // MACD open level (pips 기준)
input int    InpMACDCloseLevel=2;   // MACD close level (pips 기준)
input int    InpMATrendPeriod =26;  // MA 트렌드 기간

입력 매개변수의 이름에는 접두어 "Inp"가 있습니다. 또한 전역 변수에는 "Ext"가 접두사로 붙습니다. 이러한 접근 변수 이름 지정은 다양한 변수를 사용하는 것을 단순화합니다.

InpLots - 거래량, InpTakeProfit 및 InpTrailingStop은 이익 실현 및 트레일링 스탑의 수준을 결정합니다.

입력 매개변수 줄의 주석 텍스트는 입력 매개변수 이름 대신 기본값과 함께 "옵션" 탭에 표시됩니다.

그림 2. MACD 샘플 EA의 입력 매개변수

그림 2. MACD 샘플 EA의 입력 매개변수


1.4. 전역 변수

그런 다음 전역 변수 ExtTimeOut이 선언됩니다. 거래의 실행 시간을 제어하는 데 사용됩니다.

int ExtTimeOut=10; // 거래 실행 사이의 시간(초 단위) 

CSampleExpert 클래스 선언 후, 76행에서 또 다른 전역 변수가 선언됩니다. ExtExpert - CSampleExpert 클래스 인스턴스:

//--- the ExtExpert global variable
CSampleExpert ExtExpert;

ExtExpert 객체(CSampleExpert 클래스 샘플)에는 거래 전략(섹션 3)의 기본 논리가 포함되어 있습니다.


2. 이벤트 핸들링 함수

이벤트 핸들링 함수

2.1. OnInit() 초기화 함수

OnInit() 함수는 Expert Advisor를 처음 시작할 때 한 번 호출됩니다. 일반적으로 OnInit() 이벤트 핸들러에서 EA가 작업을 위해 준비됩니다. 입력 매개변수가 확인되고 표시기 및 매개변수가 초기화되는 등의 기능을 합니다. 심각한 오류의 경우 추가 작업이 의미가 없을 때 반환 코드 INIT_FAILED와 함께 기능이 종료됩니다.

//+------------------------------------------------------------------+
//| Expert 초기화 함수                                                 |
//+------------------------------------------------------------------+
int OnInit(void)
  {
//--- 요청된 모든 객체를 생성하고 초기화
   if(!ExtExpert.Init())
      return(INIT_FAILED);
//--- 초기화 성공
   return(INIT_SUCCEEDED);
  }

이 경우 ExtExpert 객체의 Init() 메서드가 호출되며 이는 작업에 필요한 모든 객체의 준비에 따라 true 또는 false를 반환합니다(섹션 3.4 참조). 오류가 발생하면 OnInit()과 반환 코드와 함께 종료됩니다.INIT_FAILED - 초기화에 실패한 경우 EA/indicator 동작을 완료하는 올바른 방법입니다.


2.2. OnTick() 함수

OnTick() 함수는 EA가 실행되는 차트의 심볼에 대해 새 quote가 수신될 때마다 호출됩니다.

//+------------------------------------------------------------------+
//|  EA의 새로운 틱 핸들링                                              |
//+------------------------------------------------------------------+
void OnTick(void)
  {
   static datetime limit_time=0; // 마지막 콜 시간 + 타임아웃을 저장
//--- 필요한 시간이 지나지 않으면 동작하지 않음
   if(TimeCurrent()>=limit_time)
     {
      //--- 데이터 체크
      if(Bars(Symbol(),Period())>2*InpMATrendPeriod)
        {
         //--- Processing() 메서드 요청 후에 limit_time by ExtTimeOut를 증가 시킴 
         if(ExtExpert.Processing())
            limit_time=TimeCurrent()+ExtTimeOut;
        }
     }
  }

OnTick() 이벤트 핸들러에는 거래 조건이 충족될 때 시장 분석 및 거래 작업에 사용되는 ExtExpert.Processing() 메서드를 주기적으로 호출 하기 위한 메커니즘이 포함됩니다.

호출 사이의 시간 간격은 ExtTimeOut 입력 매개변수의 값으로 설정됩니다.


2.3. OnDeInit() 초기화 해제 함수

OnDeInit()는 EA가 차트에서 제거될 때 호출됩니다. 프로그램이 작동 중에 그래픽 객체가 배치 될 경우 그래픽 객체를 차트에서 제거될 수 있습니다.

이 예제에서는 초기화 해제 기능이 사용되지 않고 작업이 수행되지 않습니다.


3. The CSampleExpert class

3.1. The CSampleExpert class

//+------------------------------------------------------------------+
//|  MACD 샘플 EA 클래스 샘플                                           |
//+------------------------------------------------------------------+
class CSampleExpert
  {
protected: 
   //--- 보호된 변수 - 클래스 멤버는 클래스 메서드 안에서만 얻을수 있습니다. 
   double            m_adjusted_point;             // 3/5-자리 쿼트를 조정합니다
   CTrade            m_trade;                      // CTrade class sample
   CSymbolInfo       m_symbol;                     // CSymbolInfo 클래스 샘플
   CPositionInfo     m_position;                   // CPositionInfo 클래스 샘플
   CAccountInfo      m_account;                    // CAccountInfo 클래스 샘플
   //--- indicator handles
   int               m_handle_macd;                // the MACD i지표 핸들
   int               m_handle_ema;                 // the Moving Average 지표 핸들
   //--- 지표 버퍼
   double            m_buff_MACD_main[];           // MACD 지표의 메인 라인의 버퍼
   double            m_buff_MACD_signal[];         // MACD 지표의 시그널 라인의 버퍼
   double            m_buff_EMA[];                 // EMA 지표 버퍼
   //--- 현재 지표의 값
   double            m_macd_current;
   double            m_macd_previous;
   double            m_signal_current;
   double            m_signal_previous;
   double            m_ema_current;
   double            m_ema_previous;
   //--- 레벨 (기본 포인트 단위)
   double            m_macd_open_level;
   double            m_macd_close_level;
   double            m_traling_stop;
   double            m_take_profit;

public: 
   //--- constructor
                     CSampleExpert(void);
   //--- destructor
                     ~CSampleExpert(void);
   //--- 클래스 외부에서 퍼블릭 메서드가 호출 될 수 있음 
   //--- 초기화 메서드
   bool              Init(void);
   //--- 초기화 해제 메서드
   void              Deinit(void);
   //--- 프로세싱 메서드
   bool              Processing(void);
protected: 
   //--- 보호된 메서드는 클래스 메서드 내부에서만 접근이 가능함 
   bool              InitCheckParameters(const int digits_adjust);
   bool              InitIndicators(void);
   bool              LongClosed(void);
   bool              ShortClosed(void);
   bool              LongModified(void);
   bool              ShortModified(void);
   bool              LongOpened(void);
   bool              ShortOpened(void);
  };

EA 클래스에는 변수(클래스 멤버) 및 함수(클래스 메서드) 선언이 포함되어 있습니다.

변수에 대한 보다 편리한 작업을 위해 모든 클래스 구성원 변수에는 변수가 클래스 구성원임을 나타내는 접두사 "m_"(member)이 포함됩니다. 변수나 메서드를 선언하기 전에 해당 형식(또는 함수의 반환 값)이 지정됩니다.

클래스 멤버 변수 및 메서드의 가시성은 다음을 사용하여 정의됩니다.access modifier. CSampleExpert에서 수정자 보호 및 공개가 사용됩니다. public 섹션에 정의된 모든 변수와 메서드는 public이며 외부에서 액세스할 수 있습니다. CSampleExpert 클래스에는 다음과 같은 5가지의 메서드가 있습니다.

  1. CSampleExpert(void) - 생성자(클래스 인스턴스를 만들 때 자동으로 호출됨)
  2. ~CSampleExpert(void) - 소멸자(클래스 인스턴스를 삭제할 때 자동으로 호출됨)
  3. bool Init(void) - 작업에 필요한 모든 데이터가 준비되는 초기화 방법.
  4. void Deinit(void) - 초기화 해제 방법.
  5. bool Processing(void) - 처리 방법.

보호된 액세스 한정자로 선언된 CSampleExpert 클래스 멤버 변수는 CSampleExpert 클래스 메서드(및 자식 클래스) 내에서만 사용할 수 있습니다.

    1. double m_adjusted_point - 3/5자리 쿼트의 올바른 연산을 위한 승수 변수.
    2. CTrade          m_trade - СTrade 클래스 샘플;
    3. CSymbolInfo  m_symbol - CSymbolInfo 클래스 샘플;
    4. CPositionInfo  m_position - СPositionInfo 클래스 샘플;
    5. CAccountInfo  m_account - CAccountInfo 클래스 샘플;
    6. int m_handle_macd - MACD 지표 핸들 값을 저장하기 위한 변수.
    7. int m_handle_ema - EMA 지표의 핸들 값을 저장하기 위한 변수;
    8. double m_buff_MACD_main[] - MACD 메인 라인의 값을 요청하는 데 사용되는 double 유형의 동적 배열.
    9. double m_buff_MACD_signal[] - MACD 시그널 라인의 값을 요청하는 데 사용되는 double 유형의 동적 배열.
    10. double m_buff_EMA[] - EMA 지표의 값을 요청하는 데 사용되는 double 유형의 동적 배열.
    11. 이중 m_macd_current - MACD 메인 라인의 현재 값을 저장하는 데 사용됩니다.
    12. 이중 m_macd_previous - MACD 메인 라인의 이전 값을 저장하는 데 사용됩니다.
    13. 이중 m_signal_current - MACD 시그널 라인의 현재 값을 저장하는 데 사용됩니다.
    14. 이중 m_signal_previous - MACD 시그널 라인의 이전 값을 저장하는 데 사용됩니다.
    15. double m_ema_current - EMA 지표의 현재 값을 저장하는 데 사용됩니다.
    16. double m_ema_previous - EMA 지표의 이전 값을 저장하는 데 사용됩니다.
    17. double           m_macd_open_level,
    18. double           m_macd_close_level,
    19. double           m_traling_stop,
    20. double m_take_profit - m_adjusted_point 승수를 고려하여 가격 수준(입력 매개변수에서 설정) 값을 저장하는 데 사용됩니다.

      보호된 액세스 한정자로 선언된 CSampleExpert 클래스 메서드:

      1. bool InitCheckParameters(const int Digits_adjust) - 입력 매개변수의 정확성 확인 및 EA 매개변수 초기화;
      2. bool InitIndicators(void) - MACD이동 평균 지표 초기화(생성);
      3. bool LongClosed(void) - 롱 포지션의 청산 조건이 충족되면 true를 반환합니다(오픈 롱 포지션을 청산함).
      4. bool ShortClosed(void) - 숏 포지션의 청산 조건이 충족되면 true를 반환합니다(오픈 숏 포지션 청산).
      5. bool LongModified(void) - 오픈 롱 포지션의 스탑로스 수준을 변경하기 위한 조건이 충족되면 true를 반환하고 스탑로스 가격을 수정합니다.
      6. bool ShortModified(void) - 오픈 숏 포지션의 스탑로스 수준을 변경하기 위한 조건이 충족되면 true를 반환하고 스탑로스 가격을 수정합니다.
      7. bool LongOpened(void) - 롱 포지션에 진입할 조건이 충족되면 true를 반환하고 롱 포지션에 진입합니다.
      8. bool ShortOpened(void) - 숏 포지션에 진입할 조건이 충족되면 true를 반환하고 숏 포지션에 진입합니다.


      3.2. CSampleExpert 클래스 생성자

      //+------------------------------------------------------------------+
      //| CSampleExpert 클래스 생성자                                        |
      //+------------------------------------------------------------------+
      CSampleExpert::CSampleExpert(void) : m_adjusted_point(0),
                                           m_handle_macd(INVALID_HANDLE),
                                           m_handle_ema(INVALID_HANDLE),
                                           m_macd_current(0),
                                           m_macd_previous(0),
                                           m_signal_current(0),
                                           m_signal_previous(0),
                                           m_ema_current(0),
                                           m_ema_previous(0),
                                           m_macd_open_level(0),
                                           m_macd_close_level(0),
                                           m_traling_stop(0),
                                           m_take_profit(0)
        {
         ArraySetAsSeries(m_buff_MACD_main,true);
         ArraySetAsSeries(m_buff_MACD_signal,true);
         ArraySetAsSeries(m_buff_EMA,true);
        }

      클래스 생성자는 클래스 샘플 객체가 생성될 때 자동으로 호출됩니다. 호출될 경우 클래스 멤버 변수의 기본값(괄호 안)이 설정되고 시계열 인덱싱 방향이 m_buff_MACD_main[], m_buff_MACD_signal[], m_buff_EMA[]에 대해 설정됩니다.


      3.3. CSampleExpert 클래스 소멸자

      //+------------------------------------------------------------------+
      //| CSampleExpert 클래스 소멸자                                        |
      //+------------------------------------------------------------------+
      CSampleExpert::~CSampleExpert(void)
        {
        }

      CSampleExpert 클래스 소멸자에는 코드가 포함되어 있지 않습니다.


      3.4. CSampleExpert 클래스의 Init 메서드

      //+------------------------------------------------------------------+
      //| 입력 패러미터의 초기화와 검증                                         |
      //+------------------------------------------------------------------+
      bool CSampleExpert::Init(void)
        {
      //--- 공통 속성 세팅
         m_symbol.Name(Symbol());              // 심볼
         m_trade.SetExpertMagicNumber(12345);  // 매직
      //--- 3/5-자리 쿼트
         int digits_adjust=1;
         if(m_symbol.Digits()==3 || m_symbol.Digits()==5)
            digits_adjust=10;
         m_adjusted_point=m_symbol.Point()*digits_adjust;
      //--- m_adjusted_point modifier의 수준 값 세팅
         m_macd_open_level =InpMACDOpenLevel*m_adjusted_point;
         m_macd_close_level=InpMACDCloseLevel*m_adjusted_point;
         m_traling_stop    =InpTrailingStop*m_adjusted_point;
         m_take_profit     =InpTakeProfit*m_adjusted_point;
      //---  3 포인트의 슬리피지 세팅
         m_trade.SetDeviationInPoints(3*digits_adjust);
      //---
         if(!InitCheckParameters(digits_adjust))
            return(false);
         if(!InitIndicators())
            return(false);
      //--- 성공 
         return(true);
        }

      Init() 메서드에서 클래스 멤버 변수가 초기화되고 입력 매개 변수가 확인됩니다.

      m_symbol 객체(C심볼 정보 클래스 인스턴스)용의 Name()메서드 호출은 Expert Advisor가 실행되는 심볼의 이름을 설정한 다음 SetExpertMagicNumber() 메서드가 호출됩니다; m_trade 객체에 대한 EA의 매직 넘버 값을 설정합니다(거래 작업에 사용됨). 그 후,Digits() 메서드는 심볼의 소수점 이하 자릿수를 요청하는 데 사용되며 필요한 경우 수준 값이 수정됩니다.

      그 다음 SetDeviationInPoints() m_trade 객체의 메소드가 호출되며, 여기서 거래 작업에서 허용되는 슬리피지의 값이 설정됩니다.


      3.5. CSampleExpert 클래스의 InitCheckParameters 메서드

      //+------------------------------------------------------------------+
      //| 입력 패러미터 체크                                                  |
      //+------------------------------------------------------------------+
      bool CSampleExpert::InitCheckParameters(const int digits_adjust)
        {
      //--- Take Profit level이 맞는지를 체크
         if(InpTakeProfit*digits_adjust<m_symbol.StopsLevel())
           {
            printf("Take Profit는 %d보다 커야 함",m_symbol.StopsLevel());
            return(false);
           }
      //--- Trailing Stop 수준이 맞는지를 체크
         if(InpTrailingStop*digits_adjust<m_symbol.StopsLevel())
           {
            printf("Trailing Stop must be greater than %d",m_symbol.StopsLevel());
            return(false);
           }
      //--- 거래 볼륨이 맞는지를 체크
         if(InpLots<m_symbol.LotsMin() || InpLots>m_symbol.LotsMax())
           {
            printf("Lots amount must be in the range from %f to %f",m_symbol.LotsMin(),m_symbol.LotsMax());
            return(false);
           }
         if(MathAbs(InpLots/m_symbol.LotsStep()-MathRound(InpLots/m_symbol.LotsStep()))>1.0E-10)
           {
            printf("Lots amount is not corresponding with lot step %f",m_symbol.LotsStep());
            return(false);
           }
      //--- Take Profit<=Trailing Stop일 경우 경고를 띄움
         if(InpTakeProfit<=InpTrailingStop)
            printf("Warning: Trailing Stop must be less than Take Profit");
      //--- 성공적인 완료
         return(true);
        }

      EA 입력 매개변수의 정확성은 InitCheckParameters() 메소드에서 확인됩니다. 매개변수 중 하나라도 유효하지 않으면 적절한 메시지가 나타나고 함수는 false를 반환합니다.


      3.6. CSampleExpert 클래스의 InitIndicators() 메서드

      //+------------------------------------------------------------------+
      //| 지표 초기화 메서드                                                  |
      //+------------------------------------------------------------------+
      bool CSampleExpert::InitIndicators(void)
        {
      //---  MACD 지표 생성
         if(m_handle_macd==INVALID_HANDLE)
            if((m_handle_macd=iMACD(NULL,0,12,26,9,PRICE_CLOSE))==INVALID_HANDLE)
              {
               printf("Error creating MACD indicator");
               return(false);
              }
      //---  EMA 지표 생성
         if(m_handle_ema==INVALID_HANDLE)
            if((m_handle_ema=iMA(NULL,0,InpMATrendPeriod,0,MODE_EMA,PRICE_CLOSE))==INVALID_HANDLE)
              {
               printf("Error creating EMA indicator");
               return(false);
              }
      //--- 성공적인 완료
         return(true);
        }

      InitIndicators() 메서드에서 m_handle_macd 및 m_handle_ema 변수의 초기 값의 정확성을 확인하고(생성자에서 초기화되었으므로 INVALID_HANDLE과 같아야 함) MACD 기술적 지표와 이동 평균이 생성됩니다(iMACD 그리고iMA 함수를 사용하여). 성공하면 함수는 true를 반환하고 지표 핸들은 m_handle_macd 및 m_handle_ema 클래스 멤버에 저장됩니다.

      생성된 지표의 핸들은 계산된 데이터의 양을 확인하는 데 사용되고(BarsCalculated) 및 Processing() 메서드의 지표 값(CopyBuffer)을 얻는데 사용됩니다.


      3.7. CSampleExpert class의 LongClosed() 메서드

      //+------------------------------------------------------------------+
      //| 매수 포지션을 청산하기 위한 조건을 체크                                 |
      //+------------------------------------------------------------------+
      bool CSampleExpert::LongClosed(void)
        {
         bool res=false;
      //--- 포지션을 청산하는가?
         if(m_macd_current>0)
            if(m_macd_current<m_signal_current && m_macd_previous>m_signal_previous)
               if(m_macd_current>m_macd_close_level)
                 {
                  //--- 포지션 청산
                  if(m_trade.PositionClose(Symbol()))
                     printf("Long position by %s to be closed",Symbol());
                  else
                     printf("Error closing position by %s : '%s'",Symbol(),m_trade.ResultComment());
                  res=true;
                 }
      //--- 결과 반환
         return(res);
        }

      LongClosed() 메서드는 포지션의 청산 조건이 충족되면 true를 반환하고 진입한 매수 포지션을 청산합니다.

      1. m_macd_current>0 - MACD 지표의 메인 라인의 현재 값이 양수입니다(MACD 히스토그램이 0 라인 위에 있음).
      2. m_macd_current<m_signal_current && m_macd_previous> m_signal_previous - MACD 지표의 메인 라인이 시그널 라인을 하향 교차했습니다.
      3. m_macd_current>m_macd_close_level - MACD 지표의 메인 라인의 현재 값이 m_macd_close_level보다 큽니다.


      3.8. CSampleExpert 클래스의 ShortClosed() 메서드

      //+------------------------------------------------------------------+
      //| 매도 포지션을 청산할 조건을 체크                                      |
      //+------------------------------------------------------------------+
      bool CSampleExpert::ShortClosed(void)
        {
         bool res=false;
      //--- 포지션을 청산 하는가?
         if(m_macd_current<0)
            if(m_macd_current>m_signal_current && m_macd_previous<m_signal_previous)
               if(MathAbs(m_macd_current)>m_macd_close_level)
                 {
                  //--- 포지션 청산
                  if(m_trade.PositionClose(Symbol()))
                     printf("Short position by %s to be closed",Symbol());
                  else
                     printf("Error closing position by %s : '%s'",Symbol(),m_trade.ResultComment());
                  res=true;
                 }
      //--- 결과를 반환
         return(res);
        }

      ShortClosed() 메소드는 매도 포지션을 청산하기 위한 포지션이 충족되면 true를 반환하고 매도 포지션을 청산합니다.

      1. m_macd_current<0 - MACD 지표의 메인 라인의 현재 값이 음수입니다(MACD 히스토그램이 0 라인 아래에 있음).
      2. m_macd_current>m_signal_current && m_macd_previous <m_signal_previous - MACD 지표의 메인 라인이 시그널 라인을 교차했습니다.
      3. MathAbs(m_macd_current)>m_macd_close_level - MACD 지표의 메인 라인의 현재 값이 m_macd_close_level보다 큽니다.


      3.9. CSampleExpert class의 LongModified() 메서드

      //+------------------------------------------------------------------+
      //| 매수 포지션을 수정 하기 위한 조건을 체크                               |
      //+------------------------------------------------------------------+
      bool CSampleExpert::LongModified(void)
        {
         bool res=false;
      //--- Trailing Stop이 필요하다면 체크
         if(InpTrailingStop>0)
           {
            if(m_symbol.Bid()-m_position.PriceOpen()>m_adjusted_point*InpTrailingStop)
              {
               double sl=NormalizeDouble(m_symbol.Bid()-m_traling_stop,m_symbol.Digits());
               double tp=m_position.TakeProfit();
               if(m_position.StopLoss()<sl || m_position.StopLoss()==0.0)
                 {
                  //--- Stop Loss와 Take Profit을 수정
                  if(m_trade.PositionModify(Symbol(),sl,tp))
                     printf("Long position by %s to be modified",Symbol());
                  else
                    {
                     printf("Error modifying position by %s : '%s'",Symbol(),m_trade.ResultComment());
                     printf("Modify parameters : SL=%f,TP=%f",sl,tp);
                    }
                  res=true;
                 }
              }
           }
      //--- 결과를 반환
         return(res);
        }

      LongModified() 메서드는 롱 포지션을 수정 할 조건이 충족되면 true를 반환하고 포지션의 스탑로스 값을 수정합니다. InpTrailingStop>0의 값이면 가격이 진입한 가격에서 InpTrailingStop을 통과하는 것을 통해 포지션의 방향을 체크합니다. 다음으로, 새로운 스탑 로스 수준의 값이 계산되고 오픈 포지션의 스탑 로스 매개변수가 수정됩니다.


      3.10. CSampleExpert 클래스의 ShortModified 메서드

      //+------------------------------------------------------------------+
      //| 매수 포지션을 수정 하기 위한 조건을 체크                               |
      //+------------------------------------------------------------------+
      bool CSampleExpert::ShortModified(void)
        {
         bool   res=false;
      //--- Trailing Stop이 필요하다면 체크
         if(InpTrailingStop>0)
           {
            if((m_position.PriceOpen()-m_symbol.Ask())>(m_adjusted_point*InpTrailingStop))
              {
               double sl=NormalizeDouble(m_symbol.Ask()+m_traling_stop,m_symbol.Digits());
               double tp=m_position.TakeProfit();
               if(m_position.StopLoss()>sl || m_position.StopLoss()==0.0)
                 {
                  //--- Stop Loss와 Take Profit를 수정
                  if(m_trade.PositionModify(Symbol(),sl,tp))
                     printf("Short position by %s to be modified",Symbol());
                  else
                    {
                     printf("Error modifying position by %s : '%s'",Symbol(),m_trade.ResultComment());
                     printf("Modify parameters : SL=%f,TP=%f",sl,tp);
                    }
                  res=true;
                 }
              }
           }
      //--- 결과를 반환
         return(res);
        }

      ShortModified() 메서드는 매도 포지션의 수정 조건이 충족되면 true를 반환하고 포지션의 손절매 값을 수정합니다. InpTrailingStop>0이면 가격이 진입한 가격에서 InpTrailingStop을 통과한다는 것을 통해 포지션의 방향을 체크합니다. 다음으로, 새로운 스탑 로스 수준의 값이 계산되고 오픈 포지션의 스탑 로스 매개변수가 수정됩니다.


      3.11. CSampleExpert 클래스의 LongOpened() 메서드

      //+------------------------------------------------------------------+
      //| 매수 포지션 진입 체크                                               |
      //+------------------------------------------------------------------+
      bool CSampleExpert::LongOpened(void)
        {
         bool res=false;
      //--- 매수 포지션 진입 조건을 체크
         if(m_macd_current<0)
            if(m_macd_current>m_signal_current && m_macd_previous<m_signal_previous)
               if(MathAbs(m_macd_current)>(m_macd_open_level) && m_ema_current>m_ema_previous)
                 {
                  double price=m_symbol.Ask();
                  double tp   =m_symbol.Bid()+m_take_profit;
                  //--- 프리 마진을 체크
                  if(m_account.FreeMarginCheck(Symbol(),ORDER_TYPE_BUY,InpLots,price)<0.0)
                     printf("We have no money. Free Margin = %f",m_account.FreeMargin());
                  else
                    {
                     //--- 매수 포지션 진입
                     if(m_trade.PositionOpen(Symbol(),ORDER_TYPE_BUY,InpLots,price,0.0,tp))
                        printf("Position by %s to be opened",Symbol());
                     else
                       {
                        printf("Error opening BUY position by %s : '%s'",Symbol(),m_trade.ResultComment());
                        printf("Open parameters : price=%f,TP=%f",price,tp);
                       }
                    }
                  res=true;
                 }
      //--- 결과 반환
         return(res);
        }

      LongOpened() 메서드는 매수 포지션에 진입할 조건이 충족되면 true를 반환하고 매수 포지션에 진입합니다.

      1. m_macd_current<0 - MACD 지표 메인 라인의 현재 값이 음수입니다(MACD 히스토그램이 0 라인 아래에 있음).
      2. m_macd_current>m_signal_current && m_macd_previous <m_signal_previous - MACD 지표 메인 라인이 시그널 라인을 교차했습니다;
      3. MathAbs(m_macd_current)>m_macd_open_level - MACD 지표의 메인 라인의 현재 값이 m_macd_open_level보다 큽니다.
      4. m_ema_current>m_ema_previous - ema 상승.

      모든 조건이 충족되면 프리 마진이 확인됩니다(CA계정정보 표준 라이브러리 클래스의 FreeMarginCheck() 메서드 및 롱 포지션은 CTrade 클래스의 PositionOpen() 메서드를 사용하여 열립니다.


      3.12. CSampleExpert 클래스의 ShortOpened 메서드

      //+------------------------------------------------------------------+
      //| 매도 포지션 진입 체크                                               |
      //+------------------------------------------------------------------+
      bool CSampleExpert::ShortOpened(void)
        {
         bool res=false;
      //--- 매도 포지션 진입 조건을 체크
         if(m_macd_current>0)
            if(m_macd_current<m_signal_current && m_macd_previous>m_signal_previous)
               if(m_macd_current>(m_macd_open_level) && m_ema_current<m_ema_previous)
                 {
                  double price=m_symbol.Bid();
                  double tp   =m_symbol.Ask()-m_take_profit;
                  //--- 프리 마진 체크
                  if(m_account.FreeMarginCheck(Symbol(),ORDER_TYPE_SELL,InpLots,price)<0.0)
                     printf("We have no money. Free Margin = %f",m_account.FreeMargin());
                  else
                    {
                     //--- 매도 포지션 진입
                     if(m_trade.PositionOpen(Symbol(),ORDER_TYPE_SELL,InpLots,price,0.0,tp))
                        printf("Position by %s to be opened",Symbol());
                     else
                       {
                        printf("Error opening SELL position by %s : '%s'",Symbol(),m_trade.ResultComment());
                        printf("Open parameters : price=%f,TP=%f",price,tp);
                       }
                    }
                  res=true;
                 }
      //--- 결과 반환
         return(res);
        }

      401: Access Denied

      1. m_macd_current>0 - MACD 지표의 메인 라인의 현재 값이 양수입니다(MACD 히스토그램이 0 라인 위에 있음).
      2. m_macd_current<m_signal_current && m_macd_previous> m_signal_previous - MACD 지표의 메인 라인이 시그널 라인을 하향 교차했습니다.
      3. m_macd_current>m_macd_open_level - MACD 메인 라인의 현재 값이 m_macd_open_level보다 큽니다.
      4. m_ema_current<m_ema_previous - ema 하락.

      모든 조건이 충족되면 프리 마진이 확인됩니다(CA계정정보 표준 라이브러리 클래스의 FreeMarginCheck() 메서드 및 숏 포지션은 CTrade 클래스의 PositionOpen() 메서드를 사용하여 열립니다.


      3.13 CSampleExpert 클래스의 Processing() 메서드

      //+------------------------------------------------------------------+
      //| 포지션이 수행되면 메인 함수가 참을 반환                                |
      //+------------------------------------------------------------------+
      bool CSampleExpert::Processing(void)
        {
      //--- 쿼트 업데이트
         if(!m_symbol.RefreshRates())
            return(false);
      //--- 지표값 업데이트
         if(BarsCalculated(m_handle_macd)<2 || BarsCalculated(m_handle_ema)<2)
            return(false);
         if(CopyBuffer(m_handle_macd,0,0,2,m_buff_MACD_main)  !=2 ||
            CopyBuffer(m_handle_macd,1,0,2,m_buff_MACD_signal)!=2 ||
            CopyBuffer(m_handle_ema,0,0,2,m_buff_EMA)         !=2)
            return(false);
      //--- 지표의 사용을 간단하게 하고 빠르게 접근하기 위헤
      //--- 지표의 현재값이 내부 변수(클래스 멤버)에 저장
         m_macd_current   =m_buff_MACD_main[0];
         m_macd_previous  =m_buff_MACD_main[1];
         m_signal_current =m_buff_MACD_signal[0];
         m_signal_previous=m_buff_MACD_signal[1];
         m_ema_current    =m_buff_EMA[0];
         m_ema_previous   =m_buff_EMA[1];
      //--- 절확한 시장 진입이 중요함 그러나 정확하게 청산하는것이 더 중요함
      //--- 진입한 포지션이 있는지를 체크
         if(m_position.Select(Symbol()))
           {
            if(m_position.PositionType()==POSITION_TYPE_BUY)
              {
               //--- 필요시 매수 포지션의 수정이나 청산을 시도
               if(LongClosed())
                  return(true);
               if(LongModified())
                  return(true);
              }
            else
              {
               //--- 필요시 매도 포지션의 수정이나 청산을 시도
               if(ShortClosed())
                  return(true);
               if(ShortModified())
                  return(true);
              }
           }
      //--- 진입한 포지션이 없음
         else
           {
            //--- 조건을 체크하고 필요시 매수 포지션에 진입
            if(LongOpened())
               return(true);
            //--- 조건을 체크하고 필요시 매도 포지션에 진입
            if(ShortOpened())
               return(true);
           }
      //--- 포지션 처리 없이 중지
          return(false);
        }

      CSampleExpert 클래스의 Processing() 메서드는 Expert Advisor의 메서드입니다. Processing() 메서드는 OnTick() 이벤트 핸들러에서 호출되며 이 메서드의 연속된 호출 사이의 시간 간격이 모니터링됩니다(ExtTimeOut 초 이상)(섹션 2.2).

      RefreshRates()메서드를 호출하여 CSymbolInfo 클래스 쿼트가 업데이트 됩니다. BarsCalculated() 함수는 지표의 바의 수를 요청하는 데 사용됩니다.MACD이동 평균 지표의 계산에(섹션 3.6.); 바의 수가 2보다 작으면 함수를 종료하고 false를 반환합니다.

      다음으로 CopyBuffer 함수의 호출은 기술적 지표의 마지막 두 값(MACD의 메인 및 시그널 라인 및 이동 평균 값)을 요청합니다; 복사된 데이터 양이 2보다 작으면 함수를 종료합니다. 그 후 배열 m_buff_MACD_main[], m_buff_MACD_signal[] 및 m_buff_EMA[]에서 얻은 지표 값이 변수 m_macd_current, m_macd_previous, m_signal_current, m_signal_previous, m_ema_current 및 .m_ema_previous에 복사됩니다.

      다음 단계는 표준 라이브러리의 CPositionInfo 클래스를 통해 수행되는 포지션을 다루는 것입니다.. 만약Select() 메서드 호출이 true를 반환하고 즉, 현재 진입한 포지션이 있고, 해당 유형은 PositionType() 메서드를 사용하여 결정됩니다. 진입한 포지션의 유형에 따라 추가적인 작업이 수행됩니다.


      4. 백테스팅

      매개 변수의 최상의 값은 MetaTrader 5 터미널의 전략 테스터를 사용하여 찾을 수 있습니다.

      그림 3은 기본 설정으로 수행한 2013년 기간의 Expert Advisor의 테스트 결과를 보여줍니다.

      그림 3. MACD Sample Expert Advisor의 백테스팅 결과

      그림 3. MACD Sample Expert Advisor의 백테스팅 결과

      결론

      표준 팩에 포함된 메타 트레이더 5 터미널의 MACD Sample Expert Advisor는 EA 개발에 있어 객체 지향 접근 방식의 한 예입니다.


      MetaQuotes Ltd에서 러시아어로 번역함.
      원본 코드: https://www.mql5.com/ru/code/2154

      이동 평균 이동 평균

      이동 평균 Expert Advisor는 가격이 MA를 교차할 때 거래합니다.

      MQL5 마법사 - 모닝 이브닝 스타스 + RSI에 기반한 매매 신호 MQL5 마법사 - 모닝 이브닝 스타스 + RSI에 기반한 매매 신호

      Relative Strength Index (RSI)에 기반한 "모닝 스타/이브닝 스타" 캔들 스틱 패턴 매매 신호를 살펴봅니다. 이 전략에 기반한 Expert Advisor 코드는 MQL5 마법사를 사용하여 자동으로 생성될 수 있습니다.

      정규식 작업을 위한 MQL5의 RegularExpressions 정규식 작업을 위한 MQL5의 RegularExpressions

      정규식은 빠르고 유연한 텍스트 처리를 위한 공식적인 언어를 제공합니다. 각 정규식은 정규식 엔진이 소스 텍스트에서 일치 항목을 찾으려고 하는 패턴(마스크)입니다. 패턴은 하나 이상의 character literals, operators, constructs으로 구성됩니다.

      Demo_BitmapOffset (OBJPROP_XOFFSET and OBJPROP_YOFFSET) Demo_BitmapOffset (OBJPROP_XOFFSET and OBJPROP_YOFFSET)

      만약 현재 이미지의 일부만 표시하고 나머지는 숨길 필요가 있는 경우 이미지가 보이는 부분을 지정하여 이동하는 창을 사용할 수 있습니다.