1. EventSetMillisecondTimer関数の概要と実務での活用法
MQL5での開発において、多くのエンジニアが最初に直面する壁は「ティックが動かないとプログラムが動かない」という制約です。標準的なOnTickイベントは、価格が動いた瞬間にのみ実行されます。しかし、実務レベルのEA開発では、価格変動(ティック)とは無関係に、一定の周期で処理を行いたい場面が多々あります。
そこで重宝するのがEventSetMillisecondTimerです。この関数は、ミリ秒単位(1/1000秒単位)でタイマーイベントを発生させ、指定した間隔でOnTimerイベントハンドラを強制的に呼び出します。
実務での主な活用法:
* パネルや情報のリアルタイム更新: 価格が動いていない土日や流動性の低い時間帯でも、UI上の時計や残高情報を更新し続ける。
* 高速な注文監視: 注文が約定したかどうかを、ティックを待たずに超短サイクルでチェックする。
* タイムアウト処理: エントリー後、一定時間内に約定しなかった場合に注文を取り消すなどの制御。
初心者がつまずきやすいポイントは、「ティックが激しい時はOnTickとOnTimerが競合して重くなるのではないか?」という懸念です。しかし、MT5のイベントキューは適切に管理されているため、ミリ秒タイマーを正しく実装することは、より堅牢でプロフェッショナルなEAへの第一歩となります。
2. 構文と戻り値
EventSetMillisecondTimer関数の基本仕様は以下の通りです。
bool EventSetMillisecondTimer(
int milliseconds // ミリ秒単位の間隔
);
- パラメーター:
milliseconds: タイマーイベントを発生させる間隔をミリ秒単位で指定します。例えば、1000を指定すると1秒ごと、100を指定すると0.1秒ごとにOnTimerが呼ばれます。
- 戻り値:
- 成功した場合は
trueを、失敗した場合はfalseを返します。
- 成功した場合は
※注意:この関数を使用する場合、EAの初期化関数(OnInit)内で呼び出すのが一般的です。また、タイマーを停止させるには EventKillTimer 関数を使用します。
3. 具体的な使い方・実践サンプルコード
以下は、0.5秒(500ミリ秒)ごとに現在のスプレッドを監視し、画面上にリアルタイム表示する実践的なEAのテンプレートです。
//+------------------------------------------------------------------+
//| MillisecondTimerEA.mq5 |
//| Copyright 2024, Quant Engineer |
//+------------------------------------------------------------------+
#property strict
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// 500ミリ秒(0.5秒)ごとにOnTimerを呼び出す設定
if(!EventSetMillisecondTimer(500))
{
Print("タイマーの作成に失敗しました。");
return(INIT_FAILED);
}
Print("EAが初期化され、ミリ秒タイマーが開始されました。");
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
// EA終了時には必ずタイマーを破棄する
EventKillTimer();
Comment(""); // 画面上のコメントを消去
}
//+------------------------------------------------------------------+
//| Timer function |
//+------------------------------------------------------------------+
void OnTimer()
{
// 現在のスプレッド(ポイント単位)を取得
int spread = (int)SymbolInfoInteger(_Symbol, SYMBOL_SPREAD);
// サーバー時刻を取得
datetime serverTime = TimeCurrent();
// 画面左上に情報を表示
// ティックが動かなくても、0.5秒ごとにこの表示が更新されます
string message = StringFormat("サーバー時刻: %s\n現在のスプレッド: %d points",
TimeToString(serverTime, TIME_DATE|TIME_SECONDS),
spread);
Comment(message);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
// 通常のエントリーロジックなどはここで行う
}
4. 使用上の注意点とよくあるエラー
- OSの最小解像度の限界:
Windows OSの仕様上、タイマーの精度は通常10〜16ミリ秒程度が限界です。そのため、EventSetMillisecondTimer(1)(1ミリ秒)と設定しても、実際には10ミリ秒以上の間隔で実行されることがほとんどです。超高頻度スキャルピングを狙う場合は、このOSレベルの制約を理解しておく必要があります。 - OnTimer内の処理は「軽く」する:
OnTimerの中に重い計算やループ処理を入れると、MT5のメインスレッドを占有してしまい、チャートの描画がカクついたり、肝心のOnTickイベントの処理が遅れたりします。タイマー内ではフラグのチェックや情報の更新など、最小限の処理に留めるのがクオンツ流の作法です。 - バックテストでの挙動:
ストラテジーテスターでは、タイマーイベントは特殊な挙動をします。MT5のバックテスト設定で「1分足OHLC」などを選択している場合、タイマーは正確にシミュレートされないことがあるため、必ず「全ティック」または「リアルティックに基づいたすべてのティック」モードで検証してください。
5. 【重要】自動売買における約定スピードと環境の罠
プロのクオンツエンジニアとして断言しますが、プログラム内でEventSetMillisecondTimerを使って1ミリ秒単位のロジックを組んだとしても、実行環境が「自宅PC」であれば、その努力の多くは無駄になります。自宅のインターネット回線は、FX業者のサーバーがあるデータセンターとの間に物理的な距離があり、数十ミリ秒から数百ミリ秒のネットワーク遅延(レイテンシ)が必ず発生するからです。
たとえプログラムが0.1ミリ秒で判断を下しても、注文信号が地球を半周してサーバーに届くまでに時間がかかれば、有利な価格は一瞬で消え去り、スリッページによる致命的な損失を招きます。このコンマ数秒の差が、年間収支をプラスにするかマイナスにするかの分水嶺となります。約定スピードを極限まで高め、プログラムの性能を100%引き出すためには、FX業者のサーバーと同じ、あるいは至近距離にあるデータセンター内に設置された専用のVPS(仮想専用サーバー)を利用することが、プロのトレーダーにとってはもはや「常識」であり、必須の投資と言えます。
💡 この記事の内容を実運用で活かすには?
この記事の内容を実運用で活かすには、正しい環境が必要です。
特にVPSを使わないと、このロジックは再現できません。

コメント