次の構文をOnTickの頭で記述してあります。
// バー数が少なすぎる場合は、処理しない。
if( iBars(Symbol(), PERIOD_D1) < 100 ) return ;
Print("iBars(Symbol(), PERIOD_D1)=", iBars(Symbol(), PERIOD_D1));
その際の操作履歴での結果で
iBars(Symbol(), PERIOD_D1)=0
と表示される場合があります。
・・・・
・・・・・・・・・・・
・・・・・・・・・・・・・・・・・・・・・・・オイ(--#
iBars(Symbol(), PERIOD_D1)を2回呼び出しています。1回目で値が100未満であれば、処理を終了してしまうアルゴリズムです。
2回目は値を単純に操作履歴に表示するだけですが、1回目と2回目の間には何も入っていないため本来であれば、100以上の値が帰ってくるはずです。
ところが、1回目では100以上の値が帰ってきたのに、2回目では0が帰ってくるという謎現象となっています。
EAは5分足をみて動かしていましたので5分足チャートで動かしています。 そのためなのか、なぜか日足のデータが正しくとれない場合があると想定しました。起動直後に1発目から取れないのであれば、まぁ仕方がないと思うのですが、続けて2回同じ関数を呼び出したうえで、1回目と2回目で結果が違うというのは、これいかに?1回目が0で2回目が1以上というのであれば、MT4の動きとして理解できるのですが・・。
ま、最終的にはMT4のバグじゃないかなぁと思うのですが、仕方がありません何かしら対策を打ちたいと思います。
さて、原因を探るためにGetLastErrorという関数をコールしてみます。
コード的にはこんな感じです。
//インジケータの計算
int ratesTotal = iBars(m_symbol, m_timeframe);
if( ratesTotal == 0 )
{
Print("iBars return zero GetLastError= ", GetLastError());
}
これで、操作履歴を見ると
GetLastError=4073
というログが残っていました。
MQL4.com Runtime Errors
から4073はNO HISTORY DATAとのこと。
・・・・。じゃぁ最初から0返せ!と言いたくなりますが、とても言いたくなります(大切なので2回言いました!)が、まぁこのように動くものは仕方がありません。
まぁ仮定に仮定を重ねる形になりますが、1回目の呼び出しではキャッシュ上かなにかの履歴を見ますが、その際実際に通信してデータが取れてきていない状態になるため、2回目で0リセットされてる・・・・・・のでしょうか・・・・。でもバックテストだし(自信なし)
ヒストリデータは、iClose関数など価格情報を読みむ関数をコールすると構築されます。
そこで、EAの頭で、あらかじめiClose関数で価格データを読み込みします。
//------------------------------------------------------------------
//初期化
int OnInit()
{
// 初回価格データを読み込み、ヒストリーを構築する。
for( int i = 0; i < 500; i++ )
{
iClose(Symbol(), PERIOD_D1, i);
}
return(INIT_SUCCEEDED);
}
上記処理を入れたところ、2回目でiBarsが0を返すような症状は発生しなくなりました。
うーん。うーん。うーーーーーーーーーーーん。
気持ち悪いですがおまじないということで。
「MT4でFXを勝ち抜く研究をするブログ」で公開している無料インジケータは、こちらの一覧から。
インジケータ一覧
Twitterもよろしくお願いします。
https://twitter.com/mt4program
ブログランキングにご協力よろしくお願いします。m(._.)m
にほんブログ村 |
お約束ですが、本ブログは、投資に対する利益を約束する物ではありません。最終的には自己責任によるご判断よろしくお願いいたします。