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

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

ArrayBsearchは、ソート(整列)済みの配列内から、指定した値がどのインデックスに存在するかを高速に検索する関数です。アルゴリズムとしては「二分探索(バイナリサーチ)」を採用しており、配列の要素数が数万件、数十万件と膨大になっても、一瞬で目的のデータを見つけ出すことができます。

実務レベルの開発では、主に以下のような場面で重用されます。

  • タイムスタンプの同期: 特定の時刻(datetime)が、時系列配列のどのバーに該当するかを特定する。
  • 価格帯の特定: 独自の計算で算出したラインや価格リストの中で、現在の価格がどの位置にあるかを判定する。
  • 計算の高速化: ループ文(for文)で先頭から一つずつ探す「線形探索」は非常に低速です。バックテストの速度を劇的に向上させるために、検索処理をArrayBsearchに置き換えるのがクオンツの定石です。

初心者の方は「配列のどこかにあるはず」という感覚で使いがちですが、この関数は「配列が昇順にソートされていること」が絶対条件である点に注意してください。

2. 構文と戻り値

ArrayBsearchの構文は非常にシンプルです。

int  ArrayBsearch(
   const void&  array[],              // 検索対象の配列
   any_type     value                 // 検索したい値
   );

パラメーター

  1. array[]: 検索対象となる配列。数値型(int, double等)やdatetime型の配列を指定します。
  2. value: 配列の中から探したい値。配列の型と一致している必要があります。

戻り値

  • 値が見つかった場合: その要素のインデックス番号を返します。
  • 値が完全一致しなかった場合: 検索した値よりも小さい値の中で、最も近い要素のインデックスを返します。
  • 配列が空、またはエラーの場合: -1を返します。

※注意:戻り値が「見つからなかった場合に最も近い小さい要素」を返すという特性は、条件分岐を作る際に非常に便利ですが、理解していないとバグの原因になります。

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

以下のコードは、過去の価格データから特定の時刻がどのインデックスにあるかを高速に検索し、その時の終値を取得する実用的な例です。

void OnStart()
{
   // 1. 過去のバーの時刻データを取得
   datetime timeArray[];
   int copied = CopyTime(_Symbol, _Period, 0, 100, timeArray);

   if(copied <= 0) {
      Print("データの取得に失敗しました。");
      return;
   }

   // 2. 重要:ArrayBsearchは「昇順」である必要がある
   // CopyTimeで取得した配列は通常「新しい順(降順)」のため、ソートして昇順にする
   ArraySort(timeArray);

   // 3. 検索したい時刻を設定(例:最新のバーから10本前の時刻)
   datetime targetTime = timeArray[copied - 10]; 

   // 4. 二分探索を実行
   int index = ArrayBsearch(timeArray, targetTime);

   // 5. 結果の出力
   if(index != -1)
   {
      // インデックスが見つかれば、その位置の情報を取得できる
      PrintFormat("ターゲット時刻: %s は、配列のインデックス [%d] に見つかりました。", 
                  TimeToString(targetTime), index);

      // 注意:ArraySortで並び替えた後のインデックスであることに留意
   }
   else
   {
      Print("指定した時刻は見つかりませんでした。");
   }
}

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

開発者が最も陥りやすい罠は、「ArraySetAsSeries」との併用です。

MQL5の時系列配列(Close[0]が最新バーとなる形式)は、インデックスが大きくなるほど古いデータになります。しかし、ArrayBsearchは「インデックスが大きくなるほど値も大きくなる(昇順)」という構造を前提としています。

  • 昇順ソートの徹底: ArraySort()を実行してから検索するか、最初から昇順でデータを格納してください。
  • 浮動小数点の比較: double型の配列を検索する場合、厳密な一致(例:1.10000と1.100000001)が起きにくいため、戻り値が「最も近い要素のインデックス」になることを前提としたロジックを組むのが安全です。
  • 多次元配列非対応: ArrayBsearchは1次元配列にしか使えません。構造体配列などを検索したい場合は、検索キーとなる項目だけを別の1次元配列に抽出する必要があります。

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

アルゴリズムの効率化においてArrayBsearchを使いこなすことは素晴らしい第一歩ですが、システムトレードの勝敗を決めるのはコードの美しさだけではありません。どれほど高速なアルゴリズムを組んだとしても、実行環境が「自宅のPC」である限り、プロの世界では勝負になりません。FX市場はミリ秒単位で価格が変動しており、自宅のインターネット回線を経由することで発生する数十〜数百ミリ秒の「ネットワーク遅延(レイテンシ)」は、スリッページを引き起こし、期待値を根底から破壊します。

特に指標発表時やボラティリティが高い局面では、注文がサーバーに届くまでの僅かな遅れが致命的な損失に繋がります。極限まで約定スピードを高め、有利な価格で約定させるためには、FX業者の取引サーバーと同じデータセンター内、あるいは極めて物理的距離が近い場所に設置された専用のVPS(仮想専用サーバー)を利用することが不可欠です。24時間安定して稼働し、物理的な遅延を最小限に抑えるインフラを整えることこそが、クオンツエンジニアとして最初に投資すべき「勝つための絶対条件」です。

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

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

コメント

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