「MACDを使った売買ロジックをEAとして自動化したい」
「ゴールデンクロス・デッドクロスをMQL4でどう判定するのか知りたい」
という方に向けて、この記事ではMT4で動くMACD EAのサンプルコードを公開します。
今回のEAでは、MACDとシグナルのクロスに加えて0ラインの位置も確認し、 MACDがマイナス圏でゴールデンクロスしたらBUY、プラス圏でデッドクロスしたらSELLするロジックを実装します。
MACD値の取得にはMT4標準のiMACD()関数を使用します。
また、当サイトで公開しているMT4 EAベーステンプレートを土台に、MACD用のパラメータと売買条件を追加する構成にしています。
- MACDの基本とゴールデンクロス・デッドクロス
- 0ラインを使ったエントリー条件
- MT4の
iMACD()でMACD・シグナル値を取得する方法 - ベーステンプレートから変更した箇所
- MACD EAのMQL4サンプルコード
- パラメータ設定とバックテスト結果
このMACD EAの仕様
まず、今回作成するMACD EAの内容をまとめます。
| 項目 | 内容 |
|---|---|
| 対応 | MT4 / MQL4 |
| 使用インジケーター | MACD |
| 使用関数 | iMACD() |
| BUY条件 | マイナス圏でMACDがシグナルを上抜け |
| SELL条件 | プラス圏でMACDがシグナルを下抜け |
| 判定タイミング | 新しいローソク足ができたとき(1本前・2本前の確定足を使用) |
| MACD初期設定 | 12 / 26 / 9 |
| 利確 | 固定pips |
| 損切り | 固定pips |
| ポジション管理 | 口座内に注文がない場合のみ新規エントリー |
| MagicNumber管理 | なし(学習用サンプルのため) |
MACDとは?ゴールデンクロス・デッドクロスの基本
MACD(Moving Average Convergence Divergence)は、短期EMAと長期EMAの差を利用して、相場の方向や勢いを確認するテクニカル指標です。
MACDでは、MACDメイン値とシグナル値の位置関係を利用したクロス判定がよく使われます。
- ゴールデンクロス:MACDがシグナルを下から上へ抜ける
- デッドクロス:MACDがシグナルを上から下へ抜ける
今回のEAでは、このクロスだけでなくMACDが0ラインより上か下かもエントリー条件に加えます。
MACDの基本的な見方やMT4での表示方法については、以下の記事で詳しく解説しています。
MACD EAのエントリーロジック
BUY条件|マイナス圏でゴールデンクロス
BUYでは、2本前の確定足でMACDがシグナル以下にあり、1本前の確定足でMACDがシグナルを上回ったことを確認します。
さらに、1本前のMACDが0未満であることを条件にしています。
MACD_2 <= Signal_2
&& MACD_1 > Signal_1
&& MACD_1 < 0つまり、MACDがマイナス圏にある状態でゴールデンクロスした場面をBUY条件とします。
SELL条件|プラス圏でデッドクロス
SELLでは、2本前の確定足でMACDがシグナル以上にあり、1本前の確定足でMACDがシグナルを下回ったことを確認します。
さらに、1本前のMACDが0より大きいことを条件にしています。
MACD_2 >= Signal_2
&& MACD_1 < Signal_1
&& MACD_1 > 0つまり、MACDがプラス圏にある状態でデッドクロスした場面をSELL条件とします。
1本前・2本前の確定足でクロスを判定する
今回のEAでは、形成中の0番足ではなく、1本前と2本前の確定足を比較してクロスを判定します。
新しいローソク足ができたタイミングで1回だけ処理するため、形成途中のMACD値が変化したことによる判定のブレを避けやすい構成です。
MACD EAを使う前の注意点
複数EAを同一口座で管理するためのMagicNumberによるポジション識別などは実装していません。
MACDはトレンド方向を確認しやすい一方、値動きが方向感を失ったレンジ相場では、クロスが繰り返されてダマシが増えることがあります。
そのため、MACDクロスだけで必ず利益が出るわけではありません。移動平均線やADXなどを追加して相場状況を絞り込む方法もありますが、変更後はバックテストで確認することが重要です。
また、このEAはOrdersTotal()で口座全体の注文数を確認するため、そのまま利用する場合は、他のEAや手動ポジションと同じ口座で併用せず、EA単独で検証する方法を推奨します。
ベーステンプレートからの変更点
今回のMACD EAは、当サイトで公開しているMT4 EAベーステンプレートを土台に作成しています。
ベーステンプレートからの主な変更点は次の通りです。
- Fast EMA・Slow EMA・Signal期間のパラメータを追加
iMACD()で1本前・2本前のMACDとシグナルを取得- マイナス圏でのゴールデンクロスをBUY条件に使用
- プラス圏でのデッドクロスをSELL条件に使用
- TP・SLはベーステンプレートの固定pips方式をそのまま使用
- 独自の決済条件は追加せず、TP・SLで決済
- 共通関数は実際に使用する
funcOrder_Send()のみ掲載
つまり、今回のMACD EAはベーステンプレートの基本構造と固定TP・SLをそのまま利用し、新規注文判断へMACDクロスと0ラインの条件を追加したEAです。
MACD EAをダウンロード
今回の記事で解説しているMACD EAはこちらからダウンロードできます。
📥 MACD EAをダウンロード無料MT4 EAビルダーでは、MACDクロスを使った売買条件を画面上で設定してEAを作成できます。
今回のサンプルを試したあと、MACD期間や売買条件を変更して自分のEAを作ってみたい方にもおすすめです。
▶ 無料MT4 EAビルダーを使ってみる
なお、この記事のサンプルEAはMACDクロスに0ライン条件を追加したロジックです。EAビルダーで作成するMACDロジックとは、設定する条件によって売買タイミングが異なる場合があります。
MACD EAのMQL4サンプルコード
以下が今回の公開版ソースコードです。
公開表記はv1.0、ソース上は#property version "1.00"としています。
背景色が付いている行が、ベースEAテンプレートから主に変更・追加した部分です。
MACD固有のパラメータと売買判定部分を中心に強調しています。
//+------------------------------------------------------------------+
//| 07_MACD.mq4 |
//| Copyright © 2020-2026 ぷろぐらむFX |
//| https://fx-prog.com/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2020-2026 ぷろぐらむFX"
#property link "https://fx-prog.com/"
#property version "1.00"
#property strict
input double Lots = 0.01; //ロット
input int TP = 100; //利確(pips)
input int SL = 100; //損切り(pips)
//***【パラメータ設定↓】***//
input int MACD_FE_PERIOD = 12; //MACD Fast EMA期間
input int MACD_SE_PERIOD = 26; //MACD Slow EMA期間
input int MACD_SS_PERIOD = 9; //MACD Signal期間
//***【パラメータ設定↑】***//
string Ea_Name = WindowExpertName(); //EA名称をオーダーコメントに使用
double PipValue; //ブローカー桁数に対応したPoint補正
datetime prevtime; //ローソク足時間保持用
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit(){
if(Digits == 3 || Digits == 5){
PipValue = Point * 10;
}else{
PipValue = Point;
}
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick(){
//新しいローソク足ができたときだけ処理
if(Time[0] != prevtime){
prevtime = Time[0];
}else{
return;
}
int total = OrdersTotal();
int ea_order_Type = -1;
double ea_order_stop_price = 0;
double ea_order_good_price = 0;
//ポジションがない場合は新規エントリー判定
if(total == 0){
bool openBuy = false;
bool openSell = false;
//***【新規注文判断↓】***//
//1本前・2本前の確定足からMACDとシグナルを取得
double MACD_1 = iMACD(NULL,0,MACD_FE_PERIOD,MACD_SE_PERIOD,MACD_SS_PERIOD,PRICE_CLOSE,MODE_MAIN,1);
double Signal_1 = iMACD(NULL,0,MACD_FE_PERIOD,MACD_SE_PERIOD,MACD_SS_PERIOD,PRICE_CLOSE,MODE_SIGNAL,1);
double MACD_2 = iMACD(NULL,0,MACD_FE_PERIOD,MACD_SE_PERIOD,MACD_SS_PERIOD,PRICE_CLOSE,MODE_MAIN,2);
double Signal_2 = iMACD(NULL,0,MACD_FE_PERIOD,MACD_SE_PERIOD,MACD_SS_PERIOD,PRICE_CLOSE,MODE_SIGNAL,2);
//マイナス圏でゴールデンクロス → BUY
if(MACD_2 <= Signal_2 && MACD_1 > Signal_1 && MACD_1 < 0){
openBuy = true;
//プラス圏でデッドクロス → SELL
}else if(MACD_2 >= Signal_2 && MACD_1 < Signal_1 && MACD_1 > 0){
openSell = true;
}
//***【新規注文判断↑】***//
if(openBuy){
ea_order_Type = OP_BUY;
}else if(openSell){
ea_order_Type = OP_SELL;
}
//***【TP/SL判断↓】***//
//ベーステンプレートの固定pips TP・SLを使用
if(openBuy){
ea_order_stop_price = Ask - SL * PipValue;
ea_order_good_price = Ask + TP * PipValue;
}else if(openSell){
ea_order_stop_price = Bid + SL * PipValue;
ea_order_good_price = Bid - TP * PipValue;
}
//***【TP/SL判断↑】***//
if(ea_order_Type > -1){
//学習用サンプルではMagicNumber管理を行わないため0
funcOrder_Send(ea_order_Type,ea_order_stop_price,ea_order_good_price,Lots,Ea_Name,0,0);
}
}
}
//★★★★★★★★★★★★★★★★★★★★ ここから下は共通関数 ★★★★★★★★★★★★★★★★★★★★
//+------------------------------------------------------------------+
//|【関数】新規注文関数 |
//|【引数】orderType:売買(0=BUY, 1=SELL) |
//|【引数】sl:損切り価格 tp:利確価格 |
//|【引数】lots:取引ロット数 |
//|【引数】orderComment:オーダーコメント |
//|【引数】magic:MagicNumber |
//|【引数】maxSpreadPoints:許容スプレッド[Point] (0=制限なし) |
//|【戻値】true=成功 false=失敗 |
//+------------------------------------------------------------------+
bool funcOrder_Send(int orderType, double sl, double tp, double lots, string orderComment, int magic, int maxSpreadPoints){
int ticket = -1;
double price = 0;
double spread = 0;
color clr = clrNONE;
//最大10回リトライ
for(int retry=0; retry<10; retry++){
RefreshRates();
spread = MarketInfo(Symbol(),MODE_SPREAD);
//スプレッドチェック
if(maxSpreadPoints > 0 && spread > maxSpreadPoints){
Print("スプレッド拡大中(",spread,"ポイント) → 待機中 (リトライ=",retry+1,")");
Sleep(2000);
continue;
}
//注文価格を取得
if(orderType == OP_BUY){
price = Ask;
clr = clrBlue;
}else if(orderType == OP_SELL){
price = Bid;
clr = clrRed;
}else{
Print("funcOrder_Send: 未対応の注文種別=",orderType);
return false;
}
price = NormalizeDouble(price,Digits);
if(sl > 0) sl = NormalizeDouble(sl,Digits);
if(tp > 0) tp = NormalizeDouble(tp,Digits);
ResetLastError();
ticket = OrderSend(Symbol(),orderType,lots,price,20,sl,tp,orderComment,magic,0,clr);
if(ticket > 0){
Print("新規注文成功! チケットNo=",ticket," レート=",price," Lots=",lots," スプレッド=",spread,"ポイント");
return true;
}
int err = GetLastError();
Print("新規注文失敗 エラーNo=",err," リトライ回数=",retry+1);
Sleep(2000);
}
return false;
}MT4のiMACD()関数でMACDの値を取得する
MQL4でMACDの値を取得するときは、MT4標準関数のiMACD()を使用します。
今回のMACDメイン値の取得例:
double MACD_1 = iMACD(NULL,0,MACD_FE_PERIOD,MACD_SE_PERIOD,MACD_SS_PERIOD,PRICE_CLOSE,MODE_MAIN,1);シグナル値の取得例:
double Signal_1 = iMACD(NULL,0,MACD_FE_PERIOD,MACD_SE_PERIOD,MACD_SS_PERIOD,PRICE_CLOSE,MODE_SIGNAL,1);iMACD()の主な引数は次の通りです。
| 引数 | 今回の指定 | 内容 |
|---|---|---|
| symbol | NULL | 現在のチャートの通貨ペア |
| timeframe | 0 | 現在のチャート時間足 |
| fast_ema_period | MACD_FE_PERIOD | Fast EMA期間。初期値12 |
| slow_ema_period | MACD_SE_PERIOD | Slow EMA期間。初期値26 |
| signal_period | MACD_SS_PERIOD | Signal期間。初期値9 |
| applied_price | PRICE_CLOSE | 終値を計算対象に使用 |
| mode | MODE_MAIN / MODE_SIGNAL | MACDメイン値またはシグナル値を指定 |
| shift | 1 / 2 | 1本前・2本前の確定足を取得 |
今回のEAでは、バーシフト1と2のMACD・シグナル値をそれぞれ取得し、2本の確定足で大小関係が入れ替わったかどうかを確認します。
MODE_MAINではMACDメイン値、MODE_SIGNALではシグナル値を取得します。今回のEAでは、この2つの値を直接比較してゴールデンクロス・デッドクロスを判定します。
MACDとシグナルのクロスを判定する
BUYでは2本前にMACDがシグナル以下、1本前にMACDがシグナルを上回っていれば、ゴールデンクロスが成立したと判断します。
if(MACD_2 <= Signal_2 && MACD_1 > Signal_1 && MACD_1 < 0){
openBuy = true;
}SELLは反対に、2本前にMACDがシグナル以上、1本前にMACDがシグナルを下回っていることを確認します。
if(MACD_2 >= Signal_2 && MACD_1 < Signal_1 && MACD_1 > 0){
openSell = true;
}さらにMACD_1 < 0またはMACD_1 > 0を加えることで、BUYはマイナス圏、SELLはプラス圏に限定しています。
MACDを使った売買判定のイメージ
- MACDがシグナルを下から上へ抜けるとゴールデンクロス
- MACDがシグナルを上から下へ抜けるとデッドクロス
- 今回のEAではBUYは0ラインより下、SELLは0ラインより上に限定
- ポジション保有後は固定TP・SLで決済
MT4標準のMACD Sampleを確認したい場合
MT4には、標準EAとして「MACD Sample」も用意されています。今回のサンプルコードとは別物ですが、MT4標準EAの動きを確認したい場合はこちらも参考にできます。
新規注文は共通関数funcOrder_Send()を使用
新規注文部分には、ベーステンプレートでも使用している共通のfuncOrder_Send()を利用しています。
今回のMACD EAでは注文変更や独自の成行決済を使用しないため、個別EAのソースには実際に使用する新規注文関数だけを掲載しています。
注文関数そのものの仕組みを詳しく確認したい場合は、以下の記事で解説しています。
MACD EAのパラメータ設定
サンプルコードでは、MACDの基本設定として12・26・9を初期値にしています。
| パラメータ | 初期値 | 内容 |
|---|---|---|
| Lots | 0.01 | 1回のエントリーで使用するロット数 |
| TP | 100 | 利確幅(pips) |
| SL | 100 | 損切り幅(pips) |
| MACD_FE_PERIOD | 12 | MACD計算に使用するFast EMA期間 |
| MACD_SE_PERIOD | 26 | MACD計算に使用するSlow EMA期間 |
| MACD_SS_PERIOD | 9 | MACDシグナルの計算期間 |
公開版ではFast EMA 12・Slow EMA 26・Signal 9を基本設定としています。
TP・SLの初期値は100pipsです。記事とダウンロードEAでは基本値を使用し、バックテストで別の値を使用する場合はテスト条件として分けて記載します。
MACD EAのバックテスト結果
最新版のMACD EAを使い、USDJPYの1時間足でバックテストを行いました。
MACDの設定は公開版と同じ12・26・9を使用し、バックテスト時のTP・SLはTP80pips / SL170pipsへ変更しています。
バックテスト条件
| 項目 | 条件 |
|---|---|
| 通貨ペア | USDJPY |
| 時間足 | H1 |
| 期間 | 2024/08/23 ~ 2026/07/30 |
| 初期証拠金 | 1,000,000円 |
| スプレッド | 5 |
| Lots | 0.01 |
| Fast EMA | 12 |
| Slow EMA | 26 |
| Signal | 9 |
| TP | 80pips |
| SL | 170pips |
バックテスト結果
| 純益 | PF | 勝率 | 最大DD | 総取引数 |
|---|---|---|---|---|
| +22,283.82円 | 1.24 | 72.82% | 10,593.48円 (1.04%) | 195回 |

テスター設定のスプレッドは5、不整合チャートエラーは0でした。
今回の条件では、純益22,283.82円、PF1.24、勝率72.82%、最大ドローダウン1.04%となりました。
MACDクロスと0ラインを組み合わせたシンプルなロジックでも、今回の設定では利益を狙える結果となっています。
同じようにMT4でEAのバックテストや最適化を行いたい場合は、FXTFのヒストリカルデータを取得してMT4へ取り込む手順を以下の記事で解説しています。
将来の利益を保証するものではなく、通貨ペア・期間・スプレッド・パラメータなどによって結果は変わります。
MACD EAの弱点と改良ポイント
レンジ相場ではクロスが増えやすい
MACDはトレンドが発生している場面では方向を確認しやすい一方、レンジ相場ではMACDとシグナルが細かく交差し、売買シグナルが増えることがあります。
今回のEAでは0ライン条件を追加していますが、それだけですべてのダマシを避けられるわけではありません。
移動平均線などでトレンド方向を絞る
改良する場合は、次のような条件を組み合わせる方法があります。
- 長期移動平均線より上ではBUYだけに限定する
- 長期移動平均線より下ではSELLだけに限定する
- ADXで一定以上のトレンドがある場面だけ取引する
- 時間帯を限定する
- TP・SLやMACD期間をバックテストで比較する
条件を追加すれば必ず成績が改善するわけではありません。ロジックを変更した場合は、バックテストで結果を比較してください。
MACDと移動平均線を組み合わせた発展例は、以下の記事でも紹介しています。
MACDを決済ロジックに使う方法
今回のEAは固定TP・SLで決済しますが、MACDの反対クロスなどを決済条件として利用する方法もあります。
MACD EAのよくある質問
はい。Fast EMA・Slow EMA・Signal期間はすべてパラメータから変更できます。サンプルコードでは基本設定として12・26・9を初期値にしています。
実装は可能です。今回のサンプルでは条件を絞るため、マイナス圏でのゴールデンクロスをBUY、プラス圏でのデッドクロスをSELLとしています。
MODE_MAINではMACDメイン値、MODE_SIGNALではシグナル値を取得します。今回のEAでは両方を取得し、1本前と2本前の大小関係を比較してクロスを判定しています。
MACDの取得やクロス判定、ベーステンプレートから変更した箇所を理解しやすくするためです。そのまま利用する場合は、他のEAや手動ポジションと同じ口座で併用せず、EA単独での検証を推奨しています。
当サイトの無料MT4 EAビルダーを利用できます。MACDクロスを使った売買条件を画面上で設定してEAを作成できます。この記事の0ライン条件とは、設定内容によって売買タイミングが異なる場合があります。
まとめ|iMACD()を使ってMACD EAを作れる
今回のMACD EAでは、MT4 EAベーステンプレートを土台に、iMACD()を使ったMACDクロスと0ラインによるエントリー条件を追加しました。
- マイナス圏でのゴールデンクロスをBUY条件に使用
- プラス圏でのデッドクロスをSELL条件に使用
iMACD()で1本前・2本前の確定足を取得- Fast EMA・Slow EMA・Signal期間をパラメータ化
- TP・SLはベーステンプレートの固定pips方式を利用
- 個別EAでは使用する共通関数だけを掲載
- ベーステンプレートからの変更箇所をコード内の背景色で確認可能
ベーステンプレートと今回のMACD版を見比べることで、共通部分を残したまま、インジケーター固有の売買条件だけを追加する流れを確認できます。
他の売買ロジックも試したい場合は、EAサンプルコード一覧から移動平均線・RSI・ボリンジャーバンドなどの実装例を確認できます。










コメント