OnTick()はあくまでティックベースで動くので、ここで売買判定を行うようなプログラムにしておくと、業者によってはエントリー・イクジット判断が10秒単位で遅れてしまう可能性があります。
それに比べ、OnTimer()関数は秒単位で動きを定義できるので、業者に依存しない安定した売買ができます(できると思います)。
ということで便利なこのOnTimer()関数なのですが、EAを作っていて大きな問題に直面してしまいました。
なんと・・・OnTimer()関数はバックテストで一切通らないのです!!
つまり、OnTimer()関数内に売買ロジックを入れ込んでいるようなEAでバックテストを行おうとしても、一切取引が行われずにバックテストが終了してしまうのです。。。
なんてこった・・・バックテストできないEAなどとても運用できないではないか!!
ということで、なんとかOnTimer()でバックテスト出来る方法を考えました。
あまりにも苦肉ですが、よかったら参考にしてみてください。
「#define DEBUG」というおまじないをコードの先頭に置き、あとは以下のコードを、OnInit()の前に置きます。
//バックテスト用
#ifdef DEBUG
int prevsec;
int BScnt = 0;
bool ForBackTest(int Timerseconds)
{
if (Seconds() != prevsec) BScnt ++;
prevsec = Seconds();
if (BScnt >= Timerseconds){
BScnt = 0;
return(true);
}
return(false);
}
#endif
おしまいに、OnTick()関数内に以下のコードを入れます。
void OnTick()
{
//---
//バックテスト用
#ifdef DEBUG
if (ForBackTest([OnTimerで設定している秒数])) OnTimer();
#endif
}
はい、こうすると擬似的にOnTimer()を表現できます。
ただ、3点注意する必要があります。
・バックテストは必ず「全ティック」で動かす必要があります。
そうしないと、秒単位の判定ロジックがバックテスト上ではまったくうまく動かなくなります。
・バックテストはこれでいいのですが、実際に動かす場合は「#define DEBUG」のおまじないは必ず削除するようにしてください。そうしないと、2重でロジックが動いてしまうことになります。
・このやり方だと、OnTimer()を正確には再現できません(30分の間隔を開けようとしても、バックテスト上は40分位の間隔になってしまう)。
これはバックテストのTickが飛んでいることが原因と思われますが、この辺りで若干リアルとの差分が出てくる可能性があります。
もし分単位以上の売買ロジックであれば、上記コードのSeconds()をMinute()にして分単位にしてあげたほうが安定するかもしれません。ロジックによって使い分けてください。
ということで、以上です。
OnTick()関数のバックテストで困っている方は是非参考にしてみてください。
#他にいい方法があれば、ぜひ教えて下さい。。。