1. ArrayResize関数の概要と実務での活用法
MQL5におけるArrayResizeは、動的配列(宣言時にサイズが決まっていない配列)のサイズを、プログラムの実行中に変更するための非常に重要な関数です。
FXの自動売買(EA)開発では、事前に扱うデータの数が確定していないケースが多々あります。例えば、「直近1時間のボラティリティが一定以上の足だけを抽出して保存したい」場合や、「特定の条件を満たしたティックデータのみを記録したい」場合などです。
実務で初心者が最もつまずきやすいのが、「配列の宣言だけして、サイズを確保せずに値を代入しようとする」ことです。MQL5では、動的配列はそのままでは箱が一つもありません。ArrayResizeでメモリを確保しなければ、実行時に「Array out of range(配列の範囲外)」という致命的なエラーが発生し、EAが停止してしまいます。
プロのクオンツエンジニアは、単にサイズを増やすだけでなく、後述する「予備サイズ(reserve_size)」を適切に設定することで、メモリ再割り当てによる計算負荷を抑え、プログラムの高速化を図ります。
2. 構文と戻り値
ArrayResize関数の構文は以下の通りです。
int ArrayResize(
void& array[], // サイズを変更する配列(参照渡し)
int new_size, // 新しいサイズ
int reserve_size = 0 // 予備のメモリ確保サイズ(オプション)
);
パラメーター
- array[]: 対象となる配列を指定します。必ず「動的配列」である必要があります。
- new_size: 新しく設定したい配列の要素数です。
- reserve_size: 非常に重要な隠れた設定です。次にサイズを増やすことを見越して、あらかじめ多めにメモリを確保しておく量です。頻繁に
ArrayResizeを繰り返す場合、この値を設定することでパフォーマンスが劇的に向上します。
戻り値
- 成功した場合:変更後の配列の要素数を返します。
- 失敗した場合:-1 を返します。メモリ不足などが原因です。
3. 具体的な使い方・実践サンプルコード
以下は、特定の条件(RSIが70以上)を満たした時の価格を動的配列に記録していく、実戦的なサンプルコードです。
//+------------------------------------------------------------------+
//| ArrayResizeSample.mq5|
//+------------------------------------------------------------------+
#property strict
// 記録用の動的配列
double highPriceHistory[];
void OnTick()
{
// 現在のRSI値を取得(計算部分は簡略化)
double rsi = CalculateRSI();
if(rsi >= 70.0)
{
// 現在の配列サイズを取得
int currentSize = ArraySize(highPriceHistory);
// 配列を1つ増やす。
// 第3引数に10を指定することで、10回に1回しか実際のメモリ確保を行わない(高速化)
int newSize = ArrayResize(highPriceHistory, currentSize + 1, 10);
if(newSize != -1)
{
// 新しく確保された末尾の要素に現在の価格を代入
highPriceHistory[currentSize] = SymbolInfoDouble(_Symbol, SYMBOL_BID);
Print("価格を記録しました。現在の記録数: ", newSize);
}
else
{
Print("エラー: ArrayResizeに失敗しました。エラーコード: ", GetLastError());
}
}
}
// ダミーのRSI計算関数
double CalculateRSI() { return 75.0; }
このコードでは、reserve_sizeに「10」を指定しています。これにより、10回分のデータが入る領域を一気に確保するため、ティック毎のメモリ再構築を防ぎ、動作を軽くしています。
4. 使用上の注意点とよくあるエラー
-
静的配列には使用不可
double my_array[10];のように、宣言時にサイズを指定している配列(静的配列)に対してArrayResizeを使うとコンパイルエラーになります。必ずdouble my_array[];と宣言してください。 -
多次元配列の制約
MQL5のArrayResizeでサイズ変更ができるのは、最初の次元のみです。2次元配列array[X][Y]の場合、Xのサイズは変えられますが、Yのサイズを動的に変えることはできません。 -
パフォーマンスの罠
reserve_sizeを指定せずに、ループの中で毎回1ずつサイズを増やすと、その都度メモリのコピーが発生します。データの件数が数千、数万となる場合は、EAの動作が極端に重くなり、約定判断の遅れ(レイテンシ)を招く原因となります。 -
ArraySetAsSeriesとの併用
ArraySetAsSeries(array, true)を使って時系列(インデックス0が最新)にしている配列にArrayResizeを行うと、新しい要素は末尾(過去方向)に追加されます。混乱しないよう、リサイズ後に再度インデックス順序を確認することが重要です。
5. 【重要】自動売買における約定スピードと環境の罠
アルゴリズムの効率化と同様に、あるいはそれ以上に重要なのが「実行環境」です。どれほどArrayResizeの予備サイズを最適化してプログラムを高速化したとしても、ご自宅のPCから一般的なインターネット回線でトレードを行っている限り、物理的な「ネットワーク遅延(レイテンシ)」という壁にぶち当たります。自宅PCからの注文は、プロバイダーを経由して証券会社のサーバーに届くまでに数十〜数百ミリ秒の時間を要し、その間に有利な価格は消え去り、スリッページによる損失を招きます。
自動売買の世界で利益を安定させるには、証券会社のデータセンターに物理的に近い場所に位置する「専用のVPS(仮想専用サーバー)」の利用が不可欠です。24時間365日安定して稼働し、ミリ秒単位のスピード競争を勝ち抜くためのインフラを整えることは、勝つための最低条件と言えます。ネットワーク遅延による致命的な損失を避けるためにも、プロレベルの取引環境を構築することをお勧めします。
💡 この記事の内容を実運用で活かすには?
この記事の内容を実運用で活かすには、正しい環境が必要です。
特にVPSを使わないと、このロジックは再現できません。

コメント