English Русский 中文 Español Deutsch 日本語 Português Français Italiano Türkçe
사용자 지정 표시기에 기반한 거래 신호 발생기

사용자 지정 표시기에 기반한 거래 신호 발생기

MetaTrader 5 | 11 10월 2021, 17:20
253 0
Vladimir Karputov
Vladimir Karputov

소개

이 글에서는 사용자 지정 표시기를 기반으로 거래 신호 발생기를 만드는 방법을 알려드리겠습니다. 사용자 지정 표시기에 대한 고유한 거래 모델을 작성하는 방법을 볼 수 있습니다. 모델 0의 목적과 왜 IS_PATTERN_USAGE(0)-유형의 구조가 거래 신호 모듈에서 쓰이는지 설명하겠습니다.

문서에는 수정하려는 코드와 이미 수정한 코드라는 두 가지 유형의 코드가 사용됩니다. 수정된 코드는 다음과 같이 강조 표시됩니다:

//+------------------------------------------------------------------+
//|                                                     MySignal.mqh |
//|                              Copyright © 2012, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+

수정된 코드는 복사하여 거래 신호 발생기에 붙여넣을 코드입니다. 하이라이트를 통해 코드를 더 잘 이해해주길 바랍니다. 

 

1. 사용자 지정 표시기

당신이 오랫동안 사용하고 싶어 했던 표준 배송에 포함되지 않은 지표가 있을 것이라고 확신합니다. 그리고 그것은 당신이 거래 신호 모듈을 만들고자 하는 지표입니다. 저는 표준 전송의 MACD 표시기를 지표로 사용할 것입니다. 표시기의 위치는 다음과 같습니다: ...MQL5\Indicators\Examples\MACD.mq5

각 지표는 하나 이상의 시장 모델을 설명할 수 있습니다. 시장 모델은 지표 가치와 가격 가치의 특정 조합입니다. MACD 표시기에 사용할 수 있는 모델은 반전, 주선과 신호선의 교차(crossover), 0레벨의 교차, 발산(divergence) 및 이중 발산이 있습니다.

1.1 새로운 지표 모델.

우리가 지표에 사용할 수 있는 주어진 시장 모델에 만족하지 못하고 자체적인 지표 모델을 도입하고 싶다고 가정해 보겠습니다. 새로운 지표 모델 설명: MACD 지표가 0 라인 미만이고 가치가 증가하고 있다면 우리는 추가적인 성장을 기대할 수 있습니다.

그림 1: 사전 지표 성장 모델 

그림 1: 사전 지표 성장 모델

MACD 표시기가 0 라인 위에 있고 값이 감소하고 있는 경우, 우리는 다음과 같은 단기 포지션을 추가로 줄이고 열 수 있습니다.

 그림 2: 사전 지표 하강 모델

그림 2: 사전 지표 하강 모델 

그래서 우리는 사용자 지정 지표를 결정하고 지표와 지표의 설명에 대한 새로운 거래 모델을 마련했습니다. 코드 작성을 진행하겠습니다.

 

2. 사용자 지정 지표에 따라 거래 신호 발생기 작성하기

저희 발생기(generator)는 CExpertSignal 베이스 클래스에서 유래합니다. CExpertSignal 베이스 클래스는 거래 신호 생성기를 만들기 위한 클래스입니다. CExpertSignal 클래스에는 Expert Advisor가 시장 진입 방향에 대한 거래 신호 발생기의 표시를 볼 수 있는 일련의 공개적인(즉, 외부 액세스 가능) 방법이 포함되어 있습니다.

자체 거래 신호 발생기를 개발 중이므로 CExpertSignal 클래스에서 나와야하며, 가상 방법이 재정의된(해당 코드로 채워짐) 것과 관련있습니다.

 

3. 거래 신호 발생기의 클래스 생성하기

거래 신호 발생기는 기본적으로 ...MQL5\Include\Expert\Signal 폴더에 있습니다. 표준 라이브러리의 ...\Signal 폴더에 너무 많은 정보로 과부하 되지않도록, ...\Expert 폴더 아래에 새 폴더를 생성합니다. 그리고 그것을 \MySignals 이라고 부릅니다:

그림 3. 새로운 MySignals 폴더 생성하기  

그림 3. 새로운 MySignals 폴더 생성하기 

그런 다음 MQL5 마법사를 사용하여 include file(포함 파일)을 생성하겠습니다. MetaEditor의 파일 메뉴에서 "새로 만들기"를 선택한 다음 "Include File(*.mqh)"을 선택합니다.

그림 4. MQL5 마법사. include file 생성하기

그림 4. MQL5 마법사. include file 생성하기

신호 발생기 클래스의 이름은 MySignal이 됩니다. Include\Expert\MySignals\MySignal 아래에 위치합니다. 그것을 지정합니다:

그림 5. MQL5 마법사. include file 의 위치

그림 5. MQL5 마법사. include file 의 위치

"마침"을 클릭하면 MQL5 마법사가 빈 템플릿을 생성합니다. 지금부터 모든 작업을 수동으로 수행하고 데이터를 복사/붙여넣기 할 것입니다. 내부적으로 표준 라이브러리의 모든 신호가 거의 동일하다는 사실에 주목해 주시기 바랍니다. 거래 모델을 결정하는 데 사용되는 알고리즘만 다를 뿐입니다.

따라서, \Include\Expert\Signal 폴더에서 원하는 파일을 가져올 수 있습니다, 내용을 복사하여 템플릿에 붙여넣습니다. 그런 다음 거래 신호 생성기의 결과 파일 편집을 시작할 수 있습니다.

 

4. 거래 신호 발생기의 클래스에 대한 설명

템플릿으로서, 머리글만 제외하고 모두 복사하여, \Include\Expert\Signal\SignalEnvelopes.mqh file을 가져왔습니다:
//+------------------------------------------------------------------+
//|                                              SignalEnvelopes.mqh |
//|                   Copyright 2009-2013, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+

거의 비어 있는 MySignal.mqh 템플릿에 모두 붙여 넣었습니다. 이게 제가 얻은 것입니다: 

//+------------------------------------------------------------------+
//|                                                     MySignal.mqh |
//|                              Copyright © 2012, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#include <Expert\ExpertSignal.mqh>
// wizard description start
//+------------------------------------------------------------------+
//| Description of the class                                         |
//| Title=Signals of indicator 'Envelopes'                           |
//| Type=SignalAdvanced                                              |
//| Name=Envelopes                                                   |
//| ShortName=Envelopes                                              |
//| Class=CSignalEnvelopes                                           |
//| Page=signal_envelopes                                            |
//| Parameter=PeriodMA,int,45,Period of averaging                    |
//| Parameter=Shift,int,0,Time shift                                 |
//| Parameter=Method,ENUM_MA_METHOD,MODE_SMA,Method of averaging     |
//| Parameter=Applied,ENUM_APPLIED_PRICE,PRICE_CLOSE,Prices series   |
//| Parameter=Deviation,double,0.15,Deviation                        |
//+------------------------------------------------------------------+
// wizard description end
//+------------------------------------------------------------------+
//| Class CSignalEnvelopes.                                          |
//| Purpose: Class of generator of trade signals based on            |
//|          the 'Envelopes' indicator.                              |
//| It is derived from the CExpertSignal class.                      |
//+------------------------------------------------------------------+
class CSignalEnvelopes : public CExpertSignal
  {
protected:
   CiEnvelopes       m_env;            // object-indicator
   //--- adjusted parameters
   int               m_ma_period;      // the "period of averaging" parameter of the indicator
   int               m_ma_shift;       // the "time shift" parameter of the indicator
   ENUM_MA_METHOD    m_ma_method;      // the "method of averaging" parameter of the indicator
   ENUM_APPLIED_PRICE m_ma_applied;    // the "object of averaging" parameter of the indicator
   double            m_deviation;      // the "deviation" parameter of the indicator
   double            m_limit_in;       // threshold sensitivity of the 'rollback zone'
   double            m_limit_out;      // threshold sensitivity of the 'break through zone'
   //--- "weights" of market models (0-100)
   int               m_pattern_0;      // model 0 "price is near the necessary border of the envelope"
   int               m_pattern_1;      // model 1 "price crossed a border of the envelope"

public:
                     CSignalEnvelopes(void);
                    ~CSignalEnvelopes(void);
   //--- methods of setting adjustable parameters
   void              PeriodMA(int value)                 { m_ma_period=value;        }
   void              Shift(int value)                    { m_ma_shift=value;         }
   void              Method(ENUM_MA_METHOD value)        { m_ma_method=value;        }
   void              Applied(ENUM_APPLIED_PRICE value)   { m_ma_applied=value;       }
   void              Deviation(double value)             { m_deviation=value;        }
   void              LimitIn(double value)               { m_limit_in=value;         }
   void              LimitOut(double value)              { m_limit_out=value;        }
   //--- methods of adjusting "weights" of market models
   void              Pattern_0(int value)                { m_pattern_0=value;        }
   void              Pattern_1(int value)                { m_pattern_1=value;        }
   //--- method of verification of settings
   virtual bool      ValidationSettings(void);
   //--- method of creating the indicator and time series
   virtual bool      InitIndicators(CIndicators *indicators);
   //--- methods of checking if the market models are formed
   virtual int       LongCondition(void);
   virtual int       ShortCondition(void);

protected:
   //--- method of initialization of the indicator
   bool              InitMA(CIndicators *indicators);
   //--- methods of getting data
   double            Upper(int ind)                      { return(m_env.Upper(ind)); }
   double            Lower(int ind)                      { return(m_env.Lower(ind)); }
  };
//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+
CSignalEnvelopes::CSignalEnvelopes(void) : m_ma_period(45),
                                           m_ma_shift(0),
                                           m_ma_method(MODE_SMA),
                                           m_ma_applied(PRICE_CLOSE),
                                           m_deviation(0.15),
                                           m_limit_in(0.2),
                                           m_limit_out(0.2),
                                           m_pattern_0(90),
                                           m_pattern_1(70)
  {
//--- initialization of protected data
   m_used_series=USE_SERIES_OPEN+USE_SERIES_HIGH+USE_SERIES_LOW+USE_SERIES_CLOSE;
  }
//+------------------------------------------------------------------+
//| Destructor                                                       |
//+------------------------------------------------------------------+
CSignalEnvelopes::~CSignalEnvelopes(void)
  {
  }
//+------------------------------------------------------------------+
//| Validation settings protected data.                              |
//+------------------------------------------------------------------+
bool CSignalEnvelopes::ValidationSettings(void)
  {
//--- validation settings of additional filters
   if(!CExpertSignal::ValidationSettings())
      return(false);
//--- initial data checks
   if(m_ma_period<=0)
     {
      printf(__FUNCTION__+": period MA must be greater than 0");
      return(false);
     }
//--- ok
   return(true);
  }
//+------------------------------------------------------------------+
//| Create indicators.                                               |
//+------------------------------------------------------------------+
bool CSignalEnvelopes::InitIndicators(CIndicators *indicators)
  {
//--- check pointer
   if(indicators==NULL)
      return(false);
//--- initialization of indicators and time series of additional filters
   if(!CExpertSignal::InitIndicators(indicators))
      return(false);
//--- create and initialize MA indicator
   if(!InitMA(indicators))
      return(false);
//--- ok
   return(true);
  }
//+------------------------------------------------------------------+
//| Initialize MA indicators.                                        |
//+------------------------------------------------------------------+
bool CSignalEnvelopes::InitMA(CIndicators *indicators)
  {
//--- check pointer
   if(indicators==NULL)
      return(false);
//--- add object to collection
   if(!indicators.Add(GetPointer(m_env)))
     {
      printf(__FUNCTION__+": error adding object");
      return(false);
     }
//--- initialize object
   if(!m_env.Create(m_symbol.Name(),m_period,m_ma_period,m_ma_shift,m_ma_method,m_ma_applied,m_deviation))
     {
      printf(__FUNCTION__+": error initializing object");
      return(false);
     }
//--- ok
   return(true);
  }
//+------------------------------------------------------------------+
//| "Voting" that the price will grow.                               |
//+------------------------------------------------------------------+
int CSignalEnvelopes::LongCondition(void)
  {
   int result=0;
   int idx   =StartIndex();
   double close=Close(idx);
   double upper=Upper(idx);
   double lower=Lower(idx);
   double width=upper-lower;
//--- if the model 0 is used and price is in the rollback zone, then there is a condition for buying
   if(IS_PATTERN_USAGE(0) && close<lower+m_limit_in*width && close>lower-m_limit_out*width)
      result=m_pattern_0;
//--- if the model 1 is used and price is above the rollback zone, then there is a condition for buying
   if(IS_PATTERN_USAGE(1) && close>upper+m_limit_out*width)
      result=m_pattern_1;
//--- return the result
   return(result);
  }
//+------------------------------------------------------------------+
//| "Voting" that the price will fall.                               |
//+------------------------------------------------------------------+
int CSignalEnvelopes::ShortCondition(void)
  {
   int result  =0;
   int idx     =StartIndex();
   double close=Close(idx);
   double upper=Upper(idx);
   double lower=Lower(idx);
   double width=upper-lower;
//--- if the model 0 is used and price is in the rollback zone, then there is a condition for selling
   if(IS_PATTERN_USAGE(0) && close>upper-m_limit_in*width && close<upper+m_limit_out*width)
      result=m_pattern_0;
//--- if the model 1 is used and price is above the rollback zone, then there is a condition for selling
   if(IS_PATTERN_USAGE(1) && close<lower-m_limit_out*width)
      result=m_pattern_1;
//--- return the result
   return(result);
  }
//+------------------------------------------------------------------+

라인 6를 주목하세요:

#include <Expert\ExpertSignal.mqh>

여기서는 전 처리 장치(preprocessor)에 템플릿에 거래 신호 발생기의 생성을 위한 CExpertSignal 베이스 클래스를 포함하도록 명령합니다.

템플릿 편집을 계속하겠습니다. 나중에 MQL5 마법사에서 템플릿을 볼 수 있도록 클래스 설명을 변경해야 합니다:

//+------------------------------------------------------------------+
//| Description of the class                                         |
//| Title=Signals of indicator 'Envelopes'                           |
//| Type=SignalAdvanced                                              |
//| Name=Envelopes                                                   |
//| ShortName=Envelopes                                              |
//| Class=CSignalEnvelopes                                           |
//| Page=signal_envelopes                                            |
//| Parameter=PeriodMA,int,45,Period of averaging                    |
//| Parameter=Shift,int,0,Time shift                                 |
//| Parameter=Method,ENUM_MA_METHOD,MODE_SMA,Method of averaging     |
//| Parameter=Applied,ENUM_APPLIED_PRICE,PRICE_CLOSE,Prices series   |
//| Parameter=Deviation,double,0.15,Deviation                        |
//+------------------------------------------------------------------+

자, 봅시다. 그 라인

//| Title=Signals of indicator 'Envelopes'                           |

 MQL5 마법사에 표시될 신호 클래스의 이름이 나와 있습니다. 우리는 이 이름을 다음과 같은 것으로 바꿀 것입니다.

//| Title=Signal of the 'Custom Indicator' indicator             |

다음 줄: 

//| Name=Envelopes                                                   |

거래 신호 클래스의 변수를 설명하는 이름을 나타냅니다. 이 설명은 MQL5 마법사에서 사용됩니다. 이 줄을 다음과 같이 수정하겠습니다:

//| Name=MyCustomIndicator                                           |

다음 줄:

//| ShortName=Envelopes                                              |

이 매개변수에 동일한 이름을 지정합니다:

//| ShortName=MyCustomIndicator                                      |

다음 행은 클래스 이름을 설정합니다:

//| Class=CSignalEnvelopes                                           |

이 매개변수의 이름을 바꿉니다:

//| Class=CSignalMyCustInd                                           |

다음 매개 변수는 그대로 둡니다.

//| Page=signal_envelopes                                            |

다음 매개 변수 그룹은 거래 신호 발생기의 기초가 되는 지표의 매개 변수에 대한 설명을 담당합니다. 앞에서 언급했듯이, 저는 사용자 지정 지표기로서, ...MQL5\Indicators\Examples\MACD.mq5을 사용할 것입니다. 다음과 같은 매개 변수가 있습니다:

//--- input parameters
input int                InpFastEMA=12;               // Fast EMA period
input int                InpSlowEMA=26;               // Slow EMA period
input int                InpSignalSMA=9;              // Signal SMA period
input ENUM_APPLIED_PRICE  InpAppliedPrice=PRICE_CLOSE; // Applied price

4.1 매개 변수 설명 블록 

위에 제공된 매개 변수는 MACD.mq5.에만 적용됩니다. 사용자 지정 표시기의 매개 변수가 완전히 다를 수 있습니다. 여기서 중요한 것은 지표 매개변수를 거래 신호 클래스의 설명과 일치시키는 것입니다. 고려 중인 사용자 지정 표시기에 대한 거래 신호 클래스의 매개변수 설명 블록, MACD.mq5, 은 다음과 같습니다:

//| Parameter=PeriodFast,int,12,Period of fast EMA                   |
//| Parameter=PeriodSlow,int,24,Period of slow EMA                   |
//| Parameter=PeriodSignal,int,9,Period of averaging of difference   |
//| Parameter=Applied,ENUM_APPLIED_PRICE,PRICE_CLOSE,Prices series   |

이제 표시기의 매개 변수가 클래스 설명 블록의 설명과 어떻게 일치하는지 살펴봅니다. 모든 수정 후, 우리 클래스의 설명 블록은 다음과 같습니다:

//+------------------------------------------------------------------+
//| Description of the class                                         |
//| Title=Signal of the 'Custom Indicator' indicator                 |
//| Type=SignalAdvanced                                              |
//| Name=MyCustomIndicator                                           |
//| ShortName=MyCustomIndicator                                      |
//| Class=CSignalMyCustInd                                           |
//| Page=signal_envelopes                                            |
//| Parameter=PeriodFast,int,12,Period of fast EMA                   |
//| Parameter=PeriodSlow,int,24,Period of slow EMA                   |
//| Parameter=PeriodSignal,int,9,Period of averaging of difference   |
//| Parameter=Applied,ENUM_APPLIED_PRICE,PRICE_CLOSE,Prices series   |
//+------------------------------------------------------------------+

프로그래밍에서는 코드에 주석을 달아 시간이 흐른 후 코드를 다시 찾을 때 코드를 쉽게 이해할 수 있도록 하는 것이 좋은 관행으로 여겨집니다. 따라서 다음 블록을 수정하겠습니다:

//+------------------------------------------------------------------+
//| Class CSignalEnvelopes.                                          |
//| Purpose: Class of generator of trade signals based on            |
//|          the 'Envelopes' indicator.                              |
//| It is derived from the CExpertSignal class.                      |
//+------------------------------------------------------------------+

이 클래스의 설명과 일치하게 합니다:

//+------------------------------------------------------------------+
//| Class CSignalMyCustInd.                                          |
//| Purpose: Class of the trading signal generator based on          |
//|          the custom indicator.                                   |
//| It is derived from the CExpertSignal class.                      |
//+------------------------------------------------------------------+

혼동을 방지하려면 모든 "CSignalEnvelopes" 값을 with "CSignalMyCustInd"로 대체해야 합니다.

그림 6. CSignalEnvelopes 를 CSignalMyCustInd 로 대체하기

그림 6. CSignalEnvelopes 를 CSignalMyCustInd 로 대체하기 

이제 몇 가지 이론적 측면을 살펴보겠습니다.

 

5. The CiCustom 클래스

사용자 지정 지표의 거래 지표 클래스 코드를 계속 작업하려면 CiCustom 클래스가 필요합니다. CiCustom 클래스는 사용자 지정 표시기로 작업하기 위해 특별히 생성되었습니다. CiCustom 클래스는 사용자 지정 표시기 데이터를 생성, 설정 및 액세스할 수 있는 기능을 제공합니다.

 

6. CIndicators 클래스.

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

특별히 저희는 CIndicators 클래스에 관심이 있습니다. 왜냐하면 창조적 방법이기 때문입니다. 이 방법은 지정된 매개 변수를 사용하여 지정된 유형의 표시기를 만듭니다.

 

7. 거래 신호 클래스를 계속 작성합니다.

우리가 수정할 다음 코드 블록(28-42)은 다음과 같습니다:
class CSignalMyCustInd : public CExpertSignal
  {
protected:
   CiEnvelopes       m_env;            // object-indicator
   //--- adjusted parameters
   int               m_ma_period;      // the "period of averaging" parameter of the indicator
   int               m_ma_shift;       // the "time shift" parameter of the indicator
   ENUM_MA_METHOD    m_ma_method;      // the "method of averaging" parameter of the indicator
   ENUM_APPLIED_PRICE m_ma_applied;    // the "object of averaging" parameter of the indicator
   double            m_deviation;      // the "deviation" parameter of the indicator
   double            m_limit_in;       // threshold sensitivity of the 'rollback zone'
   double            m_limit_out;      // threshold sensitivity of the 'break through zone'
   //--- "weights" of market models (0-100)
   int               m_pattern_0;      // model 0 "price is near the necessary border of the envelope"
   int               m_pattern_1;      // model 1 "price crossed a border of the envelope"

 

8. 거래 신호 발생기에서 사용자 지정 표시기 생성

위에 제공된 코드 블록을 확인하십시오. 그 라인

   CiEnvelopes       m_env;            // object-indicator

객체 - CiEnvelopes 클래스 지표를 선언합니다. CiEnvelopes 는 표준 라이브러리의 기술 지표로 작업하는 클래스입니다. CiEnvelopes 클래스는 표준 라이브러리의 기술 표시기를 기반으로 만들어졌습니다. 하지만, 우리는 우리의 커스텀 지표를 기반으로 생성기(generator) 코드를 작성하고 있습니다. 따라서 표준 라이브러리에는 당사 또는 귀사의 사용자 지정 표시기에 대한 미리 만들어진 클래스가 없습니다. 저희가 할 수 있는 것은 CiCustom 클래스를 사용하는 것입니다.

우리의 지표를 CiCustom 클래스로 선언하겠습니다:

   CiCustom          m_mci;            // indicator object "MyCustomIndicator"

8.1 네 개의 변수

클래스에서 매개변수 설명 블록을 기억하십니까? 그 설명에는 세 가지 변수가 있었습니다. 이제 제너레이터 클래스의 보호된 영역에서 값을 4개의 매개 변수로 전달하는 네개의 변수를 선언합니다:

   //--- adjustable parameters
   int               m_period_fast;    // "fast EMA period"
   int               m_period_slow;    // "slow EMA period"
   int               m_period_signal;  // "difference averaging period"
   ENUM_APPLIED_PRICE m_applied;       // "price type"

다음 코드 블록:

   //--- "weights" of market models (0-100)
   int               m_pattern_0;      // model 0 "price is near the necessary border of the envelope"
   int               m_pattern_1;      // model 1 "price crossed a border of the envelope"

이 코드는 거래 신호 발생기의 거래 모델에 "가중치"를 부여하는 변수를 선언합니다. "가중치" 블록을 다음 코드로 대체합니다:

   //--- "weights" of the market models (0-100)
   int               m_pattern_0;      // model 0 "the oscillator has required direction"
   int               m_pattern_1;      // model 1 "the indicator is gaining momentum - buy; the indicator is falling - sell"

 

9. 모델 0

기억하시겠지만, 기사의 첫머리에 거래 신호 발생기에 의해 생성될 새로운 모델 한가지만 기술하기로 결정되었습니다. 그러나 위의 코드에서 두 가지 시장 모델(모델 0과 모델 1)을 지정했습니다. 여기서 모델 0은 중요한 보조 모델입니다. 보류 중인 주문과 거래할 때 필요합니다. 적용 시 모델 0은 보류 중인 주문이 가격과 함께 이동하도록 보장합니다. 거래 신호 발생기와 다음 조건을 살펴보겠습니다:

  • MACD 사용자 지정 표시기가 0 라인 아래에 있습니다,
  • 그 가치가 증가하고 있습니다,
  • 우리는 바 오프닝(bar opening) 가격에서 50포인트를 정해 놓은 미결(보류 중) 주문으로 거래하고 있습니다.

이 조건들이 우리의 거래 모델을 완벽하게 설명해줍니다. 상황은 다음과 같이 진행될 것입니다: 우리의 거래 모델 조건은 바(bar)가 나타나면 확인할 것입니다. 1. 우리가 가진 것: 현재 MACD는 제로선을 밑돌고 있지만 점차 탄력이 붙고 있습니다. 이것은 구매 신호에 해당합니다. 따라서, 미결 구매 중지 주문을 작성합니다:

그림 7. 보류 중인 구매 중지 주문 배치하기
 그림 7. 보류 중인 구매 중지 주문 배치하기 

다음 바(bar)가 나타납니다. 바(bar) 2의 상태 검사에서 MACD가 0 미만이고 하강 중임을 확인합니다. 우리의 거래 모델에 따르면, 현재 매수 또는 매도 조건은 없습니다. 그러나, 주목하세요: CExpertSignal class 클래스 로직에 대한, 구매 또는 판매 조건이 없으므로 보류 중인 모든 주문을 삭제해야 합니다. 이 경우, 가격이 갑자기 그리고 급격히 상승할 경우, 미결 주문이 없어 시장 진입 기회를 오래 놓치게 됩니다.

이것이 보조 모델 0이 매우 유용한 것으로 보이는 부분입니다. 다음과 같은 경우 보조 모델 0이 적용됩니다:

  • MACD 사용자 지정 표시기가 0 라인 아래에 있습니다.

그래서 우리는 보류 중인 구매 중지 주문을 할 수 있습니다. 우리는 바(bar) 오픈 가격에서 50포인트를 주문하기 때문에, 실제로 가격 이동에 따라 보류 중인 구매 중지 주문을 이동하기만 하면 됩니다.

그림 8. 구매 중지 주문을 아래로 이동하기
  그림 8. 구매 중지 주문을 아래로 이동하기 

따라서 보조 모델 0을 사용하여 가격 이동에 따라 보류 중인 주문을 이동할 수 있습니다.

 

10. 템플릿 코드의 추가 수정 사항

다음에 수정할 코드 블록은 다음과 같습니다: 
public:
                     CSignalMyCustInd(void);
                    ~CSignalMyCustInd(void);
   //--- methods of setting adjustable parameters
   void              PeriodMA(int value)                 { m_ma_period=value;        }
   void              Shift(int value)                    { m_ma_shift=value;         }
   void              Method(ENUM_MA_METHOD value)        { m_ma_method=value;        }
   void              Applied(ENUM_APPLIED_PRICE value)   { m_ma_applied=value;       }
   void              Deviation(double value)             { m_deviation=value;        }
   void              LimitIn(double value)               { m_limit_in=value;         }
   void              LimitOut(double value)              { m_limit_out=value;        }
   //--- methods of adjusting "weights" of market models
   void              Pattern_0(int value)                { m_pattern_0=value;        }
   void              Pattern_1(int value)                { m_pattern_1=value;        }
   //--- method of verification of settings
   virtual bool      ValidationSettings(void);
   //--- method of creating the indicator and time series
   virtual bool      InitIndicators(CIndicators *indicators);
   //--- methods of checking if the market models are formed
   virtual int       LongCondition(void);
   virtual int       ShortCondition(void);

 

이 블록에서는 조정 가능한 파라미터 설정 방법, 거래 모델의 가중치 조정 방법, 설정 검증 방법, 지표 초기화 방법, 시장 모델 생성 여부 확인 방법을 선언합니다.

조정 가능한 매개변수에서 4개 변수를 선언했다는 점을 고려하면, 매개변수 설정 방법 블록은 다음과 같습니다:

   //--- methods of setting adjustable parameters
   void              PeriodFast(int value)               { m_period_fast=value;           }
   void              PeriodSlow(int value)               { m_period_slow=value;           }
   void              PeriodSignal(int value)             { m_period_signal=value;         }
   void              Applied(ENUM_APPLIED_PRICE value)   { m_applied=value;               }

다음 코드 조각은 변경되지 않은 상태로 유지됩니다:

   //--- methods of adjusting "weights" of market models
   void              Pattern_0(int value)                { m_pattern_0=value;        }
   void              Pattern_1(int value)                { m_pattern_1=value;        }
   //--- method of verification of settings
   virtual bool      ValidationSettings(void);
   //--- method of creating the indicator and time series
   virtual bool      InitIndicators(CIndicators *indicators);
   //--- methods of checking if the market models are generated
   virtual int       LongCondition(void);
   virtual int       ShortCondition(void);

다음에 수정할 코드 블록은 다음과 같습니다: 

protected:
   //--- method of initialization of the indicator
   bool              InitMA(CIndicators *indicators);
   //--- methods of getting data
   double            Upper(int ind)                      { return(m_env.Upper(ind)); }
   double            Lower(int ind)                      { return(m_env.Lower(ind)); }
  };

이 블록은 심하게 수정될 것입니다. 저는 GetData 방법을 사용하고 있습니다(CIndicator 클래스). 호출된 방법의 이름은 코드에 직접 제공됩니다:

protected:
   //--- indicator initialization method
   bool              InitMyCustomIndicator(CIndicators *indicators);
   //--- methods for getting data
   //- getting the indicator value
   double            Main(int ind) { return(m_mci.GetData(0,ind));      }
   //- getting the signal line value
   double            Signal(int ind) { return(m_mci.GetData(1,ind));    }
   //- difference between two successive indicator values
   double            DiffMain(int ind) { return(Main(ind)-Main(ind+1)); }
   int               StateMain(int ind);
   double            State(int ind) { return(Main(ind)-Signal(ind)); }
   //- preparing data for the search
   bool              ExtState(int ind);
   //- searching the market model with the specified parameters
   bool              CompareMaps(int map,int count,bool minimax=false,int start=0);
  };

 다음 코드 블록은 생성자입니다.

//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+
CSignalMyCustInd::CSignalMyCustInd(void) : m_ma_period(45),
                                           m_ma_shift(0),
                                           m_ma_method(MODE_SMA),
                                           m_ma_applied(PRICE_CLOSE),
                                           m_deviation(0.15),
                                           m_limit_in(0.2),
                                           m_limit_out(0.2),
                                           m_pattern_0(90),
                                           m_pattern_1(70)
  {
//--- initialization of protected data
   m_used_series=USE_SERIES_OPEN+USE_SERIES_HIGH+USE_SERIES_LOW+USE_SERIES_CLOSE;
  }

생성자에서는 변수의 이름을 변경할 것입니다. 또한, 두 시리즈만 사용합니다: USE_SERIES_HIGH+USE_SERIES_LOW

//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+
CSignalMyCustInd::CSignalMyCustInd(void) : m_period_fast(12),
                                           m_period_slow(24),
                                           m_period_signal(9),
                                           m_applied(PRICE_CLOSE),
                                           m_pattern_0(10),
                                           m_pattern_1(50)
  {
//--- initialization of protected data
   m_used_series=USE_SERIES_HIGH+USE_SERIES_LOW;
  }

우리 클래스의 ValidationSettings 방법을 수정해 보겠습니다.

//+------------------------------------------------------------------+
//| Validation settings protected data.                              |
//+------------------------------------------------------------------+
bool CSignalMyCustInd::ValidationSettings(void)
  {
//--- validation settings of additional filters
   if(!CExpertSignal::ValidationSettings())
      return(false);
//--- initial data checks
   if(m_ma_period<=0)
     {
      printf(__FUNCTION__+": period MA must be greater than 0");
      return(false);
     }
//--- ok
   return(true);
  }

체크 블록에서는 지정된 사용자 지정 표시기의 주 조건을 확인합니다: m_period_fast>=m_period_slow

//+------------------------------------------------------------------+
//| Checking parameters of protected data                            |
//+------------------------------------------------------------------+
bool CSignalMyCustInd::ValidationSettings(void)
  {
//--- validation settings of additional filters
   if(!CExpertSignal::ValidationSettings())
      return(false);
//--- initial data checks
   if(m_period_fast>=m_period_slow)
     {
      printf(__FUNCTION__+": slow period must be greater than fast period");
      return(false);
     }
//--- ok
   return(true);
  }

다음 블록에서는 지표 생성을 다룹니다:

//+------------------------------------------------------------------+
//| Create indicators.                                               |
//+------------------------------------------------------------------+
bool CSignalMyCustInd::InitIndicators(CIndicators *indicators)
  {
//--- check pointer
   if(indicators==NULL)
      return(false);
//--- initialization of indicators and time series of additional filters
   if(!CExpertSignal::InitIndicators(indicators))
      return(false);
//--- create and initialize MA indicator
   if(!InitMA(indicators))
      return(false);
//--- ok
   return(true);
  }

사용자 지정 표시기에 적용됩니다: 

//+------------------------------------------------------------------+
//| Creation of indicators.                                          |
//+------------------------------------------------------------------+
bool CSignalMyCustInd::InitIndicators(CIndicators *indicators)
  {
//--- check of pointer is performed in the method of the parent class
//---
//--- initialization of indicators and time series of additional filters
   if(!CExpertSignal::InitIndicators(indicators))
      return(false);
//--- creation and initialization of the custom indicator
   if(!InitMyCustomIndicator(indicators))
      return(false);
//--- ok
   return(true);
  }

다음 블록은 표시기 초기화 블록입니다:

//+------------------------------------------------------------------+
//| Initialize MA indicators.                                        |
//+------------------------------------------------------------------+
bool CSignalMyCustInd::InitMA(CIndicators *indicators)
  {
//--- check pointer
   if(indicators==NULL)
      return(false);
//--- add object to collection
   if(!indicators.Add(GetPointer(m_env)))
     {
      printf(__FUNCTION__+": error adding object");
      return(false);
     }
//--- initialize object
   if(!m_env.Create(m_symbol.Name(),m_period,m_ma_period,m_ma_shift,m_ma_method,m_ma_applied,m_deviation))
     {
      printf(__FUNCTION__+": error initializing object");
      return(false);
     }
//--- ok
   return(true);
  }

먼저 컬렉션에 객체를 추가합니다. 그런 다음 지표의 매개변수를 설정하고 생성 방법(CIndicators 클래스)을 사용하여 사용자 지정 지표를 만듭니다:

//+------------------------------------------------------------------+
//| Initialization of indicators.                                    |
//+------------------------------------------------------------------+
bool CSignalMyCustInd::InitMyCustomIndicator(CIndicators *indicators)
  {
//--- add an object to the collection
   if(!indicators.Add(GetPointer(m_mci)))
     {
      printf(__FUNCTION__+": error adding object");
      return(false);
     }
//--- set parameters of the indicator
   MqlParam parameters[4];
//---
   parameters[0].type=TYPE_STRING;
   parameters[0].string_value="Examples\\MACD.ex5";
   parameters[1].type=TYPE_INT;
   parameters[1].integer_value=m_period_fast;
   parameters[2].type=TYPE_INT;
   parameters[2].integer_value=m_period_slow;
   parameters[3].type=TYPE_INT;
   parameters[3].integer_value=m_period_signal;
//--- object initialization
   if(!m_mci.Create(m_symbol.Name(),0,IND_CUSTOM,4,parameters))
     {
      printf(__FUNCTION__+": error initializing object");
      return(false);
     }
//--- number of buffers
   if(!m_mci.NumBuffers(4)) return(false);
//--- ok
   return(true);
  }

다음 블록은 구매 조건을 확인합니다:

//+------------------------------------------------------------------+
//| "Voting" that the price will grow.                               |
//+------------------------------------------------------------------+
int CSignalMyCustInd::LongCondition(void)
  {
   int result=0;
   int idx   =StartIndex();
   double close=Close(idx);
   double upper=Upper(idx);
   double lower=Lower(idx);
   double width=upper-lower;
//--- if the model 0 is used and price is in the rollback zone, then there is a condition for buying
   if(IS_PATTERN_USAGE(0) && close<lower+m_limit_in*width && close>lower-m_limit_out*width)
      result=m_pattern_0;
//--- if the model 1 is used and price is above the rollback zone, then there is a condition for buying
   if(IS_PATTERN_USAGE(1) && close>upper+m_limit_out*width)
      result=m_pattern_1;
//--- return the result
   return(result);
  }

모델 0 구현에 따르면, 두 가지 모델이 확인됩니다:  

//+------------------------------------------------------------------+
//| "Voting" that the price will grow.                               |
//+------------------------------------------------------------------+
int CSignalMyCustInd::LongCondition(void)
  {
   int result=0;
   int idx   =StartIndex();
//--- check direction of the main line
   if(DiffMain(idx)>0.0)
     {
      //--- the main line goes upwards, which confirms the possibility of the price growth
      if(IS_PATTERN_USAGE(0))
         result=m_pattern_0;      // "confirming" signal number 0
      //--- if the model 1 is used, look for a reverse of the main line
      if(IS_PATTERN_USAGE(1) && DiffMain(idx+1)<0.0)
         result=m_pattern_1;      // signal number 1
     }
//--- return the result
   return(result);
  }

다음은 판매 조건을 확인하는 블록입니다:  

//+------------------------------------------------------------------+
//| "Voting" that the price will fall.                               |
//+------------------------------------------------------------------+
int CSignalMyCustInd::ShortCondition(void)
  {
   int result  =0;
   int idx     =StartIndex();
   double close=Close(idx);
   double upper=Upper(idx);
   double lower=Lower(idx);
   double width=upper-lower;
//--- if the model 0 is used and price is in the rollback zone, then there is a condition for selling
   if(IS_PATTERN_USAGE(0) && close>upper-m_limit_in*width && close<upper+m_limit_out*width)
      result=m_pattern_0;
//--- if the model 1 is used and price is above the rollback zone, then there is a condition for selling
   if(IS_PATTERN_USAGE(1) && close<lower-m_limit_out*width)
      result=m_pattern_1;
//--- return the result
   return(result);
  }

모델 0 구현에 따르면, 두 가지 모델이 확인됩니다:  

//+------------------------------------------------------------------+
//| "Voting" that the price will fall.                               |
//+------------------------------------------------------------------+
int CSignalMyCustInd::ShortCondition(void)
  {
   int result=0;
   int idx   =StartIndex();
//--- check direction of the main line
   if(DiffMain(idx)<0.0)
     {
            //--- the main line gown downwards, which confirms the possibility of the price fall
      if(IS_PATTERN_USAGE(0))
         result=m_pattern_0;      // "confirming" signal number 0
      //--- if the model 1 is used, look for a reverse of the main line
      if(IS_PATTERN_USAGE(1) && DiffMain(idx+1)>0.0)
         result=m_pattern_1;      // signal number 1
     }
//--- return the result
   return(result);
  }

 

결론

이 기사가 사용자 지정 표시기를 기반으로 거래 신호 발생기를 만드는 방법을 이해하는 데 도움이 되었기를 바랍니다.


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

파일 첨부됨 |
mysignal.mqh (9.38 KB)
2013년 2분기 MQL5 시장 결과 2013년 2분기 MQL5 시장 결과
1.5년간 성공적으로 운영된 MQL5 Market은 거래 전략 및 기술 지표의 최대 거래처가 되었습니다. 전 세계 350여 명의 개발자가 제공하는 800여 개의 거래 애플리케이션을 제공합니다. 거래업체에서 이미 MetaTrader 5 터미널에 100,000개 이상의 거래 프로그램을 구입하여 다운로드했습니다.
2013년 1분기 MQL5 시장 결과 2013년 1분기 MQL5 시장 결과
창립 이래 무역로봇과 기술지표 MQL5 마켓에는 이미 580여 개의 제품을 발행한 250여 명의 개발자가 몰렸습니다. 그들의 제품을 팔아서 아주 큰 수익을 올린 일부 MQL5 마켓 셀러에게는 2013년 1분기가 꽤 성공적인 것으로 나타났습니다.
MetaTrader 4 및 MetaTrader 5 Trading 플랫폼을 통한 소셜 트레이딩 MetaTrader 4 및 MetaTrader 5 Trading 플랫폼을 통한 소셜 트레이딩
소셜 트레이딩이란 무엇입니까? 성공적인 거래자가 거래에 대한 모니터링을 할 수 있도록 하고 잠재적 투자자가 더 유망해 보이는 거래자의 성과를 모니터링하고 거래를 복사할 수 있는 기회를 갖는 것은 거래자와 투자자의 상호 유익한 협력입니다.
Jeremy Scott - 성공적인 MQL5 마켓 셀러 Jeremy Scott - 성공적인 MQL5 마켓 셀러
MQL5.community에서 Johnnypasado라는 닉네임으로 더 잘 알려진 Jeremy Scott은 저희의 MQL5 마켓 서비스에서 제품을 제공하는 것으로 유명해졌습니다. Jeremy는 이미 시장에서 수천 달러를 벌었고 그것이 한계는 아닙니다. 우리는 미래의 백만장자를 자세히 살펴보고 MQL5 마켓 셀러를 위한 몇 가지 조언을 받기로 했습니다.