ホーム » FX自動売買基礎と応用 » MT5でMTF(マルチタイムフレーム)のMAを作成する【MQLプログラミングの基礎】

MT5でMTF(マルチタイムフレーム)のMAを作成する【MQLプログラミングの基礎】

1.ファイルの新規作成

この記事では、「MT5版の簡易MAにパラメーターを追加する【MQLプログラミングの基礎】」で作成した簡易MAファイルを編集し、マルチタイムフレームのMA(移動平均線)を作成します。

※この記事はMQL5の内容です。MQL4に対応した類似記事は以下を参照してください。

MQLプログラミング言語でマルチタイムフレームを表示する方法

マルチタイムフレームとは、チャートに表示されている時間足とは別の時間足の情報で計算した結果を表示する機能です。
簡易MAファイルを開いた後、MetaEditorメニューの「ファイル」から「名前を付けて保存」を開き、ファイル名称を「MTF_MA」に変更して保存し、そのファイルを編集します。

2.時間足を指定

時間足を指定するためのパラメーターを既存パラメーターの先頭に追加します。
時間足を扱う列挙型である「ENUM_TIMEFRAMES」を利用して定義します。
初期設定は1時間足を指定しています。


input ENUM_TIMEFRAMES TIMEFRAME = PERIOD_H1; // 時間足

次に、定義したパラメーターをOnInit関数内のMAハンドルへ貼り付けます。

handle = iMA(NULL, 0, PERIOD, SHIFT, METHOD, PRICE);」を
handle = iMA(NULL, TIMEFRAME, PERIOD, SHIFT, METHOD, PRICE);」へ変更します。

3.時間足情報の補正

従来は、OnCalculate関数内にて、MA用のバッファ「MABuffer」へ定義したハンドルを下記の行でコピーしていました。


CopyBuffer(handle, 0, 0, limit, MABuffer);

マルチタイムフレーム対応のため、上記の式を変更します。
別時間足の値を格納する配列を用意してMA情報はそこへコピーし、時間足の補正をしながら、MA用のバッファへ入力する式を作成します。
まずは、別時間足用の配列を定義します。
OnCalculate関数内の先頭に、下記を追加します。


  double mtfMa[];
  ArraySetAsSeries(mtfMa, true);

定義した配列へMA情報をコピーするようにします。

CopyBuffer(handle, 0, 0, limit, MABuffer);」を
CopyBuffer(handle, 0, 0, limit, mtfMa);」へ変更します。

補正の際にOnCalculate関数で定義されている時間配列「time」を利用するので、配列の並びを指定します。

ArraySetAsSeries(mtfMa, true);」の下に
ArraySetAsSeries(time, true);」を追加します。

for文を追加し、時間足を補正しながらMA用のバッファ「MABuffer」に別時間足のMA情報「mtfMa」を入力します。
指定した時間に対応する、指定した時間足のバーの値(足の位置)を出力してくれるiBarShift関数を利用して、補正の式を作成します。


   for (int i = limit - 1; i >= 0; i--) {
      int bar = iBarShift(NULL, TIMEFRAME, time[i]);
      MABuffer[i] = mtfMa[bar];
   }

  • ・time[i]:チャートで表示されている足「i」の時間
  • ・TIMEFRAME:指定時間足(1時間足)
  • ・bar:指定した時間足(1時間足)のバーの値

元から定義されていた計算範囲の変数limitのままだと、最新部の計算範囲に不足が発生するため、修正します(パラメーターで上位の時間足を指定した場合、上位足1本に対応するチャートのローソク足は複数となる)。

if (limit < 1) limit = 1;」を下記の通りに変更します。


   int min = PeriodSeconds(TIMEFRAME) / PeriodSeconds() + 1;
   if (limit < min) limit = min;

パラメーターでチャートの時間足より小さい時間足を指定した場合、あまり意味のない計算となってしまうので、その場合は計算を実行しないよう、下記をOnCalculate関数の先頭に追加します。


  if (TIMEFRAME < _Period && TIMEFRAME != PERIOD_CURRENT) return 0;

指定した時間足「TIMEFRAME」が、チャートの時間足「Period」より小さく、かつ現在の時間足「PERIOD_CURRENT」が指定されていない場合、それ以上の計算処理をしないようになります。

上記までの改修で、完成となります。
コンパイル後にチャートへセットすると、マルチタイムフレームのMAを表示できるようになります。

MAの比較

1時間足の計算をH1チャートへそのまま表示したのが上の画像です。
比較のためにM15チャートへ表示したのが下の画像です。
並べて比較することで、M15チャートでも1時間足の情報で計算されていることが分かります。

4.ソースコード

今回、作成したソースコードは下記の通りです。


//+------------------------------------------------------------------+
//|                                                       MTF_MA.mq5 |
//|                                  Copyright 2025, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1

input ENUM_TIMEFRAMES TIMEFRAME = PERIOD_H1; // 時間足
input int PERIOD = 20; // 期間
input int SHIFT = 0; // シフト
input ENUM_MA_METHOD METHOD = MODE_SMA; // MA種別
input ENUM_APPLIED_PRICE PRICE = PRICE_CLOSE; // 適用価格
input color CLR = clrRed; // 色
input ENUM_LINE_STYLE STYLE = STYLE_SOLID; // 線種
input int WIDTH = 1; // 太さ

//--- indicator buffers
double         MABuffer[];
int handle; 
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,MABuffer,INDICATOR_DATA);
   PlotIndexSetInteger(0, PLOT_LINE_COLOR, CLR);
   PlotIndexSetInteger(0, PLOT_LINE_STYLE, STYLE);
   PlotIndexSetInteger(0, PLOT_LINE_WIDTH, WIDTH);
   PlotIndexSetInteger(0, PLOT_DRAW_TYPE, DRAW_LINE);
   PlotIndexSetString(0, PLOT_LABEL, StringSubstr(EnumToString(METHOD), 5) + "(" + (string)PERIOD + ")");
   ArraySetAsSeries(MABuffer, true);
   handle = iMA(NULL, TIMEFRAME, PERIOD, SHIFT, METHOD, PRICE);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   IndicatorRelease(handle);
  }
//+------------------------------------------------------------------+
//| 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[])
  {
  if (TIMEFRAME < _Period && TIMEFRAME != PERIOD_CURRENT) return 0;
  
  double mtfMa[];
  ArraySetAsSeries(mtfMa, true);
  ArraySetAsSeries(time, true);
//---
   int limit = rates_total - prev_calculated;
   int min = PeriodSeconds(TIMEFRAME) / PeriodSeconds() + 1;
   if (limit < min) limit = min;
   CopyBuffer(handle, 0, 0, limit, mtfMa);
   
   for (int i = limit - 1; i >= 0; i--) {
      int bar = iBarShift(NULL, TIMEFRAME, time[i]);
      MABuffer[i] = mtfMa[bar];
   }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+

本記事の監修者・HT FX

2013年にFXを開始し、その後専業トレーダーへ。2014年からMT4/MT5のカスタムインジケーターの開発に取り組む。ブログでは100本を超えるインジケーターを無料公開。投資スタイルは自作の秒足インジケーターを利用したスキャルピング。

EA(自動売買)を学びたい方へオススメコンテンツ

EA運用の注意点

OANDAではEA(自動売買)を稼働するプラットフォームMT4/MT5の基本的な使い方について、画像や動画付きで詳しく解説しています。MT4/MT5のインストールからEAの設定方法までを詳しく解説しているので、初心者の方でもスムーズにEA運用を始めることが可能です。またOANDAの口座をお持ちであれば、独自開発したオリジナルインジケーターを無料で利用することもできます。EA運用をお考えであれば、ぜひ口座開設をご検討ください。


本ホームページに掲載されている事項は、投資判断の参考となる情報の提供を目的としたものであり、投資の勧誘を目的としたものではありません。投資方針、投資タイミング等は、ご自身の責任において判断してください。本サービスの情報に基づいて行った取引のいかなる損失についても、当社は一切の責を負いかねますのでご了承ください。また、当社は、当該情報の正確性および完全性を保証または約束するものでなく、今後、予告なしに内容を変更または廃止する場合があります。なお、当該情報の欠落・誤謬等につきましてもその責を負いかねますのでご了承ください。

この記事をシェアする