MT4でバー(ローソク足)を使ったEA処理の基本|初心者向けに関数付き解説

EAサンプル・ノウハウ
記事内に商品プロモーションを含む場合があります
スポンサーリンク

はじめに

EA(エキスパートアドバイザー)を自作しようとしたとき、「ローソク足(バー)をどう使えばいいの?」「陽線・陰線の数を数えるってどうやるの?」と疑問に思ったことはありませんか?

この記事では、MT4でEAを作成する際に役立つバー(ローソク足)関連の処理方法を、関数コード付きで初心者向けにわかりやすく解説します。

この記事でわかること

  • ローソク足を使ったEAの基本的な処理
  • 陽線・陰線のカウント方法
  • バーの出現タイミングに合わせた処理の書き方
  • 決済タイミングの作り方

バー関連処理の重要性とは?

ローソク足の状態を把握する意義

ローソク足は、価格の始値・終値・高値・安値を示す重要な情報です。特に自動売買では、一定本数の陽線や陰線をパターンとしてとらえ、売買の判断に使うことが多くあります。

インジケーターではなく「バー」で判断する理由

インジケーターは価格の変動を加工したもので、ややタイムラグがあります。それに対しバーの状態は生の情報であり、より早く正確に判断するために使われます。


MT4 EAで使えるバー関連関数5選

1. エントリーから何本のバーが経過したかを判定する関数

▸ 関数

int CountBarsSinceEntry(int positionType)
{
   datetime entryTime = 0;

   // 指定タイプのポジションを探す(現在のシンボル)
   for (int i = OrdersTotal() - 1; i >= 0; i--)
   {
      if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
         if (OrderSymbol() == Symbol() && OrderType() == positionType)
         {
            entryTime = OrderOpenTime();
            break;  // 最初に見つけたポジションだけ使う
         }
      }
   }

   if (entryTime == 0)
   {
      return -1;
   }

   int barCount = 1;

   for (int i = 1; i < Bars; i++)  // 確定済み足のみ
   {
      if (Time[i] <= entryTime)
         break;

      barCount++;
   }

   return barCount;
}

▸ 引数と戻り値

  • 引数OP_BUY または OP_SELL
  • 戻り値:エントリーから経過したバー数。ポジションがない場合は-1

▸ 使用例

         //新規注文(買い)から10バー経過でクローズ
         if(CountBarsSinceEntry(OP_BUY) >= 10){
            funcOrder_Close(OP_BUY,0,MAGIC_NO,clrGray);
         }
         //新規注文(売り)から30バー経過でクローズ
         if(CountBarsSinceEntry(OP_SELL) >= 30){
            funcOrder_Close(OP_SELL,0,MAGIC_NO,clrGray);
         } 

新規注文から一定期間(バー数)経過で決済をしています。

スポンサーリンク

2. 直近の陽線(上昇ローソク足)をカウントする関数

▸ 関数

// 直近countBars本のローソク足で陽線の数をカウントする関数
int CountYousen(int countBars)
{
   int bearishCount = 0;

   for (int i = 1; i <= countBars; i++)  // i=1から。i=0は未確定足のため除外
   {
      if (Close[i] > Open[i]) {
         bearishCount++;
      }
   }

   return bearishCount;
}

▸ 引数と戻り値

  • 引数:直近から何本分カウントするかを渡しましょう。
  • 戻り値:陽線の数

▸ 使用例

            if(CountYousen(5) >= 5){
               Print("陽線が5本連続したためクローズします");
               funcOrder_Close(OP_BUY,0,MAGIC_NO,clrGray);
            }

陽線が5本連続したらクローズ。

スポンサーリンク

3. 直近の陰線(下降ローソク足)をカウントする関数

先ほどの陽線とは逆の陰線バージョンです。

▸ 関数

// 直近countBars本のローソク足で陰線の数をカウントする関数
int CountInsen(int countBars)
{
   int bearishCount = 0;

   for (int i = 1; i <= countBars; i++)  // i=1から。i=0は未確定足のため除外
   {
      if (Close[i] < Open[i]) {
         bearishCount++;
      }
   }

   return bearishCount;
}

▸ 引数と戻り値

  • 引数:直近から何本分カウントするかを渡しましょう。
  • 戻り値:陰線の数

▸ 使用例

            if(CountInsen(20) >= 10){
               Print("陰線が複数確認されたので決済します");
               funcOrder_Close(OP_BUY,0,MAGIC_NO,clrGray);
            }

直近のローソク足20本中に陰線が10本確認されたらクローズ。

スポンサーリンク

4. エントリー後、バーが○本経過&損失中で決済する関数

▸ 関数の説明

// エントリー後、バーが〇本を経過&損失中で決済する関数
void CountCloseChk(int countBars)
{
   if(OrderSelect(0,SELECT_BY_POS,MODE_TRADES)==true){
      //オーダー後、バーが10本を超えた かつ 損失中の場合決済する
      if(OrderOpenTime() < iTime(NULL, 0, countBars) && OrderProfit() < 0){
         OrderKekka = OrderClose(OrderTicket(),OrderLots(),Bid,10,Violet);
      }
   }
}

▸ 引数と戻り値

  • 引数:バー何本から決済チェックするか
  • 戻り値:なし

▸ 使用例

//エントリー後、バーが10本を経過&損失中で決済する
CountCloseChk(10);

基本呼び出すだけ(損切りロジックに組み込み)でOKです。

スポンサーリンク

5. バーが新たに出来た時だけ処理を行う仕組み

▸ Time[0]とprevtimeによる制御の基本

datetime prevtime = 0;
  
void OnTick()
{
  
   //新しい足ができた時だけ処理する
   if(Time[0] != prevtime){
      //時間を更新して処理を続行する
      prevtime = Time[0];
   }else{
      //処理せずに終わる
      return;
   }
  
  
~~~~~~~~~~~~

▸ 解説

この仕組みで「1バーに1回だけ処理する」EAを作ることができ、過剰な注文やエラーを防げます。

まず、Time[0]の値をセット(退避)するためにprevtimeというグローバル変数を設けます。

Time[0]は新しい足ができた時の時間がセットされているので、簡単に15分足とかでイメージしてもらうと 2021/04/01 18:15:00.000のような感じの値がセットされています。(実際は秒数)
このTime[0]は2021/04/01 18:30:00.000になるまで変わりません。

よって、2021/04/01 18:18:40.000とかの場合は、

Time[0]=2021/04/01/ 18:15:00.000
prevtime=2021/04/01/ 18:15:00.000

で同じ値となるためreturn;が実行されるので、以降処理はしない作りになっています。よって、エントリーもしないしエントリーするかどうかの判断もなくなります。

時間が進み2021/04/01 18:30:00.000になったジャストタイミングで、

Time[0]=2021/04/01/ 18:30:00.000
prevtime=2021/04/01/ 18:15:00.000

という状況になります。この場合は値が違うので、prevtimeに2021/04/01/ 18:30:00.000をセットし、
エントリーするかどうかの判断をしたりエントリーする場合はエントリーするといった形になります。
※if文の条件からreturn;は実行されません

こうすることで、『バーが新たに出来た時だけ処理を行う』という事ができるわけです。
※私が作っているサンプルソースは基本殆どがこの形です

コーディングの注意点とアドバイス

  • 未確定足(i=0)は基本使わない:動いている最中の足なので、誤判定を招く可能性があります。
  • グローバル変数は慎重に設計prevtimeのように時間を保持する変数は、意図しない挙動を避けるために適切に初期化しましょう。
  • 決済関数(funcOrder_Closeなど)との連携:処理ミスでクローズできない場合に備えて、ログ出力も検討しましょう。

まとめ

本記事では、MT4でローソク足(バー)を使ったEA処理の基本を、5つの関数(処理)を通じて学んでいただきました。

自動売買EAを作るうえで、”バー”は最もシンプルで強力な判断材料です。 ぜひ、あなたのオリジナルEA作成にチャレンジしてみてください!



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

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

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


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

コメント