MACD線とシグナル線をサブウィンドウに表示させるコードを紹介

macd

MACD線とシグナル線をサブウィンドウに表示させるコードを紹介しています。MT5のMACDを使っても良いのですが見づらいので、線だけで表示される専用のインジケーターを作成しています。

MACD線は「期間12の短期EMA - 期間26の長期EMA」、シグナル線は「MACD線の移動平均線(EMA)9日移動平均線」になります。





//+------------------------------------------------------------------+
//|                       MACD Line and Signal EMA Line              |
//+------------------------------------------------------------------+
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots   2

//--- プロパティ設定
#property indicator_label1 "MACD Line"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrDodgerBlue
#property indicator_width1  2

#property indicator_label2 "Signal EMA Line"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrRed
#property indicator_width2  2

//--- インプットパラメータ
input int FastEMA = 12;
input int SlowEMA = 26;
input int SignalEMA = 9;

//--- バッファ
double MACDLineBuffer[];
double SignalLineBuffer[];

double MACDArray[];

//--- ハンドル
int handleFastEMA, handleSlowEMA;

//+------------------------------------------------------------------+
//| 初期化関数                                                       |
//+------------------------------------------------------------------+
int OnInit()
  {
   // バッファ設定
   SetIndexBuffer(0, MACDLineBuffer, INDICATOR_DATA);
   SetIndexBuffer(1, SignalLineBuffer, INDICATOR_DATA);

   // Fast EMA ハンドル作成
   handleFastEMA = iMA(NULL, 0, FastEMA, 0, MODE_EMA, PRICE_CLOSE);
   if(handleFastEMA == INVALID_HANDLE)
     {
      Print("Fast EMA handle creation failed. Error: ", GetLastError());
      return INIT_FAILED;
     }

   // Slow EMA ハンドル作成
   handleSlowEMA = iMA(NULL, 0, SlowEMA, 0, MODE_EMA, PRICE_CLOSE);
   if(handleSlowEMA == INVALID_HANDLE)
     {
      Print("Slow EMA handle creation failed. Error: ", GetLastError());
      return INIT_FAILED;
     }

   return INIT_SUCCEEDED;
  }
//+------------------------------------------------------------------+
//| 計算関数                                                         |
//+------------------------------------------------------------------+
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 start = prev_calculated;

   if(start == 0)
     {
      ArrayInitialize(MACDLineBuffer, EMPTY_VALUE);
      ArrayInitialize(SignalLineBuffer, EMPTY_VALUE);
      start = MathMax(FastEMA, SlowEMA);
     }

   double FastEMAArray[], SlowEMAArray[];

   // Fast EMA データ取得
   if(CopyBuffer(handleFastEMA, 0, 0, rates_total, FastEMAArray) <= 0)
      return 0;

   // Slow EMA データ取得
   if(CopyBuffer(handleSlowEMA, 0, 0, rates_total, SlowEMAArray) <= 0)
      return 0;

   // MACD ラインの計算
   ArrayResize(MACDArray, rates_total);
   for(int i = start; i < rates_total; i++)
      MACDArray[i] = FastEMAArray[i] - SlowEMAArray[i];

   // MACD Line バッファへの反映
   for(int i = start; i < rates_total; i++)
      MACDLineBuffer[i] = MACDArray[i];

   // Signal Line (EMA) 計算
   double alpha = 2.0 / (SignalEMA + 1);
   SignalLineBuffer[start - 1] = MACDArray[start - 1];  // 初期値設定

   for(int i = start; i < rates_total; i++)
     {
      SignalLineBuffer[i] = SignalLineBuffer[i - 1] + alpha * (MACDArray[i] - SignalLineBuffer[i - 1]);
     }

   return rates_total;
  }
//+------------------------------------------------------------------+
//| 終了関数                                                         |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   if(handleFastEMA != INVALID_HANDLE) IndicatorRelease(handleFastEMA);
   if(handleSlowEMA != INVALID_HANDLE) IndicatorRelease(handleSlowEMA);
  }
//+------------------------------------------------------------------+



#property の設定

設定項目 初心者向け説明
indicator_separate_window チャート下に小さな別窓を作って、ラインを表示します。
indicator_buffers 2 計算結果を保存するための場所を2つ用意します。
indicator_plots 2 2本のライン(MACD と Signal)を表示する設定です。
indicator_type1 / indicator_type2 DRAW_LINE ライン(折れ線)表示モードを使います。
indicator_color1 clrDodgerBlue
indicator_color2 clrRed
MACD は水色、Signal EMA は赤色で描きます。
indicator_width1 / indicator_width2 2 線の太さを2ピクセルにします。

バッファの定義

変数名 何を保存する?
MACDLineBuffer[] チャートに描く MACD の値を保存します。
SignalLineBuffer[] チャートに描く Signal EMA の値を保存します。
MACDArray[] FastEMA − SlowEMA を計算した結果を一時的にためます。

OnInit() の処理(インジケーター起動時に一度だけ実行)

ステップ 初心者向け説明
SetIndexBuffer() 先ほどのバッファ配列をチャート描画用に登録します。
iMA() FastEMA と SlowEMA を計算する“計算機”(ハンドル)を準備します。
エラーチェック もしハンドルの準備に失敗したら、メッセージを出して初期化を中断します。

OnCalculate() のロジック(足が更新されるたびに実行)

処理内容 初心者向け説明
初期化 (start==0) 一番最初だけ、バッファを空(表示しない)でリセットします。
CopyBuffer() FastEMA と SlowEMA の値を最新の足すべて分、配列に読み込みます。
MACDArray の計算 ループで「FastEMA − SlowEMA」を計算し、MACDArray に入れます。
MACDLineBuffer への反映 計算した MACDArray の値を、そのまま MACDLineBuffer に保存します。
Signal EMA の計算 自分で EMA を計算し直して SignalLineBuffer に保存します。

OnDeinit() の処理(インジケーター解除時に実行)

処理 初心者向け説明
IndicatorRelease() 準備した EMA 計算のハンドルを解放して、メモリを片付けます。