インジケーター作成09

マルチタイムフレーム機能付きのインジケーターにしてみよう!

ここでは、以前作成した終値を結んだラインを描画するインジケーター【Sample_Indcator_02.mq4】をカスタマイズして、表示チャートの時間足より長期の時間足の終値を結んだラインを描画するインジケーターにする方法を解説します。

インジケーター【Sample_Indcator_02.mq4】は、記事[インジケーター作成2【過去部分の描画方法】]で完成したインジケーターファイルです。
過去記事 インジケーター作成2【過去部分の描画方法】へ

カスタマイズ前のコード

Dr.EADr.EA

インジケーター作成2【過去部分の描画方法】で完成したファイルのコードがこちら

#property strict
#property indicator_chart_window
#property indicator_buffers 1          // インジケーターバッファ 1つ
#property indicator_color1 clrRed      // 1つ目の色 赤色
#property indicator_width1 2           // 1つ目の太さ 2

double buf[];                          // ライン用の配列を宣言

//+------------------------------------------------------------------+
int OnInit()
{
   SetIndexBuffer(0, buf);             // 配列 buf[]をインジケーター用に割り当てる
   SetIndexStyle(0, DRAW_LINE);        // 描画タイプをラインと定義

   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 i;
   int limit;
   if (prev_calculated == 0)              // 最初
      limit = rates_total - 1;               // 左端のローソク足から全部
   else                                   // それ以外
      limit = rates_total - prev_calculated; // ローソク足増加時「1」、通常「0」
   
   for (i=limit; i>=0; i--)               // limit本前から現在のローソク足を処理
   {
      buf[i] = Close[i];
   }
   
   return(rates_total);
}

【Sample_Indicator_02.mq4】をダウンロード

カスタマイズ内容

パラメーターを追加する

マルチタイムフレーム機能付きにするために、次のように時間足周期を選択するパラメーターを追加します。

extern ENUM_TIMEFRAMES  Timeframe   = PERIOD_D1;

パラメーター設定を補正

パラメーター「Timeframe」で表示チャートより短い周期を設定した場合は、OnInit()関数内でパラメーター変数「Timeframe」を表示チャートの時間足に補正します。

   if (Timeframe != PERIOD_CURRENT && Timeframe < Period()) Timeframe = PERIOD_CURRENT;

表示させる値を取得

表示チャート以外の終値を取得するには、iClose()関数を使用します。

iClose(通貨ペア名, 時間足, シフト数)

表示チャート以外のシフト数を知るには、iBarShift()関数を使用します。

iBarShift()関数について

iBarShift()関数の()括弧内は次のように指定します。

iBarShift(通貨ペア名, 時間足, 時間, 戻り値モード)

通貨ペア名
通貨ペアを文字列で指定します。NULLとすると表示チャートの通貨ペアのことになります。

時間足
時間足を整数または定数で指定します。0またはPERIOD_CURRENTとすると表示チャートの時間足のことになります。
1分足は1またはPERIOD_M1、5分足は5またはPRIOD_M5というように指定します。

時間
datetime型の時間を指定します。

戻り値モード
false(または省略): 指定した時間のバーがない場合は、最も近いバーのシフト数を返します。
true: 指定した時間のバーがない場合は、-1 を返します。

OnCalculate()関数内のfor()文内で、次のようにClose[]の代わりに、iClose()関数を使用してパラメーター「Timeframe」で指定した時間足の終値を取得します。

      int bar_shift = iBarShift(NULL, Timeframe, Time[i]);  // シフト数iの指定時間足のシフト数
      buf[i] = iClose(NULL, Timeframe, bar_shift);          // 指定時間足のシフト数の終値をbuf[i]に代入

経過途中のバーにも値を反映させる

例えば1時間足に日足の終値を表示させる場合には、0時から23時の24個の値を日足の終値に揃えるようにします。そのため表示開始後からは、次のようにTimeframeで指定したローソク足のシフト数が変わるまでさかのぼって代入し直します。

      if (i > 1) continue; // 表示開始時は以降スキップ
      
      // 経過途中をbuf[i]に揃える
      for (j=1; i+j<rates_total ;j++)
      {
         if (iBarShift(NULL, Timeframe, Time[i+j]) != bar_shift) break;
         buf[i+j] = buf[i];
      }
Dr.EADr.EA

今回完成ファイルのコードがこちら

#property strict
#property indicator_chart_window
#property indicator_buffers 1          // インジケーターバッファ 1つ
#property indicator_color1 clrRed      // 1つ目の色 赤色
#property indicator_width1 2           // 1つ目の太さ 2

extern ENUM_TIMEFRAMES  Timeframe   = PERIOD_D1;

double buf[];                          // ライン用の配列を宣言

//+------------------------------------------------------------------+
int OnInit()
{
   // Timeframe 設定補正
   if (Timeframe != PERIOD_CURRENT && Timeframe < Period()) Timeframe = PERIOD_CURRENT;
   
   SetIndexBuffer(0, buf);             // 配列 buf[]をインジケーター用に割り当てる
   SetIndexStyle(0, DRAW_LINE);        // 描画タイプをラインと定義
   
   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 i, j;
   int limit;
   if (prev_calculated == 0)              // 最初
      limit = rates_total - 1;               // 左端のローソク足から全部
   else                                   // それ以外
      limit = rates_total - prev_calculated; // ローソク足増加時「1」、通常「0」
   
   for (i=limit; i>=0; i--)               // limit本前から現在のローソク足を処理
   {
      int bar_shift = iBarShift(NULL, Timeframe, Time[i]);  // シフト数iの指定時間足のシフト数
      buf[i] = iClose(NULL, Timeframe, bar_shift);          // 指定時間足のシフト数の終値をbuf[i]に代入
      
      if (i > 1) continue; // 表示開始時は以降スキップ
      
      // 経過途中をbuf[i]に揃える
      for (j=1; i+j<rates_total ;j++)
      {
         if (iBarShift(NULL, Timeframe, Time[i+j]) != bar_shift) break;
         buf[i+j] = buf[i];
      }
   }
   
   return(rates_total);
}

今回完成ファイル【Sample_Indicator_09.mq4】をダウンロード

あとがき

今回は簡単にMTF(マルチタイムフレーム)機能付きのインジケーターにする方法を紹介しました。他にも、いろんなやり方があるので挑戦してみてください^^

MTF機能を使用する場合は、指定時間足のヒストリカルデータがあるかどうかを確認してから使用するようにしましょう。