【MQL5】ChartIndicatorAdd関数について

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

ChartIndicatorAdd関数の働き・役割

ChartIndicatorAdd関数は、指定されたチャートウィンドウに指定されたハンドルを持つインジケータを追加するための関数です。この関数を使用することで、チャート上にインジケータを追加し、視覚的な分析を容易に行うことができます。インジケータとチャートは同一のシンボル(特定の文字や記号)と時間軸で生成される必要があります。

ChartIndicatorAdd関数の引数について

bool  ChartIndicatorAdd(
  long  chart_id,                // チャート識別子
  int  sub_window,               // サブウィンドウ番号
  int  indicator_handle          // 指標ハンドル
);

ChartIndicatorAdd関数は、次の3つの引数を取ります。

  1. chart_id
  • 種類: long型
  • 説明: チャート識別子を指定します。0を指定すると現在のチャートを意味します。
  1. sub_window
  • 種類: int型
  • 説明: チャートサブウィンドウの番号を指定します。0はメインチャートウィンドウを指します。新しいウィンドウでインジケータを追加するには、CHART_WINDOWS_TOTAL(チャートのサブウィンドウの総数)より1大きい値を指定する必要があります。
  1. indicator_handle

ChartIndicatorAdd関数の戻り値について

ChartIndicatorAdd関数戻り値は、インジケータがチャートに正常に追加された場合にはtrueを返し、失敗した場合にはfalseを返します。エラー情報を取得するためには、GetLastError関数を使用します。

例えば、エラー4114は、チャートと追加されたインジケータのシンボル(特定の文字や記号)または時間軸が異なることを意味します。このエラーが発生すると、インジケータはチャートに追加されません。

例えば、現在のチャートがEURUSDのH1(1時間足)であり、追加しようとしているインジケータがUSDJPYのM15(15分足)で計算されている場合、エラー4114が発生します。この場合、インジケータは異なるシンボルと時間軸で生成されているため、追加が拒否されます。

ChartIndicatorAdd関数を使う際の注意点

サブウィンドウに表示するべきインジケータがメインチャートウィンドウに適用されると、表示に問題が発生します。これは、インジケータがリストには存在するものの、実際のチャート上には表示されないことを意味します。

技術的にはエラーは発生していないため、GetLastError関数はエラーが存在しないことを示すゼロを返します。

このような場合でも、インジケータの値はデータウィンドウに表示され、他のMQL5アプリケーションから取得して利用することが可能です。要するに、インジケータを追加する際には適切なウィンドウを指定することが重要です

インジケータの追加が失敗した場合は、GetLastError関数を使用してエラーコードを確認し、原因を特定します。指定されたインジケータハンドルが無効な場合や、チャート識別子が正しくない場合などが考えられます。適切なエラー処理を行い、ユーザーに通知することが重要です。

公式リファレンスのChartIndicatorAdd関数を使ったサンプルコードを解説

以下に、公式リファレンス内にある、ChartIndicatorAdd関数を使ったサンプルコードを示します。こちらを使って、ChartIndicatorAdd関数の挙動を解説していきたいと思います。

//--- 入力パラメータ
input string symbol = "AUDUSD"; // 銘柄名
input ENUM_TIMEFRAMES period = PERIOD_M12; // 時間軸
input int fast_ema_period = 12; // MACDの高速EMA期間
input int slow_ema_period = 26; // MACDの低速EMA期間
input int signal_period = 9; // シグナル期間
input ENUM_APPLIED_PRICE apr = PRICE_CLOSE; // MACD計算に使用する価格の型

int indicator_handle = INVALID_HANDLE; // インジケータハンドルの初期値

//+------------------------------------------------------------------+
//| エキスパート初期化に使用される関数                              |
//+------------------------------------------------------------------+
int OnInit()
{
  // MACDインジケータのハンドルを取得
  indicator_handle = iMACD(symbol, period, fast_ema_period, slow_ema_period, signal_period, apr);
  // チャートにインジケータを追加しようとする
  if (!AddIndicator())
  {
    // AddIndicator関数が、チャートにインジケータを追加することを拒否した場合
    int answer = MessageBox("Do you want to add MACD on the chart anyway?",
                            "Incorrect symbol and/or time frame for adding the indicator",
                            MB_YESNO // 「はい(Y)」 と 「いいえ(N)」 ボタンが表示される
    );
    // ユーザが「はい」を選択した場合の処理
    if (answer == IDYES)
    {
      // 操作ログにこのことを記載する
      PrintFormat("Attention! %s: Trying to add MACD(%s/%s) indicator on %s/%s chart. Receiving error 4114",
                  __FUNCTION__, symbol, EnumToString(period), _Symbol, EnumToString(_Period));
      // 新たなサブウィンドウの数を取得し、インジケータを追加しようとする
      int subwindow = (int)ChartGetInteger(0, CHART_WINDOWS_TOTAL);
      // インジケータの追加を試み、エラーが発生する場合
      if (!ChartIndicatorAdd(0, subwindow, indicator_handle))
        PrintFormat("Failed to add MACD indicator on %d chart window. Error code %d",
                    subwindow, GetLastError());
    }
  }
  // 初期化成功を示す
  return (INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| エキスパートティック関数                                         |
//+------------------------------------------------------------------+
void OnTick()
{
  // エキスパートアドバイザは何もしない
}

//+------------------------------------------------------------------+
//| チェックしてチャートに指標を追加する関数                         |
//+------------------------------------------------------------------+
bool AddIndicator()
{
  // 表示メッセージ
  string message;
  // インジケータシンボルとチャートシンボルが一致するかどうかを確認する
  if (symbol != _Symbol)
  {
    message = "Displaying the use of Demo_ChartIndicatorAdd() function:";
    message = message + "\r\n"; // 改行を追加
    message = message + "Unable to add the indicator calculated on another symbol on the chart.";
    message = message + "\r\n"; // 改行を追加
    message = message + "Specify the chart symbol in Expert Advisor's property - " + _Symbol + ".";
    Alert(message);
    // 早期の終了。インジケータはチャート上に追加されない
    return false;
  }
  // インジケータとチャートの時間軸が一致しているかどうかを確認する
  if (period != _Period)
  {
    message = "Unable to add the indicator calculated on another time frame on the chart.";
    message = message + "\r\n"; // 改行を追加
    message = message + "Specify the chart time frame in Expert Advisor properties - " + EnumToString(_Period) + ".";
    Alert(message);
    // 早期の終了。インジケータはチャート上に追加されない
    return false;
  }
  // 全てのチェックが完了し、シンボルと時間軸がチャートに一致する
  if (indicator_handle == INVALID_HANDLE)
  {
    Print(__FUNCTION__, " Creating MACD indicator"); // 現在の関数名とメッセージをログに出力
    indicator_handle = iMACD(symbol, period, fast_ema_period, slow_ema_period, signal_period, apr); // MACDインジケータを作成
    if (indicator_handle == INVALID_HANDLE)
    {
      Print("Failed to create MACD indicator. Error code ", GetLastError()); // インジケータ作成失敗をログに出力
    }
  }
  // 前回のエラーコードをリセット
  ResetLastError();
  // インジケータをチャートに適用する
  Print(__FUNCTION__, "  Adding MACD indicator on the chart"); // 現在の関数名とメッセージをログに出力
  Print("MACD is generated on ", symbol, "/", EnumToString(period)); // インジケータ生成をログに出力
  // MACDインジケータが追加された新たなサブウィンドウの番号を取得
  int subwindow = (int)ChartGetInteger(0, CHART_WINDOWS_TOTAL);
  PrintFormat("Adding MACD indicator on %d chart window", subwindow); // サブウィンドウ番号をログに出力
  if (!ChartIndicatorAdd(0, subwindow, indicator_handle))
  {
    PrintFormat("Failed to add MACD indicator on %d chart window. Error code %d",
                subwindow, GetLastError()); // インジケータ追加失敗をログに出力
  }
  // インジケータが正常に追加されたことを示す
  return (true);
}

かなり複雑なので、小分けにして解説していきたいと思います。

解説1:グローバル領域での定義

まず、グローバル領域での変数と入力パラメータの定義を解説します。このセクションでは、エキスパートアドバイザーEA)の設定とインジケータハンドルを定義しています。

//--- 入力パラメータ
input string         symbol="AUDUSD";   // 銘柄名
input ENUM_TIMEFRAMES period=PERIOD_M12; // 時間軸
input int   fast_ema_period=12;         // MACDが高速期間
input int   slow_ema_period=26;         // MACDが低速期間
input int     signal_period=9;           // シグナル期間
input ENUM_APPLIED_PRICE apr=PRICE_CLOSE; // MACD計算に使用する値の型

int indicator_handle=INVALID_HANDLE;

各要素の解説

  • inputEAの入力パラメータを定義します。ユーザーはEAの設定を変更することで、実行時にこれらのパラメータを調整できます。
  • symbol
  • 種類: string型
  • 説明: 取引する銘柄名を指定します。この例では、デフォルトとして”AUDUSD”が設定されています。
  • period
  • 種類: ENUM_TIMEFRAMES
  • 説明: 時間軸を指定します。ここでは、カスタム時間軸のPERIOD_M12(12分足)が設定されています。
  • fast_ema_period
  • 種類: int型
  • 説明: MACDの高速期間を指定します。デフォルト値は12です。
  • slow_ema_period
  • 種類: int型
  • 説明: MACDの低速期間を指定します。デフォルト値は26です。
  • signal_period
  • 種類: int型
  • 説明: MACDのシグナル期間を指定します。デフォルト値は9です。
  • apr
  • 種類: ENUM_APPLIED_PRICE
  • 説明: MACD計算に使用する価格の型を指定します。デフォルトでは、終値(PRICE_CLOSE)が設定されています。
  • indicator_handle
  • 種類: int型
  • 説明: インジケータハンドルを格納するための変数です。初期値はINVALID_HANDLE(無効なハンドル)です。このハンドルは、インジケータを生成する関数(例えば、iMACD関数)によって設定されます。

これらの定義により、ユーザーはEAの実行時に柔軟に設定を変更でき、異なる銘柄や時間軸でMACDインジケータを適用することが可能になります。

解説2:OnInit関数の中1

次に、OnInit関数の一部について解説します。このセクションでは、エキスパートアドバイザーの初期化処理を行い、MACDを生成してチャートに追加する処理が含まれています。

int OnInit()
{
  //---
  indicator_handle=iMACD(symbol,period,fast_ema_period,slow_ema_period,signal_period,apr);
  //--- チャートに指標を追加しようとする
  if(!AddIndicator())
    {
    //--- AddIndicator() 関数が、チャートに指標を追加することを拒否した
    int answer=MessageBox("Do you want to add MACD on the chart anyway?",
                          "Incorrect symbol and/or time frame for adding the indicator",
                          MB_YESNO // 「はい(Y)」 と 「いいえ(N)」 ボタンが表示される

各要素の解説

  • OnInit関数
  • EAの初期化時に自動的に呼び出される関数です。この関数内でインジケータの設定や初期化処理を行います。
  • indicator_handle=iMACD(…)
  • iMACD関数を使用してMACDハンドルを取得しています。
  • 引数として、symbol(銘柄名)、period(時間軸)、fast_ema_period(高速EMA期間)、slow_ema_period(低速EMA期間)、signal_period(シグナル期間)、apr(計算に使用する価格の型)を渡しています。
  • AddIndicator()インジケータをチャートに追加するためのカスタム関数です。カスタム関数につき、関数の定義はグローバル領域でされています。戻り値がfalseの場合、インジケータの追加に失敗したことを意味します。
  • MessageBox関MessageBox関数はユーザーに対してメッセージボックスを表示し、インジケータの追加を続行するかどうかを確認します。
  • 最初の引数は表示されるメッセージ、二つ目の引数はメッセージボックスのタイトル、三つ目の引数は表示されるボタン(MB_YESNO)です。例えば、「はい」を選択するとインジケータの追加を試み、「いいえ」を選択すると処理が終了します。

この部分のコードは、MACDを生成し、チャートに追加する初期処理を行っています。もしインジケータの追加に失敗した場合、ユーザーに確認を求めるメッセージボックスが表示されます。

解説3:OnInit関数の中2

次に、OnInit関数の残りの部分について解説します。このセクションでは、メッセージボックスでユーザーが「はい」と答えた場合の処理と、インジケータをサブウィンドウに追加する処理が含まれています。

 //--- ユーザが ChartIndicatorAdd() の不正な使用方法を主張する場合
    if(answer==IDYES)
       {
        //--- まず、操作ログにこのことを記載する
        PrintFormat("Attention! %s: Trying to add MACD(%s/%s) indicator on %s/%s chart. Receiving error 4114",
                    __FUNCTION__,symbol,EnumToString(period),_Symbol,EnumToString(_Period));
        //--- 新たなサブウィンドウの数を受け取り指標を追加しようとする
        int subwindow=(int)ChartGetInteger(0,CHART_WINDOWS_TOTAL);
        //--- 試んでエラーを発生する
        if(!ChartIndicatorAdd(0,subwindow,indicator_handle))
          PrintFormat("Failed to add MACD indicator on %d chart window. Error code  %d",
                       subwindow,GetLastError());
       }
    }
//---
  return(INIT_SUCCEEDED);
 }

ユーザーが「はい」を選択した場合の処理が始まります。PrintFormat関数はエキスパートログにメッセージを記録するための関数です。

フォーマット指定子(%sや%dなど)を使用して、変数の値を埋め込んだ文字列を作成します。

次に、EnumToString関数は、列挙型の値を対応する文字列に変換するための関数です。ここでは、時間軸(periodと_Period)を文字列に変換してログに記録しています。

新たなサブウィンドウの数を取得するためにChartGetInteger関数を使用します。CHART_WINDOWS_TOTALはチャートのサブウィンドウの総数を示す識別子です。

取得したサブウィンドウ番号を使用して、インジケータを新しいサブウィンドウに追加するためにChartIndicatorAdd関数を使用します。戻り値がfalseの場合、インジケータの追加に失敗したことを意味します。

再びPrintFormat関数を使用して、インジケータの追加に失敗した場合、その旨とエラーコードをエキスパートログに記録します。

OnInit関数の最後に、初期化が成功したことを示すためにINIT_SUCCEEDEDを返します。

この部分のコードは、ユーザーがインジケータの追加する場合の処理を行っています。新しいサブウィンドウを取得し、インジケータの追加を試みますが、失敗した場合にはそのエラーをログに記録します。これにより、ユーザーはインジケータの追加が成功したかどうかを確認でき、必要に応じて対策を取ることができます。

解説4:オリジナル関数AddIndicator()の定義1

次に、オリジナル関数AddIndicatorの定義について解説します。このセクションでは、インジケータをチャートに追加する際の検証とエラーメッセージの処理が含まれています。

bool AddIndicator()
 {
  //--- 表示メッセージ
  string message;
  //--- 指標シンボルとチャートシンボルが一致するかどうかを確認する
  if(symbol != _Symbol)
    {
     message = "Displaying the use of Demo_ChartIndicatorAdd() function:";
     message = message + "\r\n";
     message = message + "Unable to add the indicator calculated on another symbol on the chart.";
     message = message + "\r\n";
     message = message + "Specify the chart symbol in Expert Advisor's property - " + _Symbol + ".";
     Alert(message);
     //--- 早期の終了。指標はチャート上に追加されない
     return false;
    }

各要素の解説

  • AddIndicator関数:インジケータをチャートに追加するためのカスタム関数です。戻り値として、インジケータの追加が成功したかどうかを示すブール値(trueまたはfalse)を返します。
  • string message
  • メッセージを格納するための変数です。この変数を使用して、エラーメッセージや情報メッセージを組み立てます。
  • if文:インジケータの計算に使用するシンボルと現在のチャートのシンボルが一致しているかを確認します。一致しない場合、エラーメッセージを組み立てて表示します。
  • “\r\n”
  • メッセージに改行コードを追加します。”\r\n”は改行を意味し、次の行にテキストを続けることを示します。これはメッセージの読みやすさを向上させるために使用します。
    MQL5では、\n でも改行できますが、Windows環境で動作させる場合は \r\n を使用した方が、他のWindowsアプリケーションとの互換性が保たれ、文字化けなどの問題が発生しにくくなります。
  • Alert関数:組み立てたメッセージをアラートボックスに表示します。
  • return false
  • インジケータの追加が失敗したことを示すためにfalseを返します。これにより、関数の呼び出し元に処理を戻します。

この部分のコードは、インジケータをチャートに追加する前にシンボルの一致を確認し、一致しない場合にユーザーにエラーメッセージを表示します。これにより、誤ったシンボルでのインジケータ追加を防ぎます。

解説5:オリジナル関数AddIndicator()の定義2

オリジナル関数AddIndicatorの定義の続きについて解説します。このセクションでは、インジケータをチャートに追加する際の時間軸の一致を検証し、エラーメッセージの処理が含まれています。

//--- 指標とチャートの時間軸が一致しているかどうかを確認する
  if(period != _Period)
    {
     message = "Unable to add the indicator calculated on another time frame on the chart.";
     message = message + "\r\n";
     message = message + "Specify the chart time frame in Expert Advisor properties - " + EnumToString(_Period) + ".";
     Alert(message);
     //--- 早期の終了。指標はチャート上に追加されない
     return false;
    }

各要素の解説

  • if文
  • インジケータの計算に使用する時間軸(period)と現在のチャートの時間軸(_Period)が一致しているかを確認します。一致しない場合、エラーメッセージを組み立てて表示します。
  • message = “Unable to add the indicator calculated on another time frame on the chart.”;
  • メッセージの初期部分を設定します。このメッセージは、異なる時間軸で計算されたインジケータをチャートに追加できないことを示しています。
  • “\r\n”
  • メッセージに改行コードを追加します。”\r\n”は改行を意味し、次の行にテキストを続けることを示します。これはメッセージの読みやすさを向上させるために使用します。
  • message = message + “Specify the chart time frame in Expert Advisor properties – ” + EnumToString(_Period) + “.”;
  • チャートの時間軸を指定するようユーザーに指示するメッセージを追加します。EnumToString関数は、時間軸(_Period)を文字列に変換します。
  • Alert関数:組み立てたメッセージをアラートボックスに表示します。Alert関数は、メッセージをユーザーに通知するための関数です。
  • return false:インジケータの追加が失敗したことを示すためにfalseを返します。これにより、関数の呼び出し元に処理を戻します。

この部分のコードは、インジケータをチャートに追加する前に時間軸の一致を確認し、一致しない場合にユーザーにエラーメッセージを表示します。これにより、誤った時間軸でのインジケータ追加を防ぎます。

解説6:オリジナル関数AddIndicator()の定義3

引き続き、オリジナル関数AddIndicatorの定義の続きについて解説します。このセクションでは、シンボルと時間軸の一致確認後にインジケータハンドルを作成し、エラーメッセージを処理する部分を含みます。

//--- 全てのチェックが完了し、シンボルと指標時間軸はチャートに一致する
  if(indicator_handle == INVALID_HANDLE)
  {
   Print(__FUNCTION__, " Creating MACD indicator");
   indicator_handle = iMACD(symbol, period, fast_ema_period, slow_ema_period, signal_period, apr);
   if(indicator_handle == INVALID_HANDLE)
    {
     Print("Failed to create MACD indicator. Error code ", GetLastError());
    }

各要素の解説

  • if(indicator_handle == INVALID_HANDLE)
  • インジケータハンドルが無効(INVALID_HANDLE)かどうかを確認します。無効な場合、新たにインジケータハンドルを作成する処理を行います。
  • Print関数:現在の関数名と「Creating MACD indicator」というメッセージをエキスパートログに記録します。Print関数は、指定されたメッセージをログに出力するための関数です。ここでは、インジケータの作成開始を示しています。
  • __FUNCTION__:現在実行中の関数名を示すマクロ(プログラム中で頻繁に使用される定義やコードブロックを簡略化するために用いられるツール)です。
    デバッグやログ出力の際に、どの関数から出力されたかを明示するのに役立ちます。この例では、AddIndicator関数内からの出力であることを示しています。
  • iMACD関数MACDを作成し、そのハンドルを取得します。iMACD関数は、指定されたシンボルと時間軸に基づいてMACDを生成する関数です。
  • 引数として、シンボル(symbol)、時間軸(period)、高速EMA期間(fast_ema_period)、低速EMA期間(slow_ema_period)、シグナル期間(signal_period)、価格の型(apr)を渡します。
  • if(indicator_handle == INVALID_HANDLE):再度、インジケータハンドルが無効かどうかを確認します。無効な場合、インジケータの作成に失敗したことを意味します。
  • Print関数(エラー発生時):「Failed to create MACD indicator. Error code 」というメッセージとともに、GetLastError関数を使用して取得したエラーコードをエキスパートログに記録します。GetLastError関数は、直前に発生したエラーコードを取得するための関数です。

この部分のコードは、シンボルと時間軸の一致を確認した後、MACDを作成し、そのハンドルを取得する処理を行っています。もしインジケータハンドル作成に失敗した場合、エラーコードをログに記録します。これにより、インジケータの作成プロセスが正しく実行されたかどうかを確認できます。

解説7:オリジナル関数AddIndicator()の定義4

オリジナル関数AddIndicatorの定義のラストです。このセクションでは、インジケータのエラーリセット、チャートへのインジケータ追加、およびその結果の処理が含まれています。

 ResetLastError();
 //--- 指標をチャートに適用する
  Print(__FUNCTION__, "  Adding MACD indicator on the chart");
  Print("MACD is generated on ", symbol, "/", EnumToString(period));
 //--- MACD指標が付加された新たなサブウィンドウの番号を受け取る
  int subwindow = (int)ChartGetInteger(0, CHART_WINDOWS_TOTAL);
  PrintFormat("Adding MACD indicator on %d chart window", subwindow);
  if(!ChartIndicatorAdd(0, subwindow, indicator_handle))
    {
    PrintFormat("Failed to add MACD indicator on %d chart window. Error code %d",
                 subwindow, GetLastError());
    }
 //--- 指標が正常に追加された
  return(true);
 }

各要素の解説

  • ResetLastError関数:前回のエラーコードをリセットします。ResetLastError関数は、次にエラーが発生したときに正確なエラーコードを取得するために使用されます。
  • Print関数:現在の関数名と「Adding MACD indicator on the chart」というメッセージをエキスパートログに記録します。これは、インジケータをチャートに追加しようとしていることを示します。
  • Print関数:「MACD is generated on」というメッセージと共に、シンボルと時間軸をエキスパートログに記録します。ここでは、生成されたMACDのシンボルと時間軸を示しています。
  • ChartGetInteger関数:現在のチャートのサブウィンドウの総数を取得します。ChartGetInteger関数は、指定されたチャートプロパティの整数値を取得するための関数です。CHART_WINDOWS_TOTALはチャートのサブウィンドウの総数を示す識別子です。
  • PrintFormat関数:「Adding MACD indicator on %d chart window」というメッセージをエキスパートログに記録します。ここでは、新しいサブウィンドウの番号をログに記録しています。
  • ChartIndicatorAdd関数インジケータを指定されたチャートウィンドウに追加します。ChartIndicatorAdd関数は、指定されたチャートウィンドウにインジケータを追加するための関数です。戻り値がfalseの場合、インジケータの追加に失敗したことを意味します。
  • PrintFormat関数(エラー発生時):「Failed to add MACD indicator on %d chart window」というメッセージと共に、エラーコードをエキスパートログに記録します。GetLastError関数を使用して取得したエラーコードも一緒に記録されます。
  • return(true)
  • インジケータが正常に追加されたことを示すためにtrueを返します。これにより、AddIndicator関数が正常に完了したことを示します。

この部分のコードは、エラーリセット、インジケータの追加、追加後の結果の記録を行います。インジケータが正常に追加されると、trueが返されます。エラーが発生した場合、適切なエラーメッセージがログに記録されます。これにより、インジケータの追加プロセスが正しく実行されたかどうかを確認できます。

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