English

MQL5の書き方(for MQL4デザイナー)

 

2023.07

林貴晴/AMSER Inc.

経済指標発表情報イベントの取得

MetaTrader 5(MT5)の革新的な機能の一つに、経済指標発表情報があります。この機能はMT4には搭載されていないMT5独自のもので、裁量取引と自動売買の両方に大きな利点をもたらします。チャート上に経済指標発表情報を表示することで、市場の動きを視覚的に理解しやすくすることができ、自動売買システムでは、重要な指標発表時にポジションを自動的に調整するなど、より洗練された戦略を実装できます。この記事では、MT5の経済カレンダー機能を活用したMQL5コードの実装例を紹介します。

このコード例では、MQL5サーバーから日本またはアメリカの経済指標発表情報を取得し、各イベントの国名、指標名、重要度、時間を表示します。表示される時間は気配値表示に表示される証券会社の設定した時間となります。なお、日本時間を使用している証券会社(例:フィリップ証券)では時差を考慮する必要がないため、このような経済カレンダーの表示に適しています。

経済指標発表情報は頻繁に変更されないため、アクセスを1時間に1回に制限することで、使用するPCやMQL5サーバーへの負荷を減らします。

以下のコードの動作条件は前回の経済指標発表情報取得から1時間以上経過した次のティックを受信した時になります。ティック配信のない土日は更新されません。

static datetime last_update = 0;
   datetime current = TimeCurrent();

   // 1時間ごとに経済指標データを更新
   if(current - last_update >= 3600)//1時間ごとに動作
      {
//ここにコードを書く
}
                    
 

次に、経済指標発表情報の取得と処理に必要な変数と構造体を宣言します。これらは1週間分の経済指標発表情報を扱うために使用します。
まず、現在の時刻から1週間後の日時を計算し、end変数に格納します。
次に、個々のイベント情報を格納するための変数を用意します。event_timeはイベントの時間、event_nameはイベントの名前、event_countryはイベントの国、event_importanceはイベントの重要度を保存します。
最後に、MQL5の経済カレンダー機能を利用するための構造体を宣言します。calendar_values配列は経済指標イベントを格納し、event構造体は個別のイベント情報を、country構造体は国の情報を保持します。

datetime end = current + 7 * 24 * 60 * 60; // 1週間先まで取得
datetime event_time = 0;
string event_name = "";
string event_country = "";
string event_importance = "";
MqlCalendarValue calendar_values[];
MqlCalendarEvent event;
MqlCalendarCountry country;
                    
 

カレンダーの取得

現在の時間(current)から1週間後の時間(end)までの期間における経済指標発表情報を取得し、calendar_values配列に格納します。CalendarValueHistory()関数の呼び出しにより、指定した期間内のすべての経済指標イベントがcalendar_values配列に格納されます。複数のイベントが存在する場合でも、それらは配列内に一つずつ順番に格納されます。

CalendarValueHistory(calendar_values, current, end, NULL);   
                    
 

イベントの確認と最も近いイベントの取得
calendar_values配列に格納された経済指標発表情報を一つずつ確認します。この処理では日本と米国の経済指標のみを対象とし、それ以外の国の情報は除外します。また、最も近い将来に予定されているイベントの情報を特定し、関連する変数に保存します。
まず、配列内の各イベントについて、CalendarEventById関数を使ってイベントの詳細情報を取得します。次に、CalendarCountryById関数でイベントの国情報を取得します。これらの情報が正しく取得できない場合は、次のイベントに進みます。
イベントの国が日本または米国の場合のみ処理を続行します。それ以外の国のイベントはスキップします。
現在処理中のイベントが、これまでに記録した中で最も近い将来のイベントである場合、そのイベントの情報を保存します。具体的には、イベントの時間、名前、重要度、国名を対応する変数に格納します。
この処理を全てのイベントに対して行うことで、日本または米国の経済指標の中で、最も近い将来に予定されているイベントの情報が特定されます。

for(int i = 0; i < ArraySize(calendar_values); i++)
   {
   if(!CalendarEventById(calendar_values[i].event_id, event))continue;//eventを取得
   if(!CalendarCountryById(event.country_id, country))continue;//eventの国を取得
   if(country.name != "日本" && country.name != "米国")continue;//日本、米国以外のニュースを排除
   if(event_time == 0 || calendar_values[i].time < event_time)
      {
      event_time = calendar_values[i].time;
      event_name = event.name;
      event_importance = (string)event.importance;
      event_country = country.name;
       }
   }
                    
 

最後に、取得した経済指標発表情報をチャート上にコメントとして表示します。
表示する情報が複数あるため、StringFormat()関数を使って一つの文字列にまとめます。この関数を使うことで、複数の情報を見やすく整形できます。
Comment()関数を使って、整形した文字列をチャート上にコメントとして表示します。表示される情報は、国名、指標名、重要度、そして時間です。時間の表示にはTimeToString()関数を使い、日付と分まで表示するよう設定しています。
は改行を表す記号で、各情報を別々の行に表示するために使用しています。

for(int i = 0; i < ArraySize(calendar_values); i++)
   {
   if(!CalendarEventById(calendar_values[i].event_id, event))continue;//eventを取得
   if(!CalendarCountryById(event.country_id, country))continue;//eventの国を取得
   if(country.name != "日本" && country.name != "米国")continue;//日本、米国以外のニュースを排除
   if(event_time == 0 || calendar_values[i].time < event_time)
      {
      event_time = calendar_values[i].time;
      event_name = event.name;
      event_importance = (string)event.importance;
      event_country = country.name;
       }
   }
                    
 

最後に、取得した経済指標発表情報をチャート上にコメントとして表示します。
表示する情報が複数あるため、StringFormat()関数を使って一つの文字列にまとめます。この関数を使うことで、複数の情報を見やすく整形できます。
Comment()関数を使って、整形した文字列をチャート上にコメントとして表示します。表示される情報は、国名、指標名、重要度、そして時間です。時間の表示にはTimeToString()関数を使い、日付と分まで表示するよう設定しています。
は改行を表す記号で、各情報を別々の行に表示するために使用しています。

Comment(StringFormat("次の日本/アメリカの指標:\n国: %s\n指標: %s\n重要度: %s\n時間: %s",
               event_country,
               event_name,
               event_importance,
               TimeToString(event_time, TIME_DATE | TIME_MINUTES)));
                    
 

全体のコードは以下のようになります。
今回はトレード時に見やすいように直近の経済指標発表情報をコメントに表示しましたが、このコードは自動売買システムにも応用できます。例えば、重要度が高い経済指標発表時にはポジションを閉じる、新規発注を控える、または逆に重要な指標発表時にポジションを持つといった戦略を実装できます。
経済指標の発表日程は複雑です。例えば、雇用統計は12日を含む週の3週間後の金曜日、FOMCは前回の6週間後の水曜日といった具合です。このコードを使用することで、そのような複雑な日程を正確に把握することができます。
経済ニュースを自動で取得することで、日程の間違いを防ぎ、よりトレードの精度を上げることができます。

#property strict

void OnTick()
   {
   static datetime last_update = 0;
   datetime current = TimeCurrent();

   // 1時間ごとに経済指標データを更新
   if(current - last_update >= 3600)//1時間ごとに動作
      {
      datetime end = current + 7 * 24 * 60 * 60; // 1週間先まで取得
      datetime event_time = 0;
      string event_name = "";
      string event_country = "";
      string event_importance = "";
      MqlCalendarValue calendar_values[];
      MqlCalendarEvent event;
      MqlCalendarCountry country;
      CalendarValueHistory(calendar_values, current, end, NULL);//期間current ~ endまでのイベントをcalender_valiesに取得
      for(int i = 0; i < ArraySize(calendar_values); i++)
         {
         if(!CalendarEventById(calendar_values[i].event_id, event))continue;//eventを取得
         if(!CalendarCountryById(event.country_id, country))continue;//eventの国を取得
         if(country.name != "日本" && country.name != "米国")continue;//日本、米国以外のニュースを排除
         //国名:日本 米国 英国 欧州連合 ドイツ スペイン フランス イタリア スイス カナダ オーストラリア 香港 中国 韓国
         if(event_time == 0 || calendar_values[i].time < event_time)
            {
            event_time = calendar_values[i].time;
            event_name = event.name;
            event_importance = (string)event.importance;
            event_country = country.name;
            }
         }
      Comment(StringFormat("次の日本/アメリカの指標:\n国: %s\n指標: %s\n重要度: %s\n時間: %s",
                           event_country,
                           event_name,
                           event_importance,
                           TimeToString(event_time, TIME_DATE | TIME_MINUTES)));
      }
   }

                    
 

 

執筆者紹介
林貴晴

林 貴晴(AMSER株式会社代表取締役)

内資系薬品会社で約10年勤務の後、
外資系製薬会社(現IQVIA及びGSK)で合計約10年を勤務
その後EA AMSERを開発し、その成績を評価され、株式会社ゴゴジャンの部長として抜擢。
現在はAMSER株式会社代表取締役。