ホーム » FX自動売買基礎と応用 » MT5で移動平均線クロスの矢印サインを表示する【MQLプログラミングの基礎】

MT5で移動平均線クロスの矢印サインを表示する【MQLプログラミングの基礎】

1.2本のMAを表示する

この記事では、「MT5版の簡易MAにパラメーターを追加する【MQLプログラミングの基礎】」で作成した簡易MAファイルを編集し、2本の移動平均線(MA)を利用したサイン表示プログラムを作成します。
簡易MAファイルを開いた後、MetaEditorメニューの「ファイル」から「名前を付けて保存」を開き、ファイル名称を「MA_Cross_Sign」に変更して保存し、そのファイルを編集します。

まずは、MAを2本表示できるようにします。
バッファ数を「2」に変更し、パラメーター1式をコピー・貼り付けして増やします。
2本を区別できるよう、1つ目のMA関係のパラメーターの末尾に「0」を、2つ目の末尾に「1」をつけます。
1つ目と2つ目の区切りが分かりやすいよう、「group」行を追加します。
1つ目のMA(短期)の期間を「5」とし、2つ目のMA(長期)の色は「Yellow」に変更しています。


#property indicator_buffers 2
#property indicator_plots   2

input group "【MA1】"
input int PERIOD0 = 5; // 期間
input int SHIFT0 = 0; // シフト
input ENUM_MA_METHOD METHOD0 = MODE_SMA; // MA種別
input ENUM_APPLIED_PRICE PRICE0 = PRICE_CLOSE; // 適用価格
input color CLR0 = clrRed; // 色
input ENUM_LINE_STYLE STYLE0 = STYLE_SOLID; // 線種
input int WIDTH0 = 1; // 太さ

input group ""
input group "【MA2】"
input int PERIOD1 = 20; // 期間
input int SHIFT1 = 0; // シフト
input ENUM_MA_METHOD METHOD1 = MODE_SMA; // MA種別
input ENUM_APPLIED_PRICE PRICE1 = PRICE_CLOSE; // 適用価格
input color CLR1 = clrYellow; // 色
input ENUM_LINE_STYLE STYLE1 = STYLE_SOLID; // 線種
input int WIDTH1 = 1; // 太さ

計算用にそれぞれのバッファおよびハンドルが必要なので、1つ目を「0」、2つ目を「1」とします。


double MABuffer0[], MABuffer1[];
int handle0, handle1;

OnInit関数内の記述もMA2本に対応するよう、コピー後にそれぞれに「0」「1」を追記します。


SetIndexBuffer(0, MABuffer0,INDICATOR_DATA);
SetIndexBuffer(1, MABuffer1,INDICATOR_DATA);
PlotIndexSetInteger(0, PLOT_LINE_COLOR, CLR0);
PlotIndexSetInteger(1, PLOT_LINE_COLOR, CLR1);
PlotIndexSetInteger(0, PLOT_LINE_STYLE, STYLE0);
PlotIndexSetInteger(1, PLOT_LINE_STYLE, STYLE1);
PlotIndexSetInteger(0, PLOT_LINE_WIDTH, WIDTH0);
PlotIndexSetInteger(1, PLOT_LINE_WIDTH, WIDTH1);
PlotIndexSetInteger(0, PLOT_DRAW_TYPE, DRAW_LINE);
PlotIndexSetInteger(1, PLOT_DRAW_TYPE, DRAW_LINE);
PlotIndexSetString(0, PLOT_LABEL, StringSubstr(EnumToString(METHOD0), 5) + "(" + (string)PERIOD0 + ")");
PlotIndexSetString(1, PLOT_LABEL, StringSubstr(EnumToString(METHOD1), 5) + "(" + (string)PERIOD1 + ")");
ArraySetAsSeries(MABuffer0, true);
ArraySetAsSeries(MABuffer1, true);
handle0 = iMA(NULL, 0, PERIOD0, SHIFT0, METHOD0, PRICE0);
handle1 = iMA(NULL, 0, PERIOD1, SHIFT1, METHOD1, PRICE1);

OnDeinit関数内の記述も同様に、コピー後「0」「1」を追記します。


IndicatorRelease(handle0);
IndicatorRelease(handle1);

OnCalculate関数内の記述も同様に、コピー後「0」「1」を追記します。


CopyBuffer(handle0, 0, 0, limit, MABuffer0);
CopyBuffer(handle1, 0, 0, limit, MABuffer1);

上記までの変更後にコンパイルし、チャートにセットするとパラメーターは下記のように表示され、期間5の短期MA(赤)と、期間20の長期MA(黄)が表示されます。

2MA パラメーター

2.矢印サイン表示機能を追加

2本のMAがクロスした場所に、矢印サインを表示させるプログラムを追加します。
バッファを2つ追加します。(2を4に変更)


#property indicator_buffers 4
#property indicator_plots   4

買いサインバッファを「buy」、売りサインバッファを「sell」として追加します。


double buy[], sell[];

OnInit関数内に、各種表示条件等を追記します。
番号の指定は、買いサインが「2」、売りサインが「3」となります。
色は買いサインを「赤」、売りサインを「青」とし、サインの大きさは「2」にしています。


SetIndexBuffer(2, buy,INDICATOR_DATA);
SetIndexBuffer(3, sell,INDICATOR_DATA);
PlotIndexSetInteger(2, PLOT_LINE_COLOR, clrRed);
PlotIndexSetInteger(3, PLOT_LINE_COLOR, clrDodgerBlue);
PlotIndexSetInteger(2, PLOT_LINE_WIDTH, 2);
PlotIndexSetInteger(3, PLOT_LINE_WIDTH, 2);

矢印サインなので、タイプは「ARROW」にします。


PlotIndexSetInteger(2, PLOT_DRAW_TYPE, DRAW_ARROW);
PlotIndexSetInteger(3, PLOT_DRAW_TYPE, DRAW_ARROW);

矢印サインの場合は、サイン形状のコード番号を指定する必要があります。
ここでは、買いを「233」(上向き矢印)、売りを「234」(下向き矢印)とします。


PlotIndexSetInteger(2, PLOT_ARROW, 233);
PlotIndexSetInteger(3, PLOT_ARROW, 234);

矢印の形状は、MetaEditorメニューの「ヘルプ」から「MQL5リファレンス」を開き、「wingdings」で検索すると、特殊文字の一覧表で確認できます。

2MA wingdings

矢印サインは、上下の表示位置のずらし(シフト)量を指定できます。
買いは下へ「10」ピクセル、売りは上へ「10」ピクセルシフトする指定とします。


PlotIndexSetInteger(2, PLOT_ARROW_SHIFT, 10);
PlotIndexSetInteger(3, PLOT_ARROW_SHIFT, -10);

名称は「Buy」「Sell」と指定します。


PlotIndexSetString(2, PLOT_LABEL, "Buy");
PlotIndexSetString(3, PLOT_LABEL, "Sell");

配列の並び方向は、MAと同様に指定します。


ArraySetAsSeries(buy, true);
ArraySetAsSeries(sell, true);

3.MAクロス判定

2本のMAがクロスする判定式をOnCalculate関数内に追加します。
サインをローソク足の高値と安値に表示したいのですが、OnCalculate関数の配列「high」(高値)と「low」(安値)は、何も指定しないと配列の並び順が逆なので、MAやサインに合わせて指定します。


ArraySetAsSeries(high, true);
ArraySetAsSeries(low, true);

短期のMA1(MABuffer0)が、長期のMA2(MABuffer1)を下から上に抜いたゴールデンクロスを、買いサイン表示条件とします。
条件が成立した場合は、安値(low)の値を入力してサインを表示させて、条件不成立の場合は、空の値「EMPTY_VALUE」を入力します。
for文を利用して、チャートの過去から現在の全範囲を計算させます。


   for (int i = limit - 1; i >= 0; i--) {
      if (MABuffer0[i] > MABuffer1[i] && MABuffer0[i + 1] <= MABuffer1[i + 1]) buy[i] = low[i];
      else buy[i] = EMPTY_VALUE;
   }

売りサインは不等号を逆にして判定し、成立した場合、高値に表示させます。


      if (MABuffer0[i] < MABuffer1[i] && MABuffer0[i + 1] >= MABuffer1[i + 1]) sell[i] = high[i];
      else sell[i] = EMPTY_VALUE;

上記までの記述で完成なので、コンパイルします。
MAクロス位置に矢印サインが表示されるようになります。

2MA クロスサイン

4.ソースコード

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


//+------------------------------------------------------------------+
//|                                                MA_Cross_Sign.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 4
#property indicator_plots   4

input group "【MA1】"
input int PERIOD0 = 5; // 期間
input int SHIFT0 = 0; // シフト
input ENUM_MA_METHOD METHOD0 = MODE_SMA; // MA種別
input ENUM_APPLIED_PRICE PRICE0 = PRICE_CLOSE; // 適用価格
input color CLR0 = clrRed; // 色
input ENUM_LINE_STYLE STYLE0 = STYLE_SOLID; // 線種
input int WIDTH0 = 1; // 太さ

input group ""
input group "【MA2】"
input int PERIOD1 = 20; // 期間
input int SHIFT1 = 0; // シフト
input ENUM_MA_METHOD METHOD1 = MODE_SMA; // MA種別
input ENUM_APPLIED_PRICE PRICE1 = PRICE_CLOSE; // 適用価格
input color CLR1 = clrYellow; // 色
input ENUM_LINE_STYLE STYLE1 = STYLE_SOLID; // 線種
input int WIDTH1 = 1; // 太さ

//--- indicator buffers
double MABuffer0[], MABuffer1[];
double buy[], sell[];
int handle0, handle1; 
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0, MABuffer0,INDICATOR_DATA);
   SetIndexBuffer(1, MABuffer1,INDICATOR_DATA);
   PlotIndexSetInteger(0, PLOT_LINE_COLOR, CLR0);
   PlotIndexSetInteger(1, PLOT_LINE_COLOR, CLR1);
   PlotIndexSetInteger(0, PLOT_LINE_STYLE, STYLE0);
   PlotIndexSetInteger(1, PLOT_LINE_STYLE, STYLE1);
   PlotIndexSetInteger(0, PLOT_LINE_WIDTH, WIDTH0);
   PlotIndexSetInteger(1, PLOT_LINE_WIDTH, WIDTH1);
   PlotIndexSetInteger(0, PLOT_DRAW_TYPE, DRAW_LINE);
   PlotIndexSetInteger(1, PLOT_DRAW_TYPE, DRAW_LINE);
   PlotIndexSetString(0, PLOT_LABEL, StringSubstr(EnumToString(METHOD0), 5) + "(" + (string)PERIOD0 + ")");
   PlotIndexSetString(1, PLOT_LABEL, StringSubstr(EnumToString(METHOD1), 5) + "(" + (string)PERIOD1 + ")");
   ArraySetAsSeries(MABuffer0, true);
   ArraySetAsSeries(MABuffer1, true);
   handle0 = iMA(NULL, 0, PERIOD0, SHIFT0, METHOD0, PRICE0);
   handle1 = iMA(NULL, 0, PERIOD1, SHIFT1, METHOD1, PRICE1);

   SetIndexBuffer(2, buy,INDICATOR_DATA);
   SetIndexBuffer(3, sell,INDICATOR_DATA);
   PlotIndexSetInteger(2, PLOT_LINE_COLOR, clrRed);
   PlotIndexSetInteger(3, PLOT_LINE_COLOR, clrDodgerBlue);
   PlotIndexSetInteger(2, PLOT_LINE_WIDTH, 2);
   PlotIndexSetInteger(3, PLOT_LINE_WIDTH, 2);
   PlotIndexSetInteger(2, PLOT_DRAW_TYPE, DRAW_ARROW);
   PlotIndexSetInteger(3, PLOT_DRAW_TYPE, DRAW_ARROW);
   PlotIndexSetInteger(2, PLOT_ARROW, 233);
   PlotIndexSetInteger(3, PLOT_ARROW, 234);
   PlotIndexSetInteger(2, PLOT_ARROW_SHIFT, 10);
   PlotIndexSetInteger(3, PLOT_ARROW_SHIFT, -10);
   PlotIndexSetString(2, PLOT_LABEL, "Buy");
   PlotIndexSetString(3, PLOT_LABEL, "Sell");
   ArraySetAsSeries(buy, true);
   ArraySetAsSeries(sell, true);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   IndicatorRelease(handle0);
   IndicatorRelease(handle1);
  }
//+------------------------------------------------------------------+
//| 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[])
  {
//---
   ArraySetAsSeries(high, true);
   ArraySetAsSeries(low, true);

   int limit = rates_total - prev_calculated;
   if (limit < 1) limit = 1;
   CopyBuffer(handle0, 0, 0, limit, MABuffer0);
   CopyBuffer(handle1, 0, 0, limit, MABuffer1);

   for (int i = limit - 1; i >= 0; i--) {
      if (MABuffer0[i] > MABuffer1[i] && MABuffer0[i + 1] <= MABuffer1[i + 1]) buy[i] = low[i];
      else buy[i] = EMPTY_VALUE;

      if (MABuffer0[i] < MABuffer1[i] && MABuffer0[i + 1] >= MABuffer1[i + 1]) sell[i] = high[i];
      else sell[i] = EMPTY_VALUE;
   }
//--- 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運用をお考えであれば、ぜひ口座開設をご検討ください。


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

この記事をシェアする