インジケーター作成07

矢印(アロー)を表示させるインジケーターにしてみよう!

ここでは、前回完成したMACDとそのシグナルラインを描画するインジケーターに矢印が表示されるようにカスタマイズする方法を解説します。

記事一覧で前回までの記事をチェックしよう!
「MT4インジケーター作成入門」の記事一覧

前回記事のおさらい

Dr.EADr.EA

前回は説明文や短縮名が表示されるようにしたぞい
次のコードが前回完成したインジケーターじゃ

#property copyright "Dr.EA公式ブログ"
#property link      "https://www.dr-ea.com/meta-blog/"
#property version   "1.00"
#property description "このインジケーターはブログ記事MT4インジケーター作成入門シリーズのサンプルインジケーターです。"
#property description "上の「Dr.EA公式ブログ」へのリンクからブログトップページをご覧いただけます。"
#property strict

#property indicator_separate_window
#property indicator_buffers 2          // 表示用インジケーターバッファ 2つ
#property indicator_color1 clrSilver   // 1つ目の色
#property indicator_width1 1           // 1つ目の太さ
#property indicator_color2 clrRed      // 2つ目の色
#property indicator_width2 1           // 2つ目の太さ
#property indicator_style2 STYLE_DOT   // 2つ目のスタイル

extern int  FastEMA_Period = 12;       // 短期EMAの期間
extern int  SlowEMA_Period = 26;       // 長期EMAの期間
extern int  Signal_Period  = 9;        // MACDシグナルライン期間

double macd[];                         // MACD用配列
double macd_sig[];                     // MACDシグナル用配列
double fast_ema[];                     // 短期EMA用配列
double slow_ema[];                     // 長期EMA用配列

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
   IndicatorBuffers(4);             // インジケータ―用配列は4つ
   
   SetIndexBuffer(0, macd);         // 配列 macd[]をインジ用に割り当て
   SetIndexStyle(0, DRAW_HISTOGRAM);// 描画タイプをヒストグラムと定義
   SetIndexBuffer(1, macd_sig);     // 配列 macd_sig[]をインジ用に割り当て
   SetIndexStyle(1, DRAW_LINE);     // 描画タイプをラインと定義
   
   SetIndexBuffer(2, fast_ema);     // 配列 fast_ema[]をインジ用に割り当て
   SetIndexBuffer(3, slow_ema);     // 配列 slow_ema[]をインジ用に割り当て
   
   SetIndexLabel(0, "MACD");        // ラベルを設定
   SetIndexLabel(1, "Signal");      // ラベルを設定
   
   // ShortNameを設定
   string short_name = "MACD(" + (string)FastEMA_Period + ",";
   short_name += (string)SlowEMA_Period + ",";
   short_name += (string)Signal_Period + ")";
   IndicatorShortName(short_name);
   
   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 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本前から現在のローソク足を処理
   {
      fast_ema[i] = iMA(NULL, 0, FastEMA_Period, 0, MODE_EMA, PRICE_CLOSE, i);   // Fast EMA
      slow_ema[i] = iMA(NULL, 0, SlowEMA_Period, 0, MODE_EMA, PRICE_CLOSE, i);   // Slow EMA
      
      macd[i] = fast_ema[i] - slow_ema[i];   // MACD
      
      if (i + Signal_Period <= Bars)         // MACDシグナル
      {
         macd_sig[i] = 0;
         for (j=0; j<Signal_Period; j++) macd_sig[i] += macd[i+j];
         macd_sig[i] /= Signal_Period;
      }
   }
   
   return(rates_total);
}

前回の完成ファイル【Sample_Indicator_06.mq4】をダウンロード

矢印表示の準備

MACDがシグナルラインを下から上にクロス(ゴールデンクロス)した場合に水色の上矢印を、逆のクロス(デッドクロス)をした場合にピンク色の下矢印を表示させます。

インジケーターバッファを増やす

上矢印と下矢印の2つのインジケーター用配列を追加するため、表示用インジケーターバッファ数を2から4に増やします。

#property indicator_buffers 4   // 表示用インジケーターバッファ個数

OnInit()関数内で設定するインジケーターバッファ個数も4から6に増やします。

   IndicatorBuffers(6);   // インジケータ―用配列個数

色と大きさを指定する

次のコードを追加して、上下矢印の色と大きさの初期値を指定します。

#property indicator_color3 clrLightBlue // 3つ目の色
#property indicator_width3 2             // 3つ目の太さ
#property indicator_color4 clrLightPink // 4つ目の色
#property indicator_width4 2             // 4つ目の太さ

矢印用配列をインジケーター用配列に割り当てる

矢印用に配列up[]と配列dn[]を宣言しておきます。

double up[];  // 上矢印用配列
double dn[];  // 下矢印用配列

OnInit()関数内で、配列up[]とdn[]をインジケーター用配列に割り当てます。次のように描画タイプをアローに設定します。
※ここで、配列fast_ema[]とslow_ema[]のインデックスを2つずつ増やします。

   SetIndexBuffer(2, up);           // 配列 up[]をインジ用に割り当て
   SetIndexStyle(2, DRAW_ARROW);    // 描画タイプをアローと定義
   SetIndexBuffer(3, dn);           // 配列 dn[]をインジ用に割り当て
   SetIndexStyle(3, DRAW_ARROW);    // 描画タイプをアローと定義
   
   SetIndexBuffer(4, fast_ema);     // 配列 fast_ema[]をインジ用に割り当て
   SetIndexBuffer(5, slow_ema);     // 配列 slow_ema[]をインジ用に割り当て

矢印の形を指定する

アローの形をSetIndexArrow()関数で指定します。

SetIndexArrow()関数について

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

SetIndexArrow(バッファインデックス, アローの番号)

バッファインデックス
インジケーターバッファインデックスの番号を指定します。

アローの番号
表示させるアローコードを指定します。
アローの番号(アローコード)は、mql4リファレンスのConstants, Enumerations and Structures / Object Constants の中の【Wingdings】や【Arrow codes】を参照します。MQL4公式ページでも参照できます。
MQL4 Reference Wingdings MQL4 Reference Arrow codes

mql4_wingdings

OnInit()関数内に次のコードを追加して、上矢印と下矢印の形を指定します。

   SetIndexArrow(2, 233);           // 上矢印
   SetIndexArrow(3, 234);           // 下矢印

矢印を表示させる処理

矢印用の配列up[]やdn[]に値を格納することで、それぞれの矢印が表示されます。逆に初期値と同じEMPTY_VALUEを代入すると矢印は消えます。

条件を満たした場合のみ表示させる

OnCalculate()関数内のfor()文の中で、MACDシグナル算出コードの下に、次のコードを追加します。

      if (i + Signal_Period < Bars)
      {
         // 一旦矢印を消す
         up[i] = EMPTY_VALUE;
         dn[i] = EMPTY_VALUE;

         // 矢印表示判定
         if (macd[i+1] <= macd_sig[i+1] && macd[i] > macd_sig[i]) up[i] = macd_sig[i];
         if (macd[i+1] >= macd_sig[i+1] && macd[i] < macd_sig[i]) dn[i] = macd_sig[i];
      }

MACDシグナルを算出し始めるローソク足の次のローソク足から矢印表示判定をしています。
上記コードでは、一旦矢印を消してから再度表示判定をしていますが、表示判定のif()文にelseを追加して矢印を消してもかまいません。

Dr.EADr.EA

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

#property strict

#property indicator_separate_window
#property indicator_buffers 4          // 表示用インジケーターバッファ個数
#property indicator_color1 clrSilver   // 1つ目の色
#property indicator_width1 1           // 1つ目の太さ
#property indicator_color2 clrRed      // 2つ目の色
#property indicator_width2 1           // 2つ目の太さ
#property indicator_style2 STYLE_DOT   // 2つ目のスタイル
#property indicator_color3 clrLightBlue// 3つ目の色
#property indicator_width3 2           // 3つ目の太さ
#property indicator_color4 clrLightPink// 4つ目の色
#property indicator_width4 2           // 4つ目の太さ

extern int  FastEMA_Period = 12;       // 短期EMAの期間
extern int  SlowEMA_Period = 26;       // 長期EMAの期間
extern int  Signal_Period  = 9;        // MACDシグナルライン期間

double macd[];                         // MACD用配列
double macd_sig[];                     // MACDシグナル用配列
double up[];                           // 上矢印用配列
double dn[];                           // 下矢印用配列
double fast_ema[];                     // 短期EMA用配列
double slow_ema[];                     // 長期EMA用配列

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
   IndicatorBuffers(6);             // インジケータ―用配列個数
   
   SetIndexBuffer(0, macd);         // 配列 macd[]をインジ用に割り当て
   SetIndexStyle(0, DRAW_HISTOGRAM);// 描画タイプをヒストグラムと定義
   SetIndexBuffer(1, macd_sig);     // 配列 macd_sig[]をインジ用に割り当て
   SetIndexStyle(1, DRAW_LINE);     // 描画タイプをラインと定義
   
   SetIndexBuffer(2, up);           // 配列 up[]をインジ用に割り当て
   SetIndexStyle(2, DRAW_ARROW);    // 描画タイプをアローと定義
   SetIndexBuffer(3, dn);           // 配列 dn[]をインジ用に割り当て
   SetIndexStyle(3, DRAW_ARROW);    // 描画タイプをアローと定義
   
   SetIndexArrow(2, 233);           // 上矢印
   SetIndexArrow(3, 234);           // 下矢印
   
   SetIndexBuffer(4, fast_ema);     // 配列 fast_ema[]をインジ用に割り当て
   SetIndexBuffer(5, slow_ema);     // 配列 slow_ema[]をインジ用に割り当て
   
   SetIndexLabel(0, "MACD");        // ラベルを設定
   SetIndexLabel(1, "Signal");      // ラベルを設定
   
   // ShortNameを設定
   string short_name = "MACD(" + (string)FastEMA_Period + ",";
   short_name += (string)SlowEMA_Period + ",";
   short_name += (string)Signal_Period + ")";
   IndicatorShortName(short_name);
   
   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 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本前から現在のローソク足を処理
   {
      fast_ema[i] = iMA(NULL, 0, FastEMA_Period, 0, MODE_EMA, PRICE_CLOSE, i);   // Fast EMA
      slow_ema[i] = iMA(NULL, 0, SlowEMA_Period, 0, MODE_EMA, PRICE_CLOSE, i);   // Slow EMA
      
      macd[i] = fast_ema[i] - slow_ema[i];   // MACD
      
      if (i + Signal_Period <= Bars)         // MACDシグナル
      {
         macd_sig[i] = 0;
         for (j=0; j<Signal_Period; j++) macd_sig[i] += macd[i+j];
         macd_sig[i] /= Signal_Period;
      }
      
      // 矢印
      if (i + Signal_Period < Bars)
      {
         // 一旦矢印を消す
         up[i] = EMPTY_VALUE;
         dn[i] = EMPTY_VALUE;
         
         // 矢印表示判定
         if (macd[i+1] <= macd_sig[i+1] && macd[i] > macd_sig[i]) up[i] = macd_sig[i];
         if (macd[i+1] >= macd_sig[i+1] && macd[i] < macd_sig[i]) dn[i] = macd_sig[i];
      }
   }
   
   return(rates_total);
}

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

あとがき

シグナル矢印(アロー)を表示させるインジケーターでは、描画タイプでDRAW_ARROWを指定することに加え、SetIndexArrow()関数でアローの形を指定することと、表示条件不満足の場合にはアローを消すことを忘れないようにしましょう^^

ではまた、次回をお楽しみに!