MT4 EAの作り方|移動平均線(MA)で順張りするEAを作る方法

MT4チャートで移動平均線EAがMAクロスを使って順張り判定するイメージ画像
EAサンプル・ノウハウ
記事内に商品プロモーションを含む場合があります
スポンサーリンク

「移動平均線を使った順張りロジックをEA化したい」
「MAクロスをMQL4でどう判定するのか知りたい」
という方に向けて、この記事ではMT4で動く移動平均線(MA)EAのサンプルコードを公開します。

短期MAと中期MAのゴールデンクロス/デッドクロスに加え、短期MAの傾きも確認してエントリーします。
MAの値取得には、MT4標準のiMA()関数を使用します。

今回のEAは、当サイトで公開しているMT4 EAベーステンプレートを土台に、MA用の売買条件とTP・SLロジックを追加したサンプルです。

📘 この記事で解説する内容
  • MT4のiMA()で移動平均線の値を取得する方法
  • ゴールデンクロス/デッドクロスの判定
  • 確定足とMAの傾きを使ったエントリー
  • 中期MAを基準にSL・TPを設定する方法
  • ベーステンプレートから変更した箇所
  • 公開サンプルコードとバックテスト結果

この移動平均線EAの仕様

まず、今回作成するEAの内容をまとめます。

項目内容
対応MT4 / MQL4
使用インジケーター移動平均線(MA)
使用関数iMA()
BUY条件短期MAが中期MAを上抜け+短期MAが上向き
SELL条件短期MAが中期MAを下抜け+短期MAが下向き
判定タイミング新しいローソク足ができたとき(確定足を使用)
損切り中期MA ± 設定pips
利確エントリー価格からSLまでの距離と1:1
ポジション管理口座内に注文がない場合のみ新規エントリー
MagicNumber管理なし(学習用サンプルのため)

移動平均線(MA)とは?

移動平均線(Moving Average / MA)は、一定期間の価格を平均し、その推移を線で表示するインジケーターです。

EAでは、短期MAと中長期MAの位置関係やクロスを売買条件として利用できます。

  • ゴールデンクロス:短期MAが中期MAを下から上へ抜ける
  • デッドクロス:短期MAが中期MAを上から下へ抜ける

この記事ではEA化に必要な部分へ絞って解説します。
移動平均線そのものの種類や使い方を詳しく確認したい場合は、以下の記事をご覧ください。

MA EAのエントリーロジック

BUY条件

  • 2本前は「短期MA < 中期MA」
  • 1本前は「短期MA > 中期MA」
  • さらに短期MAが上向き

短期MAが中期MAを下から上へ抜け、短期MA自体も上昇している場合にBUYします。

SELL条件

  • 2本前は「短期MA > 中期MA」
  • 1本前は「短期MA < 中期MA」
  • さらに短期MAが下向き

短期MAが中期MAを上から下へ抜け、短期MA自体も下降している場合にSELLします。

確定足で判定する

MAの取得には現在形成中の0番足ではなく、1本前・2本前の確定足を使用します。

これにより、ローソク足形成途中でMAの位置関係が一時的に変化しただけでエントリーするのを避けています。

別のMA判定方法もある

移動平均線を使ったEAには、クロス以外にも「価格がMAを上抜けた」「MAの傾きだけを見る」といった設計があります。

このサンプルEAを使う前の注意点

このコードは、MAロジックを理解・検証しやすくすることを優先したサンプルです。
複数EAを同一口座で管理するためのMagicNumberによるポジション識別などは、あえて実装していません。

このEAでは、口座全体の注文数をOrdersTotal()で確認し、注文が1件でも存在する場合は新規エントリーしません。

そのため、サンプルをそのまま使用する場合は、他のEAや手動ポジションと同じ口座で併用せず、このEA単独で検証する方法を推奨します。

複数EAを同じ口座で個別管理したい場合はMagicNumberなどの注文識別処理が必要になります。

また、MAクロスはレンジ相場ではクロスが繰り返され、ダマシが増えることがあります。必要に応じてRSI・ADX・上位足・時間帯などをフィルターとして追加し、バックテストで効果を確認してください。

ベーステンプレートからの変更点

今回の移動平均線EAは、当サイトで公開しているMT4 EAベーステンプレートを土台に作成しています。

ベーステンプレートからの主な変更点は次の通りです。

  • 短期MA期間・中期MA期間・MA種別・SL距離のパラメータを追加
  • iMA()で1本前・2本前の短期MAと中期MAを取得
  • MAクロス+短期MAの傾きでBUY / SELLを判定
  • 固定pipsのTP・SLではなく、中期MAを基準にSLを設定
  • TPはエントリー価格からSLまでの距離と1:1に設定
  • 独自の決済シグナルは使用せず、TP・SLで決済
  • 共通関数は実際に使用するfuncOrder_Send()のみ掲載

つまり、新規注文などの基本構造はベーステンプレートを利用し、売買判定とSL・TPの決め方をMA用に変更したEAです。

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

今回の記事で解説している移動平均線EAはこちらからダウンロードできます。

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

👉 ダウンロード後のパラメータ設定を見る

💡 コードを書かずにEAを作ってみたい方へ
無料MT4 EAビルダーでは、移動平均線のクロスを使った売買条件を画面上で設定してEAを作成できます。
今回のサンプルを試したあと、MA期間や売買条件を変えて自分のEAを作ってみたい方にもおすすめです。

▶ 無料MT4 EAビルダーを使ってみる

なお、この記事のサンプルEAは「MAクロス+短期MAの傾き」をエントリー条件にしています。EAビルダーの標準MAクロスとは売買条件が一部異なるため、まったく同じEAではありません。

移動平均線EAのMQL4サンプルコード

以下が今回の公開版ソースコードです。
公開表記はv1.0、ソース上は#property version "1.00"としています。

💡 コードの見方
背景色が付いている行が、ベースEAテンプレートから主に変更・追加した部分です。
MA固有のパラメータ・売買判定・TP/SL計算を中心に強調しています。
//+------------------------------------------------------------------+
//|                                             01_MovingAverage.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 FasterMA = 21;               //短期移動平均線期間
input int MediumMA = 84;               //中期移動平均線期間
input int MAMode = 1;                  //0=SMA 1=EMA 2=SMMA 3=LWMA
input int SL_GOSA = 6;                 //中期MAからSLまでの距離(pips)

//***【パラメータ設定↑】***//

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本前の確定足からMAを取得
      double fasterMA_1 = iMA(NULL,0,FasterMA,0,MAMode,PRICE_CLOSE,1);
      double fasterMA_2 = iMA(NULL,0,FasterMA,0,MAMode,PRICE_CLOSE,2);
      double mediumMA_1 = iMA(NULL,0,MediumMA,0,MAMode,PRICE_CLOSE,1);
      double mediumMA_2 = iMA(NULL,0,MediumMA,0,MAMode,PRICE_CLOSE,2);

      //ゴールデンクロス+短期MAが上向き
      if(fasterMA_1 > mediumMA_1 && fasterMA_2 < mediumMA_2 && fasterMA_1 > fasterMA_2){
         openBuy = true;

      //デッドクロス+短期MAが下向き
      }else if(fasterMA_1 < mediumMA_1 && fasterMA_2 > mediumMA_2 && fasterMA_1 < fasterMA_2){
         openSell = true;
      }

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

      if(openBuy){
         ea_order_Type = OP_BUY;
      }else if(openSell){
         ea_order_Type = OP_SELL;
      }

//***【TP/SL判断↓】***//

      //中期MAを基準にSLを設定し、SL幅と1:1でTPを設定
      double risk = 0;

      if(openBuy){
         ea_order_stop_price = mediumMA_1 - SL_GOSA * PipValue;
         risk = MathAbs(Ask - ea_order_stop_price);
         ea_order_good_price = Ask + risk;
      }else if(openSell){
         ea_order_stop_price = mediumMA_1 + SL_GOSA * PipValue;
         risk = MathAbs(ea_order_stop_price - Bid);
         ea_order_good_price = Bid - risk;
      }

//***【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のiMA()関数で移動平均線の値を取得する

MT4で移動平均線の値をEAから取得するときは、標準関数のiMA()を使用します。

使用例:

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

iMA()の主な引数は次の通りです。

引数今回の指定内容
symbolNULL現在のチャートの通貨ペア
timeframe0現在のチャート時間足
ma_periodFasterMA / MediumMA移動平均線の計算期間
ma_shift0MAの表示シフト
ma_methodMAModeSMA / EMA / SMMA / LWMAを指定
applied_pricePRICE_CLOSE終値を計算対象に使用
shift1 / 21本前・2本前の確定足を取得

今回のEAではバーシフト1と2のMAを比較し、確定した2本のローソク足でクロスを判定しています。

ゴールデンクロスとデッドクロスを判定する

1本前と2本前の短期MA・中期MAを比較することで、クロスが発生したかを判定できます。

if(fasterMA_1 > mediumMA_1 && fasterMA_2 < mediumMA_2 && fasterMA_1 > fasterMA_2){
   openBuy = true;
}

BUYでは、2本前に短期MAが中期MAより下、1本前に短期MAが中期MAより上になっていることを確認します。

さらにfasterMA_1 > fasterMA_2を加えることで、短期MA自体が上向きであることも条件にしています。

SELLはこの反対で、デッドクロスに加えて短期MAが下向きであることを確認します。

中期MAを基準にSL・TPを設定する

今回のEAでは、ベーステンプレートの固定pipsによるTP・SLは使用していません。

BUYの場合は中期MAよりSL_GOSA分だけ下へSLを置き、現在価格からSLまでの距離をriskとして計算します。

ea_order_stop_price = mediumMA_1 - SL_GOSA * PipValue;
risk = MathAbs(Ask - ea_order_stop_price);
ea_order_good_price = Ask + risk;

TPはSLまでの距離と同じ値幅にするため、リスクリワードは1:1です。SELLの場合は上下を反転して計算します。

MAを使った売買判定のイメージ

移動平均線EAのトレードイメージ画像
画像をクリックすると拡大できます
  • 短期MAと中期MAのクロスで方向を判定
  • 短期MAの傾きも確認
  • SLは中期MAから指定pips離した価格
  • TPはSL幅と同じ距離(リスクリワード1:1)
  • エントリー後はSL・TPで決済

新規注文は共通関数funcOrder_Send()を使用

新規注文部分には、ベーステンプレートでも使用している共通のfuncOrder_Send()を利用しています。

今回のMA EAでは注文変更や独自の成行決済を使用しないため、個別EAのソースには実際に使用する新規注文関数だけを掲載しています。

注文関数そのものの仕組みを詳しく確認したい場合は、以下の記事で解説しています。

移動平均線EAのパラメータ設定

公開版の基本パラメータは次の通りです。

パラメータ初期値内容
Lots0.011回のエントリーで使用するロット数
FasterMA21短期移動平均線の計算期間
MediumMA84中期移動平均線の計算期間
MAMode10=SMA / 1=EMA / 2=SMMA / 3=LWMA
SL_GOSA6中期MAからSLまで離す距離(pips)

初期設定では、短期MA21・中期MA84・EMAを使用します。

SL_GOSAでは、中期MAから損切りラインをどれだけ離すかをpipsで指定します。

このEAでは固定TP・SLのパラメータは使用せず、中期MAの位置からSLを計算し、そのSL幅と1:1になるようTPを自動計算します。

スポンサーリンク

移動平均線EAのバックテスト結果

USDJPY・H1、2024年8月~2025年8月、初期証拠金100万円、FXTFヒストリカルデータを使用してバックテストを行いました。

通貨ペア・時間足PF勝率最大DD取引回数
USDJPY H11.7461%0.36%90回
移動平均線EAのバックテストレポート
画像をクリックするとバックテストレポートを拡大できます

今回の条件では、PF1.74、勝率61%、最大ドローダウン0.36%という結果になりました。

シンプルなMAクロスに短期MAの傾きを加えたロジックでも、条件次第では十分に利益を狙えることが分かります。

同じようにMT4でEAのバックテストを行いたい場合は、FXTFのヒストリカルデータを取得してMT4へ取り込む手順を以下の記事で解説しています。

この結果は掲載条件で行ったバックテスト結果です。
将来の利益を保証するものではなく、通貨ペア・期間・スプレッド・パラメータなどによって結果は変わります。

MA EAの弱点と改良ポイント

移動平均線クロスは仕組みが分かりやすく、EA化の教材としても使いやすい一方、相場状況によっては弱点もあります。

レンジ相場ではダマシが増えやすい

値動きに方向性がない場面では短期MAと中期MAが何度も交差し、エントリー後にすぐ逆方向へ動くケースがあります。

フィルター追加を検討できる

改良する場合は、例えば次のような条件を追加できます。

  • 上位足MAで大きな方向を限定する
  • ADXでトレンドの強さを確認する
  • RSIで買われすぎ・売られすぎを除外する
  • 稼働時間帯を限定する
  • MA期間やMA種別を変更して比較する

ただし、条件を追加すれば必ず成績が良くなるわけではありません。ロジックを変更した場合は、バックテストで結果を比較してください。

移動平均線EAのよくある質問

Q. このMA EAはそのままMT4で使えますか?

MT4用のMQL4サンプルとして利用できます。ただし学習・検証用途を想定したシンプルな構成のため、実運用前には必ずデモ口座やバックテストで動作を確認してください。

Q. SMAからEMAへ変更できますか?

できます。MAModeを変更することで、SMA・EMA・SMMA・LWMAを切り替えられます。初期値の1はEMAです。

Q. ベーステンプレートの固定TP・SLを使わないのはなぜですか?

今回のMA EAでは固定pipsではなく、中期MAを基準にSLを設定し、そのSLまでの値幅と1:1になる位置へTPを設定するためです。そのため、個別EAの公開コードから固定TP・SLパラメータは省いています。

Q. なぜMagicNumberを使っていないのですか?

MAの取得やクロス判定、ベーステンプレートからの変更箇所を理解しやすくするためです。複数EAを同じ口座で動かす場合はMagicNumberによる注文識別が必要になるため、本サンプルをそのまま使う場合はEA単独での検証を推奨しています。

Q. MAクロスだけで実用的なEAになりますか?

MAクロスはEAの基本ロジックとして利用できますが、相場状況によってはレンジでダマシが増えます。必要に応じてフィルターや時間帯条件を追加し、バックテストで確認することが重要です。

Q. コードを書かずにMA EAを作ることはできますか?

当サイトの無料MT4 EAビルダーを利用する方法があります。MQL4を直接編集するのが難しい場合は、画面上で移動平均線の条件を設定しながらEAを作成できます。

まとめ|iMA()を使って移動平均線EAを作れる

今回のMA EAでは、MT4 EAベーステンプレートを土台に、iMA()を使った移動平均線クロスの売買ロジックを追加しました。

  • iMA()で短期・中期MAを取得
  • 1本前・2本前の確定足でクロスを判定
  • 短期MAの傾きもエントリー条件に利用
  • 中期MAを基準にSLを設定
  • TPはエントリー価格からSLまでの値幅と1:1
  • 個別EAでは使用する共通関数だけを掲載
  • ベーステンプレートからの変更箇所をコード内の背景色で確認可能

ベーステンプレートと今回のMA版を見比べることで、EAの共通部分を残しながら、売買ロジック固有の部分だけを追加・変更する流れを確認できます。

他の売買ロジックも試したい場合は、EAサンプルコード一覧からRSI・MACD・ボリンジャーバンドなどの実装例も確認できます。

コメント

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

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

    • りょうさんのアイコン りょう より:

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

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