結構知らない人も多いようなので、書いてみました。
自分でバックテストを取って、それをシグナル化しようと思った場合、エントリー条件に達した際にアラートを鳴らしたいと思った人はたくさんいるはずです。
しかし、実際にコードを書いてみると条件に達している間、ずっとアラートが鳴り続けてしまうといった問題にぶつかった人も多いはず。
当然コードの書き方に問題があるのですが、ティック更新のたびにstart関数/OnCalculate関数が実行されて、その度に条件に達してアラートを鳴らすといったコードを書いているからだと思います。
これを解決しようと思うと、一度アラートが鳴ったらフラグを立てて、そのフラグが立っている間はアラートを鳴らさないようにして、その後どこかのタイミングでフラグを下す…
といったコードを考えたりもしたかと思いますが、実際にどのようにコードを書けばいいか分からないなんて悩んでいる人がいるのではないでしょうか?
そんな人の目に留まってくれたらうれしいです。
同一足で一度だけしかアラートを鳴らさないコード
早速ですが、答えです。
if(SoundTime != iTime(NULL,NULL,0)) { Alert("アラートメッセージ"); SoundTime = iTime(NULL,NULL,0); }
このようにすれば、同一足で一度しかアラートが鳴りません。
「SoundTime」はグローバル変数で宣言しておいてください。
datetime SoundTime;
解説
流れを説明すると、グローバル変数として宣言したタイミングでは、変数内にはどの時間も格納されていませんのでNULL状態です。
そのため、初回if文の条件はtrueとなります。(SoundTimeが現在時刻と一致しない場合はtrueという式なので)
if文の中が実行されるので、アラート関数が実行されます。
その後、SoundTimeに現在時刻が格納しています。
ここまでがif文の中身です。
その後再度ティックが更新されstart関数/OnCalculate関数が実行されるタイミングで再度if文に到達します。
先ほどSoundTimeに現在時刻を格納しているので、ティックの更新タイミングが同時刻であればif文はfalseとなります。
そのためアラートが鳴らないという動作となります。
どのタイムフレームでも有効
上記の例は同一足で一度だけしかアラートを鳴らさないようにしましたが、5分足で1度だけ、15分足で1度だけ、といったようにすることも出来ます。
こちらも簡単です。
以下のようにタイムフレームを指定するだけです。(5分足の場合)
if(SoundTime != iTime(NULL,PERIOD_M5,0)) { Alert("アラートメッセージ"); SoundTime = iTime(NULL,PERIOD_M5,0); }
もちろん他にもやり方はあるかと思いますが、これが一番簡単に出来るコードかと思いますので、良かったら参考にしてみてください。
コメント