[MQL] インジケーターバッファの使い方まとめ(サンプルコード)

インジケーターバッファの使い方をまとめた記事です。

最小構成のサンプルプログラムを載せておきますので、必要な個所を書き換えるだけでインジ化できます。

ではどうぞ。

インジケーターバッファとは?

インジケーターバッファとは一言で言うと「インジケーター用の配列」です。

通常の配列とインジケーターバッファの違いは下表の通り。

比較項目 通常の配列 インジケータバッファ
データ型 任意指定(double型、int型、string型 など) double型のみ
次元数 任意指定 1次元のみ
要素数 任意指定 自動で決まる(チャート上のバー本数と同数)
特殊な性質① なし 新規バーが増えると、要素数が自動で追加され、インデックスの振り直し(一つづつシフトするイメージ)が行われる
特殊な性質② なし インジケーターバッファの値をチャート上にライン・矢印・ヒストグラムなどでグラフィカルに表示できる

インジケーターバッファをもう少しかみ砕いて言うと、

  • チャート上にグラフィカルに値を示す機能を持った配列
  • 機能を実現するためにあらかじめいくつかの特別な仕様が定められている配列

であるといえますね。

他のプログラム言語には無い概念のためはじめはとっつきにくいかもしれません。ですが、インジケータバッファを使っていくつかプログラムを作っていくうちに仕組みが理解できるようになります。

以下では、インジケーターバッファを使ったサンプルプログラムを紹介します。

インジケーターバッファを使ったプログラム例

インジケーターバッファを使ってシンプルなインジを作成しました。(下図)

インジケータバッファを使ったサンプルインジ

ローソク足の高値と安値の範囲を示すインジケーターです。赤いラインは各バーの高値をつないでおり、青いラインが安値をつないでいます。インジケーターバッファを2つ使用しています。(ちなみに実際のトレードにはほぼ役に立ちません。)

このインジケーターのプログラム内容は下記の通りです。

//+------------------------------------------------------------------+
//|                                             Mi_Buffer_sample.mq4 |
//|                                                     minagachi FX |
//|                                            https://minagachi.com |
//+------------------------------------------------------------------+
#property copyright "minagachi fX"
#property link      "https://minagachi.com"
#property description "https://minagachi.com"
#property version   "1.00"
#property strict
#property indicator_chart_window

//インジケーターバッファの数を宣言(2つ)
#property indicator_buffers 2

//インジケーターバッファ用の配列
double Buffer_A[];
double Buffer_B[];

//入力パラメーター
input ENUM_LINE_STYLE style_A = STYLE_SOLID; //スタイル
input ENUM_LINE_STYLE style_B = STYLE_SOLID; //スタイル
input int             width_A = 2;           //太さ
input int             width_B = 2;           //太さ
input color           color_A = clrRed;      //色
input color           color_B = clrBlue;     //色

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit(){

   //インジ名称
   IndicatorShortName("NAME"); //マウスオバー時にポップアップ表示される

   //各インデックスに配列を紐づけ
   SetIndexBuffer(0, Buffer_A);
   SetIndexBuffer(1, Buffer_B);

   //各インデックスのスタイルを設定
   SetIndexStyle(0, DRAW_LINE, style_A, width_A, color_A);
   SetIndexStyle(1, DRAW_LINE, style_B, width_B, color_B);

   //各インデックスのラベル名
   SetIndexLabel(0, "HIGH"); //マウスオバー時にポップアップ表示される
   SetIndexLabel(1, "LOW");  //マウスオバー時にポップアップ表示される

   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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[])
{

   //まだ計算していない最古バーのインデックス番号を算出し、変数limitに代入
   int limit = rates_total - prev_calculated - 1;
   if(limit < 0) limit = 0;

   //バッファの値を計算
   CalculateBuffer(limit);

   return(rates_total);
}
//+------------------------------------------------------------------+
//| Functions                                                        |
//+------------------------------------------------------------------+
void CalculateBuffer(int limit){

   //limitから最新バーまでを計算する
   for(int i = limit; i >= 0; i--){

      //空値で初期化
      Buffer_A[i] = EMPTY_VALUE;
      Buffer_B[i] = EMPTY_VALUE;

      //値を入れる
      Buffer_A[i] = iHigh(NULL, 0, i);
      Buffer_B[i] = iLow(NULL, 0, i);
   }

}

↑全ソースコードです。汎用的に書いてありますので、適当にいじってカスタマイズしてください。

プログラミングのポイント

インジケーターバッファを使ったプログラミングのポイントを順にメモします。

①最初にバッファ数を宣言

使用するインジケーターバッファの数を冒頭の#propertyにて宣言します。今回は2つのバッファを使用しました。

//インジケーターバッファの数を宣言(2つ)
#property indicator_buffers 2

②グローバルエリアで配列を宣言

インジケーターバッファとして使用する配列は、グローバルエリアで宣言します。

//インジケーターバッファ用の配列
double Buffer_A[];
double Buffer_B[];

③配列の紐づける

OnInit()内にて、インジケーターバッファとして使用する配列をインデックス番号で紐づけます。

//各インデックスに配列を紐づけ
SetIndexBuffer(0, Buffer_A);
SetIndexBuffer(1, Buffer_B);

④ラインや矢印などの表示スタイル指定する

インジケーターバッファの値は、自動でラインや矢印などの形にビジュアル化されます。その際の表示形式をSetIndexStyle()で指定します。

//各インデックスのスタイルを設定
SetIndexStyle(0, DRAW_LINE, style_A, width_A, color_A);
SetIndexStyle(1, DRAW_LINE, style_B, width_B, color_B);

⑤各バッファの値を計算する

OnCalculate()内にて、各インジケータバッファの値を計算します。計算量を最小限にするために、まだ計算していないバッファのみが計算対象となるように処理を書きます。下は、まだ計算していないバッファのインデックスをlimitとしています。

//まだ計算していない最古バーのインデックス番号を算出し、変数limitに代入
int limit = rates_total - prev_calculated - 1;
if(limit < 0) limit = 0;

//バッファの値を計算
CalculateBuffer(limit);

return(rates_total);

↑ここの処理の意味が分からない場合は、rates_totalprev_calculatedがどのような値なのかをリファレンスで調べると良いと思います。

まとめ

この記事では、インジケーターバッファを使ったプログラミングの例を説明しました。

インジケーターバッファを使う際はいくつか「お約束」の手続きを行いますが、「あと何が必要だったっけ?」といつも忘れてしまって調べ直していました。さすがに面倒だということで、今回テンプレートに近い形にまとめて記事としました。

それでは

コメント

この記事へのコメント(0 件)