EAを実行すると、一定の時間ごとにプログラムを実行したい場面が頻繁に発生します。
MQL4では、そのようなニーズに対応するために、OnTimer関数が用意されています。
今回は、一定時間ごとにプログラムを正確に実行するためのOnTimer関数について解説し、その書き方についてまとめました。
最後に、サンプルコードも紹介します。
こんな方におすすめ
- 一定のタイミングでプログラムを動かしたい
- EAにタイミングの要素を加えたい
- ローソク足に関係なく実行してくれる関数を知りたい
OnTimer関数とは
OnTimer関数は、一定時間ごとにプログラムを実行するための関数です。
この関数はイベント関数とも呼ばれ、ローソク足に関係なく定期的に実行される特徴があります。
ただし、OnTimer関数は単独では使用できず、EventSetTimer関数とEventKillTimer関数と組み合わせて使用する必要があります。
以下では、OnTimer関数の使用方法に加えて、EventSetTimer関数とEventKillTimer関数についても説明します。
まず、EventSetTimer関数は、EAやインジケーターのタイマーイベント生成間隔を指定し、クライアントターミナルへイベントを実行するタイミングを指示するための関数です。
クライアントターミナルとは、FX業者の取引プラットフォームのことを指します。
したがって、EventSetTimer関数は、FX業者へ特定のタイミング(秒単位)で実行したいイベントを指示するための関数と言えます。
これは車に例えると、発車するためのアクセルとも言える関数です。
記述例)30秒単位で指定する
int OnInit(){
EventSetTimer(30);
return(INIT_SUCCEEDED);
}
次に、EventKillTimer関数について説明します。
この関数は、作成されたタイマーを無効にするためのものです。
EventKillTimer関数は、OnTimer関数の停止命令をクライアントターミナルに送る役割を果たします。
これにより、繰り返し実行されているイベントを停止する指示がFX業者に送信されます。
記述例
void EventKillTimer();
OnTimer関数を動作させるためには、2つの関数が必要です。
これらの関数を紹介した後に、OnTimer関数自体の特徴について見ていきましょう。
OnTimer関数の特徴は以下の2つです。
- 価格の変動に影響されない
- EAでもインジケーターでも利用できる
OnTimer関数は価格の変動に影響を受けません。
一定の時間が経過すると動作するため、チャート上の価格変動に関係なく実行されます。
この一定の動作間隔がOnTimer関数の利点と言えます。
また、OnTimer関数はEA(自動売買)やインジケーターの両方で利用することができます。
今回はEAの運用をメインに説明しましたが、幅広い用途で利用できる関数であることを知っておいてください。
OnTimer関数の書き方
OnTimer関数の基本的な書き方は以下の通りです。
記述例)基本的な書き方
void OnTimer()
{
}
このように非常にシンプルで、引数や戻り値はありません。
厳密に言えば、戻り値はvoid型であり、値が存在しないことを表しています。
通常、関数には引数や戻り値があるため、長くなることが多いですが、OnTimer関数は単独で使用する場合は簡潔で短い書き方になります。
ただし、注意点として、OnTimer関数は単独で使用するよりも、先述したEventSetTimer関数やEventKillTimer関数と組み合わせて使用する場合が一般的です。
そのため、実際に利用する場合はそれなりの長さになることがあります。
OnTimer関数の戻り値
OnTimer関数は、戻り値や返り値がありません。
この関数は、決められたタイミングでプログラムを実行するためのものであり、void型の戻り値を持ちます。
void型は、プログラミング言語において「何もない」という意味を持つデータ型であり、戻り値が存在しないことを示します。
OnTimer関数にvoid型を指定することで、戻り値がないことを明示しています。
実際には、OnTimer関数は他の関数と組み合わせて使用され、単独で動作するためには戻り値は必要ありません。
そのため、void型を戻り値として指定することで、正常に動作します。
OnTimer関数の引数
MQL4の関数には多くの引数が設定されている場合もありますが、今回紹介するOnTimer関数には引数がありません。
そのため、OnTimer関数をそのまま使用すれば、一定時間ごとに実行されるイベント関数として機能します。
OnTimer関数の使い方
OnTimer関数を実際に利用する方法について解説します。
まず、サンプルのコードを一気に紹介しましょう。
datetime start_time = TimeCurrent();
datetime start_tradeserver_time = 0;
datetime calculated_server_time = 0;
int OnInit()
{
EventSetTimer(1);
return(INIT_SUCCEEDED);
void OnDeinit(const int reason)
{
EventKillTimer();
void OnTick()
void OnTimer()
{
datetime local_time = TimeLocal();
datetime trade_server_time = TimeCurrent();
if(trade_server_time == 0)
return;
if(start_tradeserver_time == 0)
{
start_tradeserver_time = trade_server_time;
calculated_server_time = trade_server_time;
Print(start_tradeserver_time);
}
else
{
calculated_server_time = calculated_server_time + 1;
}
string com = StringFormat(" start_time: %s\r\n", TimeToString(start_time, TIME_MINUTES | TIME_SECONDS));
com = com + StringFormat(" local_time: %s\r\n", TimeToString(local_time, TIME_MINUTES | TIME_SECONDS));
com = com + StringFormat("trade_server_time: %s\r\n", TimeToString(trade_server_time, TIME_MINUTES | TIME_SECONDS));
com = com + StringFormat("calculated_server_time: %s\r\n", TimeToString(calculated_server_time, TIME_MINUTES | TIME_SECONDS));
Comment(com);
}
このコードだけでは理解しづらいかもしれませんので、順番に解説します。
まず、時間に関する記述です。
//EAを実行したサーバー時間
datetime start_time = TimeCurrent();
//EAを実行したサーバー時間
datetime start_tradeserver_time = 0;
//遅延を考慮したサーバー時間
datetime calculated_server_time = 0;
これによって、EAの時間が適切に設定されます。
次に、イベント関数の初期化に関する記述です。
int OnInit()
{
//初期化に成功したらタイマーを設定していきます。
//1秒ごとにOnTimer関数を実行する
EventSetTimer(1);
//---
return(INIT_SUCCEEDED);
}
この部分では、イベント関数の初期化に成功したら、タイマーを設定しています。
タイマー機能の解除に関する記述です。
void OnDeinit(const int reason)
{
//--- destroy timer
//時間の設定を消去する
EventKillTimer();
}
これによって、タイマーの設定を解除します。
サンプルコードの中には、トレードに関連するタイミングのプログラムも記述されています。
void OnTick()
{
// ここにトレードに関するコードを入力します
}
ここからはOnTimer関数の記述になります。
void OnTimer()
{
//最初にローカルPCの時間を呼び出します。
datetime local_time = TimeLocal();
//サーバーの現在時刻を呼び出します。
datetime trade_server_time = TimeCurrent();
//問題が起こった場合や時間が取得できない場合に終了する記述をします。
if(trade_server_time == 0)
return;
//サーバーの初期時間が設定していない場合の対処となる記述をします。
if(start_tradeserver_time == 0)
{
start_tradeserver_time = trade_server_time;
calculated_server_time = trade_server_time;
//このタイミングで現在のサーバー時刻を表示します。
Print(start_tradeserver_time);
}
else
{
//通信での遅延を考慮して1ミリ秒追加します。
calculated_server_time = calculated_server_time + 1;
}
//最後にコメントを作成していく記述ですが、ここはOnTimer関数と直接関係ありません。
string com = StringFormat(" start_time: %s\r\n", TimeToString(start_time, TIME_MINUTES | TIME_SECONDS));
com = com + StringFormat(" local_time: %s\r\n", TimeToString(local_time, TIME_MINUTES | TIME_SECONDS));
com = com + StringFormat("trade_server_time: %s\r\n", TimeToString(trade_server_time, TIME_MINUTES | TIME_SECONDS));
com = com + StringFormat("calculated_server_time: %s\r\n", TimeToString(calculated_server_time, TIME_MINUTES | TIME_SECONDS));
//この記述でコメントを表示させます。
Comment(com);
}
OnTimer関数は単体で使用することはありませんが、このように長いサンプルコードを記述し、厳密な時刻設定を行う必要があります。
コメントを残す