MACDのゴールデンクロス・デッドクロスを、チャート上で矢印を目で追うだけでなく、
実際に自動で発注するEAにしたい。
そう思った人のために、この記事では既刊の矢印表示インジケーターを土台に、
損切り必須・ポジション重複防止という資金管理の基本まで備えたEAを作ります。
・iMACD関数のmode引数を使ったクロス判定をEAの発注条件にする方法
・「またいだ瞬間」だけエントリーする設計
・損切り必須
・ポジション重複防止という資金管理の基本
・実際に動くEAのコード全体
MACDクロスEAの全体像
まず、このEAがどういう流れで動くのかを確認します。
既刊インジケーターとの役割分担
・既刊macd-cross-arrow-indicator-mt4.mdは矢印のみ
・本記事は同じ判定ロジックで発注まで行うEAに発展
・判定の考え方は共通だが、損切り・重複防止はEA側の要素
このEAが対応するポジションの数
シンプルさを優先し、この記事のEAは同時に1ポジションまでしか持たない設計にしています。
複数ポジションへの拡張は、後述の「よくある質問」で考え方だけ触れます。
状態ではなく変化を検知する
「メインラインがシグナルラインより上にある」という状態のまま条件にすると、
その状態が続く間ずっとエントリーしようとしてしまいます。
このEAも既刊インジケーターと同じく、「いま交差したか」という変化だけを発注条件にします。
iMACD関数の引数とクロス判定
発注条件の土台になる、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 );
`mode`に`MODE_MAIN`(0)を指定するとメインラインの値、
`MODE_SIGNAL`(1)を指定するとシグナルラインの値が、
それぞれ取得できます。
1本前との比較でクロスを検知する
//今の確定足と1本前の確定足を比較 currentMain > currentSignal && previousMain <= previousSignal //ゴールデンクロス currentMain < currentSignal && previousMain >= previousSignal //デッドクロス
1本前の関係と今の関係を比較することで、クロスが発生した瞬間だけを取り出せます。
確定足だけを判定に使う理由
形成中の0番目の足は値が変化し続けて確定していないため、
このEAはshift=1(直近の確定足)とshift=2(その1本前)を基準に判定します。
未確定の足を使うと、同じシグナルが出たり消えたりする不具合の原因になります。
エントリー条件を組み立てる
クロス判定から、実際の発注条件を作ります。
買い・売りエントリーの条件
double currentMain = iMACD(NULL, 0, FastEmaPeriod, SlowEmaPeriod, SignalPeriod, PRICE_CLOSE, MODE_MAIN, 1); double currentSignal = iMACD(NULL, 0, FastEmaPeriod, SlowEmaPeriod, SignalPeriod, PRICE_CLOSE, MODE_SIGNAL, 1); double previousMain = iMACD(NULL, 0, FastEmaPeriod, SlowEmaPeriod, SignalPeriod, PRICE_CLOSE, MODE_MAIN, 2); double previousSignal = iMACD(NULL, 0, FastEmaPeriod, SlowEmaPeriod, SignalPeriod, PRICE_CLOSE, MODE_SIGNAL, 2); bool buySignal = (currentMain > currentSignal && previousMain <= previousSignal); bool sellSignal = (currentMain < currentSignal && previousMain >= previousSignal);
ゴールデンクロスが発生した瞬間だけ`buySignal`が、
デッドクロスが発生した瞬間だけ`sellSignal`がtrueになります。
レンジ相場ではダマシが増える
・レンジ相場では2本のラインが絡み合い、クロスが連発しやすい
・このEAはクロスの発生だけを見ており、トレンドの強さは判定していない
・既刊ADX
・効率比系の記事と組み合わせたフィルターの追加を推奨します
OsMA・ストキャスティクスとの違い
既刊osma-cross-arrow-indicator.mdのゼロクロスと、
このMACDクロスは理論上ほぼ同じ現象を見ています。
一方でストキャスティクスのクロスは、買われすぎ・売られすぎという別の情報を持つため、
組み合わせるフィルターとして相性が良いです。
損切り・ポジション重複防止という資金管理の基本
発注する前に、必ず組み込むべき安全策を確認します。
損切り(StopLoss)は必ず設定する
・損切りを設定しないEAは、1回の逆行で大きな損失につながる
・この記事のEAはInpStopLossPipsで必ず損切り値を指定する設計にする
・0を指定しても動くコードにはしない(人為的に無効化できないようにする)
マジックナンバーで自分の注文だけを数える
int CountMyOrders()
{
int count = 0;
for(int i = 0; i < OrdersTotal(); i++)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderMagicNumber() == InpMagicNumber && OrderSymbol() == _Symbol)
count++;
}
}
return(count);
}
他のEAや手動注文を数に含めないよう、マジックナンバーと通貨ペアで絞り込みます。
ポジション重複エントリーを防ぐ
`CountMyOrders() == 0`を新規エントリーの条件に加えることで、
すでに1ポジション持っている状態での二重発注を防ぎます。
実際に動くEAのコード全体
ここまでの要素をまとめたEAの全体です。
//+------------------------------------------------------------------+
//| MacdCrossEA.mq4 |
//| Copyright 2026, FX-EA System Project Creator |
//| https://creator.fx-ea-system-project.com/ |
//+------------------------------------------------------------------+
#property strict
input int FastEmaPeriod = 12; //MACD高速EMA期間
input int SlowEmaPeriod = 26; //MACD低速EMA期間
input int SignalPeriod = 9; //シグナルライン期間
input double InpLots = 0.1; //発注ロット数
input int InpStopLossPips = 20; //損切り(pips)
input int InpSlippage = 3; //許容スリッページ
input int InpMagicNumber = 20261015;//マジックナンバー
int CountMyOrders()
{
int count = 0;
for(int i = 0; i < OrdersTotal(); i++)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderMagicNumber() == InpMagicNumber && OrderSymbol() == _Symbol)
count++;
}
}
return(count);
}
int OnInit()
{
if(InpStopLossPips <= 0)
{
Alert("InpStopLossPipsは1以上を指定してください(損切り必須設計)");
return(INIT_PARAMETERS_INCORRECT);
}
return(INIT_SUCCEEDED);
}
void OnTick()
{
int needed = SlowEmaPeriod + SignalPeriod + 3;
if(Bars < needed)
return;
double currentMain = iMACD(NULL, 0, FastEmaPeriod, SlowEmaPeriod, SignalPeriod, PRICE_CLOSE, MODE_MAIN, 1);
double currentSignal = iMACD(NULL, 0, FastEmaPeriod, SlowEmaPeriod, SignalPeriod, PRICE_CLOSE, MODE_SIGNAL, 1);
double previousMain = iMACD(NULL, 0, FastEmaPeriod, SlowEmaPeriod, SignalPeriod, PRICE_CLOSE, MODE_MAIN, 2);
double previousSignal = iMACD(NULL, 0, FastEmaPeriod, SlowEmaPeriod, SignalPeriod, PRICE_CLOSE, MODE_SIGNAL, 2);
bool buySignal = (currentMain > currentSignal && previousMain <= previousSignal);
bool sellSignal = (currentMain < currentSignal && previousMain >= previousSignal);
if(CountMyOrders() > 0)
return;
double pip = (Digits == 3 || Digits == 5) ? Point * 10 : Point;
if(buySignal)
{
double sl = Bid - InpStopLossPips * pip;
OrderSend(_Symbol, OP_BUY, InpLots, Ask, InpSlippage, sl, 0,
"MacdCrossEA", InpMagicNumber, 0, clrBlue);
}
else if(sellSignal)
{
double sl = Ask + InpStopLossPips * pip;
OrderSend(_Symbol, OP_SELL, InpLots, Bid, InpSlippage, sl, 0,
"MacdCrossEA", InpMagicNumber, 0, clrRed);
}
}
`pip`の計算で5桁(3桁)ブローカーに対応しているのは、
既刊の複数のEA記事と同じ、よくある落とし穴への対応です。
MetaEditorでのコンパイル・バックテスト手順
実際に動かすまでの手順です。
- MetaEditorで新規EA「MacdCrossEA」を作成し、上のコードを貼り付けてコンパイルする
- 「0 error(s), 0 warning(s)」になることを確認する
- ストラテジーテスターで任意の通貨ペア・期間を指定し、「全ティック」モードでバックテストする
- InpStopLossPipsを0や負の値にして、Alertが出てEAが起動しないことを確認する
よくあるエラーと注意点
実装・運用でつまずきやすいポイントをまとめます。
OrderSendが失敗してもエラー処理がない
・このコードは解説用にOrderSendの戻り値チェックを省略している
・実運用では戻り値が-1の場合にGetLastError()で原因を調べる処理を追加する
・既刊get-last-error.mdのエラーコード確認方法が参考になる
クロスが連発してシグナルが多すぎる
レンジ相場ではクロスが頻発し、エントリーと損切りを繰り返すことがあります。
既刊adx-strength-indicator.mdのようなトレンド強さの指標を、
フィルターとして組み合わせることを検討してください。
損切り幅を狭くしすぎるとすぐ決済される
InpStopLossPipsを極端に小さくすると、
通常のスプレッドの範囲内で損切りに達してしまうことがあります。
通貨ペアのスプレッドより十分に広い値を設定してください。
よくある質問
MACDクロスEAについて、よく検索される疑問に回答します。
既刊の矢印インジケーターとの違いは何ですか?
既刊macd-cross-arrow-indicator-mt4.mdは、
画面に矢印を表示するだけのインジケーターです。
本記事はまったく同じクロス判定ロジックを使いながら、
実際にOrderSendで発注するところまで実装している点が違いです。
他のオシレーターと組み合わせられますか?
できます。
既刊stochastic-cross-arrow-indicator-mt4.mdの、
買われすぎ・売られすぎ判定をif文に追加すれば、
MACDクロス+ストキャスティクスの2条件フィルターにできます。
このEAは必ず勝てますか?
断定はできません。
MACDクロスはトレンドの切り替わりを捉えやすい一方、
レンジ相場ではダマシが増える手法もあります。
損切り設定は外さずに運用することをおすすめします。
【MQL4】MACDのゴールデンクロス・デッドクロスでエントリーするEAの作り方(損切り必須+ポジション重複防止設計):まとめ
既刊の矢印表示インジケーターで使ったiMACDのクロス判定ロジックは、
if文の条件をそのままOrderSendの発注条件に転用できます。
「またいだ瞬間」だけ反応する判定と、
損切り必須・ポジション重複防止という資金管理の基本を、
組み合わせることが、実運用に耐える設計の最低条件です。
コメント