MQL4 array out of range エラーの原因と直し方|配列・Bars・バッファ別確認手順
投資は自己責任であり、過去の成績は将来の利益を保証しません。本記事は投資助言ではありません。売買の判断は各自の責任において行ってください。
本記事は投資助言ではありません。公式ページで最新条件を確認してください。
はじめに
この記事では、MQL4で array out of range が出たときに、原因を順番に切り分けるための確認手順を整理します。扱うのは配列・ループ・バッファ・バー数まわりで、発注コードや売買ロジックには踏み込みません。
本記事はMQL4の配列エラーの切り分けが目的で、売買タイミング・銘柄・ロット数を推奨するものではありません。掲載するサンプルコードは学習用・検証用です。実運用や利益を保証するものではありません。コードを試す場合は、実口座で使用する前提ではなく、デモ環境または検証環境で確認してください。MT4のビルドやブローカー環境により、表示や動作が異なる場合があります。
array out of range とは
array out of range は、配列の「存在しない番号」にアクセスしたときに発生する実行時エラーです。発生すると、MT4のターミナル → 「エキスパート」タブや「操作履歴」に、ファイル名と行番号つきでエラーが記録されます。
まず確認するチェックリスト
| 症状 | よくある原因 | 確認する場所 |
|---|---|---|
| 起動直後・チャート切替時に出る | バー数・ヒストリカルデータ不足 | データ量・ガード処理 |
| ループの最後で出る | <= と < の混同/i+1 の超過 | for の条件式 |
i=0 のときに出る | i-1 で -1 を参照している | ループの開始値 |
| 特定の時間足だけ出る | その時間足のバー数が少ない | 時間足ごとのデータ量 |
| 自分で作った配列で出る | ArrayResize() 未実施・サイズ不足 | 配列の確保サイズ |
原因1:配列の最後を1つ超えて読んでいる
// NG例:i = 5 で範囲外になる
double arr[5];
for(int i = 0; i <= 5; i++)
{
Print(arr[i]);
}
// 修正例:< で回す
for(int i = 0; i < 5; i++)
{
Print(arr[i]);
}
原因2:i + 1 / i - 1 の範囲を見落としている
// NG例:i = 0 のとき arr[-1] を参照してしまう
for(int i = 0; i < ArraySize(arr); i++)
{
double diff = arr[i] - arr[i - 1];
}
// 修正例:i を 1 から始める
for(int i = 1; i < ArraySize(arr); i++)
{
double diff = arr[i] - arr[i - 1];
}
// NG例:最後の i で arr[最後+1] を参照してしまう
for(int i = 0; i < ArraySize(arr); i++)
{
double next = arr[i + 1];
}
// 修正例:終了を 1 つ手前にする
for(int i = 0; i < ArraySize(arr) - 1; i++)
{
double next = arr[i + 1];
}
原因3:ArraySize() とループ条件の使い方を間違えている
// NG例:i = size のとき範囲外
int size = ArraySize(arr);
for(int i = 0; i <= size; i++)
{
Print(arr[i]);
}
// 修正例:< で使う
for(int i = 0; i < size; i++)
{
Print(arr[i]);
}
原因4:OnCalculate と rates_total の扱いを誤解している
// NG例:i = rates_total で範囲外
for(int i = 0; i <= rates_total; i++)
{
buffer[i] = close[i];
}
// 修正例:< rates_total で回す
for(int i = 0; i < rates_total; i++)
{
buffer[i] = close[i];
}
原因5:ヒストリカルデータやバー数が足りない
過去の足を参照するコードでは、必要な本数が読み込まれていないと範囲外になります。起動直後やチャート切り替え直後、データ取得が追いついていないときに起きやすい原因です。
int period = 14;
if(rates_total < period + 1)
return(rates_total);
バーやヒストリカルデータが不足している場合は、MT4のヒストリカルデータを確認・補充する手順 を確認してください。データ取得が止まっている・更新待ちの場合は、MT4のアップデートが終わらないときの確認手順 もあわせて確認すると切り分けやすくなります。
修正例:範囲チェックを入れる
int idx = i + 1;
if(idx >= 0 && idx < ArraySize(arr))
{
double value = arr[idx];
Print(value);
}
インジケーターバッファで注意すること
SetIndexBuffer() で結びつけたバッファは、rates_total に応じてサイズが確保されます。そのため、OnCalculate() 内で rates_total を超える番号に書き込もうとすると範囲外になります。
FAQ
Q. array out of range はコンパイルエラーですか?
A. いいえ。これは実行時(ランタイム)のエラーです。
Q. i <= ArraySize(array) はなぜ危ないですか?
A. ArraySize() は要素数を返し、最後の有効番号はそれより1つ小さい値だからです。
Q. OnCalculate の rates_total とは何ですか?
A. チャート全体のバー数です。rates_total をそのまま番号に使うと範囲外になる点に注意してください。
Q. ヒストリカルデータ不足でも array out of range は起きますか?
A. 起きることがあります。必要な本数が足りないときは処理をスキップするガードを入れると防ぎやすくなります。
まとめ
- ループの終了条件が
<=になっていないか確認する i + 1/i - 1で端を超えていないか確認するArraySize()を<で使っているか確認するrates_totalを番号にそのまま使っていないか確認する- 必要なバー数・ヒストリカルデータが足りているか確認する
まずはエラーログでファイル名と行番号を確認し、その行のループ条件と参照番号を見直すと、原因にたどり着きやすくなります。