FX EAの時間帯フィルター設定方法|MQL4/MQL5コード例と運用ポイント
Photo by Maxim Hopman on Unsplash
最終更新: 2026年6月
この記事でわかること
- 時間帯フィルターが必要な理由(流動性・スプレッド・ギャップの3リスク)
- MQL4(
TimeHour(TimeCurrent())関数)を使った時間フィルターのコード実装とパラメーター設計- MQL5(
TimeTradeServer()関数)を使った改善版の実装とMQL4との違い- 経済指標前後の自動停止フィルター(
CalendarValueHistory()応用)- バックテストでの効果検証手順と過剰最適化を防ぐ3つのアプローチ
EA開発をやってきた人なら、一度はこんな体験をしているんじゃないか。バックテストでは安定して勝てていたのに、本番運用に切り替えた途端に成績が崩れる。原因を追うと、深夜帯のスリッページや指標発表のスパイクが根っこにある——というパターンだ。
FX EAの時間帯フィルター設定は、EA長期稼働における最もコスパの高いリスク管理実装の一つだ。流動性が枯れた深夜にスリッページで損切りが滑る、経済指標発表の瞬間にスプレッドが10倍になって約定する、月曜の始値ギャップでポジションが焼かれる——いずれも時間帯フィルターの不備が原因になりやすい。
本記事では、MQL4とMQL5それぞれの実装コード(コピペで即使用可)から、バックテストによる効果検証、過剰最適化を避ける運用ポイントまでを体系的に解説する。コードの「意味」を先に説明してから実装に入る構成を取ったので、ある程度EA開発の経験がある方はコード部分まで読み飛ばしてもらっても構わない。
EA開発自体が初めての場合は先に「MQL4・MQL5プログラミング入門:EA開発を始める初心者が最初に知るべきこと」を参照してほしい。
時間帯フィルターが必要な理由
直接回答: FX EAの時間帯フィルターが必要な理由は「深夜帯のスリッページ」「経済指標前後のスプレッド拡大」「週末ギャップ」という3種類の時間帯依存リスクを機械的に排除できるためだ。これらをフィルターせずに24時間稼働させると、バックテストとフォワード成績の乖離が拡大する。
流動性の低い時間帯でのスリッページリスク
FX市場は24時間稼働しているが、すべての時間帯で同質の流動性が供給されているわけではない。三大市場の特性を整理すると以下のようになる。
| 市場 | 日本時間(目安・冬時間基準) | 特徴 | |---|---|---| | 東京時間 | 9:00〜17:00 | ボラティリティ小、JPY・AUD・NZDに影響大 | | ロンドン時間 | 16:00〜深夜2:00 | 欧州機関投資家が参入。EUR/GBP主導でボラティリティ急拡大 | | NY時間 | 21:00〜翌6:00 | USD中心。ロンドンとの重複帯(21:00〜翌1:00)が最高ボラティリティ |
※夏時間(サマータイム)期間は各市場が1時間前倒しになる。実装時は使用ブローカーのサーバー時間を必ず確認すること。
問題になるのは、NYクローズ後から東京オープン前にあたる日本時間 午前2:00〜8:00だ。この時間帯は三大市場のいずれも閉まっており、値動きはほぼ止まる。ところがスプレッドは逆に広がる。板が薄いから当然で、EAが発注しても希望値からずれた価格で約定するスリッページが常態化する。
スキャルピング系EAにとって、スプレッド2〜3pipの拡大は1回の取引の期待値をそのまま消し飛ばす。この時間帯の新規エントリーをカットするだけで、期待値が大幅に改善するケースは珍しくない。
指標発表前後のスパイクで損失を防ぐ
FOMC・米雇用統計・CPIなどの重要経済指標の発表前後は、スプレッドが数倍から十数倍に瞬間拡大する。約定はするが、スリッページが極端に大きくなるため、EAのロジックが前提にしているリスクリワードが完全に崩壊する。
対処の標準実装は発表5分前から新規エントリーを停止することだ。より慎重な設計では30分前から停止し、発表後3時間は稼働しないパラメーターを採用するケースもある。
ただし「いつ何の指標が発表されるか」をEA内部で自動判定するには外部カレンダーAPIとの連携が必要になる(後述の応用編を参照)。シンプルな実装では、指標が集中しやすい時間帯ごとEAを止める「時間ブロック型」フィルターの方が現実的だ。
週末・祝日のギャップリスク
金融機関が週末に市場を閉めている間も、地政学的イベントや要人発言は止まらない。その結果、月曜の始値が金曜の終値から大きくずれた「窓開け」が生じることがある。
ポジションを週末に持ち越したEAはこの窓開けをそのまま受ける。スキャルピング・デイトレード系のEAでは、金曜の深夜(サーバー時間で21:00前後)までにポジションをクローズし、新規エントリーも禁止するロジックが標準実装になっている。
年末年始(12月25日〜1月3日頃)も同様の流動性低下が発生し、窓開けリスクが通常より高くなる。この期間はEAを完全停止する運用が安全だ。
リスク注意: 金融庁は流動性リスクとして「スプレッドが広くなって意図した取引ができなくなったり」する可能性を公式サイトで説明している(出典: 金融庁 fsa.go.jp/ordinary/iwagai/)。時間帯フィルターはこのリスクを軽減する設計であるが、完全な排除はできない。実際の運用では自己責任で判断してほしい。
MQL4での時間帯フィルター設定方法
直接回答(「MQL4 時間帯フィルター コード 書き方」への回答): MQL4の時間帯フィルターはTimeHour(TimeCurrent())でサーバー時間の「時」を取得し、if (!IsTradeTime()) return;をOnTick()先頭に置くパターンで実装する。日付をまたぐ場合はStartHour > EndHourの条件分岐が必須。
Photo by Fotis Fotopoulos on Unsplash
Hour()関数と TimeHour(TimeCurrent()) の違い
MQL4でEAに時間帯フィルターを設定する際に使う主な関数は以下の2つだ。
Hour(): プログラム起動時点のサーバー時間の「時」を0〜23の整数で返す。実行中に値は更新されないため、OnTick()内での時間判定には不向きTimeHour(TimeCurrent()):TimeCurrent()で最新ティック時刻を取得し、TimeHour()でその「時」の部分を取り出す。OnTick()内で呼び出すたびに最新の時刻を返すため、時間帯フィルターに適しているDayOfWeek(): 曜日を0(日曜)〜6(土曜)で返す
前提として押さえておきたいのは、TimeCurrent()が返すのはブローカーのサーバー時間であって、日本時間ではないという点だ。ほとんどのブローカーはGMT+2(冬時間)またはGMT+3(夏時間)でサーバーを運用している。日本時間(GMT+9)との差は冬時間(GMT+2)で7時間、夏時間(GMT+3)で6時間——この変換を意識してパラメーターを設定することが、実装の第一のポイントになる。
例えば日本時間の午前2:00は、GMT+2のサーバーでは前日の17:00だ。ここを間違えると、フィルターが意図した通りに機能しない。
もう一点。Hour()はプログラム起動時の値で固定され、実行中に更新されない仕様だ。OnTick()ハンドラ内で常に最新の時刻を参照するにはTimeHour(TimeCurrent())を使う必要がある。MQL5ではTimeTradeServer()でよりシンプルに解決できる(後述)。
MQL4 時間帯フィルター コードサンプル(コピペ可)
以下のコードは実際に動作するMQL4の時間帯フィルター実装例だ。OnTick()の先頭でIsTradeTime()を呼び出し、falseが返ってきたら即座にリターンする構造を取る。
#property strict
input int StartHour = 3; // 取引開始時間(ブローカーサーバー時間)
input int EndHour = 21; // 取引終了時間(ブローカーサーバー時間)
input int FridayCloseHour = 21; // 金曜日の取引停止時間(サーバー時間)
// 時間フィルター判定関数
bool IsTradeTime() {
// 金曜日の指定時間以降は取引禁止
if (DayOfWeek() == 5 && TimeHour(TimeCurrent()) >= FridayCloseHour) {
return false;
}
int h = TimeHour(TimeCurrent()); // 最新ティック時刻からサーバー時間の「時」を取得
if (StartHour < EndHour) {
// 日付をまたがない場合(例: 3時〜21時)
return (h >= StartHour && h < EndHour);
} else {
// 日付をまたぐ場合(例: 22時〜翌6時)
return (h >= StartHour || h < EndHour);
}
}
// OnTick()内での使い方
void OnTick() {
if (!IsTradeTime()) {
return; // 取引時間外はエントリーしない
}
// 以下にエントリーロジックを記述
}
注意: このコードサンプルは動作の参考を示すものであり、動作を保証するものではありません。実際の取引への適用は自己責任で行ってください。バックテストで十分に検証した上で使用することを推奨します。
パラメーター化(外部から時間を変更できる設計)
上記コードではinput修飾子を使ってStartHour・EndHour・FridayCloseHourをパラメーター化している。MT4の「EAの設定」画面から時間を変えられるので、ソースコードを触らずに調整できる点が地味に便利だ。
StartHour < EndHourの条件分岐は、日付をまたぐフィルター(例: 22時〜翌6時の夜間稼働)に対応するために必須だ。この分岐がないと、例えばStartHour=22, EndHour=6と設定した場合、常にfalseが返ってしまう。
実際の運用では、ブローカーを変更するたびにサーバー時間のオフセットが変わる可能性がある。パラメーターを外部化しておけば、オフセットに合わせた再設定が容易になる——これは長期運用を前提にすると意外と大事な設計判断だ。
EAのバックテスト設定全般については「EAバックテストのスプレッド設定:適切な値の決め方と実務的な考え方」も合わせて参照してほしい。
MQL5での時間帯フィルター設定方法
直接回答(「MQL5 時間フィルター EA 実装」への回答): MQL5ではTimeTradeServer()でMqlDateTime構造体に時刻を格納し、timeStruct.hourとtimeStruct.day_of_weekを参照する。MQL4のTimeHour(TimeCurrent())と異なりティック到達を待たずにサーバー時刻を推定取得できるため、閑散時間帯でも正確な判定ができる。
MQL4との違い(TimeTradeServer()の扱い)
MQL5で時間帯フィルターを実装するとき、MQL4との最大の違いは**TimeTradeServer()関数の存在**だ。
MQL4のTimeCurrent()はティック受信時刻に依存する。対してMQL5のTimeTradeServer()はティックが届かない時間帯でも推定サーバー時刻を取得できる。つまり閑散時間帯でのフィルター判定の信頼性がMQL5の方が高いということだ。
MQL5では時刻情報をMqlDateTime構造体に格納して扱うスタイルが推奨される。hour・day_of_weekなどのメンバーに直接アクセスできるため、コードの可読性も上がる。
| 比較項目 | MQL4 | MQL5 |
|---|---|---|
| サーバー時間取得 | TimeHour(TimeCurrent()) | TimeTradeServer() |
| ティック依存 | あり(TimeCurrent()はティック依存) | なし(TimeTradeServer()はティック非依存) |
| GMT差取得 | 手動計算が必要 | TimeGMTOffset()で取得可能 |
| 時刻構造体 | なし(個別関数で取得) | MqlDateTime構造体でまとめて取得 |
MQL5 時間帯フィルター コードサンプル(コピペ可)
#property strict
input int InpStartHour = 3; // 取引開始時間(ブローカーサーバー時間)
input int InpEndHour = 21; // 取引終了時間(ブローカーサーバー時間)
input int InpFridayCloseHour = 21; // 金曜日の取引停止時間(サーバー時間)
// 時間フィルター判定関数(MQL5版)
bool IsTradeTime() {
MqlDateTime timeStruct;
TimeTradeServer(timeStruct); // ティックに依存しないサーバー時間を取得
int h = timeStruct.hour;
int dow = timeStruct.day_of_week; // 0=日曜, 1=月曜, ..., 5=金曜, 6=土曜
// 金曜日の指定時間以降は取引禁止
if (dow == 5 && h >= InpFridayCloseHour) {
return false;
}
if (InpStartHour < InpEndHour) {
return (h >= InpStartHour && h < InpEndHour);
} else {
return (h >= InpStartHour || h < InpEndHour);
}
}
// OnTick()内での使い方
void OnTick() {
if (!IsTradeTime()) {
return;
}
// エントリーロジック
}
MQL4版との構造上の違いはほぼIsTradeTime()の内部だけだ。パラメーター名にInpプレフィックスをつけているのはMQL5の慣習に合わせたもので、動作的な意味はない。
注意: このコードサンプルは動作の参考を示すものであり、動作を保証するものではありません。実際の取引への適用は自己責任で行ってください。
MQL5の時間フィルターをさらに深く学ぶ場合は「MQL5時間フィルターEA実装ガイド【セッション・夏冬時間完全対応】」も参照してほしい。夏冬時間(GMTオフセット変動)への対応方法まで解説している。
経済指標前後の自動停止フィルター設計
外部カレンダーAPIとの連携(応用編)
直接回答(「経済指標 前後 EA 停止 実装」への回答): MQL5ではCalendarValueHistory()でMT5ビルトインカレンダーを参照し、重要度CALENDAR_IMPORTANCE_HIGHのイベント前後30分・60分を動的に停止できる。MQL4では公式APIがないため、時間ブロック型の静的フィルターが現実的。
ここまでの実装は「決まった時間帯を除外する」静的なフィルターだ。より高度な実装として、経済指標カレンダーを取得して指標発表の前後だけEAを自動停止する動的フィルターがある。
MQL5ではCalendarValueHistory()関数が用意されており、MT5のビルトインカレンダーデータを参照できる。実装の概要は以下の通りだ。
// MQL5 組み込みカレンダー参照の骨格(簡略版)
bool IsHighImpactEventNear(int minutesBefore = 30, int minutesAfter = 60) {
MqlCalendarValue values[];
datetime from = TimeCurrent() - minutesBefore * 60;
datetime to = TimeCurrent() + minutesAfter * 60;
// 対象通貨のイベントを取得(例: USDとJPY)
if (CalendarValueHistory(values, from, to, "USD") > 0) {
for (int i = 0; i < ArraySize(values); i++) {
MqlCalendarEvent event;
if (CalendarEventById(values[i].event_id, event)) {
// 重要度が高いイベント(HIGH)のみフィルター
if (event.importance == CALENDAR_IMPORTANCE_HIGH) {
return true;
}
}
}
}
return false;
}
このアプローチのメリットは、指標発表がない日は通常通り稼働できる点だ。デメリットは、カレンダーデータの更新タイミングや予定外の臨時発表に対応できないこと、MT5専用の実装になることだ。
MQL4環境では公式のカレンダーAPIが存在しないため、外部のForex Factoryなどからテキストファイルを取得して読み込む実装が一般的だが、実装コストが高い。現実的な妥協点として「重要指標が多い時間帯(例: 米NY時間の主要指標は日本時間21:30が多い)を固定でブロックする」静的アプローチをベースにしつつ、手動でEAを止める運用ルールを組み合わせる方法が実用的だ。
バックテストで時間帯フィルターの効果を検証する方法
検証の前提条件
直接回答: 時間帯フィルターのバックテスト検証では「歴史データのタイムゾーン確認」「取引回数100回以上の確保」「アウトオブサンプル期間での検証」の3点が最重要チェック項目だ。
まず確認すべきことがある。
歴史データのタイムゾーン確認: ブローカーの歴史データはサーバー時間で記録されている。2015年以前の古いデータは日本時間で記録されているケースがあり、フィルターの時間帯が意図した通りに機能しない可能性がある。バックテスト環境とフィルターのサーバー時間が一致しているかを確認しておくこと。
取引回数の確保: 時間帯フィルターを追加するとエントリー回数が減る。統計的に意味のある結果を得るには最低100回以上の取引回数が必要だ。フィルターを厳しくしすぎて取引回数が20〜30回になってしまうと、バックテスト結果がノイズに支配される。
過剰最適化のリスク: 時間帯フィルターは過剰最適化が最も起きやすいパラメーターの一つだ。「3〜21時の稼働が最も成績が良かった」という結果は、特定の歴史データに過学習しているだけという可能性がある。アウトオブサンプル(最適化に使っていない期間)での検証が必須だ。
過剰最適化の一般論については「EAのカーブフィッティングとは?過剰最適化の見抜き方と回避手順を徹底解説」で詳しく解説している。
バックテスト比較の数値例
以下は参考として示す架空の数値例だ。実際の効果はEAのロジック・通貨ペア・期間によって大きく異なる。
| 設定 | 勝率 | プロフィットファクター | 最大ドローダウン | |---|---|---|---| | フィルターなし | 52% | 1.15 | 18% | | 深夜2:00〜8:00除外 | 55% | 1.32 | 12% | | 上記 + 金曜21時以降除外 | 57% | 1.41 | 10% |
免責: 上記の数値は過去の参考データに基づく例示であり、将来の運用成果を一切保証しません。FX取引には元本損失のリスクが伴います。
この例では深夜帯の除外によってプロフィットファクターが1.15から1.32に向上し、最大ドローダウンも18%から12%に改善している。ドローダウンの改善は「割に合わない負けトレードを削った」効果だが、取引回数が減っていることにも注意が必要だ。
検証の手順
- ベースラインを取る: フィルターなしで十分な期間(最低1年、理想は3〜5年)のバックテストを実施
- 単一フィルターを追加: まず深夜帯フィルターのみ追加して比較
- 金曜フィルターを追加: 次に金曜フィルターを加えて比較
- 取引回数を確認: 各ステップで100回以上の取引回数を維持しているか確認
- アウトオブサンプル検証: 最適化期間外のデータで同じフィルターを適用して結果を確認
バックテスト全体の設定方法・合格基準については「EA バックテスト やり方 完全解説|MT4/MT5 設定から合格基準の読み方まで」を参照してほしい。
Hedgrow FXで時間帯フィルター済みEAを試す
時間帯フィルターの実装・検証には相応の工数がかかる。ブローカーのサーバー時間の確認、パラメーターの調整、バックテストの繰り返し——これらをゼロから一人でこなすのは、正直かなり時間のかかる作業だ。
Hedgrow FXでは、時間帯フィルターを含む基本的なリスク管理ロジックが組み込まれたEAを提供している。深夜フィルター・金曜フィルター・重要指標前後の停止ロジックが設定済みの状態で使い始められる。
月額1,980円のサービス内で時間帯フィルターEA設定の無料サポートも受けられる。自分のEAに組み込む際のサーバー時間の確認作業や、バックテストの解釈についても対応しているので、実装詰まりのサポートとして活用してほしい。
FAQ
時間帯フィルターをつけるとバックテスト成績はどう変わる?
多くのケースでプロフィットファクターと最大ドローダウンが改善する。流動性が低い時間帯や指標発表前後のスプレッド拡大による「割に合わない負け」を除外できるためだ。ただし取引回数は減少するため、月間の絶対利益額は変わらないかむしろ下がる可能性がある。「勝率・PF・DDの改善」と「取引頻度の減少」はトレードオフの関係にある。バックテストで成績が改善しても過剰最適化の可能性があるため、アウトオブサンプル期間での検証を必ず行うこと。
金曜日の夜はEAを止めるべき?
スキャルピング・デイトレード系のEAは止めるべきケースが多い。週末ギャップのリスクはポジションを週末に持ち越すEAに限定されるため、全EAに一律に適用する必要はない。ただし金曜の閑散時間帯はスプレッドが拡大しやすく、エントリーの期待値が低下するため、新規エントリーを止めるだけでも効果がある。デフォルトでは金曜サーバー時間21:00以降を停止するパラメーター設定を推奨する。
MQL4のHour()はサーバー時間と日本時間、どちらを返す?
Hour()はブローカーのサーバー時間を返すが、プログラム起動時点の値で固定される。日本時間ではない。多くのブローカーはGMT+2(冬時間)またはGMT+3(夏時間)でサーバーを運用しており、日本時間(GMT+9)との差は冬時間で7時間、夏時間で6時間ある。OnTick()内で最新の時刻を参照するにはTimeHour(TimeCurrent())を使う必要があるため、口座を開設しているブローカーのサーバー時間を事前に確認しておくこと。
時間帯フィルターの過剰最適化を防ぐにはどうすればよい?
3つのアプローチが有効だ。第一に、パラメーターをきりのいい数字で固定する(例: 深夜2時〜8時は固定、1時30分〜7時45分のような細かい最適化はしない)。第二に、取引回数を100回以上維持してノイズに支配されない結果を確保する。第三に、アウトオブサンプル検証を必ず実施する——最適化に使った期間外のデータで同じパラメーターが有効かを確認することが最も重要だ。時間帯フィルターは直感的に「効きそう」に見えるだけに、過去データへの過学習に陥りやすい。流動性の論理的な根拠(深夜の閑散・週末ギャップ)があるフィルターに絞り込むことが過剰最適化を防ぐ基本姿勢だ。
MQL4とMQL5の時間帯フィルター、どちらを選ぶべき?
使用しているMT環境による。国内ブローカーでMT4口座を使っている場合はMQL4実装が現実的な選択肢だ。MT5環境ではMQL5のTimeTradeServer()が使えるため、ティック依存のない推定サーバー時刻の取得が可能で、閑散時間帯でのフィルター判定信頼性がMQL4より高い。新規からEAを開発するなら、MQL5を選んでおく方が後々の運用も楽になる。TimeGMTOffset()関数で夏冬時間のGMTオフセットを自動取得できるため、DST(夏時間)切り替えへの対応がコード上で完結する点もMQL5の優位点だ。
まとめ
FX EAの時間帯フィルター設定は、リスク管理において最もコスパが高い実装の一つだ。流動性が低い深夜帯・金曜の週末前・重要指標前後の3つを除外するだけで、バックテスト上のプロフィットファクターとドローダウンが改善するケースが多い。
実装のポイントをまとめておく。
TimeHour(TimeCurrent())(MQL4)・TimeTradeServer()(MQL5)はサーバー時間基準。日本時間との差(冬時間7時間・夏時間6時間)を必ず考慮するHour()はプログラム起動時点で固定されるため、OnTick()内ではTimeHour(TimeCurrent())を使うこと- 日付をまたぐフィルター(
StartHour > EndHourのケース)は条件分岐が必須 - パラメーターを
inputで外部化することで、サーバー時間変更やブローカー切替に柔軟に対応できる - バックテストでは取引回数100回以上を確保し、アウトオブサンプル検証を必ず実施する
- MQL5では
TimeTradeServer()でティック依存を解消し、CalendarValueHistory()で経済指標フィルターを動的に実装できる
免責事項: 本記事で紹介しているコードサンプル・バックテスト数値・運用方針はいずれも情報提供を目的としたものであり、特定の利益を保証するものではありません。FX取引はレバレッジにより証拠金を超える損失が生じる可能性があります(出典: 金融庁 fsa.go.jp/ordinary/iwagai/)。コードの動作保証は行っておらず、実際の取引への適用は自己責任で行ってください。バックテストの過去実績は将来の運用成果を一切保証しません。
