無料でロボットをダウンロードする方法を見る
Telegram上で私たちを見つけてください。
私たちのファンページに参加してください
興味深いスクリプト?
それではリンクにそれを投稿してください。-
他の人にそれを評価してもらいます
記事を気に入りましたか?MetaTrader 5ターミナルの中でそれを試してみてください。
エキスパート

MACD Sample - MetaTrader 5のためのエキスパート

発行者:
MetaQuotes
ビュー:
7886
評価:
(51)
パブリッシュ済み:
2015.11.26 13:37
アップデート済み:
2016.11.22 07:34
MQL5フリーランス このコードに基づいたロボットまたはインジケーターが必要なら、フリーランスでご注文ください フリーランスに移動

MACDのサンプルEAは MetaTrader 5 に標準装備されています。また、MACDを使ったEAのサンプルでもあります。

MACDのファイル Sample.mq5 は terminal_data_folder\MQL5\Experts\Examples\MACD\"にあります。このEAは、EA開発におけるオブジェクト指向の一例です。

EAの構造とどのように機能するかを見てみましょう。


1 EA プロパティ

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 "It is important to make sure that the expert works with a normal"
#property description "chart and the user did not make any mistakes setting input"
#property description "variables (Lots, TakeProfit, TrailingStop) in our case,"
#property description "we check TakeProfit on a chart of more than 2*trend_period bars"

初めの5行はコメントです。後ろの7行が MQL5 のプロパティで(copyright, link, version)、プリプロセッサー指示文#propertyを使います。

EAをはしらせるとき、これらは"Common" タブに表示されます:

MACDのサンプルEA

図1 MACDのEAの一般パラメータ

1.2. インクルードファイル

次に、#includeでコンパイラーに標準ライブラリのtrade classesを含ませることを指示します。

  • Trade.mqh (CTrade - トレードのクラス);
  • SymbolInfo.mqh (CSymbolInfo - トレードのプロパティで稼働するクラス);
  • PositionInfo.mqh (CPositionInfo - 約定したポジションプロパティで稼働するクラス);
  • AccountInfo.mqh (CAccountInfo - トレードアカウントで稼働するクラス)。
//--- include files 
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
#include <Trade\PositionInfo.mqh>
#include <Trade\AccountInfo.mqh>

適切なクラスのインスタンスが、 CExpert class (セクション 3)のメンバとして使われます。

1.3. インプット

続いて、タイプ、名前、デフォルト値、コメントです。ルールは図2の通りです。

//--- Expert Advisor input parameters
input double InpLots          =0.1; // Lots
input int    InpTakeProfit    =50;  // Take Profit (in pips)
input int    InpTrailingStop  =30;  // Trailing Stop Level (in pips)
input int    InpMACDOpenLevel =3;   // MACD open level (in pips)
input int    InpMACDCloseLevel=2;   // MACD close level (in pips)
input int    InpMATrendPeriod =26;  // MA trend period

パラメータの名前の前には"Inp"がついています。また、グローバル変数の前には"Ext"をつけます。大量の異なる変数を扱う際に、わかりやすくするためのものです。

InpLots - トレードロット、InpTakeProfit と InpTrailingStop は利確とトレーリングレベルを決めます。

パラメータラインに書かれたコメントのテキストは(デフォルト値を含む)、パラメータの名前の代わりとして"Options"タブに表示されます:

図2. MACDのEAのinputパラメータ

図2. MACDのEAのパラメータ


1.4. グローバル変数

グローバル変数 ExtTimeOut を宣言します。これは、トレード実行の有効期限の制御に使われます。

int ExtTimeOut=10; // 時間 (秒) トレード実行

CSampleExpert の宣言の後、76行目で別のグローバル変数を宣言します。 ExtExpert - CSampleExpert クラスインスタンス:

//--- ExtExpert グローバル変数
CSampleExpert ExtExpert;

ExtExpert オブジェクト (CSampleExpert サンプルクラス) は、トレード手法の基本ロジックを含みます。(セクション 3)


2. イベントハンドラ関数

イベントハンドラ関数

2.1. OnInit() 初期関数

OnInit() 関数は、EAを稼働させたときの最初に一回だけ起動します。一般的に、OnInit()ではEA実行の準備処理を行います: パラメータをチェックしやインジケーターやパラメータを初期化などクリティカルエラーが発生した場合には、その後の処理は無意味になり、関数は INIT_FAILED を返します。

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit(void)
  {
//--- initialization and creation of all the required objects
   if(!ExtExpert.Init())
      return(INIT_FAILED);
//--- successful initialization
   return(INIT_SUCCEEDED);
  }

今回の場合、ExtExpert の Init()メソッドが呼び出されます。これはすべてのオブジェクトの状態に応じてtrueかfalseを返します。(セクション 3.4 参照)。 エラーが発生した場合、 OnInit() は INIT_FAILED を返します。- これは、初期化に失敗した場合の、EA/インジケーターの挙動として正常です。


2.2. OnTick() 関数

OnTick() 関数は、EAを稼働させているチャートのシンボルに新しいクオートが来た場合に呼び出されます。

//+------------------------------------------------------------------+
//| Expert new tick handling function                                |
//+------------------------------------------------------------------+
void OnTick(void)
  {
   static datetime limit_time=0; // stores the last call time + timeout
//--- do not operate if the required time has not elapsed
   if(TimeCurrent()>=limit_time)
     {
      //--- checking data
      if(Bars(Symbol(),Period())>2*InpMATrendPeriod)
        {
         //--- after the call of the Processing() method increase the value of limit_time by ExtTimeOut 
         if(ExtExpert.Processing())
            limit_time=TimeCurrent()+ExtTimeOut;
        }
     }
  }

OnTick()では、イベントハンドラが定期的にExtExpert.Processing()を呼び出します。これは相場分析やトレード条件が整った際のトレードの実行に使われます。

呼び出される時間の間隔は、ExtTimeOut パラメータの値によって設定されます。


2.3. OnDeInit() 関数

OnDeInit()は、EAがチャートから外された際に呼ばれます。グラフィックオブジェクトを稼働中に描写していた場合、それらもチャートから取り外されます。

今回の場合、終了時に呼び出す関数を使われず、何も実行されません。


3. CSampleExpert クラス

3.1. CSampleExpert クラス

//+------------------------------------------------------------------+
//| The MACD Sample EA class sample                                  |
//+------------------------------------------------------------------+
class CSampleExpert
  {
protected: 
   //--- protected variables - class members are available only inside the class methods 
   double            m_adjusted_point;             // a multiplier for 3/5-digit quotes
   CTrade            m_trade;                      // CTrade class sample
   CSymbolInfo       m_symbol;                     // CSymbolInfo class sample
   CPositionInfo     m_position;                   // CPositionInfo class sample
   CAccountInfo      m_account;                    // CAccountInfo class sample
   //--- indicator handles
   int               m_handle_macd;                // the MACD indicator handle
   int               m_handle_ema;                 // the Moving Average indicator handle
   //--- indicator buffers
   double            m_buff_MACD_main[];           // the buffer of the main line of the MACD indicator
   double            m_buff_MACD_signal[];         // the buffer of the signal line of the MACD indicator
   double            m_buff_EMA[];                 // EMA indicator buffers
   //--- current indicator values
   double            m_macd_current;
   double            m_macd_previous;
   double            m_signal_current;
   double            m_signal_previous;
   double            m_ema_current;
   double            m_ema_previous;
   //--- levels (in standard points)
   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);
   //--- public-methods can be called from outside the class 
   //--- initialization method
   bool              Init(void);
   //--- deinitialization method
   void              Deinit(void);
   //--- method of processing
   bool              Processing(void);
protected: 
   //--- protected-methods can be accessed only inside the class methods 
   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_" (メンバ)がついています。これはその変数がクラスメンバであることを表します。変数やメソッドの宣言の前に、その型を指定します。(あるいは関数の返り値の型)

クラスメンバの変数やメソッドを見るには access modifiersを使います。クラス中では、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. double           m_macd_current - 現在のMACDのメインラインを保存;
  12. double           m_macd_previous - ひとつ前のMACDのメインラインの値を保存;
  13. double           m_signal_current - 現在のMACDのシグナルラインの値を保存;
  14. double           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) - MACDMoving Averageの初期設定;
  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 Class Constructor

//+------------------------------------------------------------------+
//| CSampleExpert Class Constructor                                  |
//+------------------------------------------------------------------+
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);
  }

Class constructorが、 サンプルオブジェクトが生成された際に自動的に呼び出されます。呼び出された際、変数のデフォルトの値がセットされ、indexing direction が m_buff_MACD_main[], m_buff_MACD_signal[], m_buff_EMA[]にセットされます。


3.3. CSampleExpert Class destructor

//+------------------------------------------------------------------+
//| CSampleExpert class destructor                                   |
//+------------------------------------------------------------------+
CSampleExpert::~CSampleExpert(void)
  {
  }

CSampleExpert デストラクタには何も記述されていません。


3.4. CSampleExpert の初期メソッド

//+------------------------------------------------------------------+
//| Initialization and verification of input parameters              |
//+------------------------------------------------------------------+
bool CSampleExpert::Init(void)
  {
//--- setting common properties
   m_symbol.Name(Symbol());              // symbol
   m_trade.SetExpertMagicNumber(12345);  // magic
//--- taking into account 3/5-digit quotes
   int digits_adjust=1;
   if(m_symbol.Digits()==3 || m_symbol.Digits()==5)
      digits_adjust=10;
   m_adjusted_point=m_symbol.Point()*digits_adjust;
//--- setting the values of the levels taking into account the 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;
//--- setting the slippage of 3 points
   m_trade.SetDeviationInPoints(3*digits_adjust);
//---
   if(!InitCheckParameters(digits_adjust))
      return(false);
   if(!InitIndicators())
      return(false);
//--- successful completion
   return(true);
  }

Init()では、変数は初期化され、パラメータは変更されます。

m_symbol (CSymbolInfo )のためのName()の呼び出しでは、EAを稼働させているシンボルの名前をセットします。次にSetExpertMagicNumber() が呼び出され、m_tradeのためのEAのマジックナンバーを設定します。後に、シンボルの桁数を取得するためDigits()が使われます。 もし修正が必要な場合には適切な値に補正されます。

次に、m_trade のSetDeviationInPoints()が呼び出されます。これは許容スリッページを設定します。


3.5. CSampleExpert の InitCheckParameters

//+------------------------------------------------------------------+
//| Checking for input parameters                                    |
//+------------------------------------------------------------------+
bool CSampleExpert::InitCheckParameters(const int digits_adjust)
  {
//--- checking correctness of the Take Profit level
   if(InpTakeProfit*digits_adjust<m_symbol.StopsLevel())
     {
      printf("Take Profit must be greater than %d",m_symbol.StopsLevel());
      return(false);
     }
//--- checking correctness of the Trailing Stop level
   if(InpTrailingStop*digits_adjust<m_symbol.StopsLevel())
     {
      printf("Trailing Stop must be greater than %d",m_symbol.StopsLevel());
      return(false);
     }
//--- checking correctness of the trade volume
   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);
     }
//--- show warning if Take Profit<=Trailing Stop
   if(InpTakeProfit<=InpTrailingStop)
      printf("Warning: Trailing Stop must be less than Take Profit");
//--- successful completion
   return(true);
  }

EAのパラメータが正しいかどうかInitCheckParameters()で確認します。もし無効なパラメータがあった場合、適切なメッセージが表示されます。そして、関数はfalseを返します。


3.6. CSampleExpert の InitIndicators()

//+------------------------------------------------------------------+
//| Indicators initialization method                                 |
//+------------------------------------------------------------------+
bool CSampleExpert::InitIndicators(void)
  {
//--- creating the MACD indicator
   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);
        }
//--- creating the EMA indicator
   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);
        }
//--- successful completion
   return(true);
  }

InitIndicators()では、m_handle_macd と m_handle_ema 変数の整合性を確認します。(コンストラクタで初期化されたので、INVALID_HANDLEと一致する必要があります。) テクニカルインジケーターMACDMoving Averageが生成されます。(iMACDiMA 関数を使用します。) 成功した場合、関数はtrueを返し、インジケーターのハンドルがm_handle_macd と m_handle_emaに保存されます。

生成されたインジケーターのハンドルは次に計算されたデータ(BarsCalculated)の確認とProcessing() のインジケーターの値(CopyBuffer)の取得に使われます。


3.7. CSampleExpert の LongClosed()

//+------------------------------------------------------------------+
//| Checking conditions for closing a long position                  |
//+------------------------------------------------------------------+
bool CSampleExpert::LongClosed(void)
  {
   bool res=false;
//--- Should the position be closed?
   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)
           {
            //--- closing the position
            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;
           }
//--- returning the result
   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()

//+------------------------------------------------------------------+
//| Checking conditions for closing a short position                 |
//+------------------------------------------------------------------+
bool CSampleExpert::ShortClosed(void)
  {
   bool res=false;
//--- Should the position be closed?
   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)
           {
            //--- closing the position
            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;
           }
//--- returning the result
   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 の LongModified()

//+------------------------------------------------------------------+
//| Checking conditions for long position modification               |
//+------------------------------------------------------------------+
bool CSampleExpert::LongModified(void)
  {
   bool res=false;
//--- checking if Trailing Stop is required
   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)
           {
            //--- modifying Stop Loss and Take Profit of the position
            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;
           }
        }
     }
//--- returning the result
   return(res);
  }

買いポジションの修正条件が整った場合、LongModified() はtrueを返し、ストップロスを修正します: InpTrailingStop>0 の場合、価格がトレーリングストップのポイントを通過するかどうかを確認します。そして、新しいストップロスの値が計算され、ストップロスが修正されます。


3.10. CSampleExpert の ShortModified

//+------------------------------------------------------------------+
//| Checking conditions for long position modification               |
//+------------------------------------------------------------------+
bool CSampleExpert::ShortModified(void)
  {
   bool   res=false;
//--- checking if Trailing Stop is required
   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)
           {
            //--- modifying Stop Loss and Take Profit of the position
            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;
           }
        }
     }
//--- returning the result
   return(res);
  }

売りポジションの修正条件が整った場合、ShortModified() はtrueを返し、ストップロスを修正します: InpTrailingStop>0 の場合、価格がトレーリングストップのポイントを通過するかどうかを確認します。そして、新しいストップロスの値が計算され、ストップロスが修正されます。


3.11. CSampleExpert の LongOpened()

//+------------------------------------------------------------------+
//| Check for long position opening                                  |
//+------------------------------------------------------------------+
bool CSampleExpert::LongOpened(void)
  {
   bool res=false;
//--- checking conditions for opening a long position
   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;
            //--- checking free margin
            if(m_account.FreeMarginCheck(Symbol(),ORDER_TYPE_BUY,InpLots,price)<0.0)
               printf("We have no money. Free Margin = %f",m_account.FreeMargin());
            else
              {
               //--- opening a long position
               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;
           }
//--- returning the result
   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が上昇

すべての条件がそろったとき、余剰証拠金を確認します。(標準ライブラリCAccountInfoFreeMarginCheck() ) 買いポジションが CTradePositionOpen()によって建てられます。


3.12. CSampleExpert の ShortOpened

//+------------------------------------------------------------------+
//| Check for short position opening                                 |
//+------------------------------------------------------------------+
bool CSampleExpert::ShortOpened(void)
  {
   bool res=false;
//--- checking conditions for opening a short position
   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;
            //--- checking free margin
            if(m_account.FreeMarginCheck(Symbol(),ORDER_TYPE_SELL,InpLots,price)<0.0)
               printf("We have no money. Free Margin = %f",m_account.FreeMargin());
            else
              {
               //--- opening a short position
               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;
           }
//--- returning the result
   return(res);
  }

ShortOpened() 売りポジションをとる条件がそろえば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_open_level - 現在のMACDのメインラインが m_macd_open_levelよりも高い;
  4. m_ema_current<m_ema_previous - EMAが減少。

すべての条件がそろったとき、余剰証拠金を確認します。(標準ライブラリCAccountInfoFreeMarginCheck() ) 売りポジションが CTradePositionOpen()によって建てられます。


3.13CSampleExpert の Processing()

//+------------------------------------------------------------------+
//| main function returns true if any position processed             |
//+------------------------------------------------------------------+
bool CSampleExpert::Processing(void)
  {
//--- updating quotes
   if(!m_symbol.RefreshRates())
      return(false);
//--- updating indicator values
   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);
//--- to simplify work with indicators and for faster access
//--- the current values of the indicators are saved in internal variables (class members)
   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];
//--- correct market entry is important, but a correct exit is even more important
//--- first check if there is an open position
   if(m_position.Select(Symbol()))
     {
      if(m_position.PositionType()==POSITION_TYPE_BUY)
        {
         //--- if necessary, we try to close or modify a long position
         if(LongClosed())
            return(true);
         if(LongModified())
            return(true);
        }
      else
        {
         //--- if necessary, we try to close or modify a short position
         if(ShortClosed())
            return(true);
         if(ShortModified())
            return(true);
        }
     }
//--- no open positions
   else
     {
      //--- check conditions and open a long position if necessary
      if(LongOpened())
         return(true);
      //--- check conditions and open a short position if necessary
      if(ShortOpened())
         return(true);
     }
//--- exit without position processing
    return(false);
  }

CSampleExpert の Processing() はEAのメソッドです。Processing() が OnTick() で呼び出され、このメソッドの連続して呼び出す時間間隔を管理します。( ExtTimeOut 秒と同等) (セクション 2.2)。

CSymbolInfoRefreshRates()を呼び出すことによって、クオートが更新されます。 BarsCalculated()関数は、 MACDMoving Averageの計算に使うバーの数のリクエストに使います。 (セクション 3.6)バーの数が2本以下の場合、関数から抜けfalseを返します。

次に、CopyBuffer関数が、最新の2つのテクニカルインジケーターの値をリクエストします。(MACDのメインとシグナルラインと移動平均の値); データ量が2つ以下の場合、関数から抜けます。その後、配列m_buff_MACD_main[]、 m_buff_MACD_signal[]、 m_buff_EMA[] のインジケーターの値が変数m_macd_previous、m_signal_current、m_signal_previous、 m_ema_current、 m_ema_previousにコピーされます。

次のステップは、標準ライブラリのCPositionInfo で取得したポジションを処理することです。Select()の呼び出しがtrueの場合、現在約定しているポジションがあることを意味します。ポジション種別はPositionType() で取得可能です。約定したポジションの種別に応じて、さらなる処理が実行されます。


4. バックテスト

パラメータの最適な値は MetaTrader 5 terminal の Strategy Testerを使うことで探索可能です。

図3 は、EAの2013年のデフォルトの結果を表します。

図3. MACDのEAのバックテスト結果

図3. MACDのEAのバックテスト結果

結果

MetaTrader 5 の標準パックにあるサンプルのMACD のEAは、EAのオブジェクト指向の一例です。

MetaQuotes Ltdによってロシア語から翻訳されました。
元のコード: https://www.mql5.com/ru/code/2154

Moving Average Moving Average

移動平均EAは価格と移動平均線のクロスでトレードを行います。

ALGLIB - 数値分析ライブラリ ALGLIB - 数値分析ライブラリ

ALGLIB 算術関数ライブラリ (v. 3.19) MQL5に移植

リアルタイムでの最適化の可視化 リアルタイムでの最適化の可視化

リアルタイムでの最適化結果の可視化の実例の紹介(資産曲線とEAの統計的パラメータ)。

ColorSchaffJJRSXTrendCycle_HTF ColorSchaffJJRSXTrendCycle_HTF

インディケータ ColorSchaffJJRSXTrendCycleは、入力パラメータのインディケータの時間軸を変更することができます。