MACDのメインラインとシグナルラインが交差する瞬間を、チャート上で目で追い続けるのは、
意外と見落としがちです。
この記事では、ゴールデンクロス・デッドクロスが発生した、
確定足だけに矢印を表示するインジケーターを作ります。
・iMACD関数のmode引数(メインライン/シグナルライン)の使い方
・状態ではなく変化(クロスの瞬間)を検知する設計
・実際に動くインジケーターのコード全体
・既刊OsMAゼロクロス記事との関係
MACDのゴールデンクロス・デッドクロスとは何か
まず、矢印の元になる、クロスの意味を確認します。
メインラインとシグナルラインの関係
MACDは、2本の移動平均線(メインライン)の差を表す、メインラインと、
その移動平均であるシグナルラインの、2本の線で構成されます。
ゴールデンクロス・デッドクロスの定義
メインラインがシグナルラインを、下から上へ抜けるとゴールデンクロス、
上から下へ抜けるとデッドクロスと呼ばれます。
既刊OsMAゼロクロス記事との関係
・OsMAはメインラインとシグナルラインの「差」をヒストグラムにしたもの
・差がゼロをまたぐ瞬間と、2本のラインが交差する瞬間は、理論上同じ現象
・この記事では「2本の線そのもの」をクロス判定の対象にします
なぜ「クロスした瞬間」だけを検知したいのか
状態と変化の違いを整理してから、実装の方針を決めます。
現在値だけの条件の弱点
main > signal
この条件だけでは、メインラインが、シグナルラインより上にある間、
ずっと条件を満たし続けてしまいます。
1本前との比較でクロスを検知する
//下から上へ抜けた(ゴールデンクロス) currentMain > currentSignal && previousMain <= previousSignal //上から下へ抜けた(デッドクロス) currentMain < currentSignal && previousMain >= previousSignal
1本前の関係と、今の関係を比較することで、クロスの瞬間だけを取り出せます。
確定足で判定する理由
形成中の0番目の足は、値が変化し続けて確定していないため、
このコードは1本前(確定足)を基準に判定します。
iMACD関数の引数とmode(メインライン/シグナルライン)
クロス判定に使う、iMACD関数の引数を確認します。
iMACDのシグネチャ
double iMACD( string symbol, int timeframe, int fast_ema_period, int slow_ema_period, int signal_period, int applied_price, int mode, int shift );
OsMAの引数(iOsMA)と似ていますが、MACDには`mode`という引数が、
追加で1つあります。
mode=0(MODE_MAIN)とmode=1(MODE_SIGNAL)の違い
`mode`に`MODE_MAIN`(0)を指定するとメインラインの値、
`MODE_SIGNAL`(1)を指定するとシグナルラインの値が、
それぞれ取得できます。
MT4標準MACDインジケーターの表示とは別物という注意
・MT4の標準MACDインジケーターは、ヒストグラムとメインラインの2本を表示する
・画面に見えているヒストグラムは、実はOsMA(メインライン-シグナルライン)である
・本記事のシグナルライン(mode=1)は、標準表示には出ていない線である
実際に動くコード全体(ゴールデンクロス・デッドクロス矢印インジケーター)
上クロスを緑の矢印、下クロスを赤の矢印で表示する、
実際にMetaEditorでコンパイルできるコードです。
//+------------------------------------------------------------------+
//| MacdCrossArrow.mq4 |
//| Copyright 2026, FX-EA System Project Creator |
//| https://creator.fx-ea-system-project.com/ |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, FX-EA System Project Creator"
#property link "https://creator.fx-ea-system-project.com/"
#property version "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 LimeGreen
#property indicator_color2 Tomato
input int FastEmaPeriod = 12;
input int SlowEmaPeriod = 26;
input int SignalPeriod = 9;
input int ArrowGapPoints = 30;//高値・安値から矢印を離すポイント数
double UpArrow[];
double DownArrow[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
SetIndexBuffer(0, UpArrow);
SetIndexStyle(0, DRAW_ARROW, STYLE_SOLID, 2);
SetIndexArrow(0, 233);
SetIndexEmptyValue(0, EMPTY_VALUE);
SetIndexBuffer(1, DownArrow);
SetIndexStyle(1, DRAW_ARROW, STYLE_SOLID, 2);
SetIndexArrow(1, 234);
SetIndexEmptyValue(1, EMPTY_VALUE);
IndicatorShortName("MACD Cross Arrow");
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 needed = SlowEmaPeriod + SignalPeriod + 3;
if(rates_total < needed)
return(0);
int limit = (prev_calculated == 0) ? rates_total-2 : rates_total-prev_calculated+1;
if(limit > rates_total-2)
limit = rates_total-2;
for(int i=limit; i>=1; i--)
{
double currentMain = iMACD(NULL, 0, FastEmaPeriod, SlowEmaPeriod, SignalPeriod, PRICE_CLOSE, MODE_MAIN, i);
double currentSignal = iMACD(NULL, 0, FastEmaPeriod, SlowEmaPeriod, SignalPeriod, PRICE_CLOSE, MODE_SIGNAL, i);
double previousMain = iMACD(NULL, 0, FastEmaPeriod, SlowEmaPeriod, SignalPeriod, PRICE_CLOSE, MODE_MAIN, i+1);
double previousSignal = iMACD(NULL, 0, FastEmaPeriod, SlowEmaPeriod, SignalPeriod, PRICE_CLOSE, MODE_SIGNAL, i+1);
UpArrow[i] = EMPTY_VALUE;
DownArrow[i] = EMPTY_VALUE;
if(currentMain > currentSignal && previousMain <= previousSignal)
UpArrow[i] = Low[i] - ArrowGapPoints * Point;
else if(currentMain < currentSignal && previousMain >= previousSignal)
DownArrow[i] = High[i] + ArrowGapPoints * Point;
}
return(rates_total);
}
//+------------------------------------------------------------------+
MetaEditorでのコンパイル・表示手順
実際にチャートへ適用するまでの手順です。
- MT4のMetaEditorで「ファイル」→「新規作成」→「カスタムインディケータ」を選ぶ
- 「MacdCrossArrow」という名前で作成し、テンプレートの中身をすべて削除して上のコードを貼り付ける
- F7キーでコンパイルし、「0 error(s), 0 warning(s)」になることを確認する
- チャートへ適用し、標準MACDインジケーターも同時に表示する
- メインラインとシグナルラインが交差する足で、矢印が出ることを目視で確認する
よくあるエラーと注意点
実際に動かす前に、確認しておきたい点です。
矢印が全く表示されない
`needed`の本数に足りるヒストリーデータがあるか確認してください。
読み込み直後は表示までに少し時間がかかることがあります。
OsMAゼロクロスの矢印と同じタイミングに見える
既刊osma-cross-arrow-indicator.mdの矢印と、
ほぼ同じタイミングで表示されるのは、理論上同じ現象を見ているためで、
不具合ではありません。
パラメータを変えても矢印が変わらない
`FastEmaPeriod`等を変更した後は、一度インジケーターを外して再度適用すると、
反映漏れを防げます。
MACDクロスの使いどころと限界
このインジケーターの、得意な場面と弱点を整理します。
トレンドの初動を捉えやすい
ゴールデンクロス・デッドクロスは、トレンドが切り替わる初動のタイミングを、
捉えやすいという特徴があります。
レンジ相場ではダマシが増える
・レンジ相場では2本のラインが絡み合い、クロスが連発しやすい
・このインジケーターは矢印を表示するだけで、トレンドの強さは判定していない
・既刊ADX・効率比系の記事と組み合わせたフィルターの追加を推奨します
よくある質問
MACDクロス矢印の実装でよく検索されている、疑問を3つにまとめて回答します。
EAのエントリー条件にそのまま使えますか?
この記事のコードは表示専用のインジケーターです。
`currentMain`・`currentSignal`等を比較するif文の部分だけを、
EAの`OnTick()`内にコピーすれば、エントリー条件として使えます。
OsMAのゼロクロスと、どちらを使うべきですか?
どちらも理論上は同じ現象を検知していますが、
線の交差よりヒストグラムの符号反転の方が、目視では判定しやすい利点があります。
適用価格をPRICE_CLOSE以外にできますか?
`iMACD()`の第6引数(`applied_price`)を、
`PRICE_TYPICAL`等の他の定数に変更すれば、
終値以外の平均価格でMACDを計算できます。
【MQL4】MACDのゴールデンクロス・デッドクロスだけを矢印表示するインジケーターの作り方について解説してみた(OsMAのゼロクロスとの違いも整理):まとめ
この記事では、MACDのメインラインとシグナルラインが、
交差した確定足だけに矢印を表示する、
インジケーターの作り方を解説しました。
「上にあるか下にあるか」という状態ではなく、「いま交差したか」
という変化を検知することが、矢印を連発させないための設計のポイントです。
コメント