FX-EA System Projectはこちら公式ラインに登録して
プレゼントをもらう

【MQL】MTF(マルチタイムフレーム)で移動平均線を表示するインジケーター【上級編】

MQL インジケーター MTF 移動平均線を表示MT4インジケーター作成

MTF(マルチタイムフレーム)で移動平均線を表示するインジケーター

MTFとはマルチタイムフレームの略語で、

ある時間軸の移動平均線を違う時間軸のチャートに表示できるインジケーターです。

MTFインジケーターを活用することで、

下位足を表示させていても上位足の状況を判断することができるといった優れものです。

今回は、MTFで移動平均線を表示するインジケーターを作成していきます。

メタエディタ(MetaEditor)を立ち上げる

メタエディタ(MetaEditor)を立ち上げましょう。操作は以下に記載しています。

【MQL】カスタムインジケーターを作成の流れについてわかりやすく説明してみた

今回は名前を「MTF-Ma」で作成します。

プロパティを記述する

プロパティを記述しましょう。バッファは1です。

#property indicator_chart_window//メインウィンドウ
#property indicator_buffers 1//バッファ
#property indicator_type1 DRAW_LINE//線
#property indicator_color1 clrAqua//色
#property indicator_style1 STYLE_SOLID//実線
#property indicator_width1 1//幅
Copy

バッファを定義する

バッファを定義しましょう。

double ma[];//バッファ
Copy

OnInit()関数を記述する

OnInit()関数を記述しましょう。

SetIndexBuffer(0, ma);//インデックスにバッファを格納
    SetIndexLabel(0, StringFormat("MA(%d) [%s]", MaPeriod, EnumToString(TimeFrame)));//ラベル
Copy

パラメーターを記述する

パラメーターを記述しましょう。

input ENUM_TIMEFRAMES    TimeFrame; // 対象の時間軸
input int                MaPeriod;//期間
input int                MaShift;//シフト
input ENUM_MA_METHOD     MaMethod;//種類
input ENUM_APPLIED_PRICE MaAppliedPrice;//適正価格
Copy

OnCalculateを記述する

OnCalculateを記述しましょう。

iBarShift()関数は、指定した通貨ペア・時間軸・日時におけるバーの位置を取得するために使用します。

int shift_need_recalculate = iBarShift(NULL, Period(), iTime(NULL, TimeFrame, 0));

rate_totalとはインジケーターが持っている配列の要素数です。

チャートに新しいバーが出るたびに1つずつ増えていきます。最初はチャートのバー本数と一致します。

rate_totalがshift_need_recalculateよりも低ければ、return0で返します。

if (rates_total <= shift_need_recalculate) 
{ 
   return 0; 
}

prev_calculatedはrate_totalに対してすでに計算済みの要素数を指定します。

ただし、実際にはOnCalculateを呼び出した際のreturnの値が格納されています。

まだ一度も呼び出されていない場合は0です。

rates_totalからprev_calculatedを引いているので現在の最新のバーが残ります。

int num_uncalculated = rates_total - prev_calculated;

MathMaxで

  • shift_need_recalculate
  • num_uncalculated – 1

の2つの値の最大値を返します。その値を初期値iに代入して、for文で0になるまでループさせます。

for (int i = MathMax(shift_need_recalculate, num_uncalculated - 1); i >= 0; i--)

iBarShiftでtime[i]をshiftに代入します。

shiftをiMA関数のシフトの引数にしてma[i]に代入します。

  int shift = iBarShift(NULL, TimeFrame, time[i]);
  ma[i] = iMA(NULL, TimeFrame, MaPeriod, MaShift, MaMethod, MaAppliedPrice, shift);

OnCalculateはこれで完了です。

int shift_need_recalculate = iBarShift(NULL, Period(), iTime(NULL, TimeFrame, 0));

if (rates_total <= shift_need_recalculate) 
{ 
   return 0; 
} 
int num_uncalculated = rates_total - prev_calculated; 
for (int i = MathMax(shift_need_recalculate, num_uncalculated - 1); i >= 0; i--) 
{
    int shift = iBarShift(NULL, TimeFrame, time[i]);
    ma[i] = iMA(NULL, TimeFrame, MaPeriod, MaShift, MaMethod, MaAppliedPrice, shift);
}
Copy

コンパイルする

コンパイルして、移動平均線の上位足を下位足にセットすれば表示されます。

MQL インジケーター MTF 移動平均線を表示

ソースコード全体

//+------------------------------------------------------------------+
//|                                                       MTF-Ma.mq4 |
//|                     Copyright 2020, FX-EA System Project Creator |
//|                        https://creator.fx-ea-system-project.com/ |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, FX-EA System Project Creator"
#property link      "https://creator.fx-ea-system-project.com/"
#property version   "1.00"
#property strict

/*プロパティ*/
#property indicator_chart_window//メインウィンドウ
#property indicator_buffers 1//バッファ
#property indicator_type1 DRAW_LINE//線
#property indicator_color1 clrAqua//色
#property indicator_style1 STYLE_SOLID//実線
#property indicator_width1 1//幅

/*バッファ*/
double ma[];//バッファ

/*パラメーター*/
input ENUM_TIMEFRAMES    TimeFrame; // 対象の時間軸
input int                MaPeriod;//期間
input int                MaShift;//シフト
input ENUM_MA_METHOD     MaMethod;//種類
input ENUM_APPLIED_PRICE MaAppliedPrice;//適正価格

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
    SetIndexBuffer(0, ma);//インデックスにバッファを格納
    SetIndexLabel(0, StringFormat("MA(%d) [%s]", MaPeriod, EnumToString(TimeFrame)));//ラベル
//---
   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[])
  {
//---
   int shift_need_recalculate = iBarShift(NULL, Period(), iTime(NULL, TimeFrame, 0));

    if (rates_total <= shift_need_recalculate) { 
   return 0;
  }
  int num_uncalculated = rates_total - prev_calculated;
  for (int i = MathMax(shift_need_recalculate, num_uncalculated - 1); i >= 0; i--) 
  {
        int shift = iBarShift(NULL, TimeFrame, time[i]);
        ma[i] = iMA(NULL, TimeFrame, MaPeriod, MaShift, MaMethod, MaAppliedPrice, shift);
    }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
Copy

まとめ

MTFは独特な考え方が必要で難易度が高くなりますが、

考え方さえわかってしまえば他にもMTFは応用が可能です。

コメント

タイトルとURLをコピーしました