MQL4の時間足、ローソク足で1回だけ計算させる

MQL4はC言語に近い文法なので、プログラミング経験がある人ほどすぐに書き始められます。ただ、FX特有の「時間足(ローソク足)」という考え方を意識せずにロジックを組むと、思わぬ問題にぶつかります。

代表的なのが、同じローソク足の中で何度もエントリーしてしまう問題です。OnTick()は価格が動くたび(ティックごと)に呼ばれるため、条件を満たしている間は、1本のローソク足が終わるまで注文を繰り返してしまいます。

[PR]


ローソク足の始値で1回だけ計算する

解決策はシンプルで、「新しいローソク足ができた最初のティックでだけロジックを計算し、次のローソク足ができるまでは何もしない」ようにします。

こうすると処理が軽くなり、同じローソク足の中で計算を繰り返したり、注文を大量に出したりすることがなくなります。新しいローソク足ができたかどうかの判定方法は、主に次の3つです。

Time[0]で判定する(おすすめ)

datetime Time[]
Time[]は、各ローソク足の開始時刻が入った配列です。Time[0]には、いま形成中のローソク足の開始時刻が入っています。

新しいローソク足ができるとTime[0]の値が変わるので、前回の値と比べれば「新しい足になったか」がわかります。ローソク足の本数やティック数に左右されないため、もっとも確実な方法です。

この書き方だと、EAをチャートに入れた直後の最初のティックでも1回処理が走ります。入れた時点のローソク足は見送りたい場合は、OnInit()の中で lastBarTime に Time[0] を入れておきます(その場合は static ではなくグローバル変数にします)。

チャートとは別の時間足(例えば5分足チャートで1時間足の切り替わり)を判定したいときは、Time[0] の代わりに iTime(NULL, PERIOD_H1, 0) を使えば同じ考え方で判定できます。

Barsで判定する

int Bars
Barsは、現在のチャートにあるバー(ローソク足)の総数です。新しいローソク足ができるとカウントが1つ増え、同じローソク足の間は変わりません。この性質を利用する方法です。

手軽ですが、Barsには次の弱点があります。

  • 最大バー数に達すると増えなくなる:MT4の「ツール」→「オプション」→「チャート」にある「チャートの最大バー数」に達すると、新しい足ができてもBarsが増えず、判定が止まってしまいます。
  • 履歴の読み込みで誤判定する:過去データがダウンロードされてチャートに足が追加されると、新しい足ができていなくてもBarsが増えるため、「新しい足」と誤判定することがあります。

Volume[0]で判定する

long Volume[]
Volume[]には各ローソク足のティック出来高(ティックの回数)が入っています。新しいローソク足の最初のティックでは Volume[0] が1になる、という性質を利用する方法です。

MT4に付属するサンプルEA「Moving Average.mq4」でも、次のように使われています。

ただし、通信の遅れや処理の重さなどで最初のティックを取りこぼすと、EAが受け取った時点ですでに Volume[0] が2以上になっていることがあります。その場合、そのローソク足では一度も処理が走らず、丸ごと見送られてしまいます。

3つの方法の比較

方法判定の仕組み注意点おすすめ度
Time[0]ローソク足の開始時刻が変わったか特になし◎
Barsチャートのバー数が増えたか最大バー数に達すると判定が止まる/履歴の読み込みで誤判定する△
Volume[0]現在の足のティック数が1か最初のティックを取りこぼすと、その足を丸ごと見送る△

これから書くEAでは、Time[0]で判定する方法を使うのが安心です。Barsを使った既存のEAも、長期間動かしていると最大バー数に達して突然エントリーしなくなることがあるため、Time[0]での判定に置き換えておくことをおすすめします。

シェアする

  • このエントリーをはてなブックマークに追加

フォローする