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

array out of range
yuki
yuki
インジケーター作成時に、コンパイルができたのにいざMT4に適用してみると何も表示されないなどのトラブルがあります
カオチャイ
カオチャイ
そんな時にエキスパートタブを見るとたまに「array out of range」とエラーがでています
yuki
yuki
今回はarray out of rangeの原因を解説したいと思います
EAやインジケーターに、認証やPaypal決済機能を追加できるMQLAuth実装サービスはこちら
EAインジケーターに口座番号認証を実装
EAやインジケーターに口座縛りをつけてコピー対策【MQLAuth実装代行】 ※MQLAuth(エム・キュー・エル・オースと呼びます) MQLAuthのイメージ こちらは口座番号を登録するM...

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

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[];

 

いくつBufferを用意するかの宣言
#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を増やすのはセットで

インジケーターに使う配列を増やしたら、必ず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とは?まとめ

yuki
yuki
array out of rangeはEAやインジケーターの開発者は必ず悩まされるエラーですね
カオチャイ
カオチャイ
コンパイルしてホッとしたのもつかの間、MT4に表示されないなんてのはメンタルにきますが、エラーにarrya out of rangeがあれば大抵は今回の内容で対処ができますよ!
ツールの二次配布を防止する口座認証はこちら
EAインジケーターに口座番号認証を実装
EAやインジケーターに口座縛りをつけてコピー対策【MQLAuth実装代行】 ※MQLAuth(エム・キュー・エル・オースと呼びます) MQLAuthのイメージ こちらは口座番号を登録するM...

 

EA・インジケーター制作のご依頼はこちら
インジケーターのバックテスト&リペイントチェック代行サービスMT4やMT5に関するツールを作成する際の流れを説明しています。 シストレファクトリーでは一からEAの制作以外にもツールの修正や、統計的なアプローチができるソフトなどお客様の欲しいツールを形にいたします。...
EA&インジケーター制作代行
【MT4&MT5】EA&インジケーター制作代行承ります EA&インジケーター制作代行とは? EA&インジケーター制作代行では、皆さんが日頃使っている手法をMT4(MT5)でエントリーサイ...

 

インジケーターをより使いやすく
MQLコードでEAをカスタマイズ
【MQLコード解説】EA・インジケーターのカスタマイズ【体験版・LINE通知】EAやインジケーターに口座番号認証を実装する方法を紹介しています。 認証システムにはMQLAuthを利用して解説していきます。...
EAやインジケーターに認証をつける方法
MT4のEAやインジケーターにサーバー認証(口座番号縛り)を実装する方法MQLAuthを使って、EAやインジケーターに口座番号認証を実装する方法を紹介しています。 従来のコピー防止だけでなく、遠隔での停止や決済機能の自動化なども可能になる画期的な認証方法です。...