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

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

MQL5で動的なデータ管理を行う際、特定の要素を削除して配列を詰め直したい場面が多々あります。例えば、「特定の条件を満たさなくなった注文チケットIDのリスト」や「計算から除外したい過去の価格データ」の整理などです。

ArrayRemove関数は、指定したインデックスから任意の数だけ要素を削除し、残りの要素を自動的に前(左方向)へ詰めてくれる非常に便利な関数です。

実務レベルの開発で初心者がつまずきやすいのが、「配列の要素を削除した後のインデックス管理」です。手動でループを回して要素を詰めようとすると、インデックスの計算ミスでバグを誘発しがちですが、ArrayRemoveを使うことで、ロジックをシンプルかつ安全に保つことができます。特に、複数の条件で動的に変化するリスト(独自のポジション管理や、特定のインジケータ値のフィルタリング)を扱う際に真価を発揮します。

2. 構文と戻り値

ArrayRemove関数の基本的な構文は以下の通りです。

bool  ArrayRemove(
   void&         array[],              // ターゲットとなる配列(動的配列である必要があります)
   int           start,                // 削除を開始するインデックス
   int           count=1               // 削除する要素の数(デフォルトは1)
   );

パラメーター

  • array[]: 要素を削除したい配列。後述しますが、動的配列(ArrayResizeが可能な配列)である必要があります。
  • start: 削除を開始する位置(0から始まるインデックス)。
  • count: 削除する個数。指定しない場合は1つだけ削除されます。

戻り値

  • 削除が成功した場合は true を、失敗した場合は false を返します。失敗の主な原因は、インデックスが範囲外であるか、配列が固定サイズである場合です。

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

以下のサンプルコードは、EA(エキスパートアドバイザー)内で「特定の条件を満たした価格水準(ターゲットリスト)から、不要になった価格を削除する」という実戦的なシナリオを想定したものです。

//+------------------------------------------------------------------+
//| 配列から特定の値を削除するサンプル                                       |
//+------------------------------------------------------------------+
void OnStart()
{
   // 1. 動的配列の宣言と初期化
   double targetPrices[];
   ArrayResize(targetPrices, 5);

   targetPrices[0] = 145.50;
   targetPrices[1] = 146.00;
   targetPrices[2] = 146.50; // これを削除したいとする
   targetPrices[3] = 147.00;
   targetPrices[4] = 147.50;

   Print("削除前:要素数 = ", ArraySize(targetPrices));
   for(int i=0; i<ArraySize(targetPrices); i++) Print("Index ", i, " : ", targetPrices[i]);

   // 2. ArrayRemoveを使用してインデックス「2」の要素を1つ削除
   // これにより、Index 3にあった 147.00 が Index 2に詰められます
   if(ArrayRemove(targetPrices, 2, 1))
   {
      Print("削除成功");
   }
   else
   {
      Print("削除失敗 エラーコード: ", GetLastError());
   }

   // 3. 結果の確認
   // ArrayRemoveを実行すると、自動的に配列サイズも1つ減ります
   Print("削除後:要素数 = ", ArraySize(targetPrices));
   for(int i=0; i<ArraySize(targetPrices); i++) Print("Index ", i, " : ", targetPrices[i]);
}

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

ArrayRemoveを使用する際には、以下の3点に特に注意してください。

  1. 動的配列(Dynamic Array)のみ使用可能
    double array[10]; のようにサイズを固定して宣言した配列に対しては使用できません。必ず double array[]; と宣言し、ArrayResize 等でメモリを確保した配列に使用してください。固定配列で使用しようとすると実行時エラーが発生します。

  2. ループ内での使用には要注意
    forループで配列をスキャンしながら条件に合うものを ArrayRemove で消していく場合、「前から(インデックス0から)回すと、削除した瞬間に次の要素が現在のインデックスに繰り上がる」ため、次の要素をスキップしてしまうバグが発生します。

    • 対策: ループを後ろから回す(for(int i = total-1; i >= 0; i--))のが定石です。
  3. 多次元配列には非対応
    ArrayRemove は1次元配列専用です。多次元配列のデータを操作したい場合は、構造体(struct)の1次元配列にするなどの設計変更が必要です。

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

アルゴリズム取引において、ArrayRemoveのような関数を駆使してコードを効率化することは重要ですが、それ以上に収益を左右するのが「実行環境のレイテンシ(遅延)」です。

どれほど洗練されたロジックを組んだとしても、自宅のPCから一般的なインターネット回線を通じて注文を出している限り、物理的な距離とネットワーク経路の不安定さから、数ミリ秒〜数百ミリ秒の遅延が必ず発生します。FX市場は一瞬で価格が飛ぶ世界であり、この遅延(スリッページ)によって、バックテストでは勝てているロジックもリアルトレードでは致命的な損失を生むことが多々あります。

プロのクオンツや熟練の開発者が、自宅PCでの運用を避け、取引サーバーの目鼻の先にあるデータセンター内の「専用VPS」を利用するのは、もはやマナーと言えるほど必須の条件です。約定スピードを極限まで高め、ネットワークトラブルによる機会損失をゼロに近づけること。これこそが、アルゴリズムトレーダーが最初に投資すべき「勝つためのインフラ」なのです。

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

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

コメント

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