MQL5 ArrayResizeの使い方完全ガイド|配列サイズ変更・reserve_size・エラー対策まで解説

目次

1. MQL5のArrayResizeとは何か

MQL5の ArrayResize は、配列(Array)のサイズを変更するための関数です。
配列とは「同じ型のデータをまとめて保存するデータ構造」であり、EA(自動売買プログラム)やインジケータでは頻繁に使用されます。

MQL5では、配列には次の2種類があります。

  • 静的配列(サイズ固定)
  • 動的配列(サイズ変更可能)

このうち ArrayResizeが使えるのは動的配列のみです。
動的配列はプログラム実行中にサイズを増減できるため、次のような処理で利用されます。

  • 価格データの保存
  • インジケータ計算結果の格納
  • トレード履歴や統計データの蓄積
  • EAの内部ログ管理

例えば、データを追加しながら処理する場合、配列サイズを途中で増やす必要があります。そのときに ArrayResizeで配列の長さを変更します。

1.1 ArrayResizeの基本役割

ArrayResizeの役割は非常にシンプルで、配列の要素数を変更することです。

例えば次のような動的配列があるとします。

double price[];

この状態では、まだ配列のサイズは 0(要素なし) です。

ここでArrayResizeを使うと、配列のサイズを変更できます。

double price[];

ArrayResize(price,10);

この処理を実行すると、配列の状態は次のようになります。

price[0]
price[1]
price[2]
...
price[9]

つまり 10個の要素を持つ配列が作成されます。

初心者がよく誤解するポイントとして、次の点があります。

よくある誤解

  • ArrayResizeは「値を追加する関数」ではない
  • あくまで「配列のサイズを変更する関数」

つまり次の処理は エラーになります

double price[];

price[0]=Close[0];

理由は単純で、配列サイズが0のままだからです。

この場合は必ず先にArrayResizeを行います。

double price[];

ArrayResize(price,1);
price[0]=Close[0];

この順番を間違えると、MQL5では非常に多いエラーである

array out of range

が発生します。

1.2 ArrayResizeが必要になる場面

ArrayResizeは、EA開発やインジケータ開発ではかなり頻繁に使われます。
特に次のようなケースで必要になります。

① データを蓄積する処理

例:価格履歴を保存

double history[];

ArrayResize(history,ArraySize(history)+1);
history[ArraySize(history)-1]=Close[0];

このコードでは

  1. 配列サイズを1つ増やす
  2. 新しい要素に価格を保存

という流れになります。


② インジケータデータの保存

インジケータの計算結果を配列に保存する場合にも利用されます。

  • RSI履歴
  • ATR履歴
  • 移動平均値

③ EAの統計データ管理

EAでは以下のデータを記録する場合があります。

  • トレード結果
  • 利益履歴
  • ドローダウン
  • ロットサイズ

こうしたデータを配列に保存する際にもArrayResizeが必要です。


つまずきやすいポイント

初心者がよく失敗するポイントを整理します。

① 配列サイズを変更せずにアクセスする

array out of range

の原因の大半がこれです。


② 静的配列にArrayResizeを使う

次のコードはエラーになります。

double price[10];
ArrayResize(price,20);

理由
静的配列は サイズ固定 のため。


③ ループ内で大量にArrayResizeする

次のようなコードは パフォーマンスが悪化する可能性があります。

for(int i=0;i<10000;i++)
{
   ArrayResize(arr,i+1);
}

この問題は reserve_size(メモリ予約) を使うことで改善できます。


ArrayResizeは単純な関数ですが、EAの安定性と速度に影響する重要な関数です。
特に大規模EAでは、メモリ管理を意識した使い方が重要になります。

Ad

2. ArrayResizeの構文と引数

ArrayResizeを正しく使うためには、関数の構文(シンタックス)と各引数の意味を理解することが重要です。
特に初心者は 第2引数(新しいサイズ)第3引数(reserve_size) の役割を混同しやすいため注意が必要です。

ArrayResizeの基本構文は次の通りです。

int ArrayResize(
   void& array[],
   int new_size,
   int reserve_size=0
);

この関数は 配列サイズの変更を行い、変更後の配列サイズを返す関数です。

2.1 第1引数:array(対象配列)

第1引数には サイズ変更を行う配列を指定します。

例:

double data[];
ArrayResize(data,10);

このコードでは data配列のサイズを10に変更します。

ポイント

  • 動的配列のみ指定可能
  • 配列名だけを書く
  • 添字(index)は付けない

誤った例

ArrayResize(data[0],10);

これは 配列要素を渡しているためエラーになります。


2.2 第2引数:new_size(新しい配列サイズ)

第2引数は 変更後の配列サイズです。

例えば次のコードでは、配列サイズが5になります。

double data[];

ArrayResize(data,5);

この場合、配列は次のようになります。

data[0]
data[1]
data[2]
data[3]
data[4]

つまり 要素数=5 です。

ここで重要な点があります。

配列インデックスは0から始まる

つまり

サイズ5 → 最大indexは4

初心者はここで次のミスをよくします。

ArrayResize(data,5);
data[5]=100;

これは array out of range エラーになります。

正しい書き方

data[4]=100;

2.3 第3引数:reserve_size(メモリ予約)

第3引数 reserve_size は少し上級者向けの機能です。

これは 配列のメモリをあらかじめ確保する機能です。

ArrayResize(data,10,100);

この意味は次の通りです。

項目意味
現在サイズ10
確保メモリ100

つまり

100要素分のメモリを確保しつつ、現在サイズは10

という状態になります。

なぜこれが必要かというと、ArrayResizeは内部でメモリ再確保が発生するためです。

配列を頻繁に拡張すると、次の処理が繰り返されます。

  1. 新しいメモリ確保
  2. 既存データコピー
  3. 古いメモリ解放

この処理は CPU負荷が高いため、EAのパフォーマンスに影響します。

そのため、次のようなケースではreserve_sizeを使うと効率が良くなります。

例:データを大量に追加する場合

double history[];

ArrayResize(history,0,10000);

これにより 1万要素分のメモリを事前確保できます。


2.4 戻り値(Return Value)

ArrayResizeは 変更後の配列サイズを返します

int size;

size=ArrayResize(data,20);

この場合

size = 20

になります。

ただし エラーの場合は -1 が返ります。

if(ArrayResize(data,20)==-1)
{
   Print("ArrayResize error");
}

実務では 戻り値チェックを入れると安全性が上がります


よくある失敗

ArrayResizeの典型的なミスをまとめます。

① 静的配列で使う

double data[10];
ArrayResize(data,20);

静的配列はサイズ固定のため コンパイルエラーになります。


② indexをサイズと勘違い

サイズ10
→ indexは0〜9

③ ループ内で毎回ArrayResize

次のコードはパフォーマンスが悪くなります。

for(int i=0;i<10000;i++)
{
   ArrayResize(data,i+1);
}

改善方法

reserve_sizeを使う

ArrayResizeの構文は単純ですが、メモリ管理とパフォーマンスに影響する重要な関数です。
正しく理解することで、EAの処理速度や安定性を大きく改善できます。

3. ArrayResizeの基本的な使い方(サンプルコード)

ArrayResizeは構文自体はシンプルですが、実際のEAやインジケータでは使い方のパターンがいくつか存在します。
ここでは、初心者が最初に理解しておくべき 基本パターン をサンプルコードとともに解説します。

実務では主に次の3つの使い方が多くなります。

  • 配列を初期化する
  • 配列を拡張する
  • 配列を縮小する

これらを順番に見ていきます。


3.1 配列を初期化する

動的配列は、宣言しただけではサイズが0の状態です。

double data[];

この状態では、まだ要素は存在しません。

data size = 0

そのため、配列を使用する前に ArrayResizeでサイズを確保する必要があります。

例:

double data[];

ArrayResize(data,10);

この処理により、配列は次の状態になります。

data[0]
data[1]
data[2]
data[3]
data[4]
data[5]
data[6]
data[7]
data[8]
data[9]

ここで初めて値を書き込めます。

data[0] = 1.0;
data[1] = 2.0;

よくある失敗

次のコードは初心者がよく書く間違いです。

double data[];

data[0] = 10;

この場合

array out of range

エラーになります。

理由

配列サイズが0だから

必ず ArrayResize → 配列アクセス の順番で書きます。


3.2 配列サイズを拡張する

EAでは、処理の途中で配列を拡張するケースがよくあります。

例えば、価格履歴を配列に保存する処理です。

例:

double history[];

int size = ArraySize(history);

ArrayResize(history, size + 1);

history[size] = Close[0];

処理の流れ

  1. 現在の配列サイズを取得
  2. 配列サイズを1つ増やす
  3. 新しい要素にデータを保存

図で表すと次のようになります。

Before
history[0]
history[1]
history[2]

After resize
history[0]
history[1]
history[2]
history[3]

新しい要素は

index = size

になります。


注意点

配列サイズを増やした場合、新しい要素の値は 初期化されない場合があります
環境や型によって動作が異なることもあるため、必要なら明示的に代入する方が安全です。

history[size] = Close[0];

3.3 配列サイズを縮小する

ArrayResizeは 配列サイズを小さくすることも可能です。

ArrayResize(data,5);

もし元のサイズが10だった場合

Before
data[0]
data[1]
data[2]
data[3]
data[4]
data[5]
data[6]
data[7]
data[8]
data[9]

After
data[0]
data[1]
data[2]
data[3]
data[4]

index 5以降のデータは削除されます。

これは完全に失われるため注意が必要です。


3.4 ArraySizeと組み合わせる

実務では ArraySize関数とセットで使うことが非常に多いです。

ArraySizeは 現在の配列サイズを取得する関数です。

double data[];

ArrayResize(data,10);

int size = ArraySize(data);
Print(size);

出力

10

配列を動的に扱う場合は、ほぼ必ず

ArrayResize
ArraySize

をセットで使用します。


よくある失敗

初心者がよくやるミスを整理します。

① resize後のindexを間違える

size = 5
→ 新しい要素は index 5

② resize前にArraySizeを取得しない

次のコードはバグの原因になります。

ArrayResize(data, ArraySize(data)+1);
data[ArraySize(data)] = value;

理由

resize後にArraySizeが変わる

安全な書き方

int size = ArraySize(data);

ArrayResize(data,size+1);
data[size]=value;

③ 大量データでresizeを繰り返す

これは EAの速度低下の原因になります。

改善方法

reserve_sizeを使う

ArrayResizeは、EAの内部データ構造を扱う際に非常に重要な関数です。
特にトレード履歴、価格履歴、統計データなどを扱う場合は必ず理解しておく必要があります。

Ad

4. reserve_sizeの意味とパフォーマンス最適化

ArrayResizeには 第3引数 reserve_size というオプションがあります。
これは 配列のメモリを事前に確保する機能であり、特に 大量データを扱うEAやインジケータでは重要なパフォーマンス最適化手法になります。

初心者はこの引数を使わなくても動作しますが、処理速度やメモリ効率を考えると理解しておく価値があります。


4.1 reserve_sizeとは何か

ArrayResizeの構文をもう一度確認します。

int ArrayResize(
   void& array[],
   int new_size,
   int reserve_size=0
);

ここで

reserve_size = 追加で確保するメモリ容量

を意味します。

例えば次のコードを見てみます。

double data[];

ArrayResize(data,10,100);

この処理は次の意味になります。

項目
現在の配列サイズ10
内部メモリ確保100

つまり

100個分のメモリを確保しておく
ただし現在使える要素は10

という状態になります。


4.2 なぜreserve_sizeが必要なのか

ArrayResizeは内部的に メモリ再確保(reallocation) を行います。

配列サイズを変更するたびに、次の処理が発生します。

1 新しいメモリ確保
2 既存データコピー
3 古いメモリ解放

この処理は CPU負荷が比較的大きい処理です。

もし次のようなコードを書くとします。

double data[];

for(int i=0;i<10000;i++)
{
   ArrayResize(data,i+1);
}

この場合、10000回メモリ再確保が発生する可能性があります。

EAでは以下の影響が出ることがあります。

  • 処理速度低下
  • CPU使用率上昇
  • ストラテジーテスターの速度低下

そのため あらかじめメモリを確保する方法が推奨されます。


4.3 reserve_sizeを使った最適化

同じ処理を reserve_sizeを使って最適化すると次のようになります。

double data[];

ArrayResize(data,0,10000);

for(int i=0;i<10000;i++)
{
   int size = ArraySize(data);
   ArrayResize(data,size+1);
   data[size]=i;
}

この場合

メモリ確保 = 1回

になる可能性が高くなります。

つまり

ArrayResizeのコストが大幅に減る

というメリットがあります。


4.4 実務でよくある使い方

実務では次のようなケースでreserve_sizeを使います。

ケース1:トレード履歴の保存

EAがトレード履歴を保存する場合

double profitHistory[];

ArrayResize(profitHistory,0,1000);

これにより

最大1000トレード分

の履歴を効率的に管理できます。


ケース2:インジケータ計算

インジケータの計算では、バー数に応じて配列を使用します。

double buffer[];

ArrayResize(buffer,0,2000);

これにより

2000バー分の計算用メモリ確保

ができます。


4.5 reserve_sizeを使うべきか?

初心者がよく疑問に思うのが

常にreserve_sizeを使うべき?

という点です。

結論は次の通りです。

ケース必要性
小規模EA不要でも問題なし
バックテスト大量データ有効
統計データ管理推奨
高頻度処理EA推奨

つまり

パフォーマンス重視なら使う

という位置付けです。


よくある失敗

reserve_sizeに関する典型的なミスをまとめます。

① reserve_sizeをサイズと勘違い

ArrayResize(data,10,100);

これは

サイズ = 10

です。

100ではありません。


② reserve_sizeを毎回変更する

次のコードは意味がありません。

ArrayResize(data,i+1,10000);

reserve_sizeは

最初の1回で十分

です。


③ メモリを過剰確保する

例えば

ArrayResize(data,0,100000000);

これは環境によっては メモリ不足になる可能性があります。


reserve_sizeは EAの高速化に役立つ重要なオプションですが、基本的には 大量データを扱う場合に意識すれば十分です。

5. ArrayResize関連エラー(array out of range)の原因と対処法

MQL5で配列を扱う際、最も多く発生するエラーの一つが

array out of range

です。

これは 配列の範囲外の要素にアクセスしたときに発生するエラーです。
ArrayResizeを正しく理解していない場合、このエラーが頻繁に発生します。

ここでは 典型的な原因と具体的な対処方法を解説します。


5.1 配列サイズを確保せずにアクセスする

最も多い原因が 配列サイズを確保していない状態でアクセスするケースです。

誤ったコード

double data[];

data[0] = Close[0];

このコードでは配列サイズが 0のままです。

data size = 0

そのため

data[0]

にアクセスすると array out of range エラーになります。


正しい書き方

必ず ArrayResizeでサイズを確保します。

double data[];

ArrayResize(data,1);

data[0] = Close[0];

処理の順序

1 配列サイズ確保
2 配列へアクセス

5.2 indexの範囲を間違える

配列のindexは 0から始まるため、初心者はここでミスをします。

ArrayResize(data,5);

この場合

data[0]
data[1]
data[2]
data[3]
data[4]

までが有効です。

しかし次のコードはエラーになります。

data[5] = 100;

理由

最大index = size - 1

だからです。


対処方法

安全な書き方は ArraySizeを使う方法です。

int size = ArraySize(data);

data[size-1] = 100;

これにより 範囲外アクセスを防止できます。


5.3 resize後のindexミス

配列拡張処理でよく起きるミスがあります。

誤ったコード

ArrayResize(data, ArraySize(data)+1);

data[ArraySize(data)] = value;

このコードは 範囲外アクセスになる可能性があります。

理由

ArrayResize後
ArraySizeが変わる

ためです。


正しい書き方

先にサイズを保存します。

int size = ArraySize(data);

ArrayResize(data,size+1);

data[size] = value;

この書き方は EA開発で非常によく使われる安全パターンです。


5.4 ループ処理でのエラー

ループ処理でも array out of range が起きやすいです。

誤った例

for(int i=0;i<=ArraySize(data);i++)
{
   Print(data[i]);
}

この場合

最後のループで
data[size]

にアクセスしてしまいます。


正しい書き方

for(int i=0;i<ArraySize(data);i++)
{
   Print(data[i]);
}

重要ポイント

<= ではなく <

を使うことです。


5.5 ArrayResizeとSeries配列の混同

インジケータや価格データでは Series配列が使われます。

Series配列は

index 0 = 最新バー

という特殊な構造です。

Close[0] 最新価格
Close[1] 1本前

しかし ArrayResizeはSeries配列には使用できません。

例えば次の配列

Close[]
Time[]
High[]
Low[]

ターミナル管理配列なので、resize不可です。

誤った例

ArrayResize(Close,100);

これは コンパイルエラーになります。


よくある失敗まとめ

ArrayResize関連の典型ミスを整理します。

失敗原因
array out of range配列サイズ未確保
indexエラーsizeとindex混同
resize後のミスArraySizeの再計算
ループバグ<= 使用
Series配列resize不可能

安全な配列操作パターン

実務では次の書き方が安全です。

int size = ArraySize(data);

ArrayResize(data,size+1);

data[size] = value;

この方法は

EA
インジケータ
スクリプト

すべてのMQL5プログラムで使われる 基本パターンです。


ArrayResizeのエラーの多くは 配列サイズ管理のミスです。
ArraySizeと組み合わせて使うことで、ほとんどの問題を防ぐことができます。

Ad

6. EA開発でよく使うArrayResizeの実践パターン

ArrayResizeは単純な関数ですが、EA(自動売買プログラム)の内部処理では非常に重要な役割を持ちます。
特に次のような場面で頻繁に使用されます。

  • トレード履歴の保存
  • 価格履歴の管理
  • インジケータ計算用データの保存
  • 統計データの管理

ここでは 実務でよく使われる代表的なパターンを紹介します。


6.1 トレード結果履歴の保存

EAでは、トレード結果を配列に保存するケースがよくあります。
例えば 利益履歴を保存する配列を作る場合です。

double profitHistory[];

トレードが発生するたびに履歴を追加するコードは次のようになります。

void AddProfit(double profit)
{
   int size = ArraySize(profitHistory);

   ArrayResize(profitHistory,size+1);

   profitHistory[size] = profit;
}

処理の流れ

  1. 現在の配列サイズ取得
  2. 配列を1つ拡張
  3. 新しい要素にデータ格納

この方法を使うことで

profitHistory[0]
profitHistory[1]
profitHistory[2]
...

という形で履歴を蓄積できます。


6.2 価格履歴の保存

EAでは、価格履歴を独自に管理することもあります。
例えば 一定期間の終値を保存する場合です。

double priceHistory[];

Tickごとに履歴を追加するコード

void AddPrice()
{
   int size = ArraySize(priceHistory);

   ArrayResize(priceHistory,size+1);

   priceHistory[size] = Close[0];
}

これにより

過去価格データの履歴

を保存できます。


注意点

Tickごとに追加すると 配列が無制限に増える可能性があります。

そのため、実務では 履歴サイズを制限する処理を入れることが多いです。

#define MAX_HISTORY 1000

void AddPrice()
{
   int size = ArraySize(priceHistory);

   if(size &gt;= MAX_HISTORY)
      return;

   ArrayResize(priceHistory,size+1);

   priceHistory[size] = Close[0];
}

これにより メモリ使用量の増加を防ぐことができます。


6.3 統計データ管理

EAでは、次のような統計データを管理することがあります。

  • 利益履歴
  • ドローダウン
  • ロットサイズ
  • トレード回数

これらを配列で管理することで、EA内部で分析処理を行うことが可能になります。

例:ロット履歴

double lotHistory[];

void AddLot(double lot)
{
   int size = ArraySize(lotHistory);

   ArrayResize(lotHistory,size+1);

   lotHistory[size] = lot;
}

このような履歴は次の分析に利用できます。

  • 平均ロット計算
  • 最大ロット
  • ロット変動

6.4 配列バッファとして使う

インジケータやEAでは 計算用バッファ配列として使うこともあります。

double maBuffer[];

初期化

ArrayResize(maBuffer,1000);

この配列に 移動平均などの計算結果を保存します。

maBuffer[i] = iMA(NULL,0,20,0,MODE_SMA,PRICE_CLOSE,i);

このように

計算結果
↓
配列に保存
↓
後で分析

という使い方ができます。


6.5 reserve_sizeを併用した履歴管理

履歴データを扱うEAでは、reserve_sizeを併用することで高速化できます。

double profitHistory[];

ArrayResize(profitHistory,0,1000);

履歴追加

void AddProfit(double profit)
{
   int size = ArraySize(profitHistory);

   ArrayResize(profitHistory,size+1);

   profitHistory[size] = profit;
}

この方法は

履歴EA
統計EA
分析EA

でよく使われる構造です。


よくある失敗

実務でよくあるミスを整理します。

① 無制限履歴

ArrayResizeを無制限に使う

→ メモリ増加


② resize頻度が高すぎる

Tickごとにresize

→ CPU負荷増加


③ ArraySizeを毎回呼びすぎる

処理速度を重視するEAでは

sizeを変数で管理

することもあります。


実務での基本パターン

EA開発では次の書き方が最もよく使われます。

int size = ArraySize(data);

ArrayResize(data,size+1);

data[size] = value;

このコードは

MQL5配列操作の基本テンプレート

と言ってよいレベルで広く使われています。


ArrayResizeは、EA内部データ構造を管理するための基本関数です。
トレード履歴、価格履歴、統計データなど、多くの処理で使用されます。

7. MQL5 ArrayResizeのFAQ(よくある質問)

ここでは、MQL5のArrayResizeに関して初心者がよく疑問に思うポイントをFAQ形式で整理します。
実際のEA開発やインジケータ作成でも頻繁に出てくる疑問なので、基本事項として理解しておくと役立ちます。


7.1 ArrayResizeはどんな配列でも使えますか?

いいえ。
ArrayResizeが使えるのは動的配列のみです。

動的配列の例

double data[];

この配列は実行中にサイズ変更できます。

一方、次のような 静的配列(サイズ固定)には使用できません。

double data[10];

静的配列にArrayResizeを使うと コンパイルエラーになります。


7.2 ArrayResizeを実行すると配列の値は消えますか?

通常は 既存の要素は保持されます。

double data[];

ArrayResize(data,3);

data[0]=1;
data[1]=2;
data[2]=3;

ArrayResize(data,5);

この場合

data[0] = 1
data[1] = 2
data[2] = 3

は保持されます。

ただし

data[3]
data[4]

未定義の値になる場合があります。

安全のため、必要なら 明示的に初期化することが推奨されます。


7.3 ArrayResizeを0にするとどうなりますか?

次のコード

ArrayResize(data,0);

配列を空にする処理になります。

つまり

配列サイズ = 0

になります。

これは 配列をリセットする用途で使われることがあります。


7.4 reserve_sizeは必ず使う必要がありますか?

必須ではありません。

次のケースでは 使わなくても問題ありません。

  • 小規模EA
  • データ量が少ない処理
  • 一度だけresizeする場合

しかし次のケースでは reserve_sizeを使うと効率が良くなります。

  • 大量データ処理
  • 履歴データ管理
  • 頻繁なresize処理

7.5 ArrayResizeとArraySizeの違いは何ですか?

役割は完全に異なります。

関数役割
ArrayResize配列サイズ変更
ArraySize現在の配列サイズ取得

double data[];

ArrayResize(data,10);

int size = ArraySize(data);

この場合

size = 10

になります。

実務では

ArraySize
↓
ArrayResize

の組み合わせで使用することが多いです。


7.6 array out of rangeエラーの原因は何ですか?

主な原因は次の3つです。

① 配列サイズ未確保

double data[];

data[0] = 10;

② indexの範囲ミス

size = 5
最大index = 4

③ resize処理の順序ミス

ArrayResize(data,ArraySize(data)+1);

data[ArraySize(data)] = value;

安全な書き方

int size = ArraySize(data);

ArrayResize(data,size+1);

data[size] = value;

7.7 ArrayResizeはEAの速度に影響しますか?

場合によっては影響します。

ArrayResizeは内部で

メモリ再確保
データコピー
メモリ解放

を行うため、大量に呼び出すと処理速度が低下する可能性があります。

対策

  • reserve_sizeを使う
  • resize回数を減らす
  • 配列サイズを事前確保する

ArrayResizeは、MQL5で配列を扱う際の基本関数です。
配列サイズ管理を正しく理解することで、EAやインジケータの安定性とパフォーマンスを大きく改善できます。