矢印(アロー)を表示させるインジケーターにしてみよう!
ここでは、前回完成したMACDとそのシグナルラインを描画するインジケーターに矢印が表示されるようにカスタマイズする方法を解説します。
記事一覧で前回までの記事をチェックしよう!
「MT4インジケーター作成入門」の記事一覧
前回記事のおさらい
前回は説明文や短縮名が表示されるようにしたぞい
次のコードが前回完成したインジケーターじゃ
#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(バッファインデックス, アローの番号)
バッファインデックス
インジケーターバッファインデックスの番号を指定します。
アローの番号
表示させるアローコードを指定します。
アローの番号(アローコード)は、mql4リファレンスのConstants, Enumerations and Structures / Object Constants の中の【Wingdings】や【Arrow codes】を参照します。MQL4公式ページでも参照できます。
MQL4 Reference Wingdings MQL4 Reference Arrow codes
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を追加して矢印を消してもかまいません。
今回完成ファイルのコードがこちら
#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()関数でアローの形を指定することと、表示条件不満足の場合にはアローを消すことを忘れないようにしましょう^^
ではまた、次回をお楽しみに!
こんばんは、秋山と申します。
自分でサインツールを作成しようと考え、本ホームページに行きつきました。
とても参考になります。
ありがとうございます。
質問なのですが、矢印を表示したときにALARTを鳴らし、通貨を通知するにはどのようにしたらよいでしょうか?
よろしくお願いいたします。
秋山さん
コメントありがとうございます。
通知方法には、Alert()関数やSendMail()関数などを利用します。
通貨ペア(銘柄)は、Symbol()関数で取得可能です。