array out of rangeは配列処理のエラー
array out of rangeは、配列のサイズを超えた場所にアクセスしようとすると発生します。例えば、ローソク足(Bars)が300本しかないのに、Open[300]で301本目の始値を取りに行った場合などです。
array out of rangeの原因は様々ですが、上記のようにローソク足のデータを取りに行くときや、インジケーターで使うBufferに入れた値を取りに行くときに起こりがちです。
array out of rangeの原因①「ローソク足がないところの値を取りに行っている」
先ほどの例では、ローソク足(Bars)が300本しかないのに、Open[300]で301本目の始値を取りに行った場合にエラーが起こると言いました。
Open[]の最大値はBars – 1なので、ローソク足が300本しかないときは、Open[]の最大値は299です。これは、配列は0から数えるというルールがあるためなのですが、このルールをよく理解していない人はよくこのミスをしちゃいます。
最新のローソク足の始値はOpen[0]とわかっているけど、最後のローソク足の始値はOpen[Bars]って書いてしまいがちですよね。
300本目の始値を取りに行くときはOpen[299]が正しいです。
また、移動平均線のように過去のローソク足を数本にわたって参照する場合は特に注意が必要です。
例えば移動平均線の期間を60にしている場合、移動平均線の計算をするのに最低60本のローソク足が必要になります。もしローソク足が300本しかない場合は、古い方から数えて59本は移動平均線が計算できず、60本目からようやく移動平均線を計算することができます。
ところが、そのことを忘れていて、forループですべてのローソク足の移動平均線を計算しにいくと、最新のローソク足から241本目までは、241本目から数えて60本、つまり300本目のローソク足まで取りに行けるので問題なく移動平均線が計算できますが、242本目の移動平均線を計算しようとすると、301本目のローソク足の終値を取りに行く必要があり、ここでarray out of rangeが発生します。
forループの処理はきちんと
期間60の移動平均線をforループで回して計算するときは、計算するローソク足の本数がBarsの最大値を超えたら計算しないようにする工夫が必要です。
int limit = Bars - IndicatorCounted();
for(int i = limit - 1; i >= 0; i--) {
if(i + 60 > Bars - 1) continue;
double iMA(Symbol(), PERIOD_CURRENT, 60, 0, MODE_SMA, PRICE_CLOSE, 0);
}
こんな感じに書けばarray out of rangeは起こりません。
array out of rangeの原因②「そもそも配列が存在しない」
インジケーターとしてラインや矢印を表示させるとき、まずインジケーター用のBufferを用意し、そこに値を入れる必要があります。
インジケーター用のBufferを用意するには、配列の宣言と、さらに「いくつBufferを用意するか」を宣言しなければいけません。
double Buf0[];
double Buf1[];
double Buf2[];
double Buf3[];
#property indicator_buffers 4
ここまでは問題ないのですが、例えばインジケーターを作っているうちにラインを1本増やしたくなった時、配列の宣言だけ追加してBufferの数の宣言を修正し忘れるケースがあります。
#property indicator_buffers 4
double Buf0[];
double Buf1[];
double Buf2[];
double Buf3[];
double Buf4[];
この状態で、Buf4[]に値を入れようとしたりすると、Buf4[]はインジケーターのBufferとして用意していない状態なので、array out of rangeが発生します。
配列を増やすのとBufferを増やすのはセットで
#property indicator_buffers 5
double Buf0[];
double Buf1[];
double Buf2[];
double Buf3[];
double Buf4[];
ここでは説明を省きましたが、もちろんSetIndexBuffer()で配列をBufferとしてマッピングすることをお忘れなく。
SetIndexBuffer(0,Buf0);
SetIndexBuffer(1,Buf1);
SetIndexBuffer(2,Buf2);
SetIndexBuffer(3,Buf3);
SetIndexBuffer(4,Buf4);
MQLでよく出現するarray out of rangeとは?まとめ