「米雇用統計が発表された瞬間、スプレッドが異常に広がって、EAが不利な価格で約定した」

という経験はないでしょうか。

経済指標の発表前後は、レートが数秒で大きく動きます。

通常のロジックのまま自動売買を続けると、意図しないタイミングでエントリーしてしまいます。

MQL5には、このタイミング判定に使える経済指標カレンダー機能が、

標準で組み込まれています。

この記事では、`CalendarValueHistory`関数で、

指標発表の日時と重要度を取得し、

「重要度の高い指標が近いときだけ新規エントリーを止める」判定関数を作る方法を、

実際に動くコードで解説します。

MQL5の経済指標カレンダー機能とは

MQL5には`Calendar`系の関数群があり、

MetaTrader 5が保持している経済指標カレンダーのデータに、

プログラムから直接アクセスできます。

MQL4にはこの機能自体が存在せず、外部のWebRequestや、

手動での指標カレンダー確認に頼るしかありませんでした。

CalendarValueHistoryで期間内の指標を取得する

指定した期間内に発表される(された)指標の一覧を取得するのが、

`CalendarValueHistory`です。

bool CalendarValueHistory(
   MqlCalendarValue& values[],       //取得結果を受け取る配列
   datetime          datetime_from,  //期間の開始
   datetime          datetime_to=0,  //期間の終了(省略可)
   const string      country_code=NULL,  //国コード(空欄で全部)
   const string      currency=NULL       //通貨コード(空欄で全部)
   );

戻り値は取得の成否で、

実際のデータは第1引数の`MqlCalendarValue`配列に格納されます。

補足: MqlCalendarValueには、

actual_valueやforecast_value等のメンバーがあります。

これらの数値は、実際の値の1,000,000倍で格納されています。

桁を戻さずに比較すると、期待した結果になりません。

この記事のサンプルでは数値そのものは使わず、

発表の有無や重要度だけを判定に使うため影響しません。

CalendarEventByIdで重要度(importance)を調べる

`MqlCalendarValue`には指標の名前や重要度が直接入っていないため、

`event_id`を使って`CalendarEventById`から詳細情報を引きます。

bool CalendarEventById(
   ulong              event_id,  //イベントID
   MqlCalendarEvent& event      //イベントの説明を受け取る変数
   );

`MqlCalendarEvent`の`importance`メンバーは、

`ENUM_CALENDAR_EVENT_IMPORTANCE`型です。

次の4段階があります。

値 意味
CALENDAR_IMPORTANCE_NONE 重要度未設定
CALENDAR_IMPORTANCE_LOW 低重要度
CALENDAR_IMPORTANCE_MODERATE 中程度の重要度
CALENDAR_IMPORTANCE_HIGH 高重要度(雇用統計・政策金利など)

「直近N分以内に高重要度指標があるか」を判定する関数を作る

やりたいことは、現在時刻の前後一定時間以内に、

`CALENDAR_IMPORTANCE_HIGH`の指標が含まれるかどうかの判定です。

この1つの判定関数さえ作れば、既存のEAのエントリー処理の先頭に、

1行足すだけで指標対策を組み込めます。

設計思想: エントリー判定と指標判定を分離する

指標判定のロジックをエントリーロジックの中に混ぜ込むと、

後から時間幅を変えたり判定条件を増やしたりするたびに、

EA全体を読み直す必要が出てきます。

判定を独立した関数に切り出しておけば、他のEAにもそのまま流用できます。

bool IsNearHighImpactEvent(int windowMinutes)
  {
   MqlCalendarValue values[];
   datetime from = TimeCurrent() - windowMinutes * 60;
   datetime to   = TimeCurrent() + windowMinutes * 60;

   if(!CalendarValueHistory(values, from, to, NULL, NULL))
     {
      Print("CalendarValueHistoryに失敗しました。error=", GetLastError());
      return(false);
     }

   for(int i = 0; i < ArraySize(values); i++)
     {
      MqlCalendarEvent event;
      if(!CalendarEventById(values[i].event_id, event))
         continue;
      if(event.importance == CALENDAR_IMPORTANCE_HIGH)
        {
         Print("高重要度指標が近い: ", event.name);
         return(true);
        }
     }
   return(false);
  }

実際に動くコード全体(高重要度指標の前後だけエントリーを止めるEA)

上の判定関数を組み込んだ、実際にMetaEditorでコンパイルできるEAの全体です。

//+------------------------------------------------------------------+
//|                                CalendarNewsFilterEA.mq5           |
//|                     Copyright 2026, FX-EA System Project Creator |
//|                        https://creator.fx-ea-system-project.com/ |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, FX-EA System Project Creator"
#property link      "https://creator.fx-ea-system-project.com/"
#property version   "1.00"

input int    NewsWindowMinutes = 30;    //指標発表の前後、止める時間(分)
input double LotSize           = 0.10;

//+------------------------------------------------------------------+
//| 直近NewsWindowMinutes分以内に高重要度指標があるか判定する            |
//+------------------------------------------------------------------+
bool IsNearHighImpactEvent(int windowMinutes)
  {
   MqlCalendarValue values[];
   datetime from = TimeCurrent() - windowMinutes * 60;
   datetime to   = TimeCurrent() + windowMinutes * 60;

   if(!CalendarValueHistory(values, from, to, NULL, NULL))
     {
      Print("CalendarValueHistoryに失敗しました。error=", GetLastError());
      return(false);
     }

   for(int i = 0; i < ArraySize(values); i++)
     {
      MqlCalendarEvent event;
      if(!CalendarEventById(values[i].event_id, event))
         continue;
      if(event.importance == CALENDAR_IMPORTANCE_HIGH)
        {
         Print("高重要度指標が近い: ", event.name);
         return(true);
        }
     }
   return(false);
  }

//+------------------------------------------------------------------+
//| Expert tick function                                              |
//+------------------------------------------------------------------+
void OnTick()
  {
   if(PositionsTotal() > 0)
      return; //保有中は何もしない(この記事の主題はエントリー抑制のため)

   if(IsNearHighImpactEvent(NewsWindowMinutes))
      return; //指標発表の前後はエントリーしない

   MqlTradeRequest request = {};
   MqlTradeResult  result  = {};

   request.action    = TRADE_ACTION_DEAL;
   request.symbol    = _Symbol;
   request.volume    = LotSize;
   request.type      = ORDER_TYPE_BUY;
   request.price     = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
   request.deviation = 10;

   if(!OrderSend(request, result))
      Print("OrderSendに失敗しました。retcode=", result.retcode);
  }

注意: このサンプルは判定ロジックの見せ方に絞った最小構成です。

実運用では、損切りや利益確定、ロット管理などの実装を別途組み込んでください。

MetaEditorで実際に動かす手順

  1. MetaEditorで「ファイル」→「新規作成」→「エキスパートアドバイザー」で「CalendarNewsFilterEA」を作成する
  2. ウィザードの中身を削除し、上のコードを丸ごと貼り付ける
  3. F7キーでコンパイルし、「0 error(s), 0 warning(s)」になることを確認する
  4. デモ口座のチャートに適用し、「エキスパート」タブに「高重要度指標が近い」のログが指標発表前後だけ出るか確認する

よくあるエラーと注意点

実際にコンパイル・実行してみると、つまずきやすいポイントが2つあります。

CalendarValueHistoryがfalseを返す・空配列になる

端末の経済指標カレンダーのデータが、未取得の状態だと空になることがあります。

一度MetaTrader 5の「ツール」メニューから「オプション」

→「経済指標カレンダー」を開き、データが表示されるか確認してください。

重要度の判定が甘い・厳しいと感じる

`CALENDAR_IMPORTANCE_HIGH`だけでなく、

`CALENDAR_IMPORTANCE_MODERATE`以上も止めたい場合は、

比較演算子を`>=`に変えれば範囲を広げられます。

要点: MQL4にはCalendar系の関数が存在しません。

同じ判定をしたい場合は、

WebRequestで外部の指標カレンダーAPIを呼ぶなど別の実装が必要になります。

MQL5だけで完結できる点が、明確な違いです。

よくある質問

CalendarValueHistoryの実装でよく検索されている疑問を、

3つにまとめて回答します。

通貨ペアごとに関係ある国の指標だけに絞れますか?

`CalendarValueHistory`の第4・第5引数に、

国コード・通貨コードを渡せば絞り込めます。

たとえばUSD関連だけにしたい場合は、`currency`に”USD”を渡してください。

指標カレンダーのデータはどこから来ていますか?

MetaTrader 5端末が定期的に取得・キャッシュしている、

経済指標カレンダーのデータです。

ブローカーやMetaQuotes側のサーバーから配信されています。

プログラム側で独自にデータを用意する必要はありません。

ポジション保有中に指標発表をまたいでも大丈夫ですか?

この記事の判定関数は、新規エントリーを止める用途のみです。

保有中のポジションをどう扱うかは、

別のロジック(強制決済・損切り幅の拡大等)として設計する必要があります。

【MQL5】経済指標発表の前後だけEAを止めたい?CalendarValueHistoryで指標発表時刻を取得する方法:まとめ

MQL5に標準搭載されている経済指標カレンダー機能を使えば、

`CalendarValueHistory`と

`CalendarEventById`の組み合わせだけで、

「重要度の高い指標が近いか」を

判定できます。

判定ロジックを独立した関数として切り出しておけば、既存のEAのエントリー処理の先頭に、

1行足すだけで指標対策を組み込めます。

MQL4にはこの機能自体が存在しない、MQL5ならではの差別化ポイントです。

関連記事