English Deutsch
preview
MQL5経済指標カレンダーを使った取引(第1回):MQL5経済指標カレンダーの機能をマスターする

MQL5経済指標カレンダーを使った取引(第1回):MQL5経済指標カレンダーの機能をマスターする

MetaTrader 5トレーディング | 29 1月 2025, 10:16
170 0
Allan Munene Mutiiria
Allan Munene Mutiiria

はじめに

この記事では、MetaQuotes Language 5 (MQL5)の経済指標カレンダーが持つ強力な機能と、それをアルゴリズム取引に統合する方法について解説します。MetaTrader 5取引端末に組み込まれている経済指標カレンダーは、金融市場の動向に大きな影響を与え得る重要なニュースや経済データを提供する、トレーダーにとって不可欠なツールです。この情報の取得方法と解釈の仕方を理解することで、経済イベントによる市場の反応を予測し、それに基づいて取引戦略を最適化できるようになります。

まず、MQL5経済指標カレンダーの概要を説明し、その主要な構成要素と仕組みについて解説します。次に、MQL5での具体的な実装方法に焦点を当て、ニュースイベントにプログラムからアクセスし、チャート上に表示する方法を紹介します。最後に、得られた知見を整理し、経済指標カレンダーを取引システムに組み込むメリットをまとめます。この記事の構成は以下のとおりです。

  1. MQL5経済指標カレンダーの概要
  2. MQL5での実装
  3. 結論

この記事を読み終えるころには、MQL5経済指標カレンダーを活用したエキスパートアドバイザー(EA)を開発し、取引戦略を強化するための知識が身についているでしょう。では、さっそく始めましょう。


MQL5経済指標カレンダーの概要

MQL5経済指標カレンダーは、金融市場に大きな影響を与える可能性のある主要な経済イベントに関する、最新かつ信頼性の高い情報を提供する優れたツールです。MetaTrader 5に標準搭載されているため、簡単にアクセスでき、非常に便利です。

このカレンダーには、金融市場に影響を及ぼす可能性のある様々な経済イベントが掲載されています。たとえば、政策金利の発表、インフレに関するレポート、国内総生産(GDP)指標、雇用統計などが含まれます。 これらの指標は、特に通貨・コモディティ・株式市場において、市場の動向を大きく左右する要因となるため、短期トレーダーにも長期トレーダーにも欠かせないツールです。

カレンダーを開くには、タスクバーに移動して[表示]を選択し、[ツールボックス]を選択します。以下に、実際の表示例を示します。

ツールボックスを開く

ツールボックスウィンドウが開いたら、[カレンダー]タブに移動してクリックします。カレンダーウィンドウが開き、以下のような内容が表示されます。

カレンダーを開く

さて、MQL5経済指標カレンダーには、市場に影響を与える今後の経済イベントが、予想される影響度順に整理されて掲載されていることは注目に値します。それぞれのイベントは、「low」「medium」「high」という明確なラベルで影響度が分類されており、どのイベントが特に重要で、どのイベントの影響が小さいのかを直感的に把握することができます。また、カレンダーでは通貨ごとにイベントをフィルタリングできるため、自分の取引に関係のあるニュースだけを確認することが可能です。イベントは影響度ごとに整理・色分けされており、情報量が多すぎて圧倒されることはありません。このフィルタリング機能のおかげで、トレーダーは不要なデータに惑わされることなく、取引戦略や保有ポジションに直接影響を与えるニュースに集中できるのです。

MQL5経済指標カレンダーの大きな利点のひとつは、MQL5と統合されていることです。これにより、トレーダーは経済データにプログラム上でアクセスし、それをEAや自動売買システムに組み込むことができます。MQL5の定義済み関数を活用すると、イベント名・発表予定時刻・対象国・予測値・実際の結果といったデータを取得できます。この機能により、トレーダーは、ボラティリティを回避するためにポジションを自動決済したり、予測データに基づいて新規取引を開始したり、ストップロスやテイクプロフィットのレベルを動的に調整したりするなど、主要なニュースイベントに自動的に反応するシステムを開発できます。このような高度な自動化により、トレーダーは手動対応を最小限に抑えつつ、最新の経済ニュースに即座に反応できるようになります。最後に、MQL5経済指標カレンダーの主要機能をまとめた詳細な視覚的な説明を以下に示します。

カレンダーデータ

画像から、データ表現には8つの列があることがわかります。1番目にはイベントの時刻、2番目には通貨記号、3番目にはイベント名、4番目にはニュースの重要度(優先度)、5番目にはデータの対象期間が含まれ、6番目、7番目、8番目にはそれぞれ実際のデータ、予測データ、前回のデータまたは修正データが表示されます。

もちろん、トレーダーにとってすべてのデータが重要というわけではなく、不必要なデータを除外するために4つの方法でフィルタリングが可能です。1つ目は時間によるフィルタリングで、例えばすでに発表されたデータに興味がない場合に使用できます。2つ目は通貨によるフィルタリングで、特定の通貨に関連するニュースのみを表示できます。3つ目は国によるフィルタリングで、例えば「AUDUSD」ペアを取引している場合、オーストラリアまたは米国に直接影響を与えるニュースが最も重要となるため、中国のニュースはこのペアには大きな影響を与えないと考えられます。

最後に、重要度フィルタを使用すると、ニュースを影響度に応じて整理できます。フィルタを適用するには、カレンダーフィールド内を右クリックし、適切なフィルタを選択します。これを再度以下に示します。

フィルタの適用

したがって、MQL5経済指標カレンダーを使用することで、トレーダーは影響の大きい市場イベントに備えて、より適切な取引計画を立てることができます。これは、MetaTrader 5でカレンダーを手動で確認する方法と、カレンダーのデータを活用する自動取引戦略を用いる方法のどちらでも可能です。この仕組みにより、MQL5経済指標カレンダーの役割を明確に理解し、それをMetaTrader 5の取引システムに組み込んで、より明確な取引と戦略を実現する方法を把握できるようになります。


MQL5での実装

EAを作成するには、MetaTrader 5端末で[ツール]タブをクリックし、[MetaQuotes言語エディタ]を選択するか、キーボードのF4を押します。または、ツールバーのIDE(統合開発環境)アイコンをクリックすることもできます。これにより、MetaQuotes言語エディタ環境が開き、取引ロボット、テクニカルインジケーター、スクリプト、関数のライブラリを作成できるようになります。

MetaEditorを開く

MetaEditorを開いたら、ツールバーの[ファイル]タブで[新しいファイル]を選択するか、CTRL + Nキーを押して新規ドキュメントを開きます。または、[ツール]タブの新規アイコンをクリックすることもできます。MQLウィザードのポップアップが表示されます。

新しいEAを作成

ウィザードが表示されたら、[EA(テンプレート)]を選択し、[次へ]をクリックします。

MQLウィザード

EAの一般プロパティで、[名前]フィールドにEAのファイル名を入力します。フォルダが存在しない場合にフォルダを指定または作成するには、EA名の前にバックスラッシュを使用することに注意してください。例えば、ここではデフォルトで「Experts\」となっています。つまり、私たちのEAはExpertsフォルダに作成され、そこで見つけることができます。他のフィールドはごく簡単ですが、ウィザードの一番下にあるリンクから、正確な手順を知ることができます。

新しいEA名

希望するEAファイル名を入力した後、[次へ]をクリックし、[完了]をクリックします。ここまでくれば、あとはコードを書いて戦略をプログラムするだけです。

まず、EAに関するメタデータを定義することから始めます。これには、EA名、著作権情報、MetaQuotes Webサイトへのリンクが含まれます。EAのバージョンも指定し、1.00とします。

//+------------------------------------------------------------------+
//|                                    MQL5 NEWS CALENDAR PART 1.mq5 |
//|      Copyright 2024, ALLAN MUNENE MUTIIRIA. #@Forex Algo-Trader. |
//|                                     https://forexalgo-trader.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, ALLAN MUNENE MUTIIRIA. #@Forex Algo-Trader"
#property link      "https://forexalgo-trader.com"
#property description "MQL5 NEWS CALENDAR PART 1"
#property version   "1.00"

この時点で、まず理解すべきなのは、経済指標カレンダーを操作するための構造体です。これには3つの構造体があります。国説明を設定するMqlCalendarCountry、イベント説明を設定するMqlCalendarEvent、イベント値を設定するMqlCalendarValueです。それぞれの構造体の詳細は以下の通りです。

カレンダーの国の構造体

struct MqlCalendarCountry 
  { 
   ulong                               id;                    // country ID (ISO 3166-1) 
   string                              name;                  // country text name (in the current terminal encoding) 
   string                              code;                  // country code name (ISO 3166-1 alpha-2) 
   string                              currency;              // country currency code 
   string                              currency_symbol;       // country currency symbol 
   string                              url_name;              // country name used in the mql5.com website URL 
  };

カレンダーイベントの構造体

struct MqlCalendarEvent 
  { 
   ulong                               id;                    // event ID 
   ENUM_CALENDAR_EVENT_TYPE            type;                  // event type from the ENUM_CALENDAR_EVENT_TYPE enumeration 
   ENUM_CALENDAR_EVENT_SECTOR          sector;                // sector an event is related to 
   ENUM_CALENDAR_EVENT_FREQUENCY       frequency;             // event frequency 
   ENUM_CALENDAR_EVENT_TIMEMODE        time_mode;             // event time mode 
   ulong                               country_id;            // country ID 
   ENUM_CALENDAR_EVENT_UNIT            unit;                  // economic indicator value's unit of measure 
   ENUM_CALENDAR_EVENT_IMPORTANCE      importance;            // event importance 
   ENUM_CALENDAR_EVENT_MULTIPLIER      multiplier;            // economic indicator value multiplier 
   uint                                digits;                // number of decimal places 
   string                              source_url;            // URL of a source where an event is published 
   string                              event_code;            // event code 
   string                              name;                  // event text name in the terminal language (in the current terminal encoding) 
  };

カレンダー値の構造体

struct MqlCalendarValue 
  { 
   ulong                               id;                    // value ID 
   ulong                               event_id;              // event ID 
   datetime                            time;                  // event date and time 
   datetime                            period;                // event reporting period 
   int                                 revision;              // revision of the published indicator relative to the reporting period 
   long                                actual_value;          // actual value multiplied by 10^6 or LONG_MIN if the value is not set 
   long                                prev_value;            // previous value multiplied by 10^6 or LONG_MIN if the value is not set 
   long                                revised_prev_value;    // revised previous value multiplied by 10^6 or LONG_MIN if the value is not set 
   long                                forecast_value;        // forecast value multiplied by 10^6 or LONG_MIN if the value is not set 
   ENUM_CALENDAR_EVENT_IMPACT          impact_type;           // potential impact on the currency rate 
  //--- functions checking the values 
   bool                         HasActualValue(void) const;   // returns true if actual_value is set 
   bool                         HasPreviousValue(void) const; // returns true if prev_value is set 
   bool                         HasRevisedValue(void) const;  // returns true if revised_prev_value is set 
   bool                         HasForecastValue(void) const; // returns true if forecast_value is set 
  //--- functions receiving the values 
   double                       GetActualValue(void) const;   // returns actual_value or nan if the value is no set 
   double                       GetPreviousValue(void) const; // returns prev_value or nan if the value is no set 
   double                       GetRevisedValue(void) const;  // returns revised_prev_value or nan if the value is no set 
   double                       GetForecastValue(void) const; // returns forecast_value or nan if the value is no set 
  };

まず最初におこなうべきことは、選択した時間範囲内で利用可能なすべての値を収集し、これまでに確認した8つの値ごとに整理し、さらにフィルターを適用することです。値を取得するために、次のロジックを適用します。

MqlCalendarValue values[];
datetime startTime = TimeTradeServer() - PeriodSeconds(PERIOD_D1);
datetime endTime = TimeTradeServer() + PeriodSeconds(PERIOD_D1);

int valuesTotal = CalendarValueHistory(values, startTime, endTime, NULL, NULL);

Print("TOTAL VALUES = ", valuesTotal, " || Array size = ", ArraySize(values));

ここでは、MqlCalendarValue構造体型のvaluesという配列を宣言し、MQL5経済指標カレンダーから取得したデータを保持します。次に、データ抽出の時間範囲を定義するため、startTimeとendTimeという2つのdatetime型の変数を設定します。開始時刻は、TimeTradeServer関数を使用して現在のサーバー時刻を取得し、PeriodSeconds関数を用いて24時間のオフセットを計算することで、サーバー時刻の1日前に設定されます。この1日の時間範囲は、PERIOD_D1定数を使用することで実現されます。同様に、endTimeはサーバー時刻の1日後に設定され、現在を中心に2日間の経済イベントを取得できるようになります。

次に、CalendarValueHistory関数を用いて、指定した時間範囲内の経済イベントをvalues配列に格納します。この関数は取得したイベントの総数を返し、その値をvaluesTotal変数に格納します。CalendarValueHistoryのパラメータには、values配列、startTime、endTimeのほか、国と通貨タイプの2つのNULLフィルタが含まれます(ここではすべてのイベントを取得するためにNULLのままにします)。最後に、Print関数を使用して取得したイベントの総数を出力し、さらにArraySize関数で配列のサイズを確認することで、配列に期待するデータが正しく格納されていることを検証します。これをコンパイルすると、次のような出力が得られます。

値の確認

次に、これらの値をログに出力して、何があるかを確認します。

if (valuesTotal >=0 ){
   Print("Calendar values as they are: ");
   ArrayPrint(values);
}

ここでは、まずvaluesTotalの値が0以上であるかを確認します。これは、CalendarValueHistory関数が経済指標カレンダーのイベントを正常に取得したか、あるいはエラーなくゼロを返したことを示します。この条件が満たされると、Print関数を使用して「Calendar values as they are:」というメッセージを出力し、続くデータのヘッダーとして機能させます。その後、ArrayPrint関数を呼び出し、values配列の全内容をログに出力します。実行すると、次のデータが得られます。

イベントログ

画像から、選択した時間枠内のすべてのイベントがログに記録されていることがわかります。ただし、イベントの特徴は数値のみで表されており、これは特定の特徴識別子として機能するものの、直接的な情報をほとんど提供していません。したがって、特定の値を選択し、そこから各イベントの詳細な特徴を構造化された方法で取得する必要があります。つまり、選択された各値をループ処理して詳細情報を取得する必要があるということです。

for (int i = 0; i < valuesTotal; i++){

//---

}

ここでは、経済指標カレンダーデータを保持するvalues配列の各要素を反復処理するforループを作成します。ループは、開始インデックスを表す整数変数「i」をゼロに初期化し、「i」が合計値(CalendarValueHistory関数によって取得されたイベントの合計数)より小さい限り実行されます。各反復で、「i」を1ずつ増やし、values配列内の各経済イベントに順番にアクセスできるようにします。ループ内では、各イベントのデータを処理または分析できるようになり、イベントのフィルタリング、イベントの詳細に基づいた特定の取引ロジックの適用、個々のイベント情報の出力などのタスクに柔軟性がもたらされます。使用する必要があるロジックは次のとおりです。

MqlCalendarEvent event;
CalendarEventById(values[i].event_id,event);

特定の経済イベントの詳細情報を格納する、MqlCalendarEvent型の変数eventを宣言します。次に、2つのパラメータを渡してCalendarEventByIdを呼び出します。最初のパラメータは、現在の経済イベントの一意のIDをvalues配列から取得します(現在のループインデックスiに基づきます)。一方、2番目のeventは、イベントの完全な詳細を格納するコンテナとして機能します。CalendarEventById関数を使用すると、各特定のイベントの名前、国、予測、実際の値などの包括的なデータにアクセスし、追加の分析や取引の決定に使用できます。これを確認するには、次のようにイベントIDを出力します。

Print("Event ID ",values[i].event_id);

ただし、これではログに出力されるデータが多すぎるため、選択する時間範囲を現在の時刻の前後1時間に減らしましょう。変更する必要があるのは、期間セクションのみです。参照しやすいように黄色で強調表示しています。

datetime startTime = TimeTradeServer() - PeriodSeconds(PERIOD_H1);
datetime endTime = TimeTradeServer() + PeriodSeconds(PERIOD_H1);

プログラムを実行すると、次の出力が得られます。

イベントID

ここで、イベント値の数字以外の、選択した特定のイベントの実際の値を取得することができます。これを実現するには、イベントキーワードを入力し、「ドット演算子」を使用して、そのクラスまたは構造体のすべてのメソッドとオブジェクトにアクセスするだけです。得るべきものは次のとおりです。

ドット演算子

同じ方法を使用して、作成したevent構造体に入力して保存したすべての情報を取得できます。

Print("Event ID ",values[i].event_id);
Print("Event Name = ",event.name);
Print("Event Code = ",event.event_code);
Print("Event Type = ",event.type);
Print("Event Sector = ",event.sector);
Print("Event Frequency = ",event.frequency);
Print("Event Release Mode = ",event.time_mode);
Print("Event Importance = ",EnumToString(event.importance));
Print("Event Time = ",values[i].time);
Print("Event URL = ",event.source_url);

Comment("Event ID ",values[i].event_id,
        "\nEvent Name = ",event.name,
        "\nEvent Code = ",event.event_code,
        "\nEvent Type = ",event.type,
        "\nEvent Sector = ",event.sector,
        "\nEvent Frequency = ",event.frequency,
        "\nEvent Release Mode = ",event.time_mode,
        "\nEvent Importance = ",EnumToString(event.importance),
        "\nEvent Time = ",values[i].time,
        "\nEvent URL = ",event.source_url);
}

ここでは、Print関数を使用して、値配列内の各経済イベントの詳細を出力し、この情報を[エキスパート]タブに表示して簡単に確認できるようにします。まず、イベントを一意に識別するイベントIDをvalues[i]から出力します。次に、イベントの名前、イベントコード、タイプ、セクター、頻度、時間モード(リリースタイミングモードを示す)、重要度(EnumToString関数を使用して読み取り可能な文字列に変換される)、実際のスケジュールされた時間など、イベントに関する特定の詳細をevent変数から取得して出力します。最後に、詳細情報へのリンクを提供するソースUniform Resource Locator (URL)を出力します。

これらのprint文に加えて、Comment関数を使用して、同じ詳細をチャートに表示し、すぐに参照できるようにします。Comment関数は、チャートのコメント領域内に各行を出力するため、トレーダーはチャート上で直接リアルタイムの更新を簡単に確認できるようになります。プログラムを実行すると、次の出力が得られます。

ID別イベントデータ

うまくいきました。国と通貨のデータにアクセスするために、国の値を処理する別の構造体を組み込みます。採用する必要があるロジックは次のとおりです。これは、使用した他のロジックと同じです。

MqlCalendarCountry country;
CalendarCountryById(event.country_id,country);

ここでは、経済イベントに関連する国固有の情報を格納するために、MqlCalendarCountry型の変数countryを宣言します。次に、CalendarCountryById関数を使用して、2つのパラメータを渡すことで国の詳細を取得します。

最初のパラメータは、現在の経済イベントに関連付けられた国の一意の識別子を提供しますが、countryパラメータはこの国のデータのコンテナとして機能します。CalendarCountryById関数を呼び出すことで、変数countryに国名、コード、その他の特性などの関連情報が入力され、このデータをよりコンテキストを意識した分析に使用したり、各経済イベントとともに国固有の詳細を表示したりできるようになります。

これを表示するには、国情報を再度出力します。

Print("Country ID ",country.id);
Print("Country Name ",country.name);
Print("Country Code ",country.code);
Print("Country Currency ",country.currency);
Print("Country Currency Symbol ",country.currency_symbol);
Print("Country URL ",country.url_name);

プログラムを実行すると、次の結果が表示されます。

国別データ

うまくいきました。これで、カレンダーデータにアクセスするために必要なMQL5の関数が完全に紹介されました。これで、コードブロックにフィルタを適用して、特定の国のデータ、優先データ、通貨、時間固有のニュースを通常どおり取引できるようになります。これを動的に実現するには、前述の目的に使用できる関数にロジックをシフトします。

//+------------------------------------------------------------------+
//|       FUNCTION TO GET NEWS EVENTS                                |
//+------------------------------------------------------------------+
bool isNewsEvent(){
   int totalNews = 0;
   bool isNews = false;
   
   //---
   
   return (isNews);
}

利用可能な経済ニュースイベントがあるかどうかを判断するブール関数isNewsEventを定義します。この関数は、ニュースイベントが存在する(true)か存在しない(false)かを示すbool値を返します。関数内で、整数変数totalNewsを宣言し、それをゼロに初期化します。この変数を使用して、関数内で後で取得する関連ニュースイベントの合計数を格納します。また、bool変数isNewsを宣言し、それをfalseに設定します。この変数はフラグとして機能し、関数の実行中に関連するニュースイベントが検出されるとtrueに切り替わります。

現在、この関数は単にisNewsの値を返します。この値は、関数内でまだニュースイベントが処理されていないため、デフォルトではfalseです。この関数構造は、後でニュースイベントを取得して確認し、イベントが検出された場合はisNewsをtrueに設定できるロジックを実装するための基盤を提供します。この関数に、OnInitイベントハンドラから以前に定義したロジックを追加します。ただし、関数のロジックに影響を与えるには、イベントハンドラーで関数を呼び出します。

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit(){
//---   
   if (isNewsEvent()){
      Print("______ ALERT: WE HAVE NEWS EVENT ___");
   }
   else if (isNewsEvent()==false){
      Print("______ ALERT: WE DON'T ANY HAVE NEWS EVENT ___");
   }
//---
   return(INIT_SUCCEEDED);
}

ここでは、OnInitイベントハンドラ内で、isNewsEvent関数を呼び出すことから始めます。関数がtrueを返してニュースイベントが利用可能であることを示している場合、ifブロックがトリガーされ、「______ ALERT:WE HAVE NEWS EVENT ___」というメッセージが出力されます。このメッセージは、経済ニュースイベントが検出されたことを警告するもので、必要に応じて取引戦略を調整するために使用できます。

falseが返された場合、つまりニュースイベントが存在しない場合には、else ifブロックがトリガーされ、「______ ALERT:WE DON'T HAVE ANY NEWS EVENT ___」が出力されます。このメッセージは、現在ニュースイベントが特定されていないことを警告しており、ニュースによる予想される混乱なしに取引が続行される可能性があることを示している可能性があります。最後に、関数はEAの初期化が成功したことを示す定数INIT_SUCCEEDEDを返します。さて、このイベントハンドラーの呼び出しの後、私たちにとって重要な種類のニュースにフィルタを適用し続けることができます。現在、このプログラムは「AUDUSD」銘柄に添付されています。米国のニュースのみが考慮されるようにするためのロジックを開発しましょう。

string currency_filter = "USD";
string currency_base = SymbolInfoString(_Symbol,SYMBOL_CURRENCY_BASE);
string currency_quote = StringSubstr(_Symbol,3,3);
if (currency_base != currency_filter && currency_quote != currency_filter){
   Print("Currency (",currency_base," | ",currency_quote,
         ") is not equal equal to ",currency_filter);
   return false;
}

まず、現在の銘柄が指定された通貨フィルタ「USD」に関連しているかどうかを確認しやすくするために、「currency_filter」と「currency_base」という2つの文字列変数を定義します。変数currency_filterは、監視対象の通貨を表す値「USD」で初期化されます。次に、SymbolInfoString関数を使用して現在の銘柄の基本通貨(例:AUDUSDペアのAUD)を取得し、それをcurrency_baseに保存します。

次に、currency_quoteを定義し、クオート通貨に直接アクセスする方法がないため、StringSubstr関数を使用して最後の3文字を取得して、現在の銘柄からクオート通貨を抽出します。たとえば、AUDUSDペアでは、StringSubstr関数はクオート通貨であるUSDを取得します。

次に、ベース通貨とクオート通貨の両方がフィルタ通貨と異なるかどうかを確認します。対象通貨フィルタ(この場合はUSD)と一致しない場合は、銘柄の通貨が通貨フィルタと一致しないことを示すメッセージを出力します。関数はfalseを返し、銘柄が指定された通貨に無関係である場合はそれ以上の処理を事実上終了します。これを別の銘柄で実行すると、次の出力が得られます。

通貨フィルタ

視覚化から、プログラムを「AUDUSD」および「USDJPY」チャートにロードするとエラーは発生しませんが、「EURJPY」チャートにロードするとエラーが発生し、どちらの通貨桁も定義済みのフィルタ通貨と一致しないことがわかります。イベントの重要度と時間に応じて、複数のフィルタを動的に適用し続けることができるようになりました。

if (StringFind(_Symbol,country.currency) >= 0){
   if (event.importance == CALENDAR_IMPORTANCE_MODERATE){
      if (values[i].time <= TimeTradeServer() && values[i].time >= timeBefore){
         Print(event.name," > ", country.currency," > ", EnumToString(event.importance)," Time= ",values[i].time," (ALREADY RELEASED)");
         totalNews++;
      }
            
      if (values[i].time >= TimeTradeServer() && values[i].time <= timeAfter){
         Print(event.name," > ", country.currency," > ", EnumToString(event.importance)," Time= ",values[i].time," (NOT YET RELEASED)");
         totalNews++;
      }
   }
}

特定の通貨に関連するニュースイベントを識別するために、一連のネストされた条件を実装し、「中程度の重要性」として分類され、特定の時間範囲内にあるイベントに重点を置きます。まず、現在の取引銘柄の名前(_Symbolで表される)に、イベントに関連付けられた通貨が含まれているかどうかを確認します。これは、StringFind関数を使用しておこないます。これにより、取引銘柄の通貨に関連付けられたイベントのみが考慮されるようになります。

これは、使用した他のロジックと似ていますが、選択した銘柄の通貨の可用性を自動的にチェックすることで動的になる点が異なります。このチェックが満たされると、次の条件に進み、イベントの重要度レベルがCALENDAR_IMPORTANCE_MODERATEと一致することを確認します。つまり、中程度の影響を持つイベントのみを対象とし、重要度が低いまたは高いイベントは除外します。

中程度の重要性のイベントを特定したら、2つの個別のチェックを使用して、サーバーの現在の時刻(TimeTradeServer)を基準としたタイミングを評価します。最初のチェックでは、イベントの時間が現在の時間より早いか等しいが、「timeBefore」より遅いかどうかを判断します。そうであれば、イベントは指定した過去の期間内にすでにリリースされていることを意味します。次に、Print関数を使用して、イベントの名前、関連する通貨、重要度、時間などのイベントの詳細を記録し、「(ALREADY RELEASED)」としてマークします。また、条件に一致するイベントを追跡するために、totalNews変数を増分します。2番目のチェックでは、イベントの時間が現在の時間より遅いか等しいが、timeAfterより早いか等しいかどうかを判断します。これは、イベントが近づいているが、指定した将来の時間枠内であることを示します。

ここでも、Print関数を使用して同様のイベントの詳細を記録し、保留中のステータスを示すために「(NOT YET RELEASED)」とマークし、この追加の関連イベントのtotalNews変数を増分します。ロジック内でいくつかの異なる時間変数を使用していることにお気づきかもしれません。これらは、イベントがアクションの実行時間範囲内にあることを確認するためのもので、そのロジックは次のとおりです。

datetime timeRange = PeriodSeconds(PERIOD_D1);
datetime timeBefore = TimeTradeServer() - timeRange;
datetime timeAfter = TimeTradeServer() + timeRange;
   
Print("FURTHEST TIME LOOK BACK = ",timeBefore," >>> CURRENT = ",TimeTradeServer());

これらのロジックをforループの直前に宣言して、現在のサーバー時間の前後に時間範囲を確立し、ニュースイベントをどの程度遡って先まで考慮するかを定義します。まず、datetime変数timeRangeを宣言し、PeriodSeconds関数を使用して1日の期間を割り当てます。これにより、24時間という標準化された時間枠で作業できるようになりますが、ニュースリリースの前後15分など、希望する範囲に調整することもできます。次に、timeBeforeとtimeAfterという2つの追加の日時変数を定義します。

現在のサーバー時間から時間範囲を減算して変数「timeBefore」を計算し、遡りたい最も遠い時点を取得します。同様に、timeAfterは現在のサーバー時間にtimeRangeを追加することによって決定され、将来的に考慮する最新の時点が提供されます。「timeBefore」と「timeAfter」を組み合わせると、現在の時刻を中心とした24時間のウィンドウが作成され、発生したばかりのイベントや間もなく発生すると予想されるイベントをキャプチャするのに役立ちます。ここにイラストがあります。

過去と未来を振り返る

画像から、現在の時刻、または1日間のスキャンを検討しているため日付が25の場合、日付24に遡って参照し、日付26に参照することがわかります。これは、現在の日付のちょうど1日前と1日後です。わかりやすくするために青色で強調表示しています。最後に、ループから記録されたニュースカウントの数を分析し、それぞれのブールフラグを返します。これを実現するために、次のロジックを採用します。

if (totalNews > 0){
   isNews = true;
   Print(">>>>>>> (FOUND NEWS) TOTAL NEWS = ",totalNews,"/",ArraySize(values));
}
else if (totalNews <= 0){
   isNews = false;
   Print(">>>>>>> (NOT FOUND NEWS) TOTAL NEWS = ",totalNews,"/",ArraySize(values));
}

ここでは、記録されたニュースの合計に基づいて、関連するニュースイベントが特定されたかどうかを評価します。ニュースの合計がゼロより大きい場合、基準に一致するニュースイベントが少なくとも1つ見つかったことを示します。この場合、isNews変数をtrueに設定し、一致するニュースイベントの合計数とvalues配列のサイズを表示するメッセージを出力します。「(FOUND NEWS)」というラベルの付いたメッセージには、特定されたニュースの合計と最初に考慮されたすべてのニュースも含まれており、取得されたイベントの合計のうち、関連するニュースイベントがいくつ見つかったかが示されます。

逆に、ニュースの合計が0以下の場合は、関連するニュースイベントが見つからなかったことを意味します。このシナリオでは、isNewsをfalseに設定し、「(NOT FOUND NEWS)」というラベルの付いたメッセージを出力して、ニュースの合計がゼロであることと、values配列のサイズを示します。この構造は、基準に一致するニュースイベントが見つかったかどうかを追跡するのに役立ち、結果のログを提供するので、ニュース確認プロセスの結果を検証するのに役立ちます。コンパイルすると、次のような出力が得られます。

0ニュース

画像から、現時点では関連するニュースはないことがわかります。したがって、時間範囲またはイベント検索範囲をこの場合は1日に拡張することで、検索範囲を拡大できます。

datetime startTime = TimeTradeServer() - PeriodSeconds(PERIOD_D1);
datetime endTime = TimeTradeServer() + PeriodSeconds(PERIOD_D1);

ニュースの範囲を1日に戻すと、次の出力が得られます。

5ニュース

画像から、81件のニュースのうち5件が関連ニュースであることがわかります。また、関連するニュースイベントがあることが出力されており、これを使用して市場に参入するか市場から撤退するかの取引決定をおこなうことができます。この部分はこれですべてです。MQL5カレンダーからのニュースの識別とフィルタリングをおこなう完全な関数は、次のコードスニペットのようになります。

//+------------------------------------------------------------------+
//|       FUNCTION TO GET NEWS EVENTS                                |
//+------------------------------------------------------------------+
bool isNewsEvent(){
   int totalNews = 0;
   bool isNews = false;
   
   MqlCalendarValue values[];
   
   datetime startTime = TimeTradeServer() - PeriodSeconds(PERIOD_D1);
   datetime endTime = TimeTradeServer() + PeriodSeconds(PERIOD_D1);
   
   //string currency_filter = "USD";
   //string currency_base = SymbolInfoString(_Symbol,SYMBOL_CURRENCY_BASE);
   //string currency_quote = StringSubstr(_Symbol,3,3);
   //if (currency_base != currency_filter && currency_quote != currency_filter){
   //   Print("Currency (",currency_base," | ",currency_quote,
   //         ") is not equal equal to ",currency_filter);
   //   return false;
   //}
   
   int valuesTotal = CalendarValueHistory(values,startTime,endTime,NULL,NULL);
   
   Print("TOTAL VALUES = ",valuesTotal," || Array size = ",ArraySize(values));
   
   //if (valuesTotal >=0 ){
   //   Print("Calendar values as they are: ");
   //   ArrayPrint(values);
   //}
   
   datetime timeRange = PeriodSeconds(PERIOD_D1);
   datetime timeBefore = TimeTradeServer() - timeRange;
   datetime timeAfter = TimeTradeServer() + timeRange;
   
   Print("Current time = ",TimeTradeServer());
   Print("FURTHEST TIME LOOK BACK = ",timeBefore," >>> LOOK FORE = ",timeAfter);
   
   for (int i = 0; i < valuesTotal; i++){
      MqlCalendarEvent event;
      CalendarEventById(values[i].event_id,event);
      
      
      MqlCalendarCountry country;
      CalendarCountryById(event.country_id,country);
      
      if (StringFind(_Symbol,country.currency) >= 0){
         if (event.importance == CALENDAR_IMPORTANCE_MODERATE){
            if (values[i].time <= TimeTradeServer() && values[i].time >= timeBefore){
               Print(event.name," > ", country.currency," > ", EnumToString(event.importance)," Time= ",values[i].time," (ALREADY RELEASED)");
               totalNews++;
            }
            
            if (values[i].time >= TimeTradeServer() && values[i].time <= timeAfter){
               Print(event.name," > ", country.currency," > ", EnumToString(event.importance)," Time= ",values[i].time," (NOT YET RELEASED)");
               totalNews++;
            }
         }
      }
      
   }
   
   if (totalNews > 0){
      isNews = true;
      Print(">>>>>>> (FOUND NEWS) TOTAL NEWS = ",totalNews,"/",ArraySize(values));
   }
   else if (totalNews <= 0){
      isNews = false;
      Print(">>>>>>> (NOT FOUND NEWS) TOTAL NEWS = ",totalNews,"/",ArraySize(values));
   }
   
   return (isNews);
}


結論

要約すると、MQL5経済指標カレンダーを調査するための初期手順を実施しました。このプロセスの中心は、通貨とイベントの重要性に基づいて、関連するデータを抽出し、分析することです。 私たちは、経済指標カレンダーからデータを取得し、通貨やイベントの重要性に基づいてフィルタリングし、イベントが差し迫っているか、すでに発生しているかを判断するための構造化されたアプローチを開発しました。この方法は、影響力のある経済発展に応じた取引システムを自動化するために不可欠であり、市場の変動をうまく乗り越えるための優位性を提供します。

次回の連載では、フィルタリングされた経済データをチャートに直接表示する機能を拡張し、リアルタイムの取引判断のために可視性を向上させます。また、この情報を活用して、主要な経済イベントに基づいて取引ポジションを建てられるように、EAを改善します。これらの機能が統合されると、経済ニュースの分析から、実際にそれを取引に活用する段階に移行します。リアルタイムのフレームワークに基づいてシステムを設計し、経済指標カレンダーのイベントから得た情報を用いて取引をトリガーすることで、システムの応答性を高めていきます。ご期待ください。

MetaQuotes Ltdにより英語から翻訳されました。
元の記事: https://www.mql5.com/en/articles/16223

添付されたファイル |
リプレイシステムの開発(第55回):コントロールモジュール リプレイシステムの開発(第55回):コントロールモジュール
この記事では、開発中のメッセージシステムに統合できるように、コントロールインジケーターを実装します。それほど難しくはありませんが、このモジュールの初期化について理解しておくべき細かい点がいくつかあります。ここで提示される資料は教育目的のみに使用されます。示された概念を学習し習得する以外の目的での利用は決して想定されていません。
知っておくべきMQL5ウィザードのテクニック(第44回):ATR (Average True Range)テクニカル指標 知っておくべきMQL5ウィザードのテクニック(第44回):ATR (Average True Range)テクニカル指標
ATRオシレーターは、特に外国為替市場において、ボラティリティの代理として機能する非常に人気のあるインジケーターです。これは、特にボリュームデータが不足している市場で広く活用されています。以前のインジケーターと同様に、パターンに基づいて分析をおこない、MQL5ウィザードライブラリのクラスとアセンブリを活用して、戦略およびテストレポートを共有します。
リプレイシステムの開発(第56回):モジュールの適応 リプレイシステムの開発(第56回):モジュールの適応
モジュール同士はすでに適切に連携していますが、リプレイサービスでマウスポインタを使用しようとするとエラーが発生します。次のステップに進む前に、この問題を修正する必要があります。さらに、マウスインジケーターのコードにある別の問題も修正します。この修正によって、今回のバージョンは最終的に安定し、洗練されたものになります。
主成分を用いた特徴量選択と次元削減 主成分を用いた特徴量選択と次元削減
この記事では、Luca Puggini氏とSean McLoone氏による論文「Forward Selection Component Analysis: Algorithms and Applications」に基づき、修正版のForward Selection Component Analysis (FSCA)アルゴリズムの実装について詳しく解説します。