MT4で移動平均線(MA)EAを作成|無料MQL4サンプルコード解説

移動平均線EAのトレードイメージ画像
EAサンプル・ノウハウ
記事内に商品プロモーションを含む場合があります
スポンサーリンク

はじめに

「移動平均線を使った順張りロジックを、FX自動売買EAとして自動化したい!」という方向けに、この記事では MT4(MQL4)で動作する無料MA EAサンプルコード を紹介します。
初心者でもコピペで動かせるので、学習用や実験用に最適です。

移動平均線は、トレンドの方向性を把握するために非常に基本的かつ有効なインジケーターで、裁量トレードでも広く使われています。
この記事では、短期・中期MAを組み合わせたゴールデンクロス/デッドクロスロジックをEA化して、自動でエントリー・決済する方法を解説します。


📈 移動平均線(MA)とは?

移動平均線(Moving Average, MA)は、一定期間の価格の平均値を線としてチャートに表示するインジケーターです。よくあるエントリー手法としては、短期MAと中期MAを見てクロスでエントリーする方法です。

  • ゴールデンクロス:短期MAが中期MAを下から上に抜ける → 買いサイン
  • デッドクロス:短期MAが中期MAを上から下に抜ける → 売りサイン

移動平均線の詳細はこちら👇
移動平均線の使い方を徹底解説|SMA・EMAの違いと活用術
【オススメ】移動平均線の設定


EAの概要とポイント

  • MT4標準インジケータの iMA() を使って自動判定
  • 短期MA・中期MAのゴールデンクロス/デッドクロスで売買エントリー
  • 損切は、エントリー時の中期MA+設定幅(利確はリスクリワード1:1で)
  • 短期・中期MA期間、MA種別、SL幅などをパラメータでカスタマイズ可能

エントリーロジック解説

買いエントリー(ロング)

  • 短期MAが中期MAを下から上に抜けた
  • 直近の短期MAの傾きが上向き
    → BUY判断

売りエントリー(ショート)

  • 短期MAが中期MAを上から下に抜けた
  • 直近の短期MAの傾きが下向き
    → SELL判断

別のエントリー方法

移動平均線といえば、ローソク足の終値が移動平均線を上抜けたらロングエントリーしていくような手法もあります。もしクロスではないサンプルを確認したい場合は以下の記事も参照ください。
超初心者向けEAプログラミング入門⑧|移動平均線で賢くエントリーしよう

他にも移動平均線のEAを作るうえで必要な知識を以下に記載しています。
移動平均線を使ったEAを作る際に必要なこと
移動平均線の上向き、下向きを判定してEAに組み込みたい場合
移動平均線の上げ下げの角度でエントリーするようEAに組み込みたい場合


⚠️ 注意点

  • MAはトレンド相場で有効ですが、レンジ相場ではダマシが多発します
  • 複数インジケーター(RSIやパラボリックなど)を組み合わせると精度が向上します
  • 新しいローソク足が形成された際に1回だけ処理を実行する設計です
  • マジックナンバーは考慮していません。(このEA単独で動かしてください)
  • パラメータ設定でTP/SLがありますが、こちらは未使用です(ベースソースの関係上)

パラボリックSAR EAのサンプルはこちら


ダウンロード

EAファイルのダウンロードはこちら👇

📥 移動平均線EA をダウンロード

📜 移動平均線EAのサンプルコード解説

以下にMQL4サンプルコードを掲載します。
そのままコピーしてMT4(MetaEditor)に貼り付ければコンパイル可能で、動作確認も済んでいます。

//+------------------------------------------------------------------+
//|                                             01_MovingAverage.mq4 |
//|                                   Copyright © 2020-2025 ぷろぐらむFX |
//|                                             https://fx-prog.com/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2020-2025 ぷろぐらむ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 FasterMA = 21;      //短期移動平均線期間
input int MediumMA = 84;      //中期移動平均線期間
input int MAMode = 1;         //移動平均線種別 0 = sma, 1 = ema, 2 = smma, 3 = lwma
input int SL_GOSA = 6;       //決済時SLライン(pips)
//***【パラメータ設定↑】***//

string Ea_Name = "MovingAverage";      //オーダーコメントに使用

double PipValue;                       //ブローカー桁数に対応した Point 補正
datetime prevtime;                     //ローソク足時間保持用
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit(){

   //デジットチェック
   if (Digits == 3 || Digits == 5){
      PipValue = Point * 10;   // 例: EURUSD 1.23456 → 1pip = 0.00010
   }else{
      PipValue = Point;        // 例: USDJPY 123.45 → 1pip = 0.01
   }

   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason){

}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick(){

   int total = OrdersTotal();    //ポジショントータル数をセット  
   int ea_order_Type = -1; //0:OP_BUY  1:OP_SELL
   double ea_order_stop_price = 0; //ストップロスレート
   double ea_order_good_price = 0; //利確レート

   //新しい足ができた時だけやる
   if(Time[0] != prevtime){
      prevtime = Time[0];
   }else{
      return;
   }

   //ポジションがない場合はエントリー判定
   if(total == 0){

      bool openBuy  = false;    //買い新規注文判断
      bool openSell = false;    //売り新規注文判断
      
//***【新規注文判断↓】***//
      bool isBullMovingAve_S = false;
      bool isBearMovingAve_S = false;

      //----MA短期値取得      
      double fasterMA_ATAI_1   = iMA(NULL, 0, FasterMA, 0, MAMode, PRICE_CLOSE, 1);    //短期移動平均線で1つ前の値を取得
      double fasterMA_ATAI_2   = iMA(NULL, 0, FasterMA, 0, MAMode, PRICE_CLOSE, 2);    //短期移動平均線で2つ前の値を取得
          
      //----MA中期値取得  
      double MediumMA_ATAI_1   = iMA(NULL, 0, MediumMA, 0, MAMode, PRICE_CLOSE, 1);    //中期移動平均線で1つ前の値を取得
      double MediumMA_ATAI_2   = iMA(NULL, 0, MediumMA, 0, MAMode, PRICE_CLOSE, 2);    //中期移動平均線で2つ前の値を取得 
   
      //MAのゴールデンクロスでロング(短期MAが上を向いている事)  
      if(fasterMA_ATAI_1 > MediumMA_ATAI_1 && fasterMA_ATAI_2 < MediumMA_ATAI_2 && fasterMA_ATAI_1 > fasterMA_ATAI_2){
         isBullMovingAve_S=true;
      }
      //MAのデッドクロスでショート(短期MAが下を向いている事)     
      else if(fasterMA_ATAI_1 < MediumMA_ATAI_1 && fasterMA_ATAI_2 > MediumMA_ATAI_2 && fasterMA_ATAI_1 < fasterMA_ATAI_2){
         isBearMovingAve_S=true;
      }

//***【新規注文判断↑】***//

      //参照するサンプルEAの買いエントリーフラグをセットしてください
      if(isBullMovingAve_S){
         openBuy =true;
         ea_order_Type = OP_BUY;
      //参照するサンプルEAの売りエントリーフラグをセットしてください      
      }else if(isBearMovingAve_S){
         openSell =true;
         ea_order_Type = OP_SELL;
      }

//***【TP/SL判断↓】***//
      double risk = 0;
      if(openBuy){
         //損切り:中期移動平均線付近(設定で変更可)
         ea_order_stop_price = MediumMA_ATAI_1 - SL_GOSA * PipValue;
         
         // リスク幅:エントリー価格(Ask) から SL までの距離
         risk = MathAbs(Ask - ea_order_stop_price);
         
         // 利確:同じ幅だけ上
         ea_order_good_price = Ask + risk;   
      }else if(openSell){
         ea_order_stop_price = MediumMA_ATAI_1 + SL_GOSA * PipValue;

         // リスク幅:エントリー価格(Bid) から SL までの距離
         risk = MathAbs(ea_order_stop_price - Bid);         
         
         ea_order_good_price = Bid - risk;  
      }
//***【TP/SL判断↑】***//

      if(ea_order_Type > -1){
         funcOrder_Send(ea_order_Type,ea_order_stop_price,ea_order_good_price,Lots,Ea_Name,777,0);
      }
      
   }

   return;
}


//★★★★★★★★★★★★★★★★★★★★ ここから下は共通関数 ★★★★★★★★★★★★★★★★★★★★
//+------------------------------------------------------------------+
//|【関数】新規注文関数
//|
//|【引数】 orderType:売買(0=BUY, 1=SELL)
//|【引数】 sl:損切り価格  tp:利確価格
//|【引数】 lots:取引ロット数
//|【引数】 orderComment:オーダーコメント
//|【引数】 magic:マジックNo
//|【引数】 maxSpreadPips: 許容スプレッド[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;
   color  clr    = clrNONE;
   double spread = 0;

   // 最大10回リトライ
   for(int retry=0; retry<10; retry++)
   {
      RefreshRates();
      
      // スプレッド取得(MT4表示と同じポイント単位)
      spread = MarketInfo(Symbol(), MODE_SPREAD);

      // スプレッドチェック(maxSpreadPoints=0 の場合はスキップ)
      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;
      }

      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;
      }else{
         int err = GetLastError();
         Print("新規注文失敗 エラーNo=", err,
               " リトライ回数=", retry+1);
         Sleep(2000);
      }
   }

   return false;
}
 

スポンサーリンク

iMA() 関数の解説

短期・中期MAの値を取得するために MT4標準関数 iMA() を使用します。

【使用例】

double value = iMA(NULL, 0, FasterMA, 0, MAMode, PRICE_CLOSE, 1);

引数の意味

  • 引数1:通貨ペア(NULLで現在のチャート)
  • 引数2:時間軸(0で現在の時間足)
  • 引数3:MA期間(例:短期21)
  • 引数4:移動平均シフト(0で最新)
  • 引数5:MA種別(0=SMA, 1=EMA, 2=SMMA, 3=LWMA)
  • 引数6:価格種別(PRICE_CLOSEなど)
  • 引数7:バーシフト(0で最新、1で1つ前の足)

MA利用箇所

  • 69〜88行目 … 新規注文処理でパラボリック値をチェック
  • 102〜120行目 … TP/SLをエントリー値と中期移動平均線の幅+設定SLpipsにしています

👉 TP/SLを変更したい場合は、(102〜120行目)をメンテナンスしてください。

MAを使った売買判定について

移動平均線EAのトレードイメージ画像

  • 短期MAと中期MAのゴールデンクロス/デッドクロスでエントリー
  • 短期MAの傾きを確認して方向性を補強
  • エントリー後の損切は、中期MA+設定SLの値段
  • エントリー後の利確は、損切り幅とリスクリワード1:1の値段
  • TP/SLでの管理のため、決済処理はありません

新規注文

本記事の移動平均線 EAで使用している「新規注文処理」は、当サイト共通のベースソースに含まれています。
EAを効率的に自作したい方は、以下の記事もあわせて参考にしてください。
👉 MT4 EAベースソースコード(無料配布・カスタマイズ容易)
👉 新規・変更・決済注文関数の詳しい解説はこちら

パラメータとカスタマイズ

今回のパラメータ設定は以下の通りです:

  • 取引ロット数(0.01で1000通貨)
  • 利確(pips)
  • 損切り(pips)
  • 短期MA期間:例 21
  • 中期MA期間:例 84
  • MA種別:0=SMA, 1=EMA, 2=SMMA, 3=LWMA
  • 決済時SLライン(pips):決済時に中期MA付近に設定
移動平均線EAのパラメータ設定画像

👉 決済時SLライン(pips)はマイナス値を設定する事で、中期移動平均線よりも手前にSLを設定します。

スポンサーリンク

EAバックテストレポート

USDJPY(H1, 2024/08〜2025/08, 初期証拠金100万円, FXTFヒストリカル)での結果:

通貨ペア・時間足PF勝率最大DD取引回数備考
USDJPY M151.7461%0.36%90回利益はしっかり出ているがトレード回数は少ない
移動平均線EAのバックテストレポート

まとめ

移動平均線EAはシンプルな順張りロジックで、初心者でも理解しやすい設計です。

  • トレンド相場で強みを発揮
  • 短期〜長期足に向く万能型
  • フィルタ追加でさらに精度向上

まずはサンプルコードを試してみて、自分の環境でバックテストを行ってみましょう。EA作成時の手ごたえとしては、可能性を感じる結果ですが単独では少し難易度が高そうです。ただフィルタ追加やロジック改良次第で、実用的なEAへと進化させることが可能なのは確かです。

🛠️ EAを効率的にカスタマイズしたい方へ
【MT4 EAベースソース】を無料公開中!初心者でもすぐに使えます。


✅ 他にも多数のEAサンプルを公開中!

今回紹介した内容以外にも、当サイトではさまざまな
FX自動売買EAのサンプルコードを提供しています。

自分に合った戦略のEAを見つけたい方は、ぜひチェックしてみてください。


📊 【2025年最新】FX自動売買EAランキングも公開中!

当サイトの「どのEA(インジ)が実際に勝っているのか?」を知りたい方はこちら👇
PF(プロフィットファクター)や勝率で徹底比較した最新ランキングから、あなたに最適なEA(インジ)を見つけましょう。


EA開発初心者向けに、今後も実践的なMQL4関数を紹介していきます。
気になる機能やロジックがあれば、ぜひ他の記事もあわせてご覧ください!

コメント

  1. 岡村さんのアイコン 岡村 より:

    このままコンパイルしてみたのですが エントリーしないようです
    やり方が悪いでしょうか?

    • りょう りょう より:

      パラメータ設定のA_SPREAD=10を20とかにしてもエントリーしないでしょうか?
      初期設定が10なので1pips以上スプレッドが開ているとエントリーしないようになっています。

タイトルとURLをコピーしました