ChartIndicatorAdd関数の働き・役割
ChartIndicatorAdd関数は、指定されたチャートウィンドウに指定されたハンドルを持つインジケータを追加するための関数です。この関数を使用することで、チャート上にインジケータを追加し、視覚的な分析を容易に行うことができます。インジケータとチャートは同一のシンボル(特定の文字や記号)と時間軸で生成される必要があります。
ChartIndicatorAdd関数の引数について
bool ChartIndicatorAdd(
long chart_id, // チャート識別子
int sub_window, // サブウィンドウ番号
int indicator_handle // 指標ハンドル
);
ChartIndicatorAdd関数は、次の3つの引数を取ります。
- chart_id
- sub_window
- 種類: int型
- 説明: チャートサブウィンドウの番号を指定します。0はメインチャートウィンドウを指します。新しいウィンドウでインジケータを追加するには、CHART_WINDOWS_TOTAL(チャートのサブウィンドウの総数)より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;
各要素の解説
- input:EAの入力パラメータを定義します。ユーザーは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など)を使用して、変数の値を埋め込んだ文字列を作成します。
- %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が返されます。エラーが発生した場合、適切なエラーメッセージがログに記録されます。これにより、インジケータの追加プロセスが正しく実行されたかどうかを確認できます。