【MQL5】Bars関数の使い方と自動売買実装コード

1. Bars関数の概要と実務での活用法

MQL5のBars関数は、指定した通貨ペアおよび時間軸において、ヒストリーデータ(過去足)が何本存在するかを取得するための関数です。一見地味な関数ですが、自動売買(EA)やインジケーターの開発において、プログラムの安定性を左右する極めて重要な役割を担います。

実務レベルでは、主に以下の2つのシーンで多用されます。

  1. 実行環境の安全確認(エラー回避):
    計算に必要なバーの数が足りない状態でインジケーターの値を参照しようとすると、「Array out of range(配列の範囲外)」エラーが発生し、EAが停止してしまいます。Bars関数を使って「最低でも100本以上のデータがあるか」をチェックすることで、こうした致命的なバグを未然に防ぎます。
  2. 計算範囲の特定:
    特定の期間内(例:昨日の0時から今日の0時まで)に何本のローソク足があるかを算出し、ループ処理の回数を決定する際に使用します。

初心者が特につまずきやすいのは、「チャートに表示されている本数」と「プログラムが取得できる本数」は必ずしも一致しないという点です。Bars関数を正しく使いこなすことは、堅牢なシステム開発の第一歩と言えます。

2. 構文と戻り値

Bars関数には、取得したい情報の範囲に応じて2つの書き方(オーバーロード)があります。

1. 全期間のバー数を取得する場合

int  Bars(
   string           symbol_name,     // 通貨ペア名(NULLで現在の通貨)
   ENUM_TIMEFRAMES  timeframe        // 時間軸(0またはPERIOD_CURRENTで現在の時間軸)
   );

2. 特定の期間内のバー数を取得する場合

int  Bars(
   string           symbol_name,     // 通貨ペア名
   ENUM_TIMEFRAMES  timeframe,       // 時間軸
   datetime         start_time,      // 開始日時
   datetime         stop_time        // 終了日時
   );

戻り値

  • 成功した場合:指定された条件に合致するバーの数(int型)を返します。
  • 失敗した場合:データがまだ読み込まれていない時などは 0 を返します。

3. 具体的な使い方・実践サンプルコード

以下は、EAの初期化時(OnInit)や計算開始時に、十分なヒストリーデータがあるかを確認する実践的なコード例です。

//+------------------------------------------------------------------+
//| 十分なデータがあるかチェックするサンプル関数                          |
//+------------------------------------------------------------------+
bool CheckHistoryAvailable(string symbol, ENUM_TIMEFRAMES period, int requiredBars)
{
   // 指定した通貨ペア・時間軸の利用可能なバー数を取得
   int availableBars = Bars(symbol, period);

   if(availableBars < requiredBars)
   {
      PrintFormat("エラー: データ不足です。必要数: %d, 現在数: %d", requiredBars, availableBars);
      return false;
   }

   PrintFormat("データチェック完了: %d 本のバーが利用可能です。", availableBars);
   return true;
}

//+------------------------------------------------------------------+
//| EAのティック時処理                                               |
//+------------------------------------------------------------------+
void OnTick()
{
   // 例:移動平均線の計算に200本必要だと仮定
   if(!CheckHistoryAvailable(_Symbol, _Period, 200))
   {
      // データが足りない場合は処理をスキップ
      return;
   }

   // ここからメインのロジックを記述
   // ...
}

また、特定の時間範囲のバー数を数える場合は以下のように記述します。

// 今日の0時から現時点までのバー数を取得する例
datetime startTime = iTime(_Symbol, PERIOD_D1, 0); // 本日の開始時間
datetime stopTime  = TimeCurrent();                // 現在時刻

int barsToday = Bars(_Symbol, _Period, startTime, stopTime);
Print("本日の発生済みバー数: ", barsToday);

4. 使用上の注意点とよくあるエラー

開発中に遭遇しやすいトラブルとその対策をまとめました。

  1. ヒストリーデータの未ロード問題:
    MT5を起動した直後や、新しい時間軸に切り替えた直後は、サーバーからデータをダウンロードするまで Bars が期待した値を返さない(0を返す)ことがあります。Bars が 0 の場合は、計算を行わずに次のティックを待つ処理を入れるのが定石です。
  2. 引数の日時の順序:
    期間指定で Bars を使う際、start_time(開始)は stop_time(終了)よりも過去の時刻である必要があります。逆になると正しい本数が取得できません。
  3. 「最大表示バー数」の制限:
    MT5のオプション設定「チャートの最大バー数」によって、取得できる上限が制限されることがあります。バックテストで数年分のデータを回したいのに Bars の値が少ない場合は、ツール > オプション > チャート タブの設定を確認してください。

5. 【重要】自動売買における約定スピードと環境の罠

アルゴリズム取引において、Bars関数などで正確なロジックを組むことは大前提ですが、それだけでは勝てないのがFXの世界です。特に注意すべきは「実行環境によるネットワーク遅延(レイテンシ)」です。

自宅のPCから一般的なインターネット回線を通じて自動売買を行う場合、ブローカーのサーバーとの間に数十ミリ秒から数百ミリ秒の遅延が発生します。このわずかな遅れが、注文時のスリッページを引き起こし、バックテストでは利益が出ていたロジックを破綻させる原因となります。極限まで約定スピードを高め、意図した価格で注文を刺すためには、ブローカーのデータセンターに近い場所に設置された専用のVPS(仮想専用サーバー)の利用が必須です。プロのクオンツエンジニアにとって、インフラへの投資はロジック開発と同じくらい、あるいはそれ以上に優先されるべき技術的課題なのです。

💡 この記事の内容を実運用で活かすには?

この記事の内容を実運用で活かすには、正しい環境が必要です。
特にVPSを使わないと、このロジックは再現できません。

コメント

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