English Русский 中文 Español Deutsch Português
preview
MQL5クックブック - 経済指標カレンダー

MQL5クックブック - 経済指標カレンダー

MetaTrader 5 | 17 1月 2022, 13:28
602 0
Denis Kirichenko
Denis Kirichenko

はじめに

MetaTrader 5ターミナルとMQL5プログラミング言語は絶えず進化しており、市場分析機能、より複雑な自動売買ロボットを開発するためのツールなどが拡張されています。新しいターミナルツールの1つは、手動とロボットの両方の助けを借りて処理できる経済指標カレンダーです。

この組み込みカレンダーには十分な柔軟性があります。ターミナルの[Calendar]タブで設定したり、Webサイトにインストールしたり、モバイル版をダウンロードしたりできます。私はアルゴリズムトレーダーで、主にツールのプログラミング機能に興味があります。

この記事では、それらをハイライトしようと思います。


1. 経済指標カレンダー — ドキュメントの内容

まず、文書化された機能を簡単に見てみましょう。一般的に、それは非常に簡潔です。MQL5リソースの場合によくあることですが、情報は一貫して表示され、小さな例を使用して示されています。


1.1 経済指標カレンダーの関数

ドキュメントには、カレンダーの10個の関数が記載されています。

  1. CalendarCountryById();
  2. CalendarEventById();
  3. CalendarValueById();
  4. CalendarCountries();
  5. CalendarEventByCountry();
  6. CalendarEventByCurrency();
  7. CalendarValueHistoryByEvent();
  8. CalendarValueHistory();
  9. CalendarValueLastByEvent();
  10. CalendarValueLast()

これらの関数は通常、カレンダーのプロパティ(国、イベント、値)または履歴イベント値のいずれかを返します。


1.2経済指標カレンダーの構造体

開発者は、MqlCalendarCountry、MqlCalendarEvent、MqlCalendarValue構造体の使用を推奨しています。


1.2.1  MqlCalendarCountry

この構造体では、関心のある国とイベントに関する詳細情報が提供されます。

現在いくつかの証券会社でWebサイトカレンダーを確認していますが、 21か国、欧州連合、全世界(グローバルイベント)のデータがありました。

[id]           [name] [code] [currency] [currency_symbol]       [url_name] [reserved]
[ 0]  999 "European Union" "EU"   "EUR"      "€"               "european-union"        ...
[ 1]  124 "Canada"         "CA"   "CAD"      "$"               "canada"                ...
[ 2]   36 "Australia"      "AU"   "AUD"      "$"               "australia"             ...
[ 3]  554 "New Zealand"    "NZ"   "NZD"      "$"               "new-zealand"           ...
[ 4]  392 "Japan"          "JP"   "JPY"      "¥"               "japan"                 ...
[ 5]  156 "China"          "CN"   "CNY"      "¥"               "china"                 ...
[ 6]  276 "Germany"        "DE"   "EUR"      "€"               "germany"               ...
[ 7]  250 "France"         "FR"   "EUR"      "€"               "france"                ...
[ 8]  380 "Italy"          "IT"   "EUR"      "€"               "italy"                 ...
[ 9]   76 "Brazil"         "BR"   "BRL"      "R$"              "brazil"                ...
[10]  344 "Hong Kong"      "HK"   "HKD"      "HK$"             "hong-kong"             ...
[11]  702 "Singapore"      "SG"   "SGD"      "R$"              "singapore"             ...
[12]  484 "Mexico"         "MX"   "MXN"      "Mex$"            "mexico"                ...
[13]  710 "South Africa"   "ZA"   "ZAR"      "R"               "south-africa"          ...
[14]  356 "India"          "IN"   "INR"      "₹"               "india"                 ...
[15]  578 "Norway"         "NO"   "NOK"      "Kr"              "norway"                ...
[16]    0 "Worldwide"      "WW"   "ALL"      ""                "worldwide"             ...
[17]  840 "United States"  "US"   "USD"      "$"               "united-states"         ...
[18]  826 "United Kingdom" "GB"   "GBP"      "£"               "united-kingdom"        ...
[19]  756 "Switzerland"    "CH"   "CHF"      "₣"               "switzerland"           ...
[20]  410 "South Korea"    "KR"   "KRW"      "₩"               "south-korea"           ...
[21]  724 "Spain"          "ES"   "EUR"      "€"               "spain"                 ...
[22]  752 "Sweden"         "SE"   "SEK"      "Kr"              "sweden"                ...

ロシアがこのリストに含まれていないのは少し奇妙です。すぐに追加されることを願います。


1.2.2  MqlCalendarEvent

この構造体では、イベントに関する詳細情報が提供されます。非常に多くのプロパティがあり、潜在的に、これは包括的なファンダメンタル分析のための優れたツールです。後に、特定の基準に従ってイベントを並び替える方法を検討します。


1.2.3  MqlCalendarValue

この構造体では、イベント値に関する詳細情報が提供されます。以前の値、実際の値、予測値があります。

この構造体を操作するときは、次の微妙な点に注意してください。

actual_value、forecast_value、prev_value、revisioned_prev_valueの各フィールド値は、百万倍に拡大して保存されます。フィールド値が設定されていない場合、フィールドにはLONG_MIN(-9223372036854775808)が格納されます。 ただし、フィールド値が設定されている場合は、1,000,000(百万)で割る必要があります。

MqlCalendarValue構造体には、指定されたフィールドの値を使用した作業を簡素化する独自のメソッドがあります。

メソッドは2つのグループに分けることができます。

最初のグループでは、指定された値が指定されているかどうかを確認します。

HasActualValue(void) — 実際の値が設定されている場合はtrueを返し、それ以外の場合はfalseを返す
HasForecastValue(void) — 予測値が設定されている場合はtrueを返し、それ以外の場合はfalseを返す
HasPreviousValue(void) — 以前の値が設定されている場合はtrueを返し、それ以外の場合はfalseを返す
HasRevisedValue(void) — 改訂値が設定されている場合はtrueを返し、それ以外の場合はfalseを返す

2番目のグループでは、特定の値を直接受け取ります。

GetActualValue(void) — イベントの実際の値(double)を返す、または関連する値が設定されていない場合はnanを返す
GetForecastValue(void) — イベントの予測値(double)を返す、または関連する値が設定されていない場合はnanを返す
GetPreviousValue(void) — イベントの以前の値(double)を返す、または関連する値が設定されていない場合はnanを返す
GetRevisedValue(void) — イベントの改訂値(double)を返す、または関連する値が設定されていない場合はnanを返す

MqlCalendarValue構造体がフィールド値を受け取り、確認する方法を見てみましょう。直近の日本銀行(BoJ)の金利決定に焦点を当てます。値を取得するための3つのアプローチを特徴とするTest_empty_value.mq5スクリプトを使用して、操作ログに必要なデータを表示します。 

//+------------------------------------------------------------------+
//| LongDouble                                                       |
//+------------------------------------------------------------------+
union LongDouble
  {
   long   long_value;
   double double_value;
  };
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- Bank of Japan (BoJ) Interest Rate Decision on 22 Sep 2021 02:47 GMT
   ulong event_id = 392060022; // "boj-interest-rate-decision"
   MqlCalendarValue values[];
   datetime date_from, date_to;
   date_from = D'22.09.2021';
   date_to = date_from + PeriodSeconds(PERIOD_D1);
   if(::CalendarValueHistoryByEvent(event_id, values, date_from, date_to))
     {
      LongDouble forecast_val;
      //--- 1) "forecast_value" field
      forecast_val.long_value = values[0].forecast_value;
      ::PrintFormat("\"forecast_value\" field: %I64d", forecast_val.long_value);
      //--- 2) MqlCalendarValue::GetForecastValue()
      forecast_val.double_value = values[0].GetForecastValue();
      ::PrintFormat("MqlCalendarValue::GetForecastValue(): %g", forecast_val.double_value);
      //--- 3) MqlCalendarValue::HasForecastValue()
      if(!values[0].HasForecastValue())
         ::PrintFormat("MqlCalendarValue::HasForecastValue(): %s", (string)false);
     }
  }
//+------------------------------------------------------------------+

最初のアプローチは、単に予測値を取得します。予測がなかったため、LONG_MIN(-9223372036854775808)を取得します。2番目のアプローチは、すでにMqlCalendarValue::GetForecastValue()構造体メソッドを適用していて、「nan」を返します。3番目のアプローチは、予測値が存在するかどうかを確認するため、最も慎重です。 

スクリプトを起動すると、操作ログに次のエントリが表示されます。

GR      0       21:23:36.076    Test_empty_value (USDCAD,H1)    "forecast_value" field: -9223372036854775808
LH      0       21:23:36.080    Test_empty_value (USDCAD,H1)    MqlCalendarValue::GetForecastValue(): nan
HM      0       21:23:36.080    Test_empty_value (USDCAD,H1)    MqlCalendarValue::HasForecastValue(): false


1.2.4 構造体の関係性

構造体は次の関係によって相互接続されています(図1)。

カレンダー列挙の関係性

図1 カレンダー構造体の関係性


MqlCalendarCountry構造体は、国IDを介してMqlCalendarEventにリンクされています。「1対多」の関係が形成します(1..*)。

MqlCalendarEvent構造体は、イベントIDを介してMqlCalendarValueにリンクされています。「1対多」の関係が形成します(1..*)。


1.3エラー

開発者は、経済指標カレンダーを操作するときにランタイムエラーグループを割り当てます。これらは次のリクエストです。

経済指標カレンダー


ERR_CALENDAR_MORE_DATA
5400 配列サイズがすべての値の説明を受け取るには不十分です
ERR_CALENDAR_TIMEOUT
5401 リクエストの制限時間を超えました
ERR_CALENDAR_NO_DATA
5402 国が見つかりません



2. 補助構造体とCiCalendarInfoクラス

私は主にOOPを支持するので、カレンダープロパティへのアクセスを提供するクラスの例を示します。

カレンダーはかなり多岐にわたることを忘れないでください。 私はデータベースの専門家ではありませんが、私が理解している限り、カレンダーは通常、複数のテーブルを持つリレーショナルデータベースです。

プロパティの取得とは別に、CiCalendarInfoクラスの提供された実装は、選択されたイベントの時系列を作成することも目的としています。

まず、補助構造体を見てみましょう。


2.1時系列構造体

TS(時系列)のデータを取得するため、そのプログラム的な基礎を築く必要があります。これは、SiTimeSeries構造体が担当します。

//+------------------------------------------------------------------+
//| Time series structure                                            |
//+------------------------------------------------------------------+
struct SiTimeSeries
  {
   private:
      bool              init;        // is initialized?
      uint              size;
      datetime          timevals[];  // time values
      double            datavals[];  // data values
      string            name;        // ts name
   public:
      //--- constructor
      void              SiTimeSeries(void);
      //--- destructor
      void             ~SiTimeSeries(void);
      //--- copy consructor
      void              SiTimeSeries(const SiTimeSeries &src_ts);
      //--- assignment operator
      void              operator=(const SiTimeSeries &src_ts);
      //--- equality operator
      bool              operator==(const SiTimeSeries &src_ts);
      //--- indexing operator
      SiTsObservation   operator[](const uint idx) const;
      //--- initialization
      bool              Init(datetime &ts_times[], const double &ts_values[],
                             const string ts_name);
      //--- get series properties
      bool              GetSeries(datetime &dst_times[], double &dst_values[], string &dst_name);
      bool              GetSeries(SiTsObservation &dst_observations[], string &dst_name);
      //--- service
      bool              IsInit(void) const
        {
         return init;
        };
      uint              Size(void) const
        {
         return size;
        };
      void              Print(const int digs = 2, const uint step = 0);
  };
//+------------------------------------------------------------------+

構造体の主な要素は、timevals[]配列とdatavals[]配列です。1つ目は時系列を含み、2つ目は一連の値を含みます。

この構造体は、その要素がprivateセクションに配置されるように実装されており、時系列は作成後に変更できません。

次の例で時系列構造体を処理してみましょう。Test_TS.mq5スクリプトは、2016年1月1日から2021年11月1日までの米国非農業部門雇用者数に関するデータを受け取り、それらを科学的なチャートに表示します。チャートが2つの曲線(実際の値と予測値)を持つようにしましょう。イベント報告期間をタイムラインとして使用します。

スクリプトを起動した後、最初に時系列値を操作ログに表示し、次にチャートに図を描画します(図2)。


非農業部門データ(2016-2021)

図2 米国非農業部門就業者数(2016-2021)

 

スクリプトには、時系列値が入力される次の文字列が含まれています。

//--- prepare time and data values for the timeseries
for(int v_idx = 0; v_idx < nfp_values_size; v_idx++)
   {
    MqlCalendarValue curr_nfp_val = nfp_values[v_idx];
    datetime curr_nfp_time = curr_nfp_val.period;
    timevals[v_idx] = curr_nfp_time;
    double curr_nfp_dataval = curr_nfp_val.GetActualValue();
    datavals1[v_idx] = curr_nfp_dataval;
    curr_nfp_dataval = curr_nfp_val.GetForecastValue();
    datavals2[v_idx] = curr_nfp_dataval;
   }

MqlCalendarValue::GetActualValue()関数とMqlCalendarValue::GetForecastValue()関数を使用して必要な値をすぐに受け取ります。


2.2時系列観察構造体

時系列はすべて観測値で構成されます。以下の単純なSiTsObservation構造が観察用に作成されています。

//+------------------------------------------------------------------+
//| Time series observation structure                                |
//+------------------------------------------------------------------+
struct SiTsObservation
  {
   datetime          time; // timestamp
   double            val;  // value
   //--- constructor
   void              SiTsObservation(void): time(0), val(EMPTY_VALUE) {}
  };
//+------------------------------------------------------------------+

インデックス演算子は、SiTimeSeries時系列構造で宣言されていて、必要な系列観測を返します。上記の例(農場以外の値の描画)では、シリーズは70個の値で構成されています。この場合、最初最後の観測値は次の方法で取得できます。

SiTsObservation first_observation, last_observation;
first_observation = nfp_ts1[0];
last_observation = nfp_ts1[nfp_values_size - 1];
string time_str = ::TimeToString(first_observation.time, TIME_DATE);
string data_str = ::DoubleToString(first_observation.val, 0);
::PrintFormat("\nFirst observation: %s, %s", time_str, data_str);
time_str = ::TimeToString(last_observation.time, TIME_DATE);
data_str = ::DoubleToString(last_observation.val, 0);
::PrintFormat("Last observation: %s, %s", time_str, data_str);

操作ログで指定されたコード文字列を実行すると、次のエントリが取得されます。

KJ      0       21:27:16.386    Test_ts (USDCAD,H1)     First observation: 2015.12.01, 292
HO      0       21:27:17.225    Test_ts (USDCAD,H1)     Last observation: 2021.09.01, 194


2.3CiCalendarInfoクラス

カレンダープロパティへのアクセスを簡素化するためにクラスが作成され、イベント値を取得することで継続性を維持します(CAccountInfoCSymbolInfo、その他の取引クラスと同様) 。<分節10739¶>

クラス宣言を以下に示します。

//+------------------------------------------------------------------+
//| Class CiCalendarInfo.                                            |
//| Appointment: Class for access to calendar info.                  |
//|              Derives from class CObject.                         |
//+------------------------------------------------------------------+
class CiCalendarInfo : public CObject
  {
      //--- === Data members === ---
   protected:
      string            m_currency;
      ulong             m_country_id;
      MqlCalendarCountry m_country_description;
      ulong             m_event_id;
      MqlCalendarEvent  m_event_description;
      static MqlCalendarCountry m_countries[];
      bool              m_is_init;
      //--- === Methods === ---
   public:
      //--- constructor/destructor
      void           CiCalendarInfo(void);
      void          ~CiCalendarInfo(void) {};
      //--- initialization
      bool           Init
      (
         const string currency = NULL,         // country currency code name
         const ulong country_id = WRONG_VALUE, // country ID
         const ulong event_id = WRONG_VALUE,   // event ID
         const bool to_log = true              // to log?
      );
      void           Deinit(void);
      //--- Сalendar structures descriptions
      bool           CountryDescription(MqlCalendarCountry &country, const bool to_log = false);
      bool           EventDescription(MqlCalendarEvent &event, const bool to_log = false);
      bool           ValueDescription(ulong value_id, MqlCalendarValue &value,
                                      const bool to_log = false);
      bool           EventsByCountryDescription(MqlCalendarEvent &events[], const bool to_log = false);
      bool           EventsByCurrencyDescription(MqlCalendarEvent &events[], const bool to_log = false);
      bool           EventsBySector(const ENUM_CALENDAR_EVENT_SECTOR event_sector,
                                    MqlCalendarEvent &events[], const bool to_log = false);
      //--- Сalendar enum descriptions
      string         EventTypeDescription(const ENUM_CALENDAR_EVENT_TYPE event_type);
      string         EventSectorDescription(const ENUM_CALENDAR_EVENT_SECTOR event_sector);
      string         EventFrequencyDescription(const ENUM_CALENDAR_EVENT_FREQUENCY event_frequency);
      string         EventTimeModeDescription(const ENUM_CALENDAR_EVENT_TIMEMODE event_time_mode);
      string         EventUnitDescription(const ENUM_CALENDAR_EVENT_UNIT event_unit);
      string         EventImportanceDescription(const ENUM_CALENDAR_EVENT_IMPORTANCE event_importance);
      string         EventMultiplierDescription(const ENUM_CALENDAR_EVENT_MULTIPLIER event_multiplier);
      string         ValueImpactDescription(const ENUM_CALENDAR_EVENT_IMPACT event_impact);
      //--- history
      bool           ValueHistorySelectByEvent
      (
         MqlCalendarValue &values[], // array for value descriptions
         datetime datetime_from,     // left border of a time range
         datetime datetime_to = 0    // right border of a time range
      )                 const;
      bool           ValueHistorySelectByEvent
      (
         SiTimeSeries &dst_ts,       // timeseries for value descriptions
         datetime datetime_from,     // left border of a time range
         datetime datetime_to = 0    // right border of a time range
      )                 const;
      bool           ValueHistorySelect
      (
         MqlCalendarValue &values[], // array for value descriptions
         datetime datetime_from,     // left border of a time range
         datetime datetime_to = 0    // right border of a time range
      )                 const;
      bool           ValueHistorySelect
      (
         SiTimeSeries &dst_ts[],     // array of timeseries for value descriptions
         datetime datetime_from,     // left border of a time range
         datetime datetime_to = 0    // right border of a time range
      );
      //--- the calendar database status
      int            ValueLastSelectByEvent
      (
         ulong&               change_id,     // Calendar change ID
         MqlCalendarValue&    values[]       // array for value descriptions
      )                 const;
      int            ValueLastSelect
      (
         ulong&               change_id,     // Calendar change ID
         MqlCalendarValue&    values[]       // array for value descriptions
      )                 const;
      //--- countries and continents
      bool           GetCountries(CArrayString &countries_arr);
      bool           GetCountries(MqlCalendarCountry &countries[]);
      bool           GetUniqueContinents(string &continents[]);
      bool           GetCountriesByContinent(const ENUM_CONTINENT src_continent,
                                             CArrayString &countries_arr);
      string         GetCountryNameById(const ulong country_id);
      //--- events
      bool           GetEventsByName(CArrayString &events_arr, const string name = NULL);
      bool           GetEventsByName(MqlCalendarEvent &events[], const string name = NULL);
      bool           FilterEvents(MqlCalendarEvent &filtered_events[],
                                  MqlCalendarEvent &src_events[], const ulong filter);
      //--- print
      void           PrintCountryDescription(const MqlCalendarCountry &country);
      void           PrintEventDescription(const MqlCalendarEvent &event);
      void           PrintValueDescription(const MqlCalendarValue &value);
      //---
   private:
      bool           ValidateProperties(void);
      bool           CountryById(const ulong country_id);
      bool           EventId(void);
  };
MqlCalendarCountry CiCalendarInfo::m_countries[];

クラスは次のメンバーデータで構成されています。

  1. m_currency — 国の通貨コード
  2. m_country_id — ISO3166-1に準拠した国ID
  3. m_country_description — 国の説明
  4. m_event_id — イベントID
  5. m_event_description —イベントの説明
  6. m_countries — カレンダーで利用可能な国の説明の配列
  7. m_is_init — 初期化フラグ

m_currency、m_country_id、m_event_idメンバーデータは、カレンダーデータベースからデータリクエストを作成するための一連の基準です。

m_country_descriptionおよびm_event_descriptionメンバーデータを使用すると、国とイベントがわかっている場合に説明にすばやくアクセスできます。

m_countriesメンバーデータは静的です。 国データは一定であるため、新しいCiCalendarInfoオブジェクトを初期化するときに毎回要求する必要はありません。

次に、いくつかのメソッドについて説明します。


2.3.1初期化メソッド

このメソッドを使用すると、クラスオブジェクトの処理を開始できます。このメソッドは、カレンダーデータを受信するために不可欠です。このメソッドは、一連の基準をパラメータ(通貨コード、国ID、イベントID)として受け取り、1つのパラメーターを使用して操作ログに初期化データを表示できるようにします。 基準により、カレンダーへのアクセスをより具体的にすることができます。

//+------------------------------------------------------------------+
//| Initialization                                                   |
//+------------------------------------------------------------------+
bool CiCalendarInfo::Init(const string currency = NULL,         // country currency code name
                          const ulong country_id = WRONG_VALUE, // country ID
                          const ulong event_id = WRONG_VALUE,   // event ID
                          const bool to_log = true              // to log?
                         )
  {
//--- check reinitialization
   if(m_is_init)
     {
      ::PrintFormat(__FUNCTION__ + ": CiCalendarInfo object already initialized!");
      return false;
     }
//--- check countries
   int countries_cnt = ::ArraySize(m_countries);
   if(countries_cnt < 1)
     {
      ::ResetLastError();
      countries_cnt = ::CalendarCountries(m_countries);
      if(countries_cnt < 1)
        {
         ::PrintFormat(__FUNCTION__ + ": CalendarCountries() returned 0! Error %d",
                       ::GetLastError());
         return false;
        }
     }
   for(int c_idx = 0; c_idx < countries_cnt; c_idx++)
     {
      MqlCalendarCountry curr_country = m_countries[c_idx];
      //--- check currency
      if(!::StringCompare(curr_country.currency, currency))
        {
         m_currency = currency;
        }
      //--- check country
      if(country_id != WRONG_VALUE)
         if(curr_country.id == country_id)
           {
            m_country_id = country_id;
           }
     }
//--- check event
   if(event_id != WRONG_VALUE)
     {
      m_event_id = event_id;
     }
//--- validate properties
   if(!this.ValidateProperties())
      return false;
//---
   if(to_log)
     {
      ::Print("\n---== New Calendar Info object ==---");
      if(m_currency != NULL)
         ::PrintFormat("   Currency: %s", m_currency);
      if(m_country_id != WRONG_VALUE)
         ::PrintFormat("   Country id: %I64u", m_country_id);
      if(m_event_id != WRONG_VALUE)
         ::PrintFormat("   Event id: %I64u", m_event_id);
     }
   m_is_init = true;
   return true;
  }
//+------------------------------------------------------------------+

簡単なスクリプトTest_initialization.mq5を使用してメソッドの操作を説明しましょう。

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- TRUE
//--- 1) all currencies, all countries, all events
   CiCalendarInfo calendar_info1;
   bool is_init = calendar_info1.Init();
//--- 2) EUR, all countries, all events
   CiCalendarInfo calendar_info2;
   is_init = calendar_info2.Init("EUR");
//--- 3) EUR, Germany, all events
   CiCalendarInfo calendar_info3;
   is_init = calendar_info3.Init("EUR", 276);
//--- 4) EUR, Germany, HICP m/m
   CiCalendarInfo calendar_info4;
   is_init = calendar_info4.Init("EUR", 276, 276010022);
//--- FALSE
//--- 5) EUR, Germany, nonfarm-payrolls
   CiCalendarInfo calendar_info5;
   is_init = calendar_info5.Init("EUR", 276, 840030016);
//--- 6) EUR, US, nonfarm-payrolls
   CiCalendarInfo calendar_info6;
   is_init = calendar_info6.Init("EUR", 840, 840030016);
//--- 7) EUR, all countries, nonfarm-payrolls
   CiCalendarInfo calendar_info7;
   is_init = calendar_info7.Init("EUR", WRONG_VALUE, 840030016);
  }
//+------------------------------------------------------------------+

スクリプトを起動すると、操作ログに次のエントリが表示されます。

DO      0       21:30:19.703    Test_initialization (USDCAD,H1) ---== New Calendar Info object ==---
GE      0       21:30:19.703    Test_initialization (USDCAD,H1) 
LL      0       21:30:19.703    Test_initialization (USDCAD,H1) ---== New Calendar Info object ==---
FI      0       21:30:19.703    Test_initialization (USDCAD,H1)    Currency: EUR
GO      0       21:30:19.703    Test_initialization (USDCAD,H1) 
LJ      0       21:30:19.703    Test_initialization (USDCAD,H1) ---== New Calendar Info object ==---
FS      0       21:30:19.703    Test_initialization (USDCAD,H1)    Currency: EUR
KO      0       21:30:19.703    Test_initialization (USDCAD,H1)    Country id: 276
CH      0       21:30:19.703    Test_initialization (USDCAD,H1) 
PI      0       21:30:19.703    Test_initialization (USDCAD,H1) ---== New Calendar Info object ==---
JF      0       21:30:19.703    Test_initialization (USDCAD,H1)    Currency: EUR
OL      0       21:30:19.703    Test_initialization (USDCAD,H1)    Country id: 276
HD      0       21:30:19.703    Test_initialization (USDCAD,H1)    Event id: 276010022
HR      0       21:30:19.703    Test_initialization (USDCAD,H1) CiCalendarInfo::ValidateProperties: failed! Country ids must be the same!
OP      0       21:30:19.703    Test_initialization (USDCAD,H1) CiCalendarInfo::ValidateProperties: failed! Currencies must be the same!
GP      0       21:30:19.703    Test_initialization (USDCAD,H1) CiCalendarInfo::ValidateProperties: failed! Currencies must be the same!

初期化メソッドは、単一の国または通貨に属するという観点から、指定されたパラメータを確認します。 したがって、次の組み合わせは「false」を返します。EUR-ドイツ-非農業部門雇用者数、EUR-米国-非農業部門雇用者数、EUR-すべての国-非農業部門雇用者数。

初期化メソッドの最初の段階では、再初期化に対する保護があります。カレンダーオブジェクトは引き続き再初期化できますが、最初に非初期化メソッドを呼び出す必要があります。たとえば、最初に、カレンダーオブジェクトがEURイベントに関するデータを収集することを定義します。次に、オブジェクトの向きをUSDに変更する必要があります。Test_reinitialization.mq5スクリプトは、このタスクの間違った解決法と正しい解決法の両方を示しています。

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
   {
//--- ERROR
   CiCalendarInfo calendar_info1;
   bool is_init = calendar_info1.Init("EUR");
   is_init = calendar_info1.Init("USD");
//--- OK
   CiCalendarInfo calendar_info2;
   is_init = calendar_info2.Init("EUR");
   calendar_info2.Deinit();
   is_init = calendar_info2.Init("USD");
   }
//+------------------------------------------------------------------+

間違ったケースでは、次のエントリが表示されます。

MP      0       21:34:19.397    Test_reinitialization (USDCAD,H1)       
FQ      0       21:34:19.397    Test_reinitialization (USDCAD,H1)       ---== New Calendar Info object ==---
HO      0       21:34:19.397    Test_reinitialization (USDCAD,H1)          Currency: EUR
KI      0       21:34:19.397    Test_reinitialization (USDCAD,H1)       CiCalendarInfo::Init: CiCalendarInfo object already initialized!
EI      0       21:34:19.397    Test_reinitialization (USDCAD,H1)       
NO      0       21:34:19.397    Test_reinitialization (USDCAD,H1)       ---== New Calendar Info object ==---
PF      0       21:34:19.397    Test_reinitialization (USDCAD,H1)          Currency: EUR
QL      0       21:34:19.397    Test_reinitialization (USDCAD,H1)       
RD      0       21:34:19.397    Test_reinitialization (USDCAD,H1)       ---== New Calendar Info object ==---
DS      0       21:34:19.397    Test_reinitialization (USDCAD,H1)          Currency: USD


2.3.2カレンダー構造体の説明を受け取るメソッド

これらのメソッドは、ある程度、標準のカレンダー関数を呼び出すことを可能にするラッパーです。CiCalendarInfo::CountryDescription()メソッドとCiCalendarInfo::EventDescription()メソッドは、カレンダーオブジェクトの初期化中に確認された場合、国とイベントの説明を返します。 

さらに、メソッドを使用すると、要求されたプロパティの説明を操作ログに表示できます。

簡単なスクリプトTest_structures_descriptions.mq5を使用して説明を受け取るメソッドの動作を説明しましょう。

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- 1) events by country
   CiCalendarInfo calendar_info;
   ulong country_id = 276; // Germany
   if(calendar_info.Init(NULL, country_id))
     {
      MqlCalendarEvent events[];
      if(calendar_info.EventsByCountryDescription(events))
        {
         Print("\n---== Events selected by country ==---");
         PrintFormat("   Country id: %I64u", country_id);
         PrintFormat("   Events number: %d", ::ArraySize(events));
        }
     }
   calendar_info.Deinit();
//--- 2) events by currency
   string country_currency = "EUR";
   if(calendar_info.Init(country_currency))
     {
      MqlCalendarEvent events[];
      if(calendar_info.EventsByCurrencyDescription(events))
        {
         Print("\n---== Events selected by currency ==---");
         PrintFormat("   Currency: %s", country_currency);
         PrintFormat("   Events number: %d", ::ArraySize(events));
        }
     }
  }
//+------------------------------------------------------------------+

操作ログには、次の文字列があります。

MK      0       21:36:35.659    Test_structures_descriptions (USDCAD,H1)        
DM      0       21:36:35.659    Test_structures_descriptions (USDCAD,H1)        ---== New Calendar Info object ==---
MP      0       21:36:35.659    Test_structures_descriptions (USDCAD,H1)           Country id: 276
FH      0       21:36:35.793    Test_structures_descriptions (USDCAD,H1)        
ON      0       21:36:35.793    Test_structures_descriptions (USDCAD,H1)        ---== Events selected by country ==---
RR      0       21:36:35.793    Test_structures_descriptions (USDCAD,H1)           Country id: 276
GD      0       21:36:35.793    Test_structures_descriptions (USDCAD,H1)           Events number: 61
FP      0       21:36:35.793    Test_structures_descriptions (USDCAD,H1)        
OG      0       21:36:35.793    Test_structures_descriptions (USDCAD,H1)        ---== New Calendar Info object ==---
KI      0       21:36:35.793    Test_structures_descriptions (USDCAD,H1)           Currency: EUR
MN      0       21:36:35.794    Test_structures_descriptions (USDCAD,H1)        
QE      0       21:36:35.794    Test_structures_descriptions (USDCAD,H1)        ---== Events selected by currency ==---
FO      0       21:36:35.794    Test_structures_descriptions (USDCAD,H1)           Currency: EUR
FJ      0       21:36:35.794    Test_structures_descriptions (USDCAD,H1)           Events number: 276

これは、ドイツで61のイベントが見つかり、ユーロ諸国で276のイベントが見つかったことを意味します。


2.3.3カレンダー列挙の説明を受け取るメソッド

カレンダー構造体には、次の8つの列挙型が含まれています。

  1. ENUM_CALENDAR_EVENT_TYPE;
  2. ENUM_CALENDAR_EVENT_SECTOR;
  3. ENUM_CALENDAR_EVENT_FREQUENCY;
  4. ENUM_CALENDAR_EVENT_TIMEMODE;
  5. ENUM_CALENDAR_EVENT_UNIT;
  6. ENUM_CALENDAR_EVENT_IMPORTANCE;
  7. ENUM_CALENDAR_EVENT_MULTIPLIER;
  8. ENUM_CALENDAR_EVENT_IMPACT.

最初の7つの列挙型はMqlCalendarEvent構造体を参照し、最後の列挙型はMqlCalendarValue構造体を参照します。

CiCalendarInfoクラスは、提案されたリストから選択された列挙値を記述する8つのメソッドを定義します。Test_enums_descriptions.mq5スクリプトを使用してメソッドをテストしてみましょう。スクリプトはランダムに10のUKイベントを選択し、操作ログの各基準に関するデータを表示します。

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
   {
   CiCalendarInfo calendar_info;
   ulong country_id = 826; // UK
   if(calendar_info.Init(NULL, country_id))
      {
      MqlCalendarEvent events[];
      if(calendar_info.EventsByCountryDescription(events))
         {
         ::MathSrand(77);
         int events_num =::ArraySize(events);
         int n = 10;
         MqlCalendarEvent events_selected[];
         ::ArrayResize(events_selected, n);
         for(int ev_idx = 0; ev_idx < n; ev_idx++)
            {
            int rand_val =::MathRand();
            int rand_idx = rand_val % events_num;
            events_selected[ev_idx] = events[rand_idx];
            }
         //--- 0) name
         ::Print("\n---== Name ==---");
         for(int ev_idx = 0; ev_idx < n; ev_idx++)
            {
            MqlCalendarEvent curr_event = events_selected[ev_idx];
            ::PrintFormat("   [%d] - %s", ev_idx + 1, curr_event.name);
            }
         //--- 1) type
         ::Print("\n---== Type ==---");
         for(int ev_idx = 0; ev_idx < n; ev_idx++)
            {
            MqlCalendarEvent curr_event = events_selected[ev_idx];
            ::PrintFormat("   [%d] - %s", ev_idx + 1,
                          calendar_info.EventTypeDescription(curr_event.type));
            }
         //--- 2) sector
         ::Print("\n---== Sector ==---");
         for(int ev_idx = 0; ev_idx < n; ev_idx++)
            {
            MqlCalendarEvent curr_event = events_selected[ev_idx];
            ::PrintFormat("   [%d] - %s", ev_idx + 1,
                          calendar_info.EventSectorDescription(curr_event.sector));
            }
         //--- 3) frequency
         ::Print("\n---== Frequency ==---");
         for(int ev_idx = 0; ev_idx < n; ev_idx++)
            {
            MqlCalendarEvent curr_event = events_selected[ev_idx];
            ::PrintFormat("   [%d] - %s", ev_idx + 1,
                          calendar_info.EventFrequencyDescription(curr_event.frequency));
            }
         //--- 3) time mode
         ::Print("\n---== Time mode ==---");
         for(int ev_idx = 0; ev_idx < n; ev_idx++)
            {
            MqlCalendarEvent curr_event = events_selected[ev_idx];
            ::PrintFormat("   [%d] - %s", ev_idx + 1,
                          calendar_info.EventTimeModeDescription(curr_event.time_mode));
            }
         //--- 4) unit
         ::Print("\n---== Unit ==---");
         for(int ev_idx = 0; ev_idx < n; ev_idx++)
            {
            MqlCalendarEvent curr_event = events_selected[ev_idx];
            ::PrintFormat("   [%d] - %s", ev_idx + 1,
                          calendar_info.EventUnitDescription(curr_event.unit));
            }
         //--- 5) importance
         ::Print("\n---== Importance ==---");
         for(int ev_idx = 0; ev_idx < n; ev_idx++)
            {
            MqlCalendarEvent curr_event = events_selected[ev_idx];
            ::PrintFormat("   [%d] - %s", ev_idx + 1,
                          calendar_info.EventImportanceDescription(curr_event.importance));
            }
         //--- 6) multiplier
         ::Print("\n---== Multiplier ==---");
         for(int ev_idx = 0; ev_idx < n; ev_idx++)
            {
            MqlCalendarEvent curr_event = events_selected[ev_idx];
            ::PrintFormat("   [%d] - %s", ev_idx + 1,
                          calendar_info.EventMultiplierDescription(curr_event.multiplier));
            }
         //--- 7) impact
         MqlCalendarValue values_by_event[];
         datetime start_dt, stop_dt;
         start_dt = D'01.01.2021';
         stop_dt = D'01.11.2021';
         ::Print("\n---== Impact ==---");
         for(int ev_idx = 0; ev_idx < n; ev_idx++)
            {
            MqlCalendarEvent curr_event = events_selected[ev_idx];
            CiCalendarInfo event_info;
            MqlCalendarValue ev_values[];
            if(event_info.Init(NULL, WRONG_VALUE, curr_event.id))
               if(event_info.ValueHistorySelectByEvent(ev_values, start_dt, stop_dt))
                  {
                  int ev_values_size =::ArraySize(ev_values);
                  ::PrintFormat("   [%d] - %s", ev_idx + 1,
                                calendar_info.ValueImpactDescription(ev_values[--ev_values_size].impact_type));
                  }
            }
         }
      }
   }
//+------------------------------------------------------------------+

得られた結果を再現するには、疑似乱数整数値ジェネレータの初期状態を特定の数値(::MathSrand(77))に設定します。スクリプトで次のイベントが選択されます。

  1. BoE住宅エクイティの引き出し前期比
  2. BoE市場および銀行部門副総裁ラムズデン氏のスピーチ
  3. 請求者数の変更
  4. コアCPI前年比
  5. 平均週収、合計給与前年比
  6. イースターマンデー
  7. BoE住宅ローン貸付前月比
  8. BoE MPC委員Vlieghe氏のスピーチ
  9. コアRPI前年比
  10. 請求者数の変更

操作ログに次の説明が表示されます。

FP      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)     ---== Type ==---
CG      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [1] - Indicator
EN      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [2] - Event
EI      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [3] - Indicator
LP      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [4] - Indicator
OK      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [5] - Indicator
OD      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [6] - Holiday
EL      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [7] - Indicator
GG      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [8] - Event
ON      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [9] - Indicator
CJ      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [10] - Indicator
DO      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)     
PE      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)     ---== Sector ==---
JR      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [1] - Money
KJ      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [2] - Money
NQ      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [3] - Labor market
QS      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [4] - Prices
HD      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [5] - Labor market
JP      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [6] - Holidays
OI      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [7] - Housing
EQ      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [8] - Money
LD      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [9] - Prices
JR      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [10] - Labor market
RS      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)     
NF      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)     ---== Frequency ==---
ML      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [1] - Quarterly
QH      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [2] - None
MN      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [3] - Monthly
PI      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [4] - Monthly
OP      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [5] - Monthly
CE      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [6] - None
CR      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [7] - Monthly
CS      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [8] - None
GE      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [9] - Monthly
OO      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [10] - Monthly
PI      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)     
NQ      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)     ---== Time mode ==---
FE      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [1] - Exact time
MS      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [2] - Exact time
PH      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [3] - Exact time
CQ      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [4] - Exact time
RO      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [5] - Exact time
PF      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [6] - Takes all day
NR      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [7] - Exact time
MK      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [8] - Exact time
DQ      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [9] - Exact time
RM      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [10] - Exact time
FK      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)     
HP      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)     ---== Unit ==---
CI      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [1] - National currency
OO      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [2] - None
MG      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [3] - People
CO      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [4] - Percentage
NE      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [5] - Percentage
OK      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [6] - None
KQ      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [7] - National currency
CH      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [8] - None
LQ      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [9] - Percentage
CE      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [10] - People
LL      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)     
PD      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)     ---== Importance ==---
FS      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [1] - Low
PD      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [2] - Moderate
DK      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [3] - High
EM      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [4] - Low
QJ      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [5] - Moderate
GQ      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [6] - None
PG      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [7] - Low
RO      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [8] - Moderate
LI      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [9] - Low
FM      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [10] - High
ND      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)     
CM      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)     ---== Multiplier ==---
HE      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [1] - Billions
MK      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [2] - None
IM      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [3] - Thousands
MI      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [4] - None
HQ      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [5] - None
OH      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [6] - None
DN      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [7] - Billions
IF      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [8] - None
LN      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [9] - None
OH      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [10] - Thousands
DM      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)     
FF      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)     ---== Impact ==---
OK      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [1] - Positive
OR      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [2] - None
EJ      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [3] - Positive
RQ      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [4] - Negative
CG      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [5] - Negative
KN      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [6] - None
JF      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [7] - None
EM      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [8] - None
GD      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [9] - Positive
QH      0       21:14:19.340    Test_enums_descriptions (USDCAD,H1)        [10] - Positive

たとえば、最初のイベント「BoE住宅エクイティ引き出し前期比」は次のように記述されます。

  1. "Type" - Indicator;
  2. "Sector" - Money;
  3. "Frequency" - Quarterly;
  4. "Time mode" - Exact time;
  5. "Unit" - National currency;
  6. "Importance" - Low;
  7. "Multiplier" - Billions;
  8. "Impact" - Positive.

最後のイベント「請求者数の変更」は、次のように記述されます。

  1. "Type" - Indicator;
  2. "Sector" - Labor;
  3. "Frequency" - Quarterly;
  4. "Time mode" - Exact time;
  5. "Unit" - National currency;
  6. "Importance" - Low;
  7. "Multiplier" - Billions;
  8. "Impact" - Positive.


2.3.4履歴にアクセスするメソッド

このメソッドは、組み込みのカレンダー関数も使用して、イベント値に関するデータを取得します。たとえば::CalendarValueHistoryByEvent()関数は、2つのオーバーロードされたメソッドCiCalendarInfo::ValueHistorySelectByEvent()によってアクセスされます。 1つ目は、指定された時間範囲内のすべてのイベントの値の配列をイベントIDによってMqlCalendarValue構造体の形式で返し、2つ目は時系列に変換された値の配列です。

Test_value_history_by_event.mq5スクリプトのCiCalendarInfo::ValueHistorySelectByEvent()メソッドの操作を見てみましょう。

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- NFP
   CiCalendarInfo nfp_info;
   ulong nfp_id = 840030016;
   if(nfp_info.Init(NULL, WRONG_VALUE, nfp_id))
     {
      SiTimeSeries nfp_ts;
      if(nfp_info.ValueHistorySelectByEvent(nfp_ts, 0, ::TimeTradeServer()))
         nfp_ts.Print(0);
     }
  }
//+------------------------------------------------------------------+

米国非農業部門就業者数の全履歴を選択します。

操作ログに以下のエントリが表示されます。

PL      0       21:45:03.581    Test_value_history_by_event (USDCAD,H1) ---== New Calendar Info object ==---
NI      0       21:45:03.581    Test_value_history_by_event (USDCAD,H1)    Event id: 840030016
OM      0       21:45:03.581    Test_value_history_by_event (USDCAD,H1) 
HG      0       21:45:03.581    Test_value_history_by_event (USDCAD,H1) ---== Times series - Nonfarm Payrolls==---
CJ      0       21:45:03.581    Test_value_history_by_event (USDCAD,H1) [1]: time - 2007.03.09 16:30, value - 97
RE      0       21:45:03.581    Test_value_history_by_event (USDCAD,H1) [2]: time - 2007.04.06 15:30, value - 177
MS      0       21:45:03.581    Test_value_history_by_event (USDCAD,H1) [3]: time - 2007.05.04 15:30, value - 80
FL      0       21:45:03.581    Test_value_history_by_event (USDCAD,H1) [4]: time - 2007.06.01 15:30, value - 190
LH      0       21:45:03.581    Test_value_history_by_event (USDCAD,H1) [5]: time - 2007.07.06 15:30, value - 69
...
JE      0       21:45:03.583    Test_value_history_by_event (USDCAD,H1) [172]: time - 2021.06.04 15:30, value - 559
JP      0       21:45:03.583    Test_value_history_by_event (USDCAD,H1) [173]: time - 2021.07.02 15:30, value - 850
IO      0       21:45:03.583    Test_value_history_by_event (USDCAD,H1) [174]: time - 2021.08.06 15:30, value - 943
NJ      0       21:45:03.583    Test_value_history_by_event (USDCAD,H1) [175]: time - 2021.09.03 15:30, value - 235
HI      0       21:45:03.583    Test_value_history_by_event (USDCAD,H1) [176]: time - 2021.10.08 15:30, value - 194

*ここでは、記事が乱雑にならないように、最初と最後の5つのイベント値を指定しました。


2.3.5カレンダーデータベースのステータスを確認するメソッド

これらのメソッドは、適切な組み込みカレンダー関数も使用します。エラーは、取得されたイベント値の数がゼロに等しく、エラー自体がゼロを超えている場合にのみ報告されます。 

CiCalendarInfo::ValueLastSelectByEvent()メソッドの例は、新しい値の出現を検出する必要がある3番目のセクション「投資筋ネットポジション指標」で検討されています。


2.3.6国と大陸のデータを取得するメソッド

これらのメソッドは特定の国のデータを返します。それぞれについて簡単に説明します。

CiCalendarInfo::GetCountries(CArrayString &countries_arr)メソッドは、初期化中に取得された国のリストを文字列型変数の動的配列として返します。

CiCalendarInfo::GetCountries(MqlCalendarCountry &countries[])メソッドは、初期化中に取得された国のリストをMqlCalendarCountry型変数の配列として返します。

CiCalendarInfo::GetUniqueContinents(string & continents[])メソッドは、国が存在する大陸のリストを返します。後者も初期化中に取得されました。

CiCalendarInfo::GetCountriesByContinent(const ENUM_CONTINENT src_continent, CArrayString &countries_arr)メソッドは、指定された大陸ごとの国のリストを返します。

CiCalendarInfo::GetCountryNameById(const ulong country_id)メソッドは、IDによって一意の国名を返します。

ENUM_CONTINENT列挙は、大陸の操作を可能にします。次の大陸について説明します。

  1. 世界
  2. アジア
  3. アフリカ
  4. ヨーロッパ
  5. 北米
  6. 南米
  7. オーストラリア/オセアニア
  8. 南極大陸

列挙に南極大陸を含めたのはおかしいように思えるかもしれませが、私は大陸の完全なリストが欲しかったので、そこにとどまらせてください。 「世界」定数は、別の大陸として配置されます。

さらに、大陸で機能するSCountryByContinent構造を作成しました。 初期化メソッドは、国コード、名前、および対応する大陸の定数配列を特徴としています。 現在のバージョンは、EUと全世界を含む197カ国を備えています。

国と大陸のデータを取得するためのメソッドの動作をチェックするTest_get_countries.mq5スクリプトを作成しましょう。

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   CiCalendarInfo country_calendar_info;
   if(country_calendar_info.Init())
     {
      //--- 1) get countries (CArrayString)
      CArrayString countries_arr;
      if(country_calendar_info.GetCountries(countries_arr))
        {
         int countries_num = countries_arr.Total();
         if(countries_num > 0)
           {
            ::Print("\n---== CArrayString list ==---");
            ::PrintFormat("   Countries list consists of %d countries.", countries_num);
            ::PrintFormat("   First country: %s", countries_arr.At(0));
            ::PrintFormat("   Last country: %s", countries_arr.At(countries_num - 1));
           }
        }
      //--- 2) get countries (MqlCalendarCountry)
      MqlCalendarCountry countries[];
      if(country_calendar_info.GetCountries(countries))
        {
         int countries_num = ::ArraySize(countries);
         if(countries_num > 0)
           {
            ::Print("\n---== MqlCalendarCountry array ==---");
            ::PrintFormat("   Countries array consists of %d countries.", countries_num);
            ::PrintFormat("   First country: %s", countries[0].name);
            ::PrintFormat("   Last country: %s", countries[countries_num - 1].name);
           }
        }
      //--- 3) get unique continents
      string continent_names[];
      int continents_num = 0;
      if(country_calendar_info.GetUniqueContinents(continent_names))
        {
         continents_num = ::ArraySize(continent_names);
         if(continents_num > 0)
           {
            ::Print("\n---== Unique continent names ==---");
            for(int c_idx = 0; c_idx < continents_num; c_idx++)
              {
               string curr_continent_name = continent_names[c_idx];
               ::PrintFormat("   [%d] - %s", c_idx + 1, curr_continent_name);
              }
           }
        }
      //--- 4) get countries by continent
      if(continents_num)
        {
         ENUM_CONTINENT continents[];
         ::ArrayResize(continents, continents_num);
         ::Print("\n---== Countries by continent ==---");
         for(int c_idx = 0; c_idx < continents_num; c_idx++)
           {
            ENUM_CONTINENT curr_continent =
               SCountryByContinent::ContinentByDescription(continent_names[c_idx]);
            if(countries_arr.Shutdown())
               if(country_calendar_info.GetCountriesByContinent(curr_continent, countries_arr))
                 {
                  int countries_by_continent = countries_arr.Total();
                  ::PrintFormat("   Continent \"%s\" includes %d country(-ies):",
                                continent_names[c_idx], countries_by_continent);
                  for(int c_jdx = 0; c_jdx < countries_by_continent; c_jdx++)
                    {
                     ::PrintFormat("   [%d] - %s", c_jdx + 1,
                                   countries_arr.At(c_jdx));
                    }
                 }
           }
        }
      //--- 5) get country description
      string country_code = "RU";
      SCountryByContinent country_continent_data;
      if(country_continent_data.Init(country_code))
        {
         ::Print("\n---== Country ==---");
         ::PrintFormat("   Name: %s", country_continent_data.Country());
         ::PrintFormat("   Code: %s", country_continent_data.Code());
         ENUM_CONTINENT curr_continent = country_continent_data.Continent();
         ::PrintFormat("   Continent enum: %s", ::EnumToString(curr_continent));
         ::PrintFormat("   Continent description: %s",
                       country_continent_data.ContinentDescription());
        }
     }
  }
//+------------------------------------------------------------------+

スクリプト作業の結果、操作ログに次の情報が表示されます。

EH      0       23:05:16.492    Test_get_countries (USDCAD,H1)  ---== New Calendar Info object ==---
HR      0       23:05:16.492    Test_get_countries (USDCAD,H1)  
QH      0       23:05:16.492    Test_get_countries (USDCAD,H1)  ---== CArrayString list ==---
NR      0       23:05:16.492    Test_get_countries (USDCAD,H1)     Countries list consists of 23 countries.
NP      0       23:05:16.492    Test_get_countries (USDCAD,H1)     First country: European Union
LF      0       23:05:16.492    Test_get_countries (USDCAD,H1)     Last country: Norway
LQ      0       23:05:16.492    Test_get_countries (USDCAD,H1)  
GG      0       23:05:16.492    Test_get_countries (USDCAD,H1)  ---== MqlCalendarCountry array ==---
IL      0       23:05:16.492    Test_get_countries (USDCAD,H1)     Countries array consists of 23 countries.
JP      0       23:05:16.492    Test_get_countries (USDCAD,H1)     First country: European Union
HG      0       23:05:16.492    Test_get_countries (USDCAD,H1)     Last country: Norway
OR      0       23:05:16.493    Test_get_countries (USDCAD,H1)  
FJ      0       23:05:16.493    Test_get_countries (USDCAD,H1)  ---== Unique continent names ==---
KS      0       23:05:16.493    Test_get_countries (USDCAD,H1)     [1] - Africa
NK      0       23:05:16.493    Test_get_countries (USDCAD,H1)     [2] - Asia
HR      0       23:05:16.493    Test_get_countries (USDCAD,H1)     [3] - Australia/Oceania
HM      0       23:05:16.493    Test_get_countries (USDCAD,H1)     [4] - Europe
RE      0       23:05:16.493    Test_get_countries (USDCAD,H1)     [5] - North America
CO      0       23:05:16.493    Test_get_countries (USDCAD,H1)     [6] - South America
GH      0       23:05:16.493    Test_get_countries (USDCAD,H1)     [7] - World
GP      0       23:05:18.606    Test_get_countries (USDCAD,H1)  
LE      0       23:05:18.606    Test_get_countries (USDCAD,H1)  ---== Countries by continent ==---
HO      0       23:05:18.608    Test_get_countries (USDCAD,H1)     Continent "Africa" includes 1 country(-ies):
RR      0       23:05:18.608    Test_get_countries (USDCAD,H1)     [1] - South Africa
NH      0       23:05:18.610    Test_get_countries (USDCAD,H1)     Continent "Asia" includes 6 country(-ies):
CM      0       23:05:18.610    Test_get_countries (USDCAD,H1)     [1] - China
RK      0       23:05:18.610    Test_get_countries (USDCAD,H1)     [2] - Hong Kong
CL      0       23:05:18.610    Test_get_countries (USDCAD,H1)     [3] - India
LJ      0       23:05:18.610    Test_get_countries (USDCAD,H1)     [4] - South Korea
LJ      0       23:05:18.610    Test_get_countries (USDCAD,H1)     [5] - Japan
IR      0       23:05:18.610    Test_get_countries (USDCAD,H1)     [6] - Singapore
OK      0       23:05:18.614    Test_get_countries (USDCAD,H1)     Continent "Australia/Oceania" includes 2 country(-ies):
RM      0       23:05:18.614    Test_get_countries (USDCAD,H1)     [1] - Australia
NJ      0       23:05:18.614    Test_get_countries (USDCAD,H1)     [2] - New Zealand
MM      0       23:05:18.616    Test_get_countries (USDCAD,H1)     Continent "Europe" includes 9 country(-ies):
LO      0       23:05:18.616    Test_get_countries (USDCAD,H1)     [1] - European Union
DF      0       23:05:18.616    Test_get_countries (USDCAD,H1)     [2] - Germany
OQ      0       23:05:18.616    Test_get_countries (USDCAD,H1)     [3] - France
CE      0       23:05:18.616    Test_get_countries (USDCAD,H1)     [4] - United Kingdom
OM      0       23:05:18.616    Test_get_countries (USDCAD,H1)     [5] - Switzerland
RS      0       23:05:18.616    Test_get_countries (USDCAD,H1)     [6] - Spain
FE      0       23:05:18.616    Test_get_countries (USDCAD,H1)     [7] - Sweden
JS      0       23:05:18.616    Test_get_countries (USDCAD,H1)     [8] - Italy
DD      0       23:05:18.616    Test_get_countries (USDCAD,H1)     [9] - Norway
LR      0       23:05:18.618    Test_get_countries (USDCAD,H1)     Continent "North America" includes 3 country(-ies):
LK      0       23:05:18.618    Test_get_countries (USDCAD,H1)     [1] - Canada
HS      0       23:05:18.618    Test_get_countries (USDCAD,H1)     [2] - United States
CK      0       23:05:18.618    Test_get_countries (USDCAD,H1)     [3] - Mexico
GL      0       23:05:18.619    Test_get_countries (USDCAD,H1)     Continent "South America" includes 1 country(-ies):
EQ      0       23:05:18.619    Test_get_countries (USDCAD,H1)     [1] - Brazil
DH      0       23:05:18.622    Test_get_countries (USDCAD,H1)     Continent "World" includes 1 country(-ies):
JK      0       23:05:18.622    Test_get_countries (USDCAD,H1)     [1] - Worldwide
QM      0       23:05:18.622    Test_get_countries (USDCAD,H1)  
KH      0       23:05:18.622    Test_get_countries (USDCAD,H1)  ---== Country ==---
PQ      0       23:05:18.622    Test_get_countries (USDCAD,H1)     Name: Russian Federation
KG      0       23:05:18.622    Test_get_countries (USDCAD,H1)     Code: RU
MR      0       23:05:18.622    Test_get_countries (USDCAD,H1)     Continent enum: CONTINENT_EUROPE
MI      0       23:05:18.622    Test_get_countries (USDCAD,H1)     Continent description: Europe

したがって、現在のカレンダーバージョンでは、7つの大陸にある23か国の経済に関連するイベントが記述されています(「世界」定数が考慮されている場合)。 


2.3.7  イベントデータを取得するメソッド

これらのメソッドでは、特定の基準に従ってイベントを選択できます。 

CiCalendarInfo::GetEventsByName(CArrayString &events_arr, const string name = NULL)メソッドは、文字列型変数の動的配列として選択を実行します。イベント名は選択基準として機能します。

CiCalendarInfo:: GetEventsByName(MqlCalendarEvent & events[], const string name = NULL)メソッドは、前のメソッドと似ています。唯一の違いは、MqlCalendarCountry型変数の配列の形式で選択を形成するということです。 

CiCalendarInfo::FilterEvents(MqlCalendarEvent &filtered_events[]、MqlCalendarEvent &src_events[], const ulong filter)メソッドも、MqlCalendarCountry型変数の配列として選択を形成します。ここには、フラグのセットに実装された複数の基準がすでにあります。 そのような基準は全部で49あります。これらはすべての列挙値(ENUM_CALENDAR_EVENT_TYPE、ENUM_CALENDAR_EVENT_SECTOR、ENUM_CALENDAR_EVENT_FREQUENCY、ENUM_CALENDAR_EVENT_TIMEMODE、ENUM_CALENDAR_EVENT_UNIT、ENUM_CALENDAR_EVENT_IMPORTANCE、ENUM_CALENDAR_EVENT_MULTIPLIER)をカバーします。

この場合は49ビットが必要ですが「enum」型は4バイトのデータ型(32ビット)であるため、新しい包括的なメガ列挙を作成することは不可能のようですが、64ビットを提供する「long」タイプが存在します。

この問題を解決するには、次のコードを使用します。

//--- defines for events filtering
//--- 1) type (3)
#define FILTER_BY_TYPE_EVENT           0x1              // 1 by type "event"
#define FILTER_BY_TYPE_INDICATOR       0x2              // 2 by type "indicator"
#define FILTER_BY_TYPE_HOLIDAY         0x4              // 3 by type "holiday"
//--- 2) sector (13)
#define FILTER_BY_SECTOR_NONE          0x8              // 4 by sector "none"
#define FILTER_BY_SECTOR_MARKET        0x10             // 5 by sector "market"
#define FILTER_BY_SECTOR_GDP           0x20             // 6 by sector "GDP"
#define FILTER_BY_SECTOR_JOBS          0x40             // 7 by sector "jobs"
#define FILTER_BY_SECTOR_PRICES        0x80             // 8 by sector "prices"
#define FILTER_BY_SECTOR_MONEY         0x100            // 9 by sector "money"
#define FILTER_BY_SECTOR_TRADE         0x200            // 10 by sector "trade"
#define FILTER_BY_SECTOR_GOVERNMENT    0x400            // 11 by sector "government"
#define FILTER_BY_SECTOR_BUSINESS      0x800            // 12 by sector "business"
#define FILTER_BY_SECTOR_CONSUMER      0x1000           // 13 by sector "consumer"
#define FILTER_BY_SECTOR_HOUSING       0x2000           // 14 by sector "housing"
#define FILTER_BY_SECTOR_TAXES         0x4000           // 15 by sector "taxes"
#define FILTER_BY_SECTOR_HOLIDAYS      0x8000           // 16 by sector "holidays"
//--- 3) frequency (6)
#define FILTER_BY_FREQUENCY_NONE       0x10000          // 17 by frequency "none"
#define FILTER_BY_FREQUENCY_WEEK       0x20000          // 18 by frequency "week"
#define FILTER_BY_FREQUENCY_MONTH      0x40000          // 19 by frequency "month"
#define FILTER_BY_FREQUENCY_QUARTER    0x80000          // 20 by frequency "quarter"
#define FILTER_BY_FREQUENCY_YEAR       0x100000         // 21 by frequency "year"
#define FILTER_BY_FREQUENCY_DAY        0x200000         // 22 by frequency "day"
//--- 4) importance (4)
#define FILTER_BY_IMPORTANCE_NONE      0x400000         // 23 by importance "none"
#define FILTER_BY_IMPORTANCE_LOW       0x800000         // 24 by importance "low"
#define FILTER_BY_IMPORTANCE_MODERATE  0x1000000        // 25 by importance "medium"
#define FILTER_BY_IMPORTANCE_HIGH      0x2000000        // 26 by importance "high"
//--- 5) unit (14)
#define FILTER_BY_UNIT_NONE            0x4000000        // 27 by unit "none"
#define FILTER_BY_UNIT_PERCENT         0x8000000        // 28 by unit "percentage"
#define FILTER_BY_UNIT_CURRENCY        0x10000000       // 29 by unit "currency"
#define FILTER_BY_UNIT_HOUR            0x20000000       // 30 by unit "hours"
#define FILTER_BY_UNIT_JOB             0x40000000       // 31 by unit "jobs"
#define FILTER_BY_UNIT_RIG             0x80000000       // 32 by unit "drilling rigs"
#define FILTER_BY_UNIT_USD             0x100000000      // 33 by unit "USD"
#define FILTER_BY_UNIT_PEOPLE          0x200000000      // 34 by unit "people"
#define FILTER_BY_UNIT_MORTGAGE        0x400000000      // 35 by unit "mortgage loans"
#define FILTER_BY_UNIT_VOTE            0x800000000      // 36 by unit "votes"
#define FILTER_BY_UNIT_BARREL          0x1000000000     // 37 by unit "barrels"
#define FILTER_BY_UNIT_CUBICFEET       0x2000000000     // 38 by unit "cubic feet"
#define FILTER_BY_UNIT_POSITION        0x4000000000     // 39 by unit "net positions"
#define FILTER_BY_UNIT_BUILDING        0x8000000000     // 40 by unit "buildings"
//--- 6) multiplier (5)
#define FILTER_BY_MULTIPLIER_NONE      0x10000000000    // 41 by multiplier "none"
#define FILTER_BY_MULTIPLIER_THOUSANDS 0x20000000000    // 42 by multiplier "thousands"
#define FILTER_BY_MULTIPLIER_MILLIONS  0x40000000000    // 43 by multiplier "millions"
#define FILTER_BY_MULTIPLIER_BILLIONS  0x80000000000    // 44 by multiplier "billions"
#define FILTER_BY_MULTIPLIER_TRILLIONS 0x100000000000   // 45 by multiplier "trillions"
//--- 7) time mode (4)
#define FILTER_BY_TIMEMODE_DATETIME    0x200000000000   // 46 by time mode "na"
#define FILTER_BY_TIMEMODE_DATE        0x400000000000   // 47 by time mode "positive"
#define FILTER_BY_TIMEMODE_NOTIME      0x800000000000   // 48 by time mode "negative"
#define FILTER_BY_TIMEMODE_TENTATIVE   0x1000000000000  // 49 by time mode "na"
//--- type
#define IS_TYPE_EVENT(filter) ((filter&FILTER_BY_TYPE_EVENT)!=0)
#define IS_TYPE_INDICATOR(filter) ((filter&FILTER_BY_TYPE_INDICATOR)!=0)
#define IS_TYPE_HOLIDAY(filter) ((filter&FILTER_BY_TYPE_HOLIDAY)!=0)
//--- sector
#define IS_SECTOR_NONE(filter) ((filter&FILTER_BY_SECTOR_NONE)!=0)
#define IS_SECTOR_MARKET(filter) ((filter&FILTER_BY_SECTOR_MARKET)!=0)
#define IS_SECTOR_GDP(filter) ((filter&FILTER_BY_SECTOR_GDP)!=0)
#define IS_SECTOR_JOBS(filter) ((filter&FILTER_BY_SECTOR_JOBS)!=0)
#define IS_SECTOR_PRICES(filter) ((filter&FILTER_BY_SECTOR_PRICES)!=0)
#define IS_SECTOR_MONEY(filter) ((filter&FILTER_BY_SECTOR_MONEY)!=0)
#define IS_SECTOR_TRADE(filter) ((filter&FILTER_BY_SECTOR_TRADE)!=0)
#define IS_SECTOR_CONSUMER(filter) ((filter&FILTER_BY_SECTOR_CONSUMER)!=0)
#define IS_SECTOR_HOUSING(filter) ((filter&FILTER_BY_SECTOR_HOUSING)!=0)
#define IS_SECTOR_TAXES(filter) ((filter&FILTER_BY_SECTOR_TAXES)!=0)
#define IS_SECTOR_HOLIDAYS(filter) ((filter&FILTER_BY_SECTOR_HOLIDAYS)!=0)
//--- frequency
#define IS_FREQUENCY_NONE(filter) ((filter&FILTER_BY_FREQUENCY_NONE)!=0)
#define IS_FREQUENCY_WEEK(filter) ((filter&FILTER_BY_FREQUENCY_WEEK)!=0)
#define IS_FREQUENCY_MONTH(filter) ((filter&FILTER_BY_FREQUENCY_MONTH)!=0)
#define IS_FREQUENCY_QUARTER(filter) ((filter&FILTER_BY_FREQUENCY_QUARTER)!=0)
#define IS_FREQUENCY_YEAR(filter) ((filter&FILTER_BY_FREQUENCY_YEAR)!=0)
#define IS_FREQUENCY_DAY(filter) ((filter&FILTER_BY_FREQUENCY_DAY)!=0)
//--- importance
#define IS_IMPORTANCE_NONE(filter) ((filter&FILTER_BY_IMPORTANCE_NONE)!=0)
#define IS_IMPORTANCE_LOW(filter) ((filter&FILTER_BY_IMPORTANCE_LOW)!=0)
#define IS_IMPORTANCE_MODERATE(filter) ((filter&FILTER_BY_IMPORTANCE_MODERATE)!=0)
#define IS_IMPORTANCE_HIGH(filter) ((filter&FILTER_BY_IMPORTANCE_HIGH)!=0)
//--- unit
#define IS_UNIT_NONE(filter) ((filter&FILTER_BY_UNIT_NONE)!=0)
#define IS_UNIT_PERCENT(filter) ((filter&FILTER_BY_UNIT_PERCENT)!=0)
#define IS_UNIT_CURRENCY(filter) ((filter&FILTER_BY_UNIT_CURRENCY)!=0)
#define IS_UNIT_HOUR(filter) ((filter&FILTER_BY_UNIT_HOUR)!=0)
#define IS_UNIT_JOB(filter) ((filter&FILTER_BY_UNIT_JOB)!=0)
#define IS_UNIT_RIG(filter) ((filter&FILTER_BY_UNIT_RIG)!=0)
#define IS_UNIT_USD(filter) ((filter&FILTER_BY_UNIT_USD)!=0)
#define IS_UNIT_PEOPLE(filter) ((filter&FILTER_BY_UNIT_PEOPLE)!=0)
#define IS_UNIT_MORTGAGE(filter) ((filter&FILTER_BY_UNIT_MORTGAGE)!=0)
#define IS_UNIT_VOTE(filter) ((filter&FILTER_BY_UNIT_VOTE)!=0)
#define IS_UNIT_BARREL(filter) ((filter&FILTER_BY_UNIT_BARREL)!=0)
#define IS_UNIT_CUBICFEET(filter) ((filter&FILTER_BY_UNIT_CUBICFEET)!=0)
#define IS_UNIT_POSITION(filter) ((filter&FILTER_BY_UNIT_POSITION)!=0)
#define IS_UNIT_BUILDING(filter) ((filter&FILTER_BY_UNIT_BUILDING)!=0)
//--- multiplier
#define IS_MULTIPLIER_NONE(filter) ((filter&FILTER_BY_MULTIPLIER_NONE)!=0)
#define IS_MULTIPLIER_THOUSANDS(filter) ((filter&FILTER_BY_MULTIPLIER_THOUSANDS)!=0)
#define IS_MULTIPLIER_MILLIONS(filter) ((filter&FILTER_BY_MULTIPLIER_MILLIONS)!=0)
#define IS_MULTIPLIER_BILLIONS(filter) ((filter&FILTER_BY_MULTIPLIER_BILLIONS)!=0)
#define IS_MULTIPLIER_TRILLIONS(filter) ((filter&FILTER_BY_MULTIPLIER_TRILLIONS)!=0)
//--- time mode
#define IS_TIMEMODE_DATETIME(filter) ((filter&FILTER_BY_TIMEMODE_DATETIME)!=0)
#define IS_TIMEMODE_DATE(filter) ((filter&FILTER_BY_TIMEMODE_DATE)!=0)
#define IS_TIMEMODE_NOTIME(filter) ((filter&FILTER_BY_TIMEMODE_NOTIME)!=0)
#define IS_TIMEMODE_TENTATIVE(filter) ((filter&FILTER_BY_TIMEMODE_TENTATIVE)!=0)

Test_filter_events.mq5スクリプトのテスト例を見てみましょう。最初に、指定されたEUR通貨のカレンダーオブジェクトが作成されます。

次に、ブロック1 で、名前に「Unemployment」が含まれるEURに関連するすべてのイベントを選択します。このタイプのイベントは33あります。イベント名は、文字列型変数の動的配列に送信されます。

ブロック2で、MqlCalendarEvent型配列に入力しながら同じことを行います。

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   CiCalendarInfo event_calendar_info;
   if(event_calendar_info.Init("EUR"))
     {
      //--- 1) get events by name (CArrayString)
      CArrayString events_arr;
      string ev_name = "Unemployment";
      if(event_calendar_info.GetEventsByName(events_arr, ev_name))
        {
         int events_num = events_arr.Total();
         if(events_num > 0)
           {
            ::Print("\n---== CArrayString list ==---");
            ::PrintFormat("   Events list consists of %d events.", events_num);
            ::PrintFormat("   First event: %s", events_arr.At(0));
            ::PrintFormat("   Last event: %s", events_arr.At(events_num - 1));
           }
        }
      //--- 2) get events by name (MqlCalendarEvent)
      MqlCalendarEvent events[];
      if(event_calendar_info.GetEventsByName(events, ev_name))
        {
         int events_num = ::ArraySize(events);
         if(events_num > 0)
           {
            ::Print("\n---== MqlCalendarEvent array ==---");
            ::PrintFormat("   Events array consists of %d events.", events_num);
            ::PrintFormat("   First event: %s", events[0].name);
            ::PrintFormat("   Last event: %s", events[events_num - 1].name);
           }
        }
      //--- 3) filter events
      MqlCalendarEvent filtered_events[];
      int indices[2];
      indices[0] = 0;
      string events_str[2];
      events_str[0] = "First";
      events_str[1] = "Last";
      ulong filter = 0;
      filter |= FILTER_BY_IMPORTANCE_HIGH;
      if(event_calendar_info.FilterEvents(filtered_events, events, filter))
        {
         int f_events_num = ::ArraySize(filtered_events);
         ::Print("\n---== Filtered events array ==---");
         ::Print("   Filtered by: importance high");
         ::PrintFormat("   Events array consists of %d events.", ::ArraySize(filtered_events));
         if(f_events_num > 0)
           {
            indices[1] = f_events_num - 1;
            for(int ind = 0; ind <::ArraySize(indices); ind++)
              {
               MqlCalendarEvent curr_event = filtered_events[indices[ind]];
               ::PrintFormat("   \n%s event:", events_str[ind]);
               event_calendar_info.PrintEventDescription(curr_event);
              }
           }
         ::ArrayFree(filtered_events);
         filter ^= FILTER_BY_IMPORTANCE_HIGH;
        }
      filter |= FILTER_BY_IMPORTANCE_MODERATE;
      if(event_calendar_info.FilterEvents(filtered_events, events, filter))
        {
         int f_events_num = ::ArraySize(filtered_events);
         ::Print("\n---== Filtered events array ==---");
         ::Print("   Filtered by: importance medium");
         ::PrintFormat("   Events array consists of %d events.", ::ArraySize(filtered_events));
         if(f_events_num > 0)
           {
            indices[1] = f_events_num - 1;
            for(int ind = 0; ind <::ArraySize(indices); ind++)
              {
               MqlCalendarEvent curr_event = filtered_events[indices[ind]];
               ::PrintFormat("   \n%s event:", events_str[ind]);
               event_calendar_info.PrintEventDescription(curr_event);
              }
           }
         ::ArrayFree(filtered_events);
         filter ^= FILTER_BY_IMPORTANCE_MODERATE;
        }
      filter |= FILTER_BY_IMPORTANCE_LOW;
      if(event_calendar_info.FilterEvents(filtered_events, events, filter))
        {
         int f_events_num = ::ArraySize(filtered_events);
         ::Print("\n---== Filtered events array ==---");
         ::Print("   Filtered by: importance low");
         ::PrintFormat("   Events array consists of %d events.", ::ArraySize(filtered_events));
         if(f_events_num > 0)
           {
            indices[1] = f_events_num - 1;
            for(int ind = 0; ind <::ArraySize(indices); ind++)
              {
               MqlCalendarEvent curr_event = filtered_events[indices[ind]];
               ::PrintFormat("   \n%s event:", events_str[ind]);
               event_calendar_info.PrintEventDescription(curr_event);
              }
           }
         ::ArrayFree(filtered_events);
         filter ^= FILTER_BY_IMPORTANCE_LOW;
        }
      filter |= FILTER_BY_IMPORTANCE_NONE;
      if(event_calendar_info.FilterEvents(filtered_events, events, filter))
        {
         int f_events_num = ::ArraySize(filtered_events);
         ::Print("\n---== Filtered events array ==---");
         ::Print("   Filtered by: importance none");
         ::PrintFormat("   Events array consists of %d events.", ::ArraySize(filtered_events));
         if(f_events_num > 0)
           {
            indices[1] = f_events_num - 1;
            for(int ind = 0; ind <::ArraySize(indices); ind++)
              {
               MqlCalendarEvent curr_event = filtered_events[indices[ind]];
               ::PrintFormat("   \n%s event:", events_str[ind]);
               event_calendar_info.PrintEventDescription(curr_event);
              }
           }
        }
     }
  }
//+------------------------------------------------------------------+

ブロック3で、イベントを重要度で並べ替えます。まず、以前に名前で選択した33のイベントのうちどれが重要であるかを見てみましょう。結局のところ、どれも重要ではありません。27のイベントの重要度は中程度であり、6つのイベントは重要度が低いです。重要度が指定されていないイベントはありません。 

操作ログは次のようになります。

JL      0       13:18:48.419    Test_filter_events (USDCAD,H1)  
FM      0       13:18:48.421    Test_filter_events (USDCAD,H1)  ---== New Calendar Info object ==---
JP      0       13:18:48.421    Test_filter_events (USDCAD,H1)     Currency: EUR
CE      0       13:18:48.630    Test_filter_events (USDCAD,H1)  
EL      0       13:18:48.631    Test_filter_events (USDCAD,H1)  ---== CArrayString list ==---
IF      0       13:18:48.631    Test_filter_events (USDCAD,H1)     Events list consists of 33 events.
MQ      0       13:18:48.631    Test_filter_events (USDCAD,H1)     First event: Unemployment Rate
RK      0       13:18:48.631    Test_filter_events (USDCAD,H1)     Last event: NAV Unemployment Change
HF      0       13:18:48.635    Test_filter_events (USDCAD,H1)  
OR      0       13:18:48.635    Test_filter_events (USDCAD,H1)  ---== MqlCalendarEvent array ==---
JH      0       13:18:48.635    Test_filter_events (USDCAD,H1)     Events array consists of 33 events.
ER      0       13:18:48.635    Test_filter_events (USDCAD,H1)     First event: Unemployment Rate
JM      0       13:18:48.635    Test_filter_events (USDCAD,H1)     Last event: NAV Unemployment Change
DH      0       13:18:48.635    Test_filter_events (USDCAD,H1)  
CR      0       13:18:48.635    Test_filter_events (USDCAD,H1)  ---== Filtered events array ==---
HH      0       13:18:48.635    Test_filter_events (USDCAD,H1)     Filtered by: importance high
DO      0       13:18:48.635    Test_filter_events (USDCAD,H1)     Events array consists of 0 events.
CN      0       13:18:48.636    Test_filter_events (USDCAD,H1)  
PI      0       13:18:48.636    Test_filter_events (USDCAD,H1)  ---== Filtered events array ==---
NO      0       13:18:48.636    Test_filter_events (USDCAD,H1)     Filtered by: importance medium
PE      0       13:18:48.636    Test_filter_events (USDCAD,H1)     Events array consists of 27 events.
KG      0       13:18:48.636    Test_filter_events (USDCAD,H1)     
KI      0       13:18:48.636    Test_filter_events (USDCAD,H1)  First event:
IS      0       13:18:48.636    Test_filter_events (USDCAD,H1)  
EJ      0       13:18:48.636    Test_filter_events (USDCAD,H1)  ---== Event description ==---
JF      0       13:18:48.636    Test_filter_events (USDCAD,H1)     Id: 999030020
DP      0       13:18:48.636    Test_filter_events (USDCAD,H1)     Type: Indicator
KJ      0       13:18:48.636    Test_filter_events (USDCAD,H1)     Sector: Labor market
JM      0       13:18:48.636    Test_filter_events (USDCAD,H1)     Frequency: Monthly
QJ      0       13:18:48.636    Test_filter_events (USDCAD,H1)     Time mode: Exact time
CN      0       13:18:48.636    Test_filter_events (USDCAD,H1)     Country id: 999
KK      0       13:18:48.636    Test_filter_events (USDCAD,H1)     Unit: Percentage
JP      0       13:18:48.636    Test_filter_events (USDCAD,H1)     Importance: Moderate
JH      0       13:18:48.636    Test_filter_events (USDCAD,H1)     Multiplier: None
JF      0       13:18:48.636    Test_filter_events (USDCAD,H1)     Digits: 1
PL      0       13:18:48.636    Test_filter_events (USDCAD,H1)     Source URL: https://ec.europa.eu/eurostat
NH      0       13:18:48.636    Test_filter_events (USDCAD,H1)     Event code: unemployment-rate
MQ      0       13:18:48.636    Test_filter_events (USDCAD,H1)     Name: Unemployment Rate
GI      0       13:18:48.636    Test_filter_events (USDCAD,H1)     
OO      0       13:18:48.636    Test_filter_events (USDCAD,H1)  Last event:
OJ      0       13:18:48.636    Test_filter_events (USDCAD,H1)  
OP      0       13:18:48.636    Test_filter_events (USDCAD,H1)  ---== Event description ==---
QH      0       13:18:48.636    Test_filter_events (USDCAD,H1)     Id: 578040001
NO      0       13:18:48.636    Test_filter_events (USDCAD,H1)     Type: Indicator
ID      0       13:18:48.636    Test_filter_events (USDCAD,H1)     Sector: Labor market
DF      0       13:18:48.636    Test_filter_events (USDCAD,H1)     Frequency: Monthly
KS      0       13:18:48.636    Test_filter_events (USDCAD,H1)     Time mode: Exact time
LI      0       13:18:48.636    Test_filter_events (USDCAD,H1)     Country id: 578
QR      0       13:18:48.636    Test_filter_events (USDCAD,H1)     Unit: Percentage
LJ      0       13:18:48.636    Test_filter_events (USDCAD,H1)     Importance: Moderate
DQ      0       13:18:48.636    Test_filter_events (USDCAD,H1)     Multiplier: None
LH      0       13:18:48.636    Test_filter_events (USDCAD,H1)     Digits: 1
IS      0       13:18:48.636    Test_filter_events (USDCAD,H1)     Source URL: https://www.nav.no/en/Home
EQ      0       13:18:48.636    Test_filter_events (USDCAD,H1)     Event code: nav-unemployment-rate-nsa
PJ      0       13:18:48.636    Test_filter_events (USDCAD,H1)     Name: NAV Unemployment Rate n.s.a.
ED      0       13:18:48.636    Test_filter_events (USDCAD,H1)  
FF      0       13:18:48.636    Test_filter_events (USDCAD,H1)  ---== Filtered events array ==---
PK      0       13:18:48.637    Test_filter_events (USDCAD,H1)     Filtered by: importance low
JS      0       13:18:48.637    Test_filter_events (USDCAD,H1)     Events array consists of 6 events.
FH      0       13:18:48.637    Test_filter_events (USDCAD,H1)     
FS      0       13:18:48.637    Test_filter_events (USDCAD,H1)  First event:
LI      0       13:18:48.637    Test_filter_events (USDCAD,H1)  
LO      0       13:18:48.637    Test_filter_events (USDCAD,H1)  ---== Event description ==---
EK      0       13:18:48.637    Test_filter_events (USDCAD,H1)     Id: 276060003
IM      0       13:18:48.637    Test_filter_events (USDCAD,H1)     Type: Indicator
FE      0       13:18:48.637    Test_filter_events (USDCAD,H1)     Sector: Labor market
OP      0       13:18:48.637    Test_filter_events (USDCAD,H1)     Frequency: Monthly
HQ      0       13:18:48.637    Test_filter_events (USDCAD,H1)     Time mode: Exact time
HH      0       13:18:48.637    Test_filter_events (USDCAD,H1)     Country id: 276
KM      0       13:18:48.637    Test_filter_events (USDCAD,H1)     Unit: People
DJ      0       13:18:48.637    Test_filter_events (USDCAD,H1)     Importance: Low
RM      0       13:18:48.637    Test_filter_events (USDCAD,H1)     Multiplier: Millions
KJ      0       13:18:48.637    Test_filter_events (USDCAD,H1)     Digits: 3
LS      0       13:18:48.637    Test_filter_events (USDCAD,H1)     Source URL: https://www.arbeitsagentur.de/en/welcome
MN      0       13:18:48.637    Test_filter_events (USDCAD,H1)     Event code: unemployment-nsa
ND      0       13:18:48.637    Test_filter_events (USDCAD,H1)     Name: Unemployment n.s.a.
LP      0       13:18:48.637    Test_filter_events (USDCAD,H1)     
LE      0       13:18:48.637    Test_filter_events (USDCAD,H1)  Last event:
DP      0       13:18:48.637    Test_filter_events (USDCAD,H1)  
DG      0       13:18:48.637    Test_filter_events (USDCAD,H1)  ---== Event description ==---
CS      0       13:18:48.637    Test_filter_events (USDCAD,H1)     Id: 578040002
QE      0       13:18:48.637    Test_filter_events (USDCAD,H1)     Type: Indicator
NM      0       13:18:48.637    Test_filter_events (USDCAD,H1)     Sector: Labor market
GH      0       13:18:48.637    Test_filter_events (USDCAD,H1)     Frequency: Monthly
PI      0       13:18:48.637    Test_filter_events (USDCAD,H1)     Time mode: Exact time
GS      0       13:18:48.637    Test_filter_events (USDCAD,H1)     Country id: 578
CE      0       13:18:48.637    Test_filter_events (USDCAD,H1)     Unit: People
LS      0       13:18:48.637    Test_filter_events (USDCAD,H1)     Importance: Low
HJ      0       13:18:48.637    Test_filter_events (USDCAD,H1)     Multiplier: Thousands
QR      0       13:18:48.637    Test_filter_events (USDCAD,H1)     Digits: 3
NI      0       13:18:48.637    Test_filter_events (USDCAD,H1)     Source URL: https://www.nav.no/en/Home
MQ      0       13:18:48.637    Test_filter_events (USDCAD,H1)     Event code: nav-unemployment-change
ES      0       13:18:48.637    Test_filter_events (USDCAD,H1)     Name: NAV Unemployment Change
PI      0       13:18:48.637    Test_filter_events (USDCAD,H1)  
CS      0       13:18:48.637    Test_filter_events (USDCAD,H1)  ---== Filtered events array ==---
DK      0       13:18:48.637    Test_filter_events (USDCAD,H1)     Filtered by: importance none
DH      0       13:18:48.637    Test_filter_events (USDCAD,H1)     Events array consists of 0 events.

すでに述べたように、イベントを選択するためには49の基準がありまり、それらは組み合わせたり、別々に使用したりできます。


3. 投機筋ネットポジション指標

経済指標カレンダーには、さまざまなイベントがあります。私は最も注目すべきイベントの1つを選択しました。商品先物取引委員会の週報でのロングポジションとショートポジションの合計量の違いの公開です。 

チャートの別のウィンドウで、選択した商品資産のデータを表示する指標を作成しましょう。

そのような資産は11あります。次の列挙を作成します。

//+------------------------------------------------------------------+
//| CFTC Non-Commercial Net Positions                                |
//+------------------------------------------------------------------+
enum ENUM_NON_COM_NET_POSITIONS
  {
   NON_COM_NET_POSITIONS_COPPER = 0,      // Copper
   NON_COM_NET_POSITIONS_SILVER = 1,      // Silver
   NON_COM_NET_POSITIONS_GOLD = 2,        // Gold
   NON_COM_NET_POSITIONS_CRUDE_OIL = 3,   // Crude oil
   NON_COM_NET_POSITIONS_SP_500 = 4,      // S&P 500
   NON_COM_NET_POSITIONS_AlUMINIUM = 5,   // Aluminium
   NON_COM_NET_POSITIONS_CORN = 6,        // Corn
   NON_COM_NET_POSITIONS_NGAS = 7,        // Natural gas
   NON_COM_NET_POSITIONS_SOYBEANS = 8,    // Soybeans
   NON_COM_NET_POSITIONS_WHEAT = 9,       // Wheat
   NON_COM_NET_POSITIONS_NASDAQ_100 = 10, // Nasdaq 100
  };

指標は、以前の値を表示し、新しい値を検出することです。最初のタスクでは、OnCalculate()ハンドラで次のコードブロックを使用することにしました。

//--- first call
if(prev_calculated == 0)
  {
//--- initialize buffer
   ::ArrayInitialize(gBuffer, EMPTY_VALUE);
//--- 1) collect all events by country
   ulong country_id = 840; // US
   if(gPtrEventsInfo.Init(NULL, country_id))
     {
      MqlCalendarEvent events[];
      if(gPtrEventsInfo.EventsByCountryDescription(events, false))
        {
         string event_code_substr = GetEventCodeSubstring();
         if(event_code_substr != NULL)
            for(int ev_idx = 0; ev_idx <::ArraySize(events); ev_idx++)
              {
               MqlCalendarEvent curr_event = events[ev_idx];
               if(::StringFind(curr_event.event_code, event_code_substr) > -1)
                 {
                  //--- 2) collect all values by event id
                  if(gPtrValuesInfo.Init(NULL, WRONG_VALUE, curr_event.id))
                    {
                     SiTimeSeries net_positions_ts;
                     if(gPtrValuesInfo.ValueHistorySelectByEvent(net_positions_ts, 0))
                       {
                        string net_positions_name;
                        SiTsObservation ts_observations[];
                        if(net_positions_ts.GetSeries(ts_observations, net_positions_name))
                          {
                           //--- consider only past observations
                           int new_size = 0;
                           for(int obs_idx =::ArraySize(ts_observations) - 1; obs_idx >= 0; obs_idx--)
                             {
                              if(ts_observations[obs_idx].val != EMPTY_VALUE)
                                 break;
                              new_size = obs_idx;
                             }
                           if(new_size > 0)
                              ::ArrayResize(ts_observations, new_size);
                           //--- find the starting date
                           datetime start_dtime, ts_start_dtime;
                           start_dtime = time[0];
                           ts_start_dtime = ts_observations[0].time;
                           if(ts_start_dtime > start_dtime)
                              start_dtime = ts_start_dtime;
                           ::IndicatorSetString(INDICATOR_SHORTNAME, net_positions_name);
                           ::IndicatorSetInteger(INDICATOR_DIGITS, 1);
                           //---
                           int start_bar_idx =::iBarShift(_Symbol, _Period, ts_start_dtime);
                           if(start_bar_idx > -1)
                             {
                              start_bar_idx = rates_total - start_bar_idx;
                              uint observations_cnt = 0;
                              SiTsObservation curr_observation = ts_observations[observations_cnt];
                              uint ts_size = ::ArraySize(ts_observations);
                              for(int bar = start_bar_idx; bar < rates_total; bar++)
                                {
                                 if((observations_cnt + 1) < ts_size)
                                   {
                                    SiTsObservation next_observation =
                                       ts_observations[observations_cnt + 1];
                                    if(time[bar] >= next_observation.time)
                                      {
                                       curr_observation = next_observation;
                                       gLastValueDate = curr_observation.time;
                                       gLastValue = curr_observation.val;
                                       observations_cnt++;
                                      }
                                   }
                                 gBuffer[bar] = curr_observation.val;
                                }
                              //--- just to get a change id
                              MqlCalendarValue values[];
                              gPtrValuesInfo.ValueLastSelectByEvent(gChangeId, values);
                             }
                          }
                       }
                    }
                  break;
                 }
              }
        }
     }
  }

ブロック内の最初のカレンダーオブジェクトを初期化します。国ID(USD)のみを示します。次に、すべての国のイベントを選択し、入力変数に設定されたイベントコードによって必要な資産を検出します。その後、2番目のカレンダーオブジェクトを初期化し、履歴をリクエストします。次に、指標バッファに入力します。

2番目のブロックは、OnCalculate()ハンドラで新しい値を検出することです。

MqlCalendarValue values[];
if(gPtrValuesInfo.ValueLastSelectByEvent(gChangeId, values) > 0)
   if(values[0].time > gLastValueDate)
     {
      gLastValueDate = values[0].time;
      gLastValue = values[0].GetActualValue();
      //--- to log
      if(InpTpLog)
        {
         ::Print("\n---== New event value ==---");
         ::PrintFormat("   Time: %s", ::TimeToString(gLastValueDate));
         datetime server_time =::TimeTradeServer();
         ::PrintFormat("   Release time: %s", ::TimeToString(server_time));
         ::PrintFormat("   Actual value: %0.1f", gLastValue);
        }
     }
//--- if a new bar
if(rates_total > prev_calculated)
   for(int bar = prev_calculated; bar < rates_total; bar++)
      gBuffer[bar] = gLastValue;

結果は次の画像のようになります(図3)。


CFTC S&P 500投機筋ネットポジション

図3 CFTC S&P 500投機筋ネットポジション

指標コードでは、指標のグローバル変数の再初期化により、カレンダーオブジェクトが動的に作成されていることがわかります。


終わりに

この記事では、カレンダーオブジェクトクラスを作成しました。このクラスは、カレンダープロパティへのアクセスを簡素化し、イベント値を受け取ります。カレンダーデータベースは非常に広大であり、サードパーティのリソースに頼ることなく重要な経済イベントを分析できます。

アーカイブには、記事で使用されているソースコードが含まれています。私のPCでは、すべてのファイルとフォルダーは%MQL5\Shared Projects\Testing\Calendarにあります。ソースの場所が異なる場合は、#includeディレクティブを使用してCalendarInfo.mqhヘッダーファイルが正しくインクルードされていることに注意してください。

MetaQuotes Ltdによってロシア語から翻訳されました。
元の記事: https://www.mql5.com/ru/articles/9874

添付されたファイル |
Code.zip (31.04 KB)
手動のチャート作成および取引ツールキット(第III部)最適化と新しいツール 手動のチャート作成および取引ツールキット(第III部)最適化と新しいツール
この記事では、キーボードショートカットを使用してチャート上にグラフィカルオブジェクトを描画するというアイデアをさらに発展させます。ライブラリに新しいツールが追加されました。これには、任意の頂点を通る直線や、反転時間とレベルの評価を可能にする一連の長方形が含まれます。また、この記事では、パフォーマンス向上のためにコードを最適化する可能性を示しています。実装例が書き直され、他の取引プログラムと一緒にShortcutsを使用できるようになりました。初心者より少し上回るコード知識レベルが必要とされます。
EAコンストラクタの開発の試み EAコンストラクタの開発の試み
この記事では、既製のEAの形で一連の取引機能を提供します。この方法では、指標を追加して入力を変更するだけで、複数の取引ストラテジーを取得できます。
より優れたプログラマー(第06部): 効果的なコーディングにつながる9つの習慣 より優れたプログラマー(第06部): 効果的なコーディングにつながる9つの習慣
効果的なコーディングにつながるのはコードを書くことだけではありません。経験を通して見つけた、効果的なコーディングにつながる特定の習慣があります。この記事では、そのいくつかについて詳しく説明します。これは、複雑なアルゴリズムをより手間をかけずに作成する能力を向上させたいすべてのプログラマーにとって必読の記事です。
時間の取扱い(第1部):基本 時間の取扱い(第1部):基本
時間の処理、証券会社のオフセット、夏時間または冬時間への変更を簡素化および明確化する関数とコードスニペット。正確なタイミングは取引において重要な要素になることがあります。現在時刻でロンドンやニューヨークの証券取引所がすでに開いているかまだ開いていないか、外国為替取引の取引時間はいつ開始および終了するかなどです。手動で取引して生活しているトレーダーにとって、これは大きな問題ではありません。