MQL5クックブック - 経済指標カレンダー
Denis Kirichenko | 17 1月, 2022
はじめに
MetaTrader 5ターミナルとMQL5プログラミング言語は絶えず進化しており、市場分析機能、より複雑な自動売買ロボットを開発するためのツールなどが拡張されています。新しいターミナルツールの1つは、手動とロボットの両方の助けを借りて処理できる経済指標カレンダーです。
この組み込みカレンダーには十分な柔軟性があります。ターミナルの[Calendar]タブで設定したり、Webサイトにインストールしたり、モバイル版をダウンロードしたりできます。私はアルゴリズムトレーダーで、主にツールのプログラミング機能に興味があります。
この記事では、それらをハイライトしようと思います。
1. 経済指標カレンダー — ドキュメントの内容
まず、文書化された機能を簡単に見てみましょう。一般的に、それは非常に簡潔です。MQL5リソースの場合によくあることですが、情報は一貫して表示され、小さな例を使用して示されています。
1.1 経済指標カレンダーの関数
ドキュメントには、カレンダーの10個の関数が記載されています。
- CalendarCountryById();
- CalendarEventById();
- CalendarValueById();
- CalendarCountries();
- CalendarEventByCountry();
- CalendarEventByCurrency();
- CalendarValueHistoryByEvent();
- CalendarValueHistory();
- CalendarValueLastByEvent();
- 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)。
図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クラス
カレンダープロパティへのアクセスを簡素化するためにクラスが作成され、イベント値を取得することで継続性を維持します(CAccountInfo、CSymbolInfo、その他の取引クラスと同様) 。<分節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[];
クラスは次のメンバーデータで構成されています。
- m_currency — 国の通貨コード
- m_country_id — ISO3166-1に準拠した国ID
- m_country_description — 国の説明
- m_event_id — イベントID
- m_event_description —イベントの説明
- m_countries — カレンダーで利用可能な国の説明の配列
- 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つの列挙型が含まれています。
- 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;
- 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))に設定します。スクリプトで次のイベントが選択されます。
- BoE住宅エクイティの引き出し前期比
- BoE市場および銀行部門副総裁ラムズデン氏のスピーチ
- 請求者数の変更
- コアCPI前年比
- 平均週収、合計給与前年比
- イースターマンデー
- BoE住宅ローン貸付前月比
- BoE MPC委員Vlieghe氏のスピーチ
- コアRPI前年比
- 請求者数の変更
操作ログに次の説明が表示されます。
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住宅エクイティ引き出し前期比」は次のように記述されます。
- "Type" - Indicator;
- "Sector" - Money;
- "Frequency" - Quarterly;
- "Time mode" - Exact time;
- "Unit" - National currency;
- "Importance" - Low;
- "Multiplier" - Billions;
- "Impact" - Positive.
最後のイベント「請求者数の変更」は、次のように記述されます。
- "Type" - Indicator;
- "Sector" - Labor;
- "Frequency" - Quarterly;
- "Time mode" - Exact time;
- "Unit" - National currency;
- "Importance" - Low;
- "Multiplier" - Billions;
- "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列挙は、大陸の操作を可能にします。次の大陸について説明します。
- 世界
- アジア
- アフリカ
- ヨーロッパ
- 北米
- 南米
- オーストラリア/オセアニア
- 南極大陸
列挙に南極大陸を含めたのはおかしいように思えるかもしれませが、私は大陸の完全なリストが欲しかったので、そこにとどまらせてください。 「世界」定数は、別の大陸として配置されます。
さらに、大陸で機能する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)。
図3 CFTC S&P 500投機筋ネットポジション
指標コードでは、指標のグローバル変数の再初期化により、カレンダーオブジェクトが動的に作成されていることがわかります。
終わりに
この記事では、カレンダーオブジェクトクラスを作成しました。このクラスは、カレンダープロパティへのアクセスを簡素化し、イベント値を受け取ります。カレンダーデータベースは非常に広大であり、サードパーティのリソースに頼ることなく重要な経済イベントを分析できます。
アーカイブには、記事で使用されているソースコードが含まれています。私のPCでは、すべてのファイルとフォルダーは%MQL5\Shared Projects\Testing\Calendarにあります。ソースの場所が異なる場合は、#includeディレクティブを使用してCalendarInfo.mqhヘッダーファイルが正しくインクルードされていることに注意してください。