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 計算のハンドルを解放して、メモリを片付けます。 |