English Русский 中文 Español Deutsch Português 한국어 Français Italiano Türkçe
6つのステップでトレーディング自動装置を作りましょう!

6つのステップでトレーディング自動装置を作りましょう!

MetaTrader 5 | 2 10月 2015, 16:15
14 221 0
MetaQuotes
MetaQuotes

MQL5ウィザードについてもう一度詳しく

私たちを取り囲む環境は急速に変化し、常にそれらに追いつく努力を重ねなければなりません。何か新しいことを学ぶ時間的余裕はないというのは人間として正常な状態であるかと思います。トレーダーは私たちと同じように、最小限の努力で最大限の結果を得ようと考えています。トレーダーにとってメタエディター5は素晴らしいMQL5ウィザードを提供しており、ライト版である「初心者のためのMQL5ウィザード」、開発者から生まれた、「MQL5ウィザード:新バージョン」などのウィザードを使用し自動取引システムを作成する方法について述べた記事はいくつかあります。

とてもよくできていて - 5回クリックするだけで、自分の取引自動システムを作成し、「戦略テスター(Startegey Tester)」にて自身の取引を試験的に行うことができ、 パラメーター設定を最適化することができます 。また、その結果を使ってあなたの口座アカウント上にて自動で取引を行ってくれるのです、手動うですることは何も必要がありません.。しかし、MQL5開発者、もしくは、トレーダーがどこにも記載されていないような仕様のシステムを作りたいと思い、実際に自身で売買シグナルのためのモジュールを作成しようとするときに問題は生じます。トレーダーがMQL5の資料を開き、「標準ライブラリ(Standard Libary)」の資料に辿りつくと、驚きの声をあげるのです。


5つの悲惨なクラス群

MQL5ウィザードは、専門アドバイザー(Expert Advisors)の開発を飛躍的に単純化させますが、まず初めに、その開発を行う上で必要な要素を知る必要があります。MQL5ウィザードを使用し、専門アドバイザー(Expert Advisors)を自動的に開発する際には、5つの基本クラスに専門アドバイザーが準拠していることを理解しましょう。

  • CExpertBase は、その他の4つのクラスの親クラスになります。
  • CExpertは、トレーディングシステムを作成するクラスであり、実際にトレードを行うクラスになります。
  • CExpertSignal 売買シグナルのためのモジュール作成用クラスで、この記事はこのクラスについて紹介します。.
  • CExpertTrailingは、ストップ・ロスを最小限に抑えるための追跡を行うクラスです。
  • CExpertMoneyは資産管理用クラスです。

これらが、オブジェクト指向プログラミング(OOP)と呼ばれる、良くもあり悪くもある開発手法の力であると言えます。しかし、たくさんの機能が携帯電話に組み込まれているにも関わらず、それらがいかに機能しているのかを知る人はほとんどいないのと同様、心配する必要はなく、全てを勉強する必要はありませんので、ここではCExpertSignal クラスのいくつかの機能を紹介します。


この記事では、売買シグナル用モジュールの開発におけるいくつかの手順を紹介し、オブジェクト指向プログラミングやその他のクラスを学習せず開発する方法を説明します。ただ、もし興味があれば、ぜひご自身でより詳しく学習を進めてみてください。


1. 1からクラスを作成する方法

混乱してしまうので、要望に応じて既存の売買シグナルを変更するという方法は取りません。従って、簡単にクラスを自作しますが、まず ナビゲーターを使用して、新しいフォルダーを作成し、MQL5/Include/Expert/に売買シグナルを保存できるようにします。

作成したフォルダー上で右クリックし、「新規ファイル(New FIle)」を選択、売買シグナル用クラスを作成します。

フィールドを埋める:

  • クラス名 - クラスを呼ぶための名前です。このクラスは、二つの移動する平均点の交差地点にてシグナルを生成するモジュールですので、MA_Crossというクラス名を設定します。
  • Base Nameとは、継承元のクラスです。このMA_Crossクラスは、CExpertSignalというクラスから継承するようにしてください。

「終了(Finish)」をクリックし、モジュールの原型の作成が完了します。今のところ複雑なものはありません。コンパイラーが派生元クラスであるCExpertSignalの場所を認識できるよう、#includeを追加で宣言する必要があります。

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

The result:

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

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

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

作成したファイルをチェックし、F7をクリックしてください。 (コンパイルエラーは表示されないはずです)エラーがなければ、次に進みましょう。


2. モジュールのハンドリング

作成したクラスは未だ空の状態で、エラーはありませんので、テストを行うことができます。そのクラスを用いて、MQL5ウィザードにて新しい専門アドバイザーを作成してみましょう。売買シグナル用モジュールを選択するところまで進めると、作成したモジュール名が表示されていないことがわかります。

では、どうすれば表示することができるのでしょうか?作成したクラスが使用できるとMQL5ウィザードが理解するための印を記述していませんので、修正してみましょう。標準パッケージのモジュールを見てみると、それぞれがファイルの最初にヘッダーを記述していることがわかります。これが特定のルールに沿ったモジュールのハンドリングになります。ルールはとても簡単です。

AMAを継承している売買シグナル用モジュールのソースコードを開きます。(適応的移動平均シグナルのロジックについての記述をご覧ください。) そして、MQL5ウィザードを走らせ、このモジュールを選択します。比較します:

ハンドリングに関する最後のブロックは、モジュールのパラメーターです。最初の行にMQL5ウィザードにて表示されるべき名前が記述されています。ご覧の通り、そこまで難しい点はありません。各モジュール用ハンドラは、以下の項目が含まれています。

  • タイトル(Title) - MQL5ウィザードに表示されるモジュール名。
  • タイプ(Type) - シグナル用モジュールのバージョン。常にSignalAdvancedというバージョン名を設定する必要があります。
  • 名前(Name) - MQL5ウィザードにて選択された後、生成された専門アドバイザーの初期変数を記述するコメントにて使用されるモジュール名(指定したほうがよい)。
  • ショートネーム(ShortName) - 専門アドバイザーにおける外部変数名におけるプレフィックス(Signal_<ShortName>_<ParameterName>という形で使われます)
  • クラス(Class) - モジュールに含まれるオブジェクトの雛形の名前
  • ページ(Page) - モジュールにおいてヘルプを参照するための変数(standard deliveryのモジュールのみです)

Parameter=list_of_valuesという形で記述されている変数について以下に説明しています。

  1. 専門アドバイザー起動時、変数に値を代入するための機能名
  2. 変数の型は、列挙型です。
  3. 変数初期値:MQL5ウィザードにて変更しない限り、変数に代入される値
  4. MQL5ウィザードの専門アドバイザー起動時に見られる変数に関する記述

それでは、売買シグナル用モジュールのハンドラを作成しましょう。二つの移動平均点の交差地点にて売買シグナルを表示するためのモジュールを作成していきます。新たに4つの変数を宣言する必要があります。

  • FastPeriod - 速く移動する平均の期間
  • FastMethod - 上記の平均の平準化におけるタイプ
  • SlowPeriod - 遅く移動する平均点の期間
  • SlowMethod - 上記平均の平準化におけるタイプ

それぞれの移動平均点を求めるための価格のシフトと種類を加えることもできますが、根本から変える形にはなりません。現在のバージョンが以下に記載されています:

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

モジュール用ハンドラの準備が完了しており、以下はすでに説明しています。

  1. MQL5ウィザードに表示される名前 - 「二つの移動平均の交差点でのシグナル」
  2. 売買シグナルの調整を行うための4つ変数
    • FastPeriod - 急速な移動平均の期間、初期値は13
    • FastMethod - 上記の移動平均の期間の平準化のタイプ、初期設定は単純な平準化です
    • SlowPeriod - 遅い移動平均の期間、初期値は21
    • SlowMethod - 上記の移動平均の期間の平準化のタイプ、初期設定は単純な平準化です

変更後は保存し、コンパイルを行ってください。エラーは表示されないはずです。MQL5ウィザードを起動し、チェックしてください。ご覧の通り、作成したモジュールが選択可能になっており、全ての変数を表示しています。

おめでとうございます、売買シグナル用モジュールが作成できました!


3. 変数の設定のためのメソッド

それでは、外部変数の処理を行いましょう。トレーディング用モジュールは、MA_Crossクラスが中心として構成され、その変数はプライベートメンバーとして同様のクラスに保持されます。クラス宣言文に新たに4行を追加しましょう。(変数の数と同じ数です)ハンドル作成において変数の説明はすでに行っており、以下の処理はご存知かと思います。

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

しかし、モジュールの外部変数の値をMA_Crossクラスの適切なメンバーに代入するのでしょうか?実はとても簡単で、MA_Crossクラスにて同じ名前のパブリックメソッドを宣言するのみです。パブリックのセクションにてさらに4つの行を追加します。

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

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

MQL5ウィザードにて、このモジュールを基盤に専門アドバイザーを作成しチャート上で起動する際、専門アドバイザーの初期化に伴ってこれら4つのメソッドが自動的に呼び出されます。ここで、簡単なルールがあります:

モジュールでの変数の生成におけるルール - ハンドルにて宣言した変数の値を扱うにあたって、値を保持するためのプライベートメンバをクラスに作成し、また、値を代入するためのパブッリクメンバを作成します。メソッド名は、変数名と同じである必要があります。

値を代入するためのメソッドが呼ばれなかった場合に使用される変数の初期値を代入する必要があります。宣言された変数やクラスメンバは初期化される必要があります。これは、見つけ難いエラーを避けるテクニックです。

自動的な初期化において最も有効な方法はコンストラクタを使用することです。オブジェクト作成時に必ず最初に呼ばれるメソッドになります。初期値に関しては、モジュールハンドラに書かれているものを利用します。

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

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

クラスメンバはintialization listを使用することで初期することができます。

ご覧の通り、未だ移動平均用インジケーターを使用していません。簡単なルールがあります。モジュールハンドラにてたくさんの変数が記述されている際、モジュールを実行するクラスに多くのメソッドやメンバが記述されいている必要があります。全く難しいことはありませんね!ただ、コンストラクタにて変数の初期値を代入することを忘れないようにしてください。


4. 入力パラメータの正誤判定

トレーディングモジュールの変数を作成し、変数に値を代入するメソッドを記述しました。次に重要な変数の正誤の判定について取り組みます。移動平均の期間とその計算のため平準化のタイプをチェックする必要があります。そのため、クラス内にて自身のValidationSettings()メソッドを記述する必要があります。このメソッドは、親クラスCExpertBaseにて定義されており、その子クラス内にて必ず再定義される必要があります。

ただ、もしオブジェクト指向プログラミングについて何も知らなければ、クラス内にて変数を持たずTrue、Falseを返すValidationSettings()メソッドを書く必要があるとだけ覚えておいてください。

class MA_Cross : public CExpertSignal
  {
...
   //--- Constructor of class
                     MA_Cross(void);
   //--- Destructor of class
                    ~MA_Cross(void);
   //--- Checking correctness of input data
   bool              ValidationSettings();
...
   };
//+------------------------------------------------------------------+
//| Checks input parameters and returns true if everything is OK     |
//+------------------------------------------------------------------+
bool MA_Cross:: ValidationSettings()
  {
   //--- Call the base class method
   if(!CExpertSignal::ValidationSettings())  return(false);
   //--- Check periods, number of bars for the calculation of the MA >=1
   if(m_period_fast<1 || m_period_slow<1)
     {
      PrintFormat("Incorrect value set for one of the periods! FastPeriod=%d, SlowPeriod=%d",
                  m_period_fast,m_period_slow);
      return false;
     }
//--- Slow MA period must be greater that the fast MA period
   if(m_period_fast>m_period_slow)
     {
      PrintFormat("SlowPeriod=%d must be greater than FastPeriod=%d!",
                  m_period_slow,m_period_fast);
      return false;
     }
//--- Fast MA smoothing type must be one of the four values of the enumeration
   if(m_method_fast!=MODE_SMA && m_method_fast!=MODE_EMA && m_method_fast!=MODE_SMMA && m_method_fast!=MODE_LWMA)
     {
      PrintFormat("Invalid type of smoothing of the fast MA!");
      return false;
     }
//--- Show MA smoothing type must be one of the four values of the enumeration
   if(m_method_slow!=MODE_SMA && m_method_slow!=MODE_EMA && m_method_slow!=MODE_SMMA && m_method_slow!=MODE_LWMA) 
     {
      PrintFormat("Invalid type of smoothing of the slow MA!");
      return false;
     }
//--- All checks are completed, everything is ok
   return true;
  }
ご覧の通り、MA_Crossのパブリック部分において、ValidationSettings()メソッドを宣言し、メソッドの内容を記述しました。
bool MA_Cross:: ValidationSettings()

まず戻り値の型を設定、次にクラス名、そして、スコープ定義演算子:: を記述します。これらは全て以前宣言したメソッド名の次に記述されます。変数名と型はクラスメソッドの宣言と記述内容が合致している必要があることを忘れないようにしていください。しかし、コンパイラによりエラーが表示されるかと思います。

まず派生元クラスが呼ばれ、入力パラメータがチェックされます。

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

この行を追加しなければ、売買シグナルの初期化ができなくなってしまいます。


5. インジケーターはどこにあるのでしょうか?

変数に関する全ての準備作業が完了したので、次はインジケータの作業に移りましょう。それぞれの売買シグナル用モジュールはInitIndicators() メソッドを所持し、専門アドバイザー起動時に自動的に呼び出されます。このメソッド内にて、移動平均用インジケーターを作成しなければなりません。

まず、lnitIndicatorsメソッドをクラス内に宣言し、以下を貼り付けてください。

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

ValidationSettingsメソッドにて行ったように、メソッドを宣言し、メソッド内を記述しましたが、簡単だったかと思います。メソッドの定義において、クラス名と演算子::を挿入するのを忘れないようにしてください。移動平均作成時に挿入するためのコードが以下にあります。成功時にはTrueを返すメソッドをそれぞれのインジケーター内にて作成しますので、正しく行いましょう。メソッド名は何でも構いませんが、目的と合致したメソッド名にしたいので、CreateFastMa、CreateSlowMAという名前にしましょう。

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

MAインジケータを生成するコードを記述するのみです。またトレーディングモジュールにこれらのインジケーターを導入し、モジュールがインジケーターの持つ変数を使用できるようにしましょう。これによりCIndicators型の変数がパラメータとして認識されるのです。以下の内容は、メタトレーダー資料にも記載されています。

Cindicatorsは、時系列でのインジケータークラスのインスタンスを保持するクラスになります。Cindicatorsクラスは、インジケータークラスのインスタンス、その補完領域、管理機能を保持します。(データの同期、ハンドリング、メモリー管理機能など)

つまり、インジケーターを作成し、コレクション内に収納する必要があるということです。CIndicator のインジケーターやその子クラスはこのコレクション内に保存されるので、それを利用したいと思います。CiCustomという上記で言及した子クラスを使用します。それぞれの移動平均の変数を、クラスのプライベート・スコープにてCiCustomオブジェクト型として宣言します。

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

もちろん、CIndicatorを継承するインジケータークラスを作成でき、MQL5ウィザードにて全てのメソッドを実行することができます。しかし、この場合、 CiCustomを使用し、売買シグナル用モジュールにてカスタム化されるインジケータの使い方を説明します。

コード内容が以下になります。

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

CreateFastMAメソッドにて、まずインディケータのコレクション用ポインターをチェックし、このコレクション内にてMA m_fast_maを追加しましょう。カスタム化されるインジケーターの変数を保持するように設計されたMqlParamを宣言し、値を代入しましょう。

標準ターミナルパッケージ内から、カスタム化MAインジケーターとしてカスタム用移動平均を使用します。インジケーター名はフォルダーと関連した名前(data_folder/MQL5/Indicators/)である必要があります。標準パッケージのCustom Moving Average.mql5は、data_folder/MQL5/Indicators/Examples/に保存されているため、Exampleフォルダーを含めたファイルパスを明示する必要があります。

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

このコードを見てみると、全ての必要なデータがわかります。

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

この変数の値は、タイプ・バリューのペアを含んでいます。

  1. 変数型 - String型(インジケーター名を転移するため)
  2. カスタムインジケーターの実行可能ファイル名 - 「Custom Moving Averages.exe」
  3. 変数型 - int型(期間の値代入用)
  4. 移動平均期間
  5. 変数型 - int型(シフト値)
  6. 平均の水平シフト値
  7. 変数型 - int型(列挙型はIntegerです)
  8. 平均化メソッド

ストラクチャーを埋めた後、このインジケーターはシンボル名、計算される時間枠、ENUM_INDICATOR列挙クラスのインジーターの型、インジケーターの変数の数、変数の値の代入されたMqlParamなど全ての変数におけるCreate()メソッドにて初期化されます。そして最後にNumBuffers()メソッドを使用し、インジケーターバッファーの数を明記します。

遅めの移動平均を作成するCreateSlowMA()メソッドは簡単です。モジュール内のカスタムインジケーターを使用する際、テスターにてMQL5ウィザードにより生成される専門アドバイザーも稼働することを忘れないようにしましょう。ファイルの最初の部分にて、インジケーターの位置をテスターに知らせる#property tester_indicatorプロパティを記述します。

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

いくつかの異なるインジケーターを使用する場合、この行をそれぞれに追加する必要があります。それでは、インジケータの追加を終了しました。より便利にするため、MA値を受け取る二つのメソッドを記述しましょう。

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

ご覧の通り、このメソッドはシンプルに作られており、特定のインジケーター用バッファーの特定の位置から値を返すSIndicatorの親クラスのGetData()メソッドを使用しています。

標準パッケージのインジケーターを扱うためのクラスが必要であれば、インジケーターを扱うクラスの章に記載しています。それでは、最後のステップに進みましょう。


6. LongCondition・ShortConditionメソッドの定義

モジュールの稼働、売買シグナルの生成の準備が全て完了しました。CExpertSignal:の子クラスにて定義されている二つのメソッドにこの機能が提供されています。

  • LongCondition() は、0から100の間にてロング・シグナルの値を返し、買い状態をチェックします。
  • ShortCondition() - 0から100の間でショートシグナルの値を 返し、 売り状態をチェックします。

このメソッドがnullを返した場合、売買シグナルがない状態を指します。シグナルが生成された場合、シグナルの強さを推測し、100までの値を返すことができます。シグナルの強さを推測することで、いくつかのモジュールと市場モデルに基づいた柔軟な売買システムを構築することができます。MQLウィザード:新バージョンにて詳しく記載しています。

売買シグナルのシンプルなモジュールを作成しているので、売買シグナルは全て同等に100で設定します。クラスの宣言文にて必要なメソッドを追加しましょう。

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

メソッドの詳細を記述します。買いシグナルがチェックされる仕組みが以下になります。(売りシグナルも同じ形です。)

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

親クラスのCExpertBaseのメソッドStartIndex()に返される値が代入されるidx変数をすでに宣言していることに注意してください。専門アドバイザーが全てのチックにおいて稼働している場合、 StartIndex() は0を返し、その時点のバーから分析をスタートします。もし専門アドバイザーが公開価格にて稼働する場合、StartIndex()は1を返し、最後に生成されたバーから分析をスタートします。

標準として StartIndex() は1を返します。チック MQL5ウィザードによって生成された専門アドバイザーは新規バー生成時に稼働し、バーの作成時の新規チックは無視します。

どのようにこの状態を稼働させ、使用することができるかについては、後ほど紹介します。

モジュールが使用できる状態になりましたので、MQL5ウィザードにてこのモジュールを使用し自動取引システムを作成しましょう。


テスターにて専門アドバイザーをチェックする

このモジュールの効果をテストするため、MQL5ウィザードにて専門アドバイザーを作成し、グラフ上に稼働させましょう。スタートウィンドウの「入力(Input)」タブに、MA_Crossモジュールの変数が含まれています。

選択した資産管理モジュールとポジション維持モジュールに基づいたEAを作成する際に、MQL5ウィザードによってその他変数も追加されています。そのため、売買シグナル用モジュールのみ作成し、あとはすでに作成されているシステムを利用するだけでいいのです。これがMQL5ウィザードを使用するメリットです。

それでは、メタトレーダー5戦略テスターにて売買システムをテストしてみましょう。変数の最適化も試してみましょう。

入力パラメータの設定にて、全ての最適化を図るには50万行以上の処理が走る必要があります。それゆえ、より高速な最適化(遺伝的アルゴリズム)を選び、追加として、MQL5クラウドネットワークをより高速な最適化のため使用しました。10分ほどで最適化が完了し、結果を得ることができます。

ご覧の通り、MQL5にて自動取引システムの作成、入力パラメータの最適化は、ポジション管理用ロジックの記述・デバッギング・最適なアルゴリズムの探索に必要だったかもしれない時間より少なく終えることができます。


最後のステップ

売買シグナルモジュールの記述で十分である際は、この項目はスキップするか、あとで参照するのみで構いません。

MQL5ウィザードにて生成された専門アドバイザーのソースコードを開くと、間違った値が代入されているグローバル変数Expert_EveryTickが見つかると思います。この変数に基づき、StartIndex()は値を返します。そして、専門アドバイザーとの連携を行います。

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

もしExpert_EveryTickにTrueを代入し、コードをコンパイルすると、自動取引システムは、全てのチックを分析し、不完全なバーの値にて意思決定を行います。仕組みを理解している場合のみこの作業を行ってください。全ての取引システムがバー内にて稼働するよう設計されています。

Expert_EveryTick変数にinputキーワードを記述でき、チャートやテスターでEAの起動時に設定できる新規専門アドバイザーの入力パラメーターを得ることができます。

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

今回行った内容のまとめを行いましょう。


売買シグナルモジュールの作成における6つのステップ

MQL5をマスターしたのであれば、専門アドバイザーを1から作成する必要はなくなります。売買シグナルモジュールを作成し、このモジュールに基づき、取引量管理モジュール、ストップロス用モジュールとともに、自動的に取引システムを作成します。たとえオブジェクト指向に詳しくない、もしくは、取引用クラスを詳しく探求したくない場合でも、6つの手順を行うことができます。

  1. MQL5ウィザードを使用し、MQL5/Include/MySignals/に新規クラスの作成 を行います。売買シグナルのモジュールはそちらに保存されます。
  2. 変数や、その型、値を記述したモジュールハンドラを作成します。
  3. クラス内にモジュールの変数を宣言し、コンストラクタ内に初期化のためのメソッドを追加します。
  4. 入力パラメータのチェック を行います。また、派生元クラスCExpertSignalのValidationSettingsを呼び出すことを忘れないようにしてください。
  5. インジケーター用オブジェクトを作成し、定義済みのlnIndiators()メソッドを追加します。
  6. LongCondition()・ShortCondition()メソッドにて、売買シグナルの条件を指定します。

それぞれのステップは簡単であり、MQL5プログラミングの技術はほとんど必要ありません。説明に従ってモジュールを作成し、何時間もコーディング・デバッギングを行わず、1時間以下にてさらなる取引のアイディアの検証を行うことができます。


初級から上級レベルへ

売買の戦略はMQL5ウィザードを使用して作成された取引システムによって実行され、売買シグナルのモジュールと同程度に複雑なものです。しかし、いくつかのルールに沿って複雑な取引システムを作成し始める前に、数点のシステムに分解し、それぞれを別々にチェックしてください。

シンプルなモジュールに基づきながら、既成の売買シグナルを使用し、複雑な売買戦略を構築することができます。しかし、これについてはまた別の記事のトピックとして紹介します!

MetaQuotes Ltdによってロシア語から翻訳されました。
元の記事: https://www.mql5.com/ru/articles/367

添付されたファイル |
testma_cross.mq5 (7.14 KB)
ma_cross.mqh (11.57 KB)
メタトレーダー5 - 想像以上の製品です! メタトレーダー5 - 想像以上の製品です!
メタトレーダー5クライアントターミナルは1から開発され、もちろん旧バージョンをはるかに超える製品となっています。この新しいトレーディングプラットフォームは、どの金融市場においても無限の取引機会を提供します。また、常により使いやすい機能・利便性を提供するため拡張し続けています。そのため、メタトレーダー5の利便性を全て挙げることは難しいものとなっています。一つの記事において簡潔に全てを説明することを試みましたが、簡潔に収めることができず大変驚きました。
セマフォインディケーターを使った簡単なトレーディングシステム セマフォインディケーターを使った簡単なトレーディングシステム
複雑なトレーディングシステムも、よく見てみると複数の簡単な取引シグナルに基づいていることがわかります。ですから、開発の初心者はすぐに複雑なアルゴリズムを書き始める必要はありません。この記事ではセマフォインディケーターを使って取引を行うトレーディングシステムの例を紹介します。
トレーリングストップを採用した利益を生み出すアルゴリズム トレーリングストップを採用した利益を生み出すアルゴリズム
この記事では、異なるエントリーとトレーリングストップを使ったエグジットで利益を生むアルゴリズムの可能性について学んでいきたいと思います。エントリーのタイプとして、ランダムエントリーとリバースエントリーを使用します。使う逆指値注文はトレーリングストップとトレーリングテイクです。この記事では、年間約30%の利益を生み出すアルゴリズムを紹介します。
マルチタイムフレームとマルチ通貨パネルの作成 マルチタイムフレームとマルチ通貨パネルの作成
この記事では、オブジェクト指向プログラミングを使うMetaTrader 5のマルチタイムフレームとマルチ通貨パネルの作成の仕方を解説します。主な目的は、パネルのコードを変更することなく、価格や価格の変化、インディケーターの値や売買条件のカスタマイズなど 多くの異なった種類のデータを表示することのできる汎用パネルの作成です。