MQL5入門|インジケータを作成するための基本的なMQL5の記述方法について

はじめに

当記事ではインジケータを作成するための基本的なMQL5の記述方法について、C言語をある程度理解している方々が、基本をマスターできるようにまとめています。


教材として使用するMQL5ソースと実行結果

教材として使用するMQL5ソースと実行結果を以下に示します。このMQL5ソースは、2本のラインを描画するだけのシンプルなインジケータです。このMQL5ソースについて、1行1行丁寧に基本を解説していきます。


/*==============================================================================
 D_MQL5_Study_001.mq5
==============================================================================*/
#property copyright "Copyright 2018, Okamori Dou"
#property link      "https://metatrader-technical.com/"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots   2
#property indicator_type1   DRAW_LINE
#property indicator_type2   DRAW_LINE
#property indicator_color1  clrRed
#property indicator_color2  C'000,255,000'
#property indicator_style1  STYLE_SOLID
#property indicator_style2  STYLE_DASH
#property indicator_width1  3
#property indicator_width2  1
#property indicator_label1  "線1"
#property indicator_label2  "線2"

input double    InputLine1   = 1.0005;
input double    InputLine2   = 0.9995;

double Line1Buffer[];
double Line2Buffer[];

int OnInit()
{
   SetIndexBuffer(0,Line1Buffer,  INDICATOR_DATA);
   SetIndexBuffer(1,Line2Buffer,  INDICATOR_DATA);

   PlotIndexSetString(0,PLOT_LABEL,"線1");
   PlotIndexSetString(1,PLOT_LABEL,"線2");
   
   return(INIT_SUCCEEDED);
}

int OnCalculate(const int      rates_total,     
                const int      prev_calculated, 
                const datetime &time[],         
                const double   &open[],         
                const double   &high[],         
                const double   &low[],          
                const double   &close[],        
                const long     &tick_volume[],  
                const long     &volume[],       
                const int      &spread[])       
{
   int limit; 
   if(prev_calculated == 0) 
   {
      limit = 0;
   } 
   else
   {
      limit = prev_calculated - 1;
   }

   for(int i = limit; i < rates_total && !IsStopped(); i++)
   {
      Line1Buffer[i] = high[i] * InputLine1;
       
      Line2Buffer[i] = Line2Calculate(low[i], InputLine2);
   }

   return(rates_total);
}

double Line2Calculate(double low, double test)
{
   double calculate = low * test;
   return(calculate);
}

void OnDeinit(const int reason)
{
}

MQL5入門|インジケータを作成するための基本的なMQL5の記述方法について

MQL5におけるプロパティの記述方法

MQL5におけるプロパティの基本的な記述方法について、以下に解説していきます。

/*==============================================================================
 1.プロパティの記述方法
   ☑プロパティでは、インジケータの根幹部分を定義します。
   ☑プロパティは以下の形式で記述します。
     #property プロパティ名 設定値
     ※プロパティ名省略するプロパティがあります。
==============================================================================*/
/*------------------------------------------------------------------------------
 (A)著作権表示の設定
   著作権表示を設定します。
   設定した著作権は、インジケータのプロパティ画面で表示されます。
   #property copyright 著作権表示
------------------------------------------------------------------------------*/
#property copyright "Copyright 2018, Okamori Dou"

/*------------------------------------------------------------------------------
 (B)リンクの設定
   リンクを設定します。
   設定したリンクは、インジケータのプロパティ画面で表示されます。
   #property link リンク
------------------------------------------------------------------------------*/
#property link      "https://metatrader-technical.com/"

/*------------------------------------------------------------------------------
 (C)バージョンの設定
   インジケータのバージョンを設定します。
   設定したバージョンは、インジケータのプロパティ画面で表示されます。
   #property version バージョン
------------------------------------------------------------------------------*/
#property version   "1.00"

/*------------------------------------------------------------------------------
 (D)インジケータを表示するウィンドウの指定
   #property indicator_chart_window   :チャートウィンドウにインジケータを表示する
   #property indicator_separate_window:分割した別ウィンドウにインジケータを表示する
------------------------------------------------------------------------------*/
#property indicator_chart_window

/*------------------------------------------------------------------------------
 (E)インジケータの計算データを格納するバッファの数を予約
   #property indicator_buffers バッファ数(無制限)
------------------------------------------------------------------------------*/
#property indicator_buffers 2

/*------------------------------------------------------------------------------
 (F)インジケータの描画データを格納するバッファの数を予約
   上記Eで予約した計算データバッファのうち描画データとして予約するバッファ数を指定します。
   #property indicator_plots バッファ数(無制限)
------------------------------------------------------------------------------*/
#property indicator_plots   2

/*------------------------------------------------------------------------------
 (G)描画データの描画タイプを設定
   上記Fで予約した描画データの描画タイプを指定します。
   #property indicator_typeN 描画タイプ
   【描画タイプの種類】
      DRAW_LINE      : 線      
      DRAW_HISTOGRAM : ヒストグラム
      DRAW_ARROW     : 矢印
      DRAW_SECTION   : セクション
      等々
------------------------------------------------------------------------------*/
#property indicator_type1   DRAW_LINE
#property indicator_type2   DRAW_LINE

/*------------------------------------------------------------------------------
 (H)描画データの色を設定
   上記Gで指定した描画タイプで描画する際の色を設定します。
   #property indicator_colorN 色
   MQL5で定義済みの色名(赤色はclrRed等)を使用することができます。
   配色にこだわる場合はRGBで指定することもできます。
------------------------------------------------------------------------------*/
#property indicator_color1  clrRed
#property indicator_color2  C'000,255,000'

/*------------------------------------------------------------------------------
 (I)描画データの線の種類を設定
   上記Gで指定した描画タイプで描画する際の線の種類を設定します。
   #property indicator_styleN 線の種類
   【線の種類】
     STYLE_SOLID     :実線
     STYLE_DASH      :破線
     STYLE_DOT       :点線
     STYLE_DASHDOT   :一点鎖線
     STYLE_DASHDOTDOT:二点鎖線
------------------------------------------------------------------------------*/
#property indicator_style1 STYLE_SOLID
#property indicator_style2 STYLE_DASH

/*------------------------------------------------------------------------------
 (J)描画データの線の種類を設定
   上記Gで指定した描画タイプで描画する際の線の太さを設定します。
   線の太さは、線の種類でSTYLE_SOLIDを指定した場合のみ有効です。
   #property indicator_widthN 線の太さ
------------------------------------------------------------------------------*/
#property indicator_width1  3
#property indicator_width2  1

/*------------------------------------------------------------------------------
 (K)描画データのラベル名を設定
   上記Gで予約した描画データのラベル名を設定します。
   インジケータのプロパティから色を変更する際に表示されるラベル名として使用されます。
   #property indicator_labelN ラベル名
------------------------------------------------------------------------------*/
#property indicator_label1  "線1"
#property indicator_label2  "線2"

インジケータのプロパティ画面(共有タブ)で著作権表示、バージョンが表示されます。また、リンクは、著作権表示の箇所をクリックするとリンク先に飛ぶ仕組みになっています。

インジケータを作成するための基本的なMQL5の記述方法について(プロパティ:共通)

インジケータのプロパティ画面(カラータブ)でラベル名、色、線の太さ、線の種類が表示されます。また、色、線の太さ、線の種類を変更することができます。

インジケータを作成するための基本的なMQL5の記述方法について(プロパティ:カラー)

MQL5におけるパラメータの記述方法

MQL5におけるパラメータの基本的な記述方法について、以下に解説していきます。

/*==============================================================================
 2.パラメータの記述方法
   ☑インジケータのプロパティから変更することができるパラメータを定義します。
   ☑パラメータは、以下の形式で記述します。
     修飾子:input  型名:intなど  変数名:任意に決めた名前
==============================================================================*/
input double    InputLine1   = 1.0005;
input double    InputLine2   = 0.9995;

インジケータのプロパティ画面(インプットタブ)でインプット変数名と設定値が表示されます。また、設定値を変更することができます。

インジケータを作成するための基本的なMQL5の記述方法について(プロパティ:インプット)

MQL5におけるグローバル変数の記述方法

MQL5におけるグローバル変数の基本的な記述方法について、以下に解説していきます。

/*==============================================================================
 3.グローバル変数の記述方法
   ☑グローバル変数は、描画データなど常に保持しておきたいデータを格納するために使用します。
==============================================================================*/
/*------------------------------------------------------------------------------
 (A)描画データを格納する配列を用意
   「1(F)」にて予約した4個のバッファの描画データを実際に格納する配列を用意します。
------------------------------------------------------------------------------*/
double Line1Buffer[];
double Line2Buffer[];

MQL5における初期化関数の記述方法

MQL5における初期化関数の基本的な記述方法について、以下に解説していきます。

/*==============================================================================
 4.初期化関数の記述方法
   ☑初期化関数は、インジケータの起動時(チャートに追加したとき)に1回だけ実行されます。
   ☑インジケータ起動時に最初の1回だけ実行するだけで良い内容を記述します。
==============================================================================*/
int OnInit()
{
   /*---------------------------------------------------------------------------
    (A)描画データと配列の紐づけ
      「3(A)」にて用意した配列を描画データと紐付けます。
   ---------------------------------------------------------------------------*/
   SetIndexBuffer(0,Line1Buffer,     INDICATOR_DATA);
   SetIndexBuffer(1,Line2Buffer,  INDICATOR_DATA);

   /*---------------------------------------------------------------------------
    (B)データウィンドウに表示されるラベル名の設定
      データウィンドウに表示されるラベル名を設定します。
      また、描画データにカーソルを当てた際に設定したラベル名が表示されます。
   ---------------------------------------------------------------------------*/
   PlotIndexSetString(0,PLOT_LABEL,"線1");
   PlotIndexSetString(1,PLOT_LABEL,"線2");
   
   /*---------------------------------------------------------------------------
    (C)初期化関数の処理を終了
      INIT_SUCCEEDED : 初期化成功 : 後述する計算関数(OnCalculate関数)が呼び出されます。
      INIT_FAILED    : 初期化失敗 : 後述する終了関数(Ondeinit関数)が呼び出されます。
   ---------------------------------------------------------------------------*/
   return(INIT_SUCCEEDED);
}

MQL5における計算関数の記述方法

MQL5における計算関数の基本的な記述方法について、以下に解説していきます。

/*==============================================================================
 5.計算関数の記述方法
   ☑計算関数は、値動きの度に(1ティックごとに)実行されます。
   ☑値動きの度に実行が必要な内容(描画データの計算など)を記述します。
   ☑計算関数のパラメータの配列は、最古のローソク足が0で、最新のローソク足がrates_total-1です。
     例)最古のローソク足の時間 : time[0]
     例)最新のローソク足の終値 : close[rates_tatal-1]  ※要は現在レートです。
==============================================================================*/
int OnCalculate(const int      rates_total,     // チャートのローソク足の合計本数
                const int      prev_calculated, // 前回の計算関数で計算済みのローソク足の合計本数
                const datetime &time[],         // 時間
                const double   &open[],         // 始値
                const double   &high[],         // 高値
                const double   &low[],          // 安値
                const double   &close[],        // 終値
                const long     &tick_volume[],  // ティック件数
                const long     &volume[],       // 出来高
                const int      &spread[])       // スプレッド
{
   /*---------------------------------------------------------------------------
    (A)計算対象のローソク足を決定する基本パターン
   ---------------------------------------------------------------------------*/
   int limit; // 計算が必要となるローソク足の開始位置を格納する変数
   if(prev_calculated == 0) // 前回の計算関数で計算済みのローソク足が0本の場合(初回計算時) 
   {
      limit = 0; // すべてのローソク足を計算対象とする。
   } 
   else
   {
      limit = prev_calculated - 1; // 直近1本のローソク足を計算対象とする。(2回目以降の計算時)
   }

   /*---------------------------------------------------------------------------
    (B)描画データを計算する基本パターン
   ---------------------------------------------------------------------------*/
   // 上記①で設定したlimit変数の値からrates_total変数の値以上になるまでfor文を使ってループ処理させるのが基本です。
   for(int i = limit; i < rates_total && !IsStopped(); i++)
   {
      //この中に独自のテクニカルのロジックを記載します。
 
      //線1の描画データを計算して格納
      Line1Buffer[i] = high[i] * InputLine1;
       
      //線2の描画データを計算して格納
      Line2Buffer[i] = Line2Calculate(low[i], InputLine2); // Line2Calculateの自作関数については「(7)」参照
   }

   /*---------------------------------------------------------------------------
    (C)計算関数の処理を終了する基本パターン
   ---------------------------------------------------------------------------*/
   // リターン値に設定した値は、次回の計算関数呼び出し時にprev_calculatedの値として設定されます。
   // このため、計算済みのローソク足の合計本数としてrates_totalをリターン値として設定するのが基本です。
   return(rates_total);
}

MQL5における自作関数の記述方法

MQL5における自作関数の基本的な記述方法について、以下に解説していきます。

/*==============================================================================
 6.自作関数の記述方法
   ☑自作関数は、基本的にC言語と同じ記述方法です。
==============================================================================*/
double Line2Calculate(double low, double test)
{
   //この中に独自のテクニカルのロジックを記載します。
   double calculate = low * test;
   return(calculate);
}

MQL5における終了関数の記述方法

MQL5における終了関数の基本的な記述方法について、以下に解説していきます。

/*==============================================================================
 7.終了関数の記述方法
   ☑終了関数は、インジケータの終了時(チャートから削除した場合など)に1回だけ実行されます。
   ☑最後の1回だけ実行するだけで良い内容(作成したオブジェクトの削除など)を記述します。
==============================================================================*/
void OnDeinit(const int reason)
{
   // 描画データは暗黙的に解放されるため、明示的な処理は不要です。
   // オブジェクトについては、明示的な削除処理が必要です。
   // 今回の例では、終了関数で実施すべきことがないため、何も記述しません。
}

MQL5によるインジケータ作成のまとめ

MQL5によるインジケータ作成のポイントを以下にまとめます。

  • プロパティでバッファを予約する。
  • input修飾子でユーザが変更可能なパラメータ変数を宣言する。
  • インジケータ起動中に常に保持したいデータはグローバル変数に格納する。
  • OnInit()初期化関数は、インジケータ起動時に1回だけ実行される。
  • OnDeinit()終了化関数は、インジケータ終了時に1回だけ実行される。
  • OnCalculate()計算関数は、値動きの度に(1ティックごとに)実行される。
  • 計算関数で描画データを再計算する際は、必要最低限のバーだけにする。
  • 自作関数はC言語と同様に記述できる。

おわりに

本記事での基本を理解することができれば、後はMQL5で予め用意されている関数群を利用しながら、テクニカル分析のロジックをコーディングするだけです。

おさらいとして、本記事の教材であるMQL5ソースのコメント付き全文を以下に示します。

/*==============================================================================
 D_MQL5_Study_001.mq5
==============================================================================*/
/*==============================================================================
 1.プロパティの記述方法
   ☑プロパティでは、インジケータの根幹部分を定義します。
   ☑プロパティは以下の形式で記述します。
     #property プロパティ名 設定値
     ※プロパティ名省略するプロパティがあります。
==============================================================================*/
/*------------------------------------------------------------------------------
 (A)著作権表示の設定
   著作権表示を設定します。
   設定した著作権は、インジケータのプロパティ画面で表示されます。
   #property copyright 著作権表示
------------------------------------------------------------------------------*/
#property copyright "Copyright 2018, Okamori Dou"

/*------------------------------------------------------------------------------
 (B)リンクの設定
   リンクを設定します。
   設定したリンクは、インジケータのプロパティ画面で表示されます。
   #property link リンク
------------------------------------------------------------------------------*/
#property link      "https://metatrader-technical.com/"

/*------------------------------------------------------------------------------
 (C)バージョンの設定
   インジケータのバージョンを設定します。
   設定したバージョンは、インジケータのプロパティ画面で表示されます。
   #property version バージョン
------------------------------------------------------------------------------*/
#property version   "1.00"

/*------------------------------------------------------------------------------
 (D)インジケータを表示するウィンドウの指定
   #property indicator_chart_window   :チャートウィンドウにインジケータを表示する
   #property indicator_separate_window:分割した別ウィンドウにインジケータを表示する
------------------------------------------------------------------------------*/
#property indicator_chart_window

/*------------------------------------------------------------------------------
 (E)インジケータの計算データを格納するバッファの数を予約
   #property indicator_buffers バッファ数(無制限)
------------------------------------------------------------------------------*/
#property indicator_buffers 2

/*------------------------------------------------------------------------------
 (F)インジケータの描画データを格納するバッファの数を予約
   上記Eで予約した計算データバッファのうち描画データとして予約するバッファ数を指定します。
   #property indicator_plots バッファ数(無制限)
------------------------------------------------------------------------------*/
#property indicator_plots   2

/*------------------------------------------------------------------------------
 (G)描画データの描画タイプを設定
   上記Fで予約した描画データの描画タイプを指定します。
   #property indicator_typeN 描画タイプ
   【描画タイプの種類】
      DRAW_LINE      : 線      
      DRAW_HISTOGRAM : ヒストグラム
      DRAW_ARROW     : 矢印
      DRAW_SECTION   : セクション
      等々
------------------------------------------------------------------------------*/
#property indicator_type1   DRAW_LINE
#property indicator_type2   DRAW_LINE

/*------------------------------------------------------------------------------
 (H)描画データの色を設定
   上記Gで指定した描画タイプで描画する際の色を設定します。
   #property indicator_colorN 色
   MQL5で定義済みの色名(赤色はclrRed等)を使用することができます。
   配色にこだわる場合はRGBで指定することもできます。
------------------------------------------------------------------------------*/
#property indicator_color1  clrRed
#property indicator_color2  C'000,255,000'

/*------------------------------------------------------------------------------
 (I)描画データの線の種類を設定
   上記Gで指定した描画タイプで描画する際の線の種類を設定します。
   #property indicator_styleN 線の種類
   【線の種類】
     STYLE_SOLID     :実線
     STYLE_DASH      :破線
     STYLE_DOT       :点線
     STYLE_DASHDOT   :一点鎖線
     STYLE_DASHDOTDOT:二点鎖線
------------------------------------------------------------------------------*/
#property indicator_style1 STYLE_SOLID
#property indicator_style2 STYLE_DASH

/*------------------------------------------------------------------------------
 (J)描画データの線の種類を設定
   上記Gで指定した描画タイプで描画する際の線の太さを設定します。
   線の太さは、線の種類でSTYLE_SOLIDを指定した場合のみ有効です。
   #property indicator_widthN 線の太さ
------------------------------------------------------------------------------*/
#property indicator_width1  3
#property indicator_width2  1

/*------------------------------------------------------------------------------
 (K)描画データのラベル名を設定
   上記Gで予約した描画データのラベル名を設定します。
   インジケータのプロパティから色を変更する際に表示されるラベル名として使用されます。
   #property indicator_labelN ラベル名
------------------------------------------------------------------------------*/
#property indicator_label1  "線1"
#property indicator_label2  "線2"

/*==============================================================================
 2.パラメータの記述方法
   ☑インジケータのプロパティから変更することができるパラメータを定義します。
   ☑パラメータは、以下の形式で記述します。
     修飾子:input  型名:intなど  変数名:任意に決めた名前
==============================================================================*/
input double    InputLine1   = 1.0005;
input double    InputLine2   = 0.9995;

/*==============================================================================
 3.グローバル変数の記述方法
   ☑グローバル変数は、描画データなど常に保持しておきたいデータを格納するために使用します。
==============================================================================*/
/*------------------------------------------------------------------------------
 (A)描画データを格納する配列を用意
   「1(F)」にて予約した4個のバッファの描画データを実際に格納する配列を用意します。
------------------------------------------------------------------------------*/
double Line1Buffer[];
double Line2Buffer[];

/*==============================================================================
 4.初期化関数の記述方法
   ☑初期化関数は、インジケータの起動時(チャートに追加したとき)に1回だけ実行されます。
   ☑インジケータ起動時に最初の1回だけ実行するだけで良い内容を記述します。
==============================================================================*/
int OnInit()
{
   /*---------------------------------------------------------------------------
    (A)描画データと配列の紐づけ
      「3(A)」にて用意した配列を描画データと紐付けます。
   ---------------------------------------------------------------------------*/
   SetIndexBuffer(0,Line1Buffer,     INDICATOR_DATA);
   SetIndexBuffer(1,Line2Buffer,  INDICATOR_DATA);

   /*---------------------------------------------------------------------------
    (B)データウィンドウに表示されるラベル名の設定
      データウィンドウに表示されるラベル名を設定します。
      また、描画データにカーソルを当てた際に設定したラベル名が表示されます。
   ---------------------------------------------------------------------------*/
   PlotIndexSetString(0,PLOT_LABEL,"線1");
   PlotIndexSetString(1,PLOT_LABEL,"線2");
   
   /*---------------------------------------------------------------------------
    (C)初期化関数の処理を終了
      INIT_SUCCEEDED : 初期化成功 : 後述する計算関数(OnCalculate関数)が呼び出されます。
      INIT_FAILED    : 初期化失敗 : 後述する終了関数(Ondeinit関数)が呼び出されます。
   ---------------------------------------------------------------------------*/
   return(INIT_SUCCEEDED);
}

/*==============================================================================
 5.計算関数の記述方法
   ☑計算関数は、値動きの度に(1ティックごとに)実行されます。
   ☑値動きの度に実行が必要な内容(描画データの計算など)を記述します。
   ☑計算関数のパラメータの配列は、最古のローソク足が0で、最新のローソク足がrates_total-1です。
     例)最古のローソク足の時間 : time[0]
     例)最新のローソク足の終値 : close[rates_tatal-1]  ※要は現在レートです。
==============================================================================*/
int OnCalculate(const int      rates_total,     // チャートのローソク足の合計本数
                const int      prev_calculated, // 前回の計算関数で計算済みのローソク足の合計本数
                const datetime &time[],         // 時間
                const double   &open[],         // 始値
                const double   &high[],         // 高値
                const double   &low[],          // 安値
                const double   &close[],        // 終値
                const long     &tick_volume[],  // ティック件数
                const long     &volume[],       // 出来高
                const int      &spread[])       // スプレッド
{
   /*---------------------------------------------------------------------------
    (A)計算対象のローソク足を決定する基本パターン
   ---------------------------------------------------------------------------*/
   int limit; // 計算が必要となるローソク足の開始位置を格納する変数
   if(prev_calculated == 0) // 前回の計算関数で計算済みのローソク足が0本の場合(初回計算時) 
   {
      limit = 0; // すべてのローソク足を計算対象とする。
   } 
   else
   {
      limit = prev_calculated - 1; // 直近1本のローソク足を計算対象とする。(2回目以降の計算時)
   }

   /*---------------------------------------------------------------------------
    (B)描画データを計算する基本パターン
   ---------------------------------------------------------------------------*/
   // 上記①で設定したlimit変数の値からrates_total変数の値以上になるまでfor文を使ってループ処理させるのが基本です。
   for(int i = limit; i < rates_total && !IsStopped(); i++)
   {
      //この中に独自のテクニカルのロジックを記載します。
 
      //線1の描画データを計算して格納
      Line1Buffer[i] = high[i] * InputLine1;
       
      //線2の描画データを計算して格納
      Line2Buffer[i] = Line2Calculate(low[i], InputLine2); // Line2Calculateの自作関数については「(7)」参照
   }

   /*---------------------------------------------------------------------------
    (C)計算関数の処理を終了する基本パターン
   ---------------------------------------------------------------------------*/
   // リターン値に設定した値は、次回の計算関数呼び出し時にprev_calculatedの値として設定されます。
   // このため、計算済みのローソク足の合計本数としてrates_totalをリターン値として設定するのが基本です。
   return(rates_total);
}

/*==============================================================================
 6.自作関数の記述方法
   ☑自作関数は、基本的にC言語と同じ記述方法です。
==============================================================================*/
double Line2Calculate(double low, double test)
{
   //この中に独自のテクニカルのロジックを記載します。
   double calculate = low * test;
   return(calculate);
}

/*==============================================================================
 7.終了関数の記述方法
   ☑終了関数は、インジケータの終了時(チャートから削除した場合など)に1回だけ実行されます。
   ☑最後の1回だけ実行するだけで良い内容(作成したオブジェクトの削除など)を記述します。
==============================================================================*/
void OnDeinit(const int reason)
{
   // 描画データは暗黙的に解放されるため、明示的な処理は不要です。
   // オブジェクトについては、明示的な削除処理が必要です。
   // 今回の例では、終了関数で実施すべきことがないため、何も記述しません。
}

コメント

非公開コメント