MACDのゴールデンクロスだけでEAを作ると、
レンジ相場でもエントリーしてしまうという問題に直面しがちです。
そこで有効なのが、移動平均線(MA)を使ったトレンドフィルターです。
MAの向きや位置関係を条件に加えることで、無駄なエントリーを減らし、相場環境に合った取引が可能になります。
本記事では、MACDと移動平均線を組み合わせたEAの作り方をテーマに、
エントリー条件の考え方から、MQL4による具体的な実装例までを初心者向けに解説します。
※ 本記事は MACDの基本EA(無料サンプルコード) をベースに、移動平均線フィルターを追加した発展編です。
MACD×移動平均線EAの考え方
MACDはトレンドの勢いや転換点を捉えるのに優れたインジケーターですが、
単体ではレンジ相場に弱いという欠点があります。
そこで本記事では、以下の役割分担でロジックを構成します。
- MACD:エントリーのタイミング判断
- 移動平均線(MA):トレンド方向のフィルター
この組み合わせにより、
- 上昇トレンド中 → 買いのみを狙う
- 下降トレンド中 → 売りのみを狙う
といった、方向性を限定したEAを作ることができます。
エントリー条件の全体像
今回のEAでは、以下の条件がすべて揃った場合にエントリーします。
買いエントリー条件
- MACDがゴールデンクロスしている
- 現在価格が移動平均線より上にある
- 移動平均線が上向きである
売りエントリー条件
- MACDがデッドクロスしている
- 現在価格が移動平均線より下にある
- 移動平均線が下向きである
このように、
MACDで「入るタイミング」を判断し、
MAで「入っていい方向か」を制限します。
移動平均線の判定ロジック
移動平均線は以下の2点をチェックします。
- 価格との位置関係(上か下か)
- MAの傾き(上向きか下向きか)
MAの値を取得する
double ma_now = iMA(NULL, 0, MAPeriod, 0, MODE_EMA, PRICE_CLOSE, 0);
double ma_prev = iMA(NULL, 0, MAPeriod, 0, MODE_EMA, PRICE_CLOSE, 1);ma_now:現在のMA値ma_prev:1本前のMA値
MAの向きを判定する
bool isMA_Up = (ma_now > ma_prev);
bool isMA_Down = (ma_now < ma_prev);このように比較することで、MAが上向きか下向きかを簡単に判定できます。
MACDエントリー判定(復習)
MACDのクロス判定は、基本EAと同じ考え方を使用します。
if(getMACDSign(3, 2, 1)){
openBuy = true;
}
else if(getMACDSign(4, 2, 1)){
openSell = true;
} MACDの取得方法や getMACDSign() の仕組みについては、以下の記事で詳しく解説しています。
👉 MT4でMACD EAを作成|無料MQL4サンプルコード解説
エントリー条件の統合
MACDとMAの条件を組み合わせると、最終的なエントリー判定は次のようになります。
if(isBullMACD && Ask > ma_now && isMA_Up){
openBuy = true;
}
if(isBearMACD && Bid < ma_now && isMA_Down){
openSell = true;
} これにより、
・トレンドと逆方向のエントリー
・レンジ中のダマシエントリー
を大きく減らすことができます。
サンプルコード(MACD×MA EA)
以下は、本記事で解説した内容を反映した MACD×移動平均線EAのサンプルコードです。
移動平均線による方向フィルターが追加された箇所(背景色強調)を中心に確認してみてください。
//+------------------------------------------------------------------+
//| MACD_MA_Sample.mq4 |
//| Copyright 2020, mef Software. |
//| https://fx-prog.com/ |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, mef Software."
#property link "https://fx-prog.com/"
#property version "1.00"
#property strict
input int MA_KIKAN = 21;
input int MACD_FAST = 12;
input int MACD_SLOW = 26;
input int MACD_SIGNAL = 9;
input int A_SPREAD = 150;
input double Lots = 0.01;
datetime prevtime;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int init()
{
//---
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
int start()
{
int orderPtn=0; //0:何もしない 1:買い 2:売り
int total=0;
int errorcode; // エラーコード
int ea_ticket_No,ea_order_entry_Type=0,ea_order_MagicNo; // チケットNo,エントリタイプ,マジックNo.
double ea_order_entry_price=0; //ストップロスレート,利確レート,エントリーレート
color order_Color = clrRed;
//---
//新しい足ができた時だけやる
if(Time[0] != prevtime){
prevtime = Time[0];
}else{
return(0);
}
//***売買判断箇所***//
double MA_ATAI = iMA(NULL, 0, MA_KIKAN, 0, 1, PRICE_CLOSE, 1);
//MACD状態取得関数から状態を取得
if(getMACDSign(3,1,0)==true && MA_ATAI < Ask)
{
orderPtn=1;
}
else if(getMACDSign(4,1,0)==true && MA_ATAI > Bid)
{
orderPtn=2;
}
else
{
orderPtn=0;
}
//***売買判断箇所***//
//***決済判断箇所***//
total=OrdersTotal();
if(total == 1){
bool OrderKekka = OrderSelect(0,SELECT_BY_POS,MODE_TRADES);
//買いエントリー中に、上から下にMACDがクロスしたら決済する
if(OrderKekka == true && OrderType() == OP_BUY && getMACDSign(2,1,0)==true){
OrderKekka = OrderClose(OrderTicket(),OrderLots(),Bid,10,Violet);
}
//売りエントリー中に、下から上にMACDがクロスしたら決済する
else if(OrderKekka == true && OrderType() == OP_SELL &&getMACDSign(1,1,0)==true){
OrderKekka = OrderClose(OrderTicket(),OrderLots(),Ask,10,Violet);
}
}
else if(total == 0 && orderPtn > 0)
{
if(orderPtn == 1)
{
ea_order_entry_price = Ask; // 現在の買値でエントリー
ea_order_entry_Type = OP_BUY; //OP_BUY
order_Color = clrBlue;
int index = iLowest(NULL,0,MODE_LOW,24,1); //直近24本前の最安値のバーを探す
}
else if(orderPtn == 2)
{
ea_order_entry_price = Bid; // 現在の売値でエントリー
ea_order_entry_Type = OP_SELL; //OP_SELL
order_Color = clrRed;
int index = iHighest(NULL,0,MODE_HIGH,24,1); //直近24本前の最高値のバーを探す
}
ea_order_MagicNo=0000; //マジックナンバーは0000固定とする
ea_ticket_No = OrderSend( // 新規エントリー注文
NULL, // 通貨ペア
ea_order_entry_Type, // オーダータイプ[OP_BUY / OP_SELL]
Lots, // ロット(0.01単位,FXTFは1=10Lot)
ea_order_entry_price, // オーダープライスレート
20, // スリップ上限
0, // ストップレート
0, // リミットレート
"テストオーダー", // オーダーコメント
ea_order_MagicNo, // マジックナンバー(識別用)
0, // オーダーリミット時間
order_Color // オーダーアイコンカラー
);
if ( ea_ticket_No == -1) // オーダーエラー
{
errorcode = GetLastError(); // エラーコード取得
if( errorcode != ERR_NO_ERROR) // エラー発生
{
printf("エラー:"+ IntegerToString(errorcode));
}
}
else { // 注文約定
Print("新規注文約定。 チケットNo=",ea_ticket_No);
}
}
return(0);
}
//***エントリー箇所***//
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//|【関数】MACDのクロスを探す
//|
//|【引数】 IN OUT 引数名 説明
//| ---------------------------------------------------------
//| ○ aType 上下
//| 1:下から上へ
//| 2:上から下へ
//| 3:下から上へ(マイナス域の場合のみ)
//| 4:上から下へ(プラス域の場合のみ)
//|
//| ○ limit どこまで遡るか
//| ○ i 現在のBar位置
//|【戻値】True(クロス有り) or False(クロス無し)
//|
//|【備考】なし
//+------------------------------------------------------------------+
bool getMACDSign(int type,int limit,int i)
{
int n;
bool sign = false;
double MACD_1,Signal_1,MACD_2,Signal_2;
limit = i + limit;
i = i + 1;
//下から上へのクロス
if(type==1){
for(n=i;n<=limit;n++){
MACD_1 = iCustom(NULL,0,"MACD",MACD_FAST,MACD_SLOW,MACD_SIGNAL,0,n);
MACD_2 = iCustom(NULL,0,"MACD",MACD_FAST,MACD_SLOW,MACD_SIGNAL,0,n+1);
Signal_1 = iCustom(NULL,0,"MACD",MACD_FAST,MACD_SLOW,MACD_SIGNAL,1,n);
Signal_2 = iCustom(NULL,0,"MACD",MACD_FAST,MACD_SLOW,MACD_SIGNAL,1,n+1);
if(MACD_2 <= Signal_2 && MACD_1 > Signal_1)
{
sign=true;
break;
}
}
}
//上から下へのクロス
else if(type==2){
for(n=i;n<=limit;n++){
MACD_1 = iCustom(NULL,0,"MACD",MACD_FAST,MACD_SLOW,MACD_SIGNAL,0,n);
Signal_1 = iCustom(NULL,0,"MACD",MACD_FAST,MACD_SLOW,MACD_SIGNAL,1,n);
MACD_2 = iCustom(NULL,0,"MACD",MACD_FAST,MACD_SLOW,MACD_SIGNAL,0,n+1);
Signal_2 = iCustom(NULL,0,"MACD",MACD_FAST,MACD_SLOW,MACD_SIGNAL,1,n+1);
if(MACD_2 >= Signal_2 && MACD_1 < Signal_1)
{
sign=true;
break;
}
}
}
//下から上へのクロス
if(type==3){
for(n=i;n<=limit;n++){
MACD_1 = iCustom(NULL,0,"MACD",MACD_FAST,MACD_SLOW,MACD_SIGNAL,0,n);
MACD_2 = iCustom(NULL,0,"MACD",MACD_FAST,MACD_SLOW,MACD_SIGNAL,0,n+1);
Signal_1 = iCustom(NULL,0,"MACD",MACD_FAST,MACD_SLOW,MACD_SIGNAL,1,n);
Signal_2 = iCustom(NULL,0,"MACD",MACD_FAST,MACD_SLOW,MACD_SIGNAL,1,n+1);
if(MACD_2 <= Signal_2 && MACD_1 > Signal_1 && MACD_1 <= 0 )
{
sign=true;
break;
}
}
}
//上から下へのクロス
else if(type==4){
for(n=i;n<=limit;n++){
MACD_1 = iCustom(NULL,0,"MACD",MACD_FAST,MACD_SLOW,MACD_SIGNAL,0,n);
Signal_1 = iCustom(NULL,0,"MACD",MACD_FAST,MACD_SLOW,MACD_SIGNAL,1,n);
MACD_2 = iCustom(NULL,0,"MACD",MACD_FAST,MACD_SLOW,MACD_SIGNAL,0,n+1);
Signal_2 = iCustom(NULL,0,"MACD",MACD_FAST,MACD_SLOW,MACD_SIGNAL,1,n+1);
if(MACD_2 >= Signal_2 && MACD_1 < Signal_1 && MACD_1 >= 0 )
{
sign=true;
break;
}
}
}
return(sign);
}EAレポート結果
作った後は、バックテストでちゃんと思った通りの動きになっている事を確認しましょう。

移動平均線の条件を加えた事で、ベースのEAよりも取引数が減少しました。
※ベースのEAは2005~2020の期間で4796件の取引だったため

ビジュアルモードで確認してみてもわかりますが、思った通りの動きになっていますね!先ほどの黄色丸の部分でエントリーされなくなりました。
ダウンロード
EAファイルのダウンロードはこちら👇
📥 MACDと移動平均線のEA をダウンロード \ 国内最大級のEAプラットフォーム /
GogoJungle(ゴゴジャン)でEAの評価・レビューをチェック!
よくあるカスタマイズ例
- MAを SMA / EMA / LWMA に変更する
- MAの期間を長くしてトレンドを厳選する
- MAを2本使い、短期・長期の位置関係を見る
これらはすべて、MAの取得方法を少し変更するだけで実装可能です。
まとめ
本記事では、MACDと移動平均線を組み合わせたEAの作り方を解説しました。
- MACDでエントリータイミングを判断
- MAでトレンド方向をフィルタリング
- ダマシを減らした実戦向きロジックを構築
MACD EAは、フィルターを1つ追加するだけで安定感が大きく変わるのが特徴です。
次のステップとして、決済条件まで含めて改良したい方は、以下の記事も参考にしてください。
👉 MT4でMACD EAを改良する方法|決済ロジックをカスタマイズする実践例
🛠️ EAを効率的に作りたい方へ
▶ MT4 EAベースソースを無料公開中







コメント