【MQL5】CalendarValueHistory関数について

MQL5リファレンス
スポンサーリンク
スポンサーリンク

CalendarValueHistory関数の働き・役割

CalendarValueHistory関数は、指定された期間内に発生したすべての経済イベントデータを取得するために使用されます。この関数を利用することで、特定の国や通貨に関連する経済指標のデータを期間で絞り込み、MqlCalendarValue構造体型の配列に格納して取得できます。

CalendarValueHistory関数は、過去の経済イベントだけでなく、将来予定されているイベントデータも含めて取得できるため、過去のデータ分析や将来のイベントに基づく戦略設計に役立ちます。また、特定の国コードや通貨コードを設定することで、取得するイベントデータを絞り込むことができます。

CalendarValueHistory関数の引数について

CalendarValueHistory関数には、経済イベントデータを取得するための5つの引数があります。

書式

bool CalendarValueHistory(
  MqlCalendarValue& values[],        // 値の説明の配列
  datetime          datetime_from,   // 期間の左の境界
  datetime          datetime_to=0,   // 期間の右の境界
  const string      country_code=NULL, // 国コード名 (ISO 3166-1 alpha-2)
  const string      currency=NULL      // 国の通貨コード名
);

第1引数
valuesは、取得した経済イベントの情報を受け取るためのMqlCalendarValue構造体型の配列です。この配列には、関数呼び出し後にイベントの詳細データが格納されます。配列サイズが不足している場合、エラーが発生するため、事前にサイズを調整する必要があります。

第2引数
datetime_fromは、取得するイベントデータの開始日を指定するdateTime型引数です。この日付から開始してデータが取得されます。datetime_fromがdatetime_toより小さい必要があります。

第3引数
datetime_toは、取得するイベントデータの終了日を指定するdateTime型引数で、デフォルトは0です。この引数が0の場合、指定した開始日以降のすべての既知のイベントが返されます。日付を設定すると、開始日から終了日までのデータが返されます。

第4引数
country_codeは、国コードを指定するための文字列です。ISO3166-1 alpha-2形式で指定する必要があり、たとえば日本の場合は「JP」を入力します。特定の国に絞り込む場合に使用し、NULLを指定するとすべての国が対象となります。

第5引数
currencyは、通貨コードを指定するための文字列です。たとえば、日本円の場合は「JPY」と入力します。この通貨コードを指定することで、特定の通貨に関連するイベントのみを取得できます。NULLを指定するとすべての通貨が対象となります。

このように、CalendarValueHistory関数は5つの引数によって取得するイベントの期間や国、通貨を柔軟に設定できるようになっています。

CalendarValueHistory関数の戻り値について

CalendarValueHistory関数は、指定された期間および条件に基づいて経済イベントのデータを取得し、成功または失敗を示す真偽値を返します。

  • 戻り値がtrueの場合、指定された条件に基づいてイベントデータの取得が成功しており、MqlCalendarValue構造体型の配列valuesにデータが格納されています。
  • 戻り値がfalseの場合、データの取得に失敗しています。詳細なエラー情報を確認するためには、GetLastError関数を利用することが推奨されます。

可能なエラーコード:

  • 4001 – ERR_INTERNAL_ERROR
    一般的なランタイムエラーで、関数の実行中に問題が発生したことを示します。
  • 4004 – ERR_NOT_ENOUGH_MEMORY
    メモリが不足しているため、必要な操作が完了できなかったことを示します。配列サイズが不十分な場合などに発生する可能性があります。
  • 5401 – ERR_CALENDAR_TIMEOUT
    リクエストがタイムアウトしたことを示します。サーバーが時間内に応答できなかった場合に発生します。
  • 5400 – ERR_CALENDAR_MORE_DATA
    values配列のサイズが足りず、すべてのイベントデータが格納されなかったことを示します。必要に応じてArrayResize関数配列サイズを調整し、再度実行することが求められます。

CalendarValueHistory関数を使ったサンプルコード

//+------------------------------------------------------------------+
//| スクリプトプログラム開始関数                                     |
//+------------------------------------------------------------------+
void OnStart()
 {
  //--- 日本の国コード(ISO 3166-1 Alpha-2)を指定
  string japan_code = "JP";
  
  //--- イベントを取得する期間の境界を設定する
  // 2018年のすべてのイベントを取得するために、開始日を2018年1月1日に設定
  datetime date_from = D'01.01.2018';
  // 終了日を0に設定すると、すべての既知のイベント(今後のイベントも含む)を取得
  datetime date_to = 0;
  
  //--- 日本のイベント値の配列を作成し、取得する
  MqlCalendarValue values[];
  int values_count = CalendarValueHistory(values, date_from, date_to, japan_code);
  
  //--- 取得したイベントがあるかどうかを確認
  if (values_count > 0)
    {
    // 取得した日本のイベントの数を出力
    PrintFormat("Number of values for Japan events: %d", values_count);
    
    //--- 値が存在しないイベントを配列から削除する
    // 具体的には、actual_valueが-9223372036854775808のものを削除
    for(int i = values_count - 1; i >= 0; i--)
       {
        if(values[i].actual_value == -9223372036854775808)
          ArrayRemove(values, i, 1);  // 配列の該当する要素を削除
       }
    //--- 空の値を削除した後のイベント数を出力
    PrintFormat("Number of values after deleting empty ones: %d", ArraySize(values));
    }
  else
    {
    // イベントの取得に失敗した場合、エラーコードとともにメッセージを出力
    PrintFormat("Failed to receive events for the country code %s, error %d",
                 japan_code, GetLastError());
    // スクリプトの終了
    return;
    }
  
  //--- values配列の要素数が10より多い場合、10個に減らす
  if (ArraySize(values) > 10)
    {
    PrintFormat("Reduce the list of values to 10 and display them");
    // 最初の要素から、指定した数を削除して配列を10個の要素に絞る
    ArrayRemove(values, 0, ArraySize(values) - 10);
    }
  //--- 配列の内容を出力
  ArrayPrint(values);
  
  //--- 各イベントのIDに基づいて詳細なイベント値を取得する
  for (int i = 0; i < ArraySize(values); i++)
    {
    // 各イベントの詳細を格納するための変数を作成
    MqlCalendarValue value;
    
    // CalendarValueById関数でイベントIDに基づいて詳細な値を取得
    CalendarValueById(values[i].id, value);
    
    // 各イベントのID、実際の値、影響度の情報を出力
    PrintFormat("%d: value_id=%d value=%d impact=%s",
                 i, values[i].id, value.actual_value, 
                 EnumToString(ENUM_CALENDAR_EVENT_IMPACT(value.impact_type)));
    }
 }
//--- 実行結果の例:
// Number of values for Japan events: 1734
// Number of values after deleting empty ones: 1017
// Reduce the list of values to 10 and display them
// [id] [event_id]              [time]            [period] [revision] [actual_value] [prev_value] [revised_prev_value] [forecast_value] [impact_type] [reserved]
// [0] 56500  392030004 2019.03.28 23:30:00 2019.03.01 00:00:00          0         900000       600000 -9223372036854775808           500000             1          0
// [1] 56501  392030005 2019.03.28 23:30:00 2019.03.01 00:00:00          0         700000       700000 -9223372036854775808           700000             0          0
// [2] 56502  392030006 2019.03.28 23:30:00 2019.03.01 00:00:00          0        1100000      1100000 -9223372036854775808           900000             1          0
// [3] 56544  392030007 2019.03.28 23:30:00 2019.02.01 00:00:00          0        2300000      2500000 -9223372036854775808          2200000             2          0
// [4] 56556  392050002 2019.03.28 23:30:00 2019.02.01 00:00:00          0        1630000      1630000              1610000          1620000             1          0
// [5] 55887  392020003 2019.03.28 23:50:00 2019.02.01 00:00:00          0         400000       600000 -9223372036854775808          1300000             2          0
// [6] 55888  392020004 2019.03.28 23:50:00 2019.02.01 00:00:00          0       -1800000     -3300000 -9223372036854775808         -2000000             1          0
// [7] 55889  392020002 2019.03.28 23:50:00 2019.02.01 00:00:00          0         200000     -2300000             -1800000           300000             2          0
// [8] 55948  392020006 2019.03.28 23:50:00 2019.02.01 00:00:00          1        1400000     -3400000 -9223372036854775808          -300000             1          0
// [9] 55949  392020007 2019.03.28 23:50:00 2019.02.01 00:00:00          1       -1000000       300000 -9223372036854775808          -100000             2          0
// Display brief data on event values based on value_id
// 0: value_id=56500 value=900000 impact=CALENDAR_IMPACT_POSITIVE
// 1: value_id=56501 value=700000 impact=CALENDAR_IMPACT_NA
// 2: value_id=56502 value=1100000 impact=CALENDAR_IMPACT_POSITIVE
// 3: value_id=56544 value=2300000 impact=CALENDAR_IMPACT_NEGATIVE
// 4: value_id=56556 value=1630000 impact=CALENDAR_IMPACT_POSITIVE
// 5: value_id=55887 value=400000 impact=CALENDAR_IMPACT_NEGATIVE
// 6: value_id=55888 value=-1800000 impact=CALENDAR_IMPACT_POSITIVE
// 7: value_id=55889 value=200000 impact=CALENDAR_IMPACT_NEGATIVE
// 8: value_id=55948 value=1400000 impact=CALENDAR_IMPACT_POSITIVE
// 9: value_id=55949 value=-1000000 impact=CALENDAR_IMPACT_NEGATIVE

このコードは、指定した期間内の日本の経済イベントを取得し、そのイベントデータを処理・表示するものです。

まず、2018年以降のすべての日本のイベントを取得し、空のデータを削除します。次に、最大10件までのイベント情報に絞り込んで一覧を表示します。その後、各イベントのIDに基づいて詳細な値(たとえば、実際の値や影響度)を取得し、結果をエキスパートログに出力します。このようにして、指定されたイベントに関する詳細情報を簡潔に確認できるようになっています。

サンプルコード解説1

//+------------------------------------------------------------------+
//| スクリプトプログラム開始関数                                     |
//+------------------------------------------------------------------+
void OnStart()
 {
  //--- 日本の国コード(ISO 3166-1 Alpha-2)を指定
  string japan_code = "JP";
  
  //--- イベントを取得する期間の境界を設定する
  // 2018年のすべてのイベントを取得するために、開始日を2018年1月1日に設定
  datetime date_from = D'01.01.2018';
  // 終了日を0に設定すると、すべての既知のイベント(今後のイベントも含む)を取得
  datetime date_to = 0;

このコードの冒頭では、日本の経済イベントを取得するための初期設定が行われています。まず、日本の国コード「JP」を指定し、ISO3166-1 Alpha-2形式で記述します。これは、経済イベントが日本のものであることを特定するために用いられます。

次に、取得するイベントの期間を定義しています。date_fromには開始日として「2018年1月1日」を指定しており、これ以降のイベントを対象としています。一方、date_toには0を指定しています。この0の指定は、すべての既知のイベント、つまり過去のデータに加え、将来発表される予定のイベントも含めて取得することを意味します。

サンプルコード解説2

  //--- 日本のイベント値の配列を作成し、取得する
  MqlCalendarValue values[];
  int values_count = CalendarValueHistory(values, date_from, date_to, japan_code);

この部分のコードでは、日本の経済イベントデータを取得するために、MqlCalendarValue構造体型の配列valuesを作成しています。この配列は、指定された期間内のイベントデータを格納するためのものです。

CalendarValueHistory関数を用いて、指定した期間内の日本の経済イベント情報をvalues配列に取得しています。
CalendarValueHistory関数には、values配列、開始日と終了日、国コードの4つの引数が渡されています。取得したイベントデータの数は、関数戻り値として返され、values_countに格納されます。

サンプルコード解説3

//--- 取得したイベントがあるかどうかを確認
  if (values_count > 0)
    {
    // 取得した日本のイベントの数を出力
    PrintFormat("Number of values for Japan events: %d", values_count);
    
    //--- 値が存在しないイベントを配列から削除する
    // 具体的には、actual_valueが-9223372036854775808のものを削除
    for(int i = values_count - 1; i >= 0; i--)
       {
        if(values[i].actual_value == -9223372036854775808)
          ArrayRemove(values, i, 1);  // 配列の該当する要素を削除
       }
    //--- 空の値を削除した後のイベント数を出力
    PrintFormat("Number of values after deleting empty ones: %d", ArraySize(values));
    }

このコードの部分では、日本の経済イベントのデータを取得し、特定の条件に合ったデータのみを残して整理する処理が行われています。

取得したイベントがあるかどうかの確認

まず、取得したイベントの数を示す変数values_countが0より大きいかどうかをif文で確認しています。if文は、指定した条件が正しい場合のみ処理を行う構文で、ここでは「取得したイベントが1件以上あるかどうか」を確認しています。

ここでは、values_countが0以上なら、取得したイベントがあると判断して次の処理を行います。もしもvalues_countが0であれば、取得したイベントがないことを意味します。

イベントの数をエキスパートログに出力

PrintFormat関数を使って、取得したイベントの数をエキスパートログに出力しています。エキスパートログとは、出力内容を確認できる画面です。

PrintFormat関数は、文字列変数の値を組み合わせて表示するための関数です。”%d”はフォーマット指定子で、「整数」を挿入する場所を示しています。ここではvalues_countがその整数値として表示されます。

空のイベント値を削除するためのforループ

次に、イベントの配列valuesから、値が入っていないデータを削除します。ここでは、forループを使用して配列の各要素を確認します。

forループは、指定した回数だけ繰り返し処理を行う構文です。iはインデックス(通し番号)として使われており、values_count – 1から0まで1ずつ減少させながら繰り返します。これにより、配列の末尾から先頭に向かって処理を行います。

actual_valueが空であるデータの削除

イベントデータの中で、actual_valueというフィールド(個々のメンバ変数)が特定の値になっているかを確認し、該当するものを削除します。actual_valueは経済イベントの「実際の値」を示すフィールドです。

MqlCalendarValue構造体では、データが存在しない場合、actual_valueには特殊な値「-9223372036854775808」が格納されます。これを確認するため、if文を使ってactual_valueがその値に等しいかどうかを確認しています。

もしもactual_valueがこの値であれば、データが存在しないと判断し、ArrayRemove関数を使って配列valuesから削除します。

ArrayRemove関数は、指定したインデックス位置にある要素を削除するための関数です。ここでは、i番目の要素を1つ削除し、配列内のデータを整理しています。

削除後のイベント数をエキスパートログに出力

空のデータをすべて削除した後、再度PrintFormat関数を使って、削除後のイベント数をエキスパートログに表示します。

ここでは、ArraySize関数を使って配列要素数を取得し、削除後のイベント数を表示しています。このようにして、不要なデータを削除し、必要なイベントデータのみが配列に残るように整理しています。

サンプルコード解説4

else
    {
    // イベントの取得に失敗した場合、エラーコードとともにメッセージを出力
    PrintFormat("Failed to receive events for the country code %s, error %d",
                 japan_code, GetLastError());
    // スクリプトの終了
    return;
    }

この部分のコードでは、イベントの取得が成功しなかった場合に、エラー情報を表示する処理が行われています。else文を使って、前の条件(イベント取得成功)が成り立たなかった場合にのみ、この処理が実行されます。

まず、PrintFormat関数を用いて、エラーコードと共にエラーメッセージをエキスパートログに出力します。ここで使用されるフォーマット指定子%sは文字列(国コード)を、%dは整数(エラーコード)を表示するためのものです。具体的には、japan_codeには国コード「JP」が含まれており、GetLastError関数は直近に発生したエラーコードを取得します。

次に、return文によってスクリプトの実行を中断しています。returnは、関数の処理を終了させ、呼び出し元に制御を戻すための記述です。この場合、エラーが発生した場合に、処理を続けるのではなく、ここでスクリプトを終了する意図で使われています。

サンプルコード解説5

 //--- values配列の要素数が10より多い場合、10個に減らす
  if (ArraySize(values) > 10)
    {
    PrintFormat("Reduce the list of values to 10 and display them");
    // 最初の要素から、指定した数を削除して配列を10個の要素に絞る
    ArrayRemove(values, 0, ArraySize(values) - 10);
    }
  //--- 配列の内容を出力
  ArrayPrint(values);

この部分のコードでは、取得した日本の経済イベントの数が多すぎる場合に、配列要素数を10個に制限する処理が行われています。

まず、ArraySize関数を使って、配列valuesに含まれる要素の数が10より大きいかどうかを確認しています。この関数は、配列内の現在の要素数を返します。

もし要素数が10を超える場合、PrintFormat関数を使って、配列要素数を10個に減らす旨をエキスパートログに表示します。

次に、ArrayRemove関数を使って、配列の最初から指定した数の要素を削除することで、配列要素数を10個に絞ります。この場合、ArraySize関数で取得した現在の要素数から10を引いた数だけ削除することで、配列に10個の要素だけが残るようにしています。

最後に、ArrayPrint関数を使用して、配列valuesに残った10件のイベント情報をエキスパートログに出力します。ArrayPrint関数は、配列の内容を一度に表示するために使われる関数です。

サンプルコード解説6

  //--- 各イベントのIDに基づいて詳細なイベント値を取得する
  for (int i = 0; i < ArraySize(values); i++)
    {
    // 各イベントの詳細を格納するための変数を作成
    MqlCalendarValue value;
    
    // CalendarValueById関数でイベントIDに基づいて詳細な値を取得
    CalendarValueById(values[i].id, value);
    
    // 各イベントのID、実際の値、影響度の情報を出力
    PrintFormat("%d: value_id=%d value=%d impact=%s",
                 i, values[i].id, value.actual_value, 
                 EnumToString(ENUM_CALENDAR_EVENT_IMPACT(value.impact_type)));
    }
 }

このコードでは、values配列に残っている各イベントについて、そのIDを使って詳細なイベント情報を取得し、エキスパートログに出力しています。

まず、forループを使用して、values配列の全要素に順番にアクセスします。ArraySize関数を用いて、配列要素数だけ繰り返し処理を行う設定にしています。

ループ内で、各イベントの詳細を格納するためのMqlCalendarValue構造体型の変数valueを作成します。この変数は、イベントごとの詳細情報を一時的に保持するためのものです。

次に、CalendarValueById関数を用いて、values配列内のイベントIDを使い、該当するイベントの詳細情報をvalueに格納します。CalendarValueById関数は、指定されたIDに基づいてイベントの詳細を取得する関数です。

最後に、PrintFormat関数を使って、エキスパートログにイベントの詳細情報を出力します。出力内容として、各イベントのインデックス(通し番号)、イベントID、実際の値、影響度の情報が含まれています。
ここで使用されているフォーマット指定子は、整数を示す%dや文字列を示す%sなどです。なお、影響度の情報はENUM_CALENDAR_EVENT_IMPACTという列挙型を使い、EnumToString関数文字列として出力しています。これにより、影響度が数値ではなく、わかりやすい文字列として表示されます。

CalendarValueHistory関数を使ってEAを作る際のアイディア

CalendarValueHistory関数は、指定期間内の経済イベントデータを大量に取得できるため、過去のデータに基づいた取引戦略の分析や、将来のイベントに対応したEAエキスパートアドバイザー)を作成する際に活用できます。以下に、EAのアイディアをいくつか紹介します。

経済イベントのデータを用いたバックテストEA

CalendarValueHistory関数を用いて、過去の経済イベントデータを取得し、特定のイベントや影響度が市場に与えた影響を確認するためのバックテストを行うEAです。たとえば、特定の通貨ペアが重要な経済指標発表後にどのように反応したかを分析し、今後の取引戦略の策定に役立てます。

イベントの頻度と影響度を考慮したポートフォリオ調整EA

影響度の高い経済イベントが多く発生する国や通貨ペアに重点を置くポートフォリオ調整EAです。過去のデータに基づいて、頻繁に重要イベントが発生する通貨を強化するなど、リスクヘッジを行いながらポートフォリオを動的に調整することができます。

通貨ごとのイベント傾向に基づく通貨ペア強化EA

CalendarValueHistory関数を使って、特定通貨の経済イベントデータを取得し、その通貨が重要イベントの前後でどう動くかを分析するEAです。特定の通貨ペアがイベント発表に敏感に反応する場合、その通貨を取引の対象とすることで、効果的なリターンを得られる可能性があります。

経済イベント発表時の価格変動を狙ったスキャルピングEA

イベント発表直後の短期的な価格変動を利用したスキャルピング型のEAです。CalendarValueHistory関数で過去のイベント後のボラティリティ(変動幅)を確認し、イベント発表直後の一定の変動幅に合わせてエントリーとクローズを行います。発表の影響が収束したと判断した場合には、即座にポジションを解消することでリスクを軽減します。

影響度によるエントリー調整機能付きEA

過去のイベントごとの影響度に基づき、エントリータイミングやロットサイズを調整するEAです。影響度の高いイベントが近づいている場合はポジションを控えたり、影響度に応じたロットサイズを設定することで、リスク管理を行いながら収益性のある取引を目指します。

CalendarValueHistory関数を活用することで、経済イベントデータに基づく取引戦略を効果的に組み込んだEAの構築が可能です。

タイトルとURLをコピーしました