お役立ち記事

MQLでよく出現するarray out of rangeとは?

array out of rangeとは
yukik-aochai
YUKI
YUKI

インジケーター作成時に、コンパイルができたのにいざMT4に適用してみると何も表示されないなどのトラブルがあります。

カオチャイ
カオチャイ

そんな時にターミナルウィンドウのエラーを確認すると、たまに「array out of range」とでていますが、今回はこのエラーが発生する主な原因と対策を解説します!

array out of rangeは配列処理のエラー

array out of range

「array out of range」は、配列の定義された領域(サイズ)を超えたインデックスへアクセスしようとした際に発生するエラーです。例えば、ローソク足(Bars)が300本しかない状態にもかかわらず、Open[300](301本目の値)を参照しようとした場合などに発生します。

このエラーは、ローソク足データを参照する際や、インジケーターの計算用Buffer(配列)へ値を格納・参照する際に頻出します。

array out of rangeの原因①「存在しない過去足の値を取りに行っている」

MQL4では配列のインデックスが「0」から始まります。そのため、チャート上の全ローソク足本数が Bars 本である場合、指定できる最大のインデックスは Bars - 1 となります。

初心者がよくやってしまうミスとして、最古のローソク足の始値を取得しようとして Open[Bars] と記述してしまうケースがあります。正しくは Open[Bars - 1] です。

また、移動平均線(MA)のように過去数本分のデータを参照するテクニカル指標を計算する際は、特に注意が必要です。期間60のSMAを計算する場合、最低でも60本分のローソク足が必要になるため、古い足の末端(Bars - 60 を超える領域)では参照エラーが発生します。

forループでの適切なガード処理

期間60の移動平均線をforループで計算する場合は、参照インデックスが Bars - 1 を超えないよう、以下のように安全に制御します。

int counted = IndicatorCounted();
if(counted < 0) return(-1);
if(counted > 0) counted–; // 直近足の再計算用

int limit = Bars – counted;

// ローソク足が計算期間(60本)未満の場合は処理をスキップ
if(Bars < 60) return(0);

// 初回計算時、配列上限を超えないように上限をガードする
if(limit > Bars – 60) limit = Bars – 60;

for(int i = limit – 1; i >= 0; i–) {
    Buf0[i] = iMA(Symbol(), PERIOD_CURRENT, 60, 0, MODE_SMA, PRICE_CLOSE, i);
}

このようにあらかじめ計算上限(limit)を配列の参照可能範囲内に制限しておくことで、array out of range を防止できます。

array out of rangeの原因②「Buffer(配列)が宣言・割り当てされていない」

インジケーターでラインや矢印を表示する場合、配列を宣言するだけでなく、プログラム側へ「使用するBufferの数」を正しく通知する必要があります。

1. 配列の宣言

double Buf0[];
double Buf1[];
double Buf2[];
double Buf3[];

2. Buffer数のプロパティ宣言

#property indicator_buffers 4

よくあるトラブルとして、開発の途中で新しいライン(`Buf4[]`)を追加した際、配列だけを増やして `#property indicator_buffers` の数値を更新し忘れるケースがあります。

#property indicator_buffers 4 // ← ここが4のままになっている!

double Buf0[];
double Buf1[];
double Buf2[];
double Buf3[];
double Buf4[]; // 新しく追加

この状態のまま `Buf4[i] = …` のように値を代入しようとすると、メタトレーダー側でバッファ領域がメモリ上に割り当てられていないため、array out of range が発生します。

解決手順:Buffer数とSetIndexBufferの設定

配列を増やした際は、必ずプロパティの数を更新し、`OnInit()` 内で `SetIndexBuffer()` を呼び出してマッピングを行ってください。

#property indicator_buffers 5 // 5に変更

double Buf0[];
double Buf1[];
double Buf2[];
double Buf3[];
double Buf4[];

int OnInit() {
   SetIndexBuffer(0, Buf0);
   SetIndexBuffer(1, Buf1);
   SetIndexBuffer(2, Buf2);
   SetIndexBuffer(3, Buf3);
   SetIndexBuffer(4, Buf4);
   return(INIT_SUCCEEDED);
}

まとめ

YUKI
YUKI

「array out of range」は初心者から上級者まで、MQL開発で必ず一度は直面するエラーですね。

カオチャイ
カオチャイ

コンパイルが通ったのに画面に何も出ないと焦りますが、ターミナルでこのエラーが出ている場合は「配列の参照範囲(`Bars – 1`)」か「Bufferの宣言漏れ」を疑えばほぼ解決できますよ!

あわせて読みたい
EA・インジケーター制作|売買ルールに合わせた自動売買ツールを開発
EA・インジケーター制作|売買ルールに合わせた自動売買ツールを開発
記事URLをコピーしました