MTF(マルチタイムフレーム)で移動平均線を表示するインジケーター
MTFとはマルチタイムフレームの略語で、
ある時間軸の移動平均線を違う時間軸のチャートに表示できるインジケーターです。
MTFインジケーターを活用することで、
下位足を表示させていても上位足の状況を判断することができるといった優れものです。
今回は、MTFで移動平均線を表示するインジケーターを作成していきます。
メタエディタ(MetaEditor)を立ち上げる
メタエディタ(MetaEditor)を立ち上げましょう。操作は以下に記載しています。

今回は名前を「MTF-Ma」で作成します。
プロパティを記述する
プロパティを記述しましょう。バッファはラインを表示させるだけなので1です。
#property indicator_buffers 1//バッファ1
線に設定します。
#property indicator_type1 DRAW_LINE//線
色を水色に設定します。
#property indicator_color1 clrAqua//色
線の種類を実線にします。
#property indicator_style1 STYLE_SOLID//実線
幅を1にします。
#property indicator_width1 1//幅
これでプロパティの記述は完了です。
#property indicator_buffers 1//バッファ1 #property indicator_type1 DRAW_LINE//線 #property indicator_color1 clrAqua//色 #property indicator_style1 STYLE_SOLID//実線 #property indicator_width1 1//幅
バッファを定義する
バッファを定義しましょう。
double ma[];//バッファ
これでバッファの定義は完了です。
double ma[];//バッファ
OnInit()関数を記述する
OnInit()関数を記述しましょう。
インデックス0にmaを格納します。
SetIndexBuffer(0, ma);//インデックス0にmaを格納
ラベルを表示させます。
SetIndexLabel(0, StringFormat("MA(%d) [%s]", MaPeriod, EnumToString(TimeFrame)));//ラベルこれでOnInit()関数の記述は完了です。
SetIndexBuffer(0, ma);//インデックスにmaを格納
SetIndexLabel(0, StringFormat("MA(%d) [%s]", MaPeriod, EnumToString(TimeFrame)));//ラベルパラメーターを記述する
パラメーターを記述しましょう。
TimeFrameは対象の時間軸を指定します。今回はCurrentにします。
input ENUM_TIMEFRAMES TimeFrame = Current;//対象の時間軸
MAの期間を21に指定します。
input int MaPeriod = 21;//期間
シフトは0に指定します。
input int MaShift = 0;//シフト
MAの種類はsimpleに指定します。
input ENUM_MA_METHOD MaMethod = simple;//種類
適正価格はClosePriceに指定します。
input ENUM_APPLIED_PRICE MaAppliedPrice = ClosePrice;//適正価格
これでパラメーターを記述は完了です。
input ENUM_TIMEFRAMES TimeFrame = Current;//対象の時間軸 input int MaPeriod = 21;//期間 input int MaShift = 0;//シフト input ENUM_MA_METHOD MaMethod = simple;//種類 input ENUM_APPLIED_PRICE MaAppliedPrice = ClosePrice;//適正価格
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);
}コンパイルする
コンパイルして、移動平均線の上位足を下位足にセットすれば表示されます。

ソースコード全体
MTF-Maのソースコード全体は以下に記載しています。
//+------------------------------------------------------------------+
//| 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//バッファ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 = Current;//対象の時間軸
input int MaPeriod = 21;//期間
input int MaShift = 0;//シフト
input ENUM_MA_METHOD MaMethod = simple;//種類
input ENUM_APPLIED_PRICE MaAppliedPrice = ClosePrice;//適正価格
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer(0, ma);//インデックス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);
}
//+------------------------------------------------------------------+まとめ
MTFは独特な考え方が必要で難易度が高くなりますが、
考え方さえわかってしまえば他にもMTFは応用が可能です。
MTFのインジケーターは非常に重要なのでぜひマスターしておきましょう。






コメント