超初心者向けEAプログラミング入門⑧|移動平均線で賢くエントリーしよう

EAプログラミング入門STEP7のデグーキャラがホワイトボードの移動平均線クロスを指し、片手にMAカードを持ってエントリー方法を説明しているイラスト。
EAを自作してみよう
スポンサーリンク

「EAを作ってみたけれど、何となく動くだけで 『なぜここでエントリーしたのか分からない』のが不安…
そんな初心者の方に向けて、今回は代表的なインジケーター移動平均線を使って、
より戦略的にエントリーするEAの作り方を解説します。

📘 この記事でわかること
  • MQL4の iMA() 関数で移動平均線の値を取得する方法
  • 「移動平均線の抜け」を使ったシンプルなエントリーロジック
  • これまで学んだ if文・演算子・変数・関数と組み合わせる流れ

本記事はEAプログラミング入門シリーズ「STEP8」です。
STEP7までで新規注文・ポジション管理の基礎は整いました。
ここからは、移動平均線を使った売買ロジックを組み込んで、EAを一歩進化させていきましょう。

※この記事は「EAのロジック設計に悩む初心者向け」です。


ではまず、iMA() 関数を使って、EAの中で移動平均線の値を取得する方法から見ていきましょう。

📈 iMA() の使い方|移動平均線の値をEAで取得する

EAで移動平均線を扱うには、MQL4で用意されている iMA() 関数を使うだけです。
例えば以下のコードでは、20期間の単純移動平均(SMA) の最新値を取得できます。

EAで移動平均線の値を取得するには、MQL4の iMA() 関数を使います。 引数が複数ありますので、順番に確認していきましょう。

double dMA_atai   = iMA(NULL, 0, 20, 0, MODE_SMA, PRICE_CLOSE, 0);

まず、iMA()関数の書き方はこんな感じです。

これだけで『20(日)』の『単純移動平均線』の『現在』の値が変数「dMA_atai」に返ってきます。

この、『』で囲まれている所はもちろん引数で指定しています。詳しく引数を見ていくと、

  • 引数1・・・通貨ペアです(NULLでチャートの通貨になります)
  • 引数2・・・時間軸です(0でチャートの時間軸になります)
  • 引数3・・・期間です(20で20移動平均線、25で25移動平均線になります)
  • 引数4・・・表示移動です
  • 引数5・・・移動平均の種別です(MODE_SMAで単純移動平均線)
  • 引数6・・・適用価格です(PRICE_CLOSEでクローズ値)
  • 引数7・・・バーシフトです(0で現在の値、1で1つ前ーのバーの時の値です)

実際にMT4の画面で移動平均線のインジケータの設定を見てみると、もっとイメージしやすくて、引数3、4、5、6の箇所が変更できることがわかりますね。

MT4で移動平均線インジケータの期間・種別・適用価格を設定する画面
※よく触る値は大体黄色マーカーの箇所だと思います

引数7について画面からも指定できなくて、バーシフトというと?となるかもしれませんが、実際にMT4で見てみるとこんな感じです。

MT4チャート上で移動平均線の現在値と1本前の値を確認する例
※実際MT4の、ユーロ/ドルチャートで確認するとこんな感じ

0が現在の移動平均線の値、1が1つ前のバーの移動平均線の値が取れるという形です。バー単位で移動平均線の値が取れるようになっています。

0にすると・・・1.08424
1にすると・・・1.08429
2にすると・・・1.08428

という形で、ユーロ/ドルの値(移動平均線の値)が取れます。

スポンサーリンク

🔼 上抜けエントリー|移動平均線より上ならロング

では実際に、移動平均線よりも現在の値段が上にいる場合のみロングでエントリーするようにプログラムを組んでみましょう。

前回入門⑦の最後で使ったプログラムに変更を加えていくと、こんな感じです。

void OnTick()
  {
//---
    
   //20移動平均線の値を取得する
   double dMA_atai   = iMA(NULL, 0, 20, 0, MODE_SMA, PRICE_CLOSE, 0);
    
   if(OrdersTotal()==0 && Ask > dMA_atai) //ポジションを保有していない かつ 移動平均線より上の時だけエントリーする
   {
      // 新規エントリー注文
      int CNo = OrderSend(
               NULL,                // 通貨ペア
               OP_BUY,              // オーダータイプ[OP_BUY / OP_SELL]
               1,                   // ロット[0.01単位](FXTFは0.01で1000通貨)
               Ask,                 // オーダープライスレート
               20,                  // スリップ上限    (int)[分解能 0.1pips]
               Ask-50 * Point,      // ストップレート
               Ask+50 * Point,      // リミットレート
               "EAテスト",            // オーダーコメント
               0,                   // マジックナンバー(識別用)
               0,                   // オーダーリミット時間
               clrRed               // オーダーアイコンカラー
               );
   }
  }

移動平均線の値を取得し、if(OrdersTotal()==0)の箇所に、移動平均線の値の条件を追加しました。

移動平均線条件を追加したEAコードの変更前と変更後の比較
※変更前(左)と変更後(右)で比較してみると、変更された場所はこんな感じです

まずは、iMA()で20移動平均線の値をdMA_atai変数に入れています。そして、その値をAsk(現在の買値)と比較しています。

Ask(現在の買値) > dMA_atai(20移動平均線の値)

※ Ask は「今すぐ買うときの価格」、Bid は「今すぐ売るときの価格」です。

という形で、現在の買値が移動平均線より大きい(上にいる)場合、ロングでエントリーするという内容をつけ足しています。

if文のつけ足しているところですが、

if(OrdersTotal()==0) 

のところを、以下のようにつけ足しています。

if(OrdersTotal()==0 && Ask > dMA_atai)

&&と書くことによって「ポジションを持っていない事」アンド「現在の買値が移動平均線より大きい事」という風に条件を追加することができます。

ですので、「ポジションを持っていない」けど「現在の買値が移動平均線より小さい」場合は新規注文しませんし、「ポジションを持っている」けど「現在の買値が移動平均線より大きい」場合も新規注文しません。どちらも合致している場合しか新規注文しないという形にしているわけですね。

🔽 下向きエントリー|移動平均線の傾きでショート

では次に別のエントリータイミングとして、移動平均線が下を向いたらショートでエントリーするプログラムを組んでみましょう。

前回入門⑦の最後で使ったプログラムに変更を加えていくと、こんな感じです。

void OnTick()
  {
//---
    
   //20移動平均線(現在値)を取得する
   double dMA_atai_0   = iMA(NULL, 0, 20, 0, MODE_SMA, PRICE_CLOSE, 0);
    
   //20移動平均線(1つ前)を取得する
   double dMA_atai_1   = iMA(NULL, 0, 20, 0, MODE_SMA, PRICE_CLOSE, 1);
    
    
   if(OrdersTotal()==0 && dMA_atai_0 < dMA_atai_1) //ポジションを保有していない かつ 移動平均線が下向きの場合エントリーする
   {
      // 新規エントリー注文
      int CNo = OrderSend(
               NULL,                // 通貨ペア
               OP_SELL,             // オーダータイプ[OP_BUY / OP_SELL]
               1,                   // ロット[0.01単位](FXTFは0.01で1000通貨)
               Bid,                 // オーダープライスレート
               20,                  // スリップ上限    (int)[分解能 0.1pips]
               Bid+50 * Point,      // ストップレート
               Bid-50 * Point,      // リミットレート
               "EAテスト",            // オーダーコメント
               0,                   // マジックナンバー(識別用)
               0,                   // オーダーリミット時間
               clrRed               // オーダーアイコンカラー
               );
   }
  }

移動平均線の現在の値と1つ前の値を取得し、if(OrdersTotal()==0)の箇所に、移動平均線の値の条件を追加しました。

dMA_atai_0(移動平均線の現在値)< dMA_atai_1(移動平均線の1つ前の値)

という形にして、移動平均線が下を向く条件としています。

どうしてこれで移動平均線が下を向いた条件になるのかわからないかもしれないですが、実際のチャート上の移動平均線を想像してみてください。

現在足と過去足の移動平均線の値から傾きを判断する例
※実際MT4の、ドル/円チャートで確認するとこんな感じ
 → 「現在足(0)・1本前(1)・2本前(2)のMA値の違いを示した例です」

移動平均線が下を向くという事は、現在の移動平均線の値の方が前回の移動平均線の値より小さいという事になっていますよね。

※反対に、移動平均線が上を向くという事は、現在の移動平均線の値の方が前回の移動平均線の値より大きいという事になっています

したがって、簡単に移動平均線の向きを確認したい場合、移動平均線の前後の値を確認すれば良いという事になりますね。

移動平均線の向きによってロングとショートを切り替えるEAロジック例
※変更前(左)と変更後(右)で比較してみると、変更された場所はこんな感じです

今回はショートにしましたので、新規エントリー注文の部分も前回入門⑦から若干変わっていますので参考にしてみてください。

スポンサーリンク

おまけ|ロング&ショート両対応パターン

これで、移動平均線とロング・ショートエントリーを組み合わせたEAが作れると思います。簡単に今回の内容を組み合わせたサンプルプログラムを組んでみました。

void OnTick()
{
//---
   int CNo = 0;
    
   //20移動平均線(現在値)を取得する
   double dMA_atai_0   = iMA(NULL, 0, 20, 0, MODE_SMA, PRICE_CLOSE, 0);
    
   //20移動平均線(1つ前)を取得する
   double dMA_atai_1   = iMA(NULL, 0, 20, 0, MODE_SMA, PRICE_CLOSE, 1);
    
   //ロングエントリー(ポジションを保有していない かつ 移動平均線より上 かつ 移動平均線が上向き)
   if(OrdersTotal()==0 && Ask > dMA_atai_0 && dMA_atai_0 > dMA_atai_1) 
   {
      // 新規エントリー注文
      CNo = OrderSend(
               NULL,                // 通貨ペア
               OP_BUY,              // オーダータイプ[OP_BUY / OP_SELL]
               1,                   // ロット[0.01単位](FXTFは0.01で1000通貨)
               Ask,                 // オーダープライスレート
               20,                  // スリップ上限    (int)[分解能 0.1pips]
               Ask-50 * Point,      // ストップレート
               Ask+50 * Point,      // リミットレート
               "EAテスト",            // オーダーコメント
               0,                   // マジックナンバー(識別用)
               0,                   // オーダーリミット時間
               clrRed               // オーダーアイコンカラー
               );
   }
   //ショートエントリー(ポジションを保有していない かつ 移動平均線より下 かつ 移動平均線が下向き)
   if(OrdersTotal()==0 && Bid < dMA_atai_0 && dMA_atai_0 < dMA_atai_1) 
   {
      // 新規エントリー注文
      CNo = OrderSend(
               NULL,                // 通貨ペア
               OP_SELL,             // オーダータイプ[OP_BUY / OP_SELL]
               1,                   // ロット[0.01単位](FXTFは0.01で1000通貨)
               Bid,                 // オーダープライスレート
               20,                  // スリップ上限    (int)[分解能 0.1pips]
               Bid+50 * Point,      // ストップレート
               Bid-50 * Point,      // リミットレート
               "EAテスト",            // オーダーコメント
               0,                   // マジックナンバー(識別用)
               0,                   // オーダーリミット時間
               clrRed               // オーダーアイコンカラー
               );
   }
}

EA動作の概要

ポジションを保有していない&移動平均線より上&移動平均線が上向きの場合にロングエントリー(利益確定、損切りともに5pips)

ポジションを保有していない&移動平均線より下&移動平均線が下向きの場合にショートエントリー(利益確定、損切りともに5pips)

あとは、実際にこのEAの動作を確認してもらうとわかりますが、わりと自動売買感が出てきて面白いと思います。

関数化してみよう

※「関数って何?どう書くの?」という方は、先に STEP6:関数でコードを整理する を軽く確認しておくと、理解がスムーズです。

上記のコードを見てみると、ロングとショートで ほとんど同じ処理を2回書いているのが分かりますね。

実はこういう場面が、関数を使うベストタイミングです。

void OnTick()
{
//---
   int CNo = 0;
    
   //20移動平均線(現在値)を取得する
   double dMA_atai_0   = iMA(NULL, 0, 20, 0, MODE_SMA, PRICE_CLOSE, 0);
    
   //20移動平均線(1つ前)を取得する
   double dMA_atai_1   = iMA(NULL, 0, 20, 0, MODE_SMA, PRICE_CLOSE, 1);

   //ロングエントリー(ポジションを保有していない かつ 移動平均線より上 かつ 移動平均線が上向き)
   if(OrdersTotal()==0 && Ask > dMA_atai_0 && dMA_atai_0 > dMA_atai_1)
   {
      CNo = EntryOrder(
      OP_BUY,                  // ロング
      Ask,                     // 現在の買値
      Ask - 50 * Point,        // SL
      Ask + 50 * Point         // TP
      );
   }
   if(OrdersTotal()==0 && Bid < dMA_atai_0 && dMA_atai_0 < dMA_atai_1)
   {
      CNo = EntryOrder(
      OP_SELL,                 // ショート
      Bid,                     // 現在の売値
      Bid + 50 * Point,        // SL
      Bid - 50 * Point         // TP
      );
   }
}

// ─────────────────────────────
// 新規エントリーを行う関数
// ─────────────────────────────
int EntryOrder(
   int    orderType,   // OP_BUY / OP_SELL
   double price,       // Ask or Bid
   double stopLoss,    // SL価格
   double takeProfit   // TP価格
)
{
   return OrderSend(
      NULL,            // 通貨ペア(現在のチャート)
      orderType,       // 売買方向
      1,               // ロット数
      price,           // 注文価格
      20,              // スリッページ
      stopLoss,        // ストップロス
      takeProfit,      // テイクプロフィット
      "EAテスト",      // コメント
      0,               // マジックナンバー
      0,               // 有効期限
      clrRed            // 矢印色
   );
}

ロジックは違うけれど、「やっている処理が同じ」場合に関数化すると、 コードが一気に読みやすくなります。

✅まとめ|EAに“チャートを読む力”を持たせよう

  • iMA() 関数で移動平均線の値を簡単取得
  • ロングとショートのエントリーを条件付きで制御
  • EAがチャートの傾向を判断して動くようになった!

ここまできたら、EAプログラミング入門シリーズ(超初心者向け)は完結です。

EAは「価格を見るだけ」から インジケーターを使って判断する存在に進化しました。

▶ 🧩次のステップ

ここまでで、移動平均線を使ったシンプルなEAロジックは一通り体験できました。
ただし実運用を考えると、 「上抜けだけで良いのか?」「傾きはどう扱うべきか?」「クロス判定は必要か?」 といった疑問が出てくるはずです。

移動平均線を使ったEAロジックを
上抜け・傾き・ゴールデンクロスの観点から体系的に整理したのが、以下の記事です。

また、納得できるEAが作れたらバックテストし、実運用に向けてチューニングしていきましょう。バックテストは過去の値動きを全て再現してくれるので、ビジュアルモードで確認してみると、このエントリーじゃまずい!等がよくわかって楽しいですよ。

以下がバックテスト動画です。(※画質が悪い場合、設定で720pを選択すると良くなります)

※この動画は、MACDのインジケータを元にエントリー・決済を行っています。

※バックテストの詳細はこちら👇
【完全ガイド】EAバックテストのやり方・最適化・ヒストリカルデータ活用まとめ

※初めてEAを作る際の、トレード戦略の立て方についてはこちら👇
勝率50%から始めるトレード戦略(ロジック)の作り方|改良手順

コメント

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