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

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

MQL5におけるArrayCompareは、2つの配列を比較し、それらが「完全に一致しているか」「どちらが値として大きいか」を判定するための高速な組み込み関数です。

実務レベルの開発において、この関数は主に以下のシーンで重宝されます。
シグナルの変化検知: 前回のティックで取得したインジケーター値の配列と、現在の配列を比較し、変化があった場合のみ計算を行う。
パターンの照合: 過去の特定のチャートパターン(価格の並び)と現在の値動きが一致しているかを高速にチェックする。
データの整合性確認: 複数のデータソースから取得した価格データが同一であるかを検証する。

初心者がやりがちな「for文で配列の要素を一つずつif文で比較する」という処理は、コードが冗長になるだけでなく、実行速度も低下します。ArrayCompareはメモリレベルで最適化されているため、特に大量のデータを扱うクオンツ的なアプローチでは必須の関数と言えます。

2. 構文と戻り値

ArrayCompare関数の基本構文は以下の通りです。

int ArrayCompare(
   const void&  array1[],  // 1番目の配列
   const void&  array2[],  // 2番目の配列
   int          start1=0,  // array1の比較開始インデックス
   int          start2=0,  // array2の比較開始インデックス
   int          count=WHOLE_ARRAY // 比較する要素数
);

戻り値の意味

比較結果は整数(int)で返されます。ここが少し特殊なので注意が必要です。

  • 0: array1array2 の内容が完全に一致している。
  • 1: array1array2 より大きい。
  • -1: array1array2 より小さい。
  • -2: エラーが発生(配列の型が異なる、または多次元配列が指定された場合など)。

※「大きい・小さい」の判定は、最初の異なる要素の値に基づきます(辞書式順序)。

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

以下のサンプルは、特定の移動平均線(MA)の値が、1ティック前と比較して変化したかどうかを判定するEAの断片です。無駄な処理を省き、変化があった時だけログを出力する実戦的な構成にしています。

//+------------------------------------------------------------------+
//|                                           ArrayCompare_Sample.mq5|
//+------------------------------------------------------------------+
double prev_ma_buffer[]; // 前回の値を保存する配列
int    ma_handle;        // 移動平均線のハンドル

int OnInit()
{
   ma_handle = iMA(_Symbol, _Period, 14, 0, MODE_SMA, PRICE_CLOSE);
   ArraySetAsSeries(prev_ma_buffer, true);
   return(INIT_SUCCEEDED);
}

void OnTick()
{
   double current_ma_buffer[];
   ArraySetAsSeries(current_ma_buffer, true);

   // 最新のMA値を3本分取得
   if(CopyBuffer(ma_handle, 0, 0, 3, current_ma_buffer) < 3) return;

   // 初回実行時は比較対象がないため、現在の値を保存して終了
   if(ArraySize(prev_ma_buffer) == 0)
   {
      ArrayCopy(prev_ma_buffer, current_ma_buffer);
      return;
   }

   // --- ArrayCompareによる比較 ---
   // 0が返ってくれば、前回のチェックから値が全く変わっていないことを意味する
   int result = ArrayCompare(current_ma_buffer, prev_ma_buffer);

   if(result != 0)
   {
      Print("MAの値に変化を検知しました。ロジックの判定を開始します。");

      // ここにエントリー判断などのロジックを記述

      // 次回比較のために現在の値を保存
      ArrayCopy(prev_ma_buffer, current_ma_buffer);
   }
   else
   {
      // 値が変わっていない場合は、重い計算をスキップしてCPU負荷を軽減
      // Print("変化なし");
   }
}

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

開発時にハマりやすいポイントがいくつかあります。

  1. 浮動小数点数(double/float)の比較:
    FXで扱う価格やインジケーター値(double型)は、計算誤差により目に見えない極小の差が出ることがあります。ArrayCompareは厳密な一致を確認するため、人間から見て同じ値でも「一致しない(0以外)」と判定される場合があります。厳密な一致が必要な場合は、NormalizeDoubleで丸めてから比較するなどの工夫が必要です。

  2. 型の一致:
    比較する2つの配列は、必ず同じ型である必要があります。int配列とdouble配列を比較しようとすると、戻り値は-2となります。

  3. 多次元配列の非対応:
    ArrayCompareは1次元配列専用です。2次元以上の配列を比較しようとするとエラーになります。構造体配列(Struct Array)は比較可能ですが、構造体の中に動的配列や文字列が含まれている場合は正しく比較できないことがあるため注意してください。

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

アルゴリズム取引において、ArrayCompareを使ってミリ秒単位の演算効率を求める姿勢は非常に重要です。しかし、プログラム側でどれだけ数マイクロ秒の高速化を実現したとしても、実行環境が「自宅PC」であればその努力は水の泡となります。一般的な家庭用インターネット回線は、FX業者の取引サーバーがあるデータセンターとの間に数百ミリ秒以上のネットワーク遅延(レイテンシ)を抱えており、これが原因で「滑り(スリッページ)」が発生し、期待した価格での約定が不可能になるからです。

プロのクオンツエンジニアにとって、トレード専用のVPS(仮想専用サーバー)を利用することは「オプション」ではなく「大前提」です。取引サーバーの目と鼻の先に位置するVPS環境を構築することで、ネットワーク遅延を極限まで排除し、EAのロジック通りの約定スピードを確保することができます。たとえどれほど優れたアルゴリズムを書き上げても、インフラが脆弱であれば、ネットワークの瞬断や遅延によって致命的な損失を招くリスクを常に抱えることになります。本気でシストレでの収益を狙うなら、まずはインフラ環境をプロ仕様に整えることから始めてください。

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

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

コメント

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