余分なループなのか?

Travis 2010/11/12 18:47
いつもお世話になっています。
インジケータの基本的なことに関する質問です。
多くのインジケータのstart関数では下記コーディングになっています。

int counted_bars=IndicatorCounted();
if(counted_bars>0) counted_bars--;
limit=Bars-counted_bars;
for(int i=0; i普通のインジケータではカレントバーの処理だけで良いと思うのですが1本前のバーの処理をしなければいけない理由があるのでしょうか?
重いインジケータの場合処理量が半分になるので効果があると思うのですが?

多くのインジケータがそうなっている経緯は、おそらくプログラマがMT4付属のインジケータやテンプレートを真似たためだと思います。

↑MT4付属のサンプルコードでも、同じループ処理になっていて、わざわざ recounted されるとコメントまで付いています。


本来のMQL4での定義は、

Bars チャート上のバーの本数
IndicatorCounted() 最後に呼ばれてから変化のないバーの本数

なので、 limit = Bars - IndicatorCounted() 本だけ再計算すればよいはずです。

↑実際にループ数を変えてインジケータを作って比較しても、どちらも同じ表示になります。


そこで、IndicatorCounted()のヘルプを読むと、

Note: The latest bar is not considered to be calculated and, in the most cases, it is necessary to recalculate only this bar. However, there occur some boundary cases where custom indicator is called from the expert at the first tick of the new bar. It is possible that the last tick of the previous bar had not been processed (because the last-but-one tick was being processed when this last tick came), the custom indicator was not called and it was not calculated because of this. To avoid indicator calculation errors in such situations, the IndicatorCounted() function returns the count of bars minus one.

黄色の部分は、Travisさんの考えたとおりですが、EAから iCustom で呼び出す場合、赤字部分の挙動が問題となるので

//---- the last counted bar will be recounted
if(counted_bars>0) counted_bars--;

↑この一行が敢えて加えられたのかなと思いました..。


ところが、Build 226 で EA から iCustom 経由でインジケータを呼び出し、IndicatorCounted() の数値を記録したところ、

最新のバーができた最初のTick では、Bars - IndicatorCounted() が 2 となっているので、最新のバーと、その前のバーが再計算されます。
これなら、ユーザが意図的に counted_bars--; する必要はなくなります。


状況証拠から推理すると、大昔は counted_bars--; して1本余分に計算しないとEAが正しく動かなかったのだけど、現在では IndicatorCounted() の仕様が改良されて不要になったのではないかと...個人的には思いました。
英文のヘルプは最後が微妙に意味不明なのでこれ以上は分かりません。。^^;