- ChartSaveTemplate関数の働き・役割
- ChartSaveTemplate関数の引数について
- ChartSaveTemplate関数の戻り値について
- ChartSaveTemplate関数を使う際の注意点
- 公式リファレンスのChartSaveTemplate関数を使ったサンプルコードを解説
- 解説1:グローバル領域での定義
- 解説2:OnStart関数の中1
- 解説3:OnStart関数の中2
- 解説4:OnStart関数の中3
- 解説5:OnStart関数の中4
- 解説6:OnStart関数の中5
- 解説7:オリジナルの関数PrepareZigzag()の定義1
- 解説8:オリジナルの関数PrepareZigzag()の定義2
- 解説9:オリジナルの関数PrepareZigzag()の定義3
- 解説10:オリジナルの関数GetLastTwoFractures()の定義1
- 解説11:オリジナルの関数GetLastTwoFractures()の定義2
- 解説12:オリジナルの関数GetLastTwoFractures()の定義3
- 解説13:オリジナルの関数GetLastTwoFractures()の定義4
ChartSaveTemplate関数の働き・役割
ChartSaveTemplate関数は、現在のチャート設定を指定したファイル名のテンプレートとして保存するために使用されます。テンプレートは、後で別のチャートに同じ設定を適用するために利用できます。この機能により、同一のチャート設定を複数のチャートで簡単に再利用することが可能です。
ChartSaveTemplate関数の引数について
ChartSaveTemplate関数は、以下の引数を取ります。
bool ChartSaveTemplate(
long chart_id, // チャート識別子
const string filename // テンプレートを保存するファイル名
);
- 第1引数: chart_id
- 種類: long
- 説明: チャートの識別子を指定します。0を指定すると現在のチャートが対象になります。
- 第2引数: filename
- 種類: const string
- 説明: テンプレートを保存するファイル名を指定します。拡張子.tplは自動的に追加されるため、ファイル名には含める必要はありません。テンプレートはterminal_directory\Profiles\Templates\に保存されます。
ChartSaveTemplate関数の戻り値について
ChartSaveTemplate関数は、操作が成功するとtrue
を返し、失敗するとfalse
を返します。失敗した場合は、GetLastError関数を使用してエラーの詳細を取得することができます。
ChartSaveTemplate関数を使う際の注意点
- テンプレートを保存する際、指定したファイル名が既に存在する場合はその内容が上書きされます。
- テンプレートを使用することで、適用されるインジケータやグラフィカルオブジェクトとチャートの設定を全て保存し、後に別のチャートに適用できます。
公式リファレンスのChartSaveTemplate関数を使ったサンプルコードを解説
以下に、公式リファレンス内にある、ChartSaveTemplate関数を使用してチャート設定をテンプレートに保存するサンプルコードを示します。こちらを使って、ChartSaveTemplate関数の挙動を確認していきたいと思います。
//+------------------------------------------------------------------+
//| Test_ChartSaveTemplate.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.MQL5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2000-2024, MetaQuotes Ltd."
#property link "https://www.mql5.com"
#property version "1.00"
#property script_show_inputs
//--- 入力パラメータ
input string symbol = "GBPUSD"; // 新しいチャートのシンボルを指定するパラメータ
input ENUM_TIMEFRAMES period = PERIOD_H3; // 新しいチャートの時間軸を指定するパラメータ
//+------------------------------------------------------------------+
//| スクリプトプログラムを開始する関数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 最初のチャートにインジケータを取り付ける
int handle;
//--- インジケータを使用に向けて準備する
if(!PrepareZigzag(NULL,0,handle)) return; // 失敗に続く終了
//--- チャートにインジケータを別ウィンドウで取り付ける
if(!ChartIndicatorAdd(0,1,handle)) return; // 失敗に続く終了
//--- チャートを更新してインジケータを表示する
ChartRedraw();
//--- ジグザグの最後の2つの切れ目を探す
double two_values[]; // ジグザグの値を格納する配列
datetime two_times[]; // ジグザグの時間を格納する配列
if(!GetLastTwoFractures(two_values,two_times,handle))
{
PrintFormat("Failed to find two last fractures in the Zigzag!"); // エラーメッセージを表示する
//--- プログラム動作を終了する
return;
}
//--- 標準偏差チャンネルを取り付ける
string channel = "StdDeviation Channel"; // 標準偏差チャンネルの名前を指定
if(!ObjectCreate(0, channel, OBJ_STDDEVCHANNEL, 0, two_times[1], 0))
{
PrintFormat("Failed to create object %s. Error code %d",
EnumToString(OBJ_STDDEVCHANNEL), GetLastError()); // エラーメッセージを表示する
return; // エラーが発生した場合はプログラムを終了する
}
else
{
//--- チャンネルが作成されたので2 番目の点を定義する
ObjectSetInteger(0, channel, OBJPROP_TIME, 1, two_times[0]);
//--- チャンネルのツールヒントテキストを設定する
ObjectSetString(0, channel, OBJPROP_TOOLTIP, "Demo from MQL5 Help");
//--- チャートを更新する
ChartRedraw();
}
//--- テンプレートに結果を保存する
ChartSaveTemplate(0, "StdDevChannelOnZigzag");
//--- 新しいチャートを開いて、保存されたテンプレートを適用する
long new_chart = ChartOpen(symbol, period);
//--- グラフィックオブジェクトのツールヒントを有効にする
ChartSetInteger(new_chart, CHART_SHOW_OBJECT_DESCR, true);
if(new_chart != 0)
{
//--- 保存されたテンプレートをチャートに適用する
ChartApplyTemplate(new_chart, "StdDevChannelOnZigzag");
}
Sleep(10000);
}
//+------------------------------------------------------------------+
//| ジグザグのハンドルを作成し、データの準備を整える |
//+------------------------------------------------------------------+
bool PrepareZigzag(string sym, ENUM_TIMEFRAMES tf, int &h)
{
ResetLastError();
//--- ジグザグ指標は terminal_data_folder\MQL5\Examples に位置する必要がある
h = iCustom(sym, tf, "Examples\\Zigzag");
if(h == INVALID_HANDLE)
{
PrintFormat("%s: Failed to create the handle of the Zigzag indicator. Error code %d",
__FUNCTION__, GetLastError());
return false;
}
int k = 0; // 指標計算を待機する試みの回数
//--- 各ループで50ミリ秒停止して計算を待機する
while(BarsCalculated(h) <= 0)
{
k++;
//--- 試みの回数を表示する
PrintFormat("%s: k=%d", __FUNCTION__, k);
//--- 指標が計算されるまで 50 ミリ秒待機する
Sleep(50);
//--- 100 回以上試みた場合は、何かがおかしい
if(k > 100)
{
//--- 問題を報告する
PrintFormat("Failed to calculate the indicator for %d attempts!", k);
//--- プログラム動作を終了する
return false;
}
}
//--- 指標が作成され、値が計算されて、準備が整う
return true;
}
//+------------------------------------------------------------------+
//| ジグザグの最後の 2 つの切れ目を探して配列に書き込む |
//+------------------------------------------------------------------+
bool GetLastTwoFractures(double &get_values[], datetime &get_times[], int handle)
{
double values[]; // ジグザグの値の配列
datetime times[]; // 時間取得の配列
int size = 100; // 配列サイズ
ResetLastError();
//--- 指標の最後の100個の値を複製する
int copied = CopyBuffer(handle, 0, 0, size, values);
if(copied < 100)
{
PrintFormat("%s: Failed to copy %d values of the indicator with the handle=%d. Error code %d",
__FUNCTION__, size, handle, GetLastError());
return false;
}
//--- 配列へのアクセスの順序を時系列のように定義する
ArraySetAsSeries(values, true);
ArraySetAsSeries(times, true);
//--- 切れ目が見つかったバーの数を書く
int positions[];
//--- 配列サイズを設定する
ArrayResize(get_values, 3);
ArrayResize(get_times, 3);
ArrayResize(positions, 3);
//---カウンタ
int i = 0, k = 0;
//--- 切れ目を探し始める
while(i < 100)
{
double v = values[i];
//--- 空の値には興味がない
if(v != 0.0)
{
//--- バー番号を覚える
positions[k] = i;
//--- 切れ目でのジグザグの値を覚える
get_values[k] = values[i];
PrintFormat("%s: Zigzag[%d]=%G", __FUNCTION__, i, values[i]);
//--- カウンタを増加する
k++;
//--- 切れ目が 2 つ見つかったら、ループから出る
if(k > 2) break;
}
i++;
}
//--- 配列へのアクセスの順序を時系列のように定義する
ArraySetAsSeries(times, true);
ArraySetAsSeries(get_times, true);
if(CopyTime(_Symbol, _Period, 0, size, times) <= 0)
{
PrintFormat("%s: Failed to copy %d values from CopyTime(). Error code %d",
__FUNCTION__, size, GetLastError());
return false;
}
//--- 最後の2つの折れ目が発生したバーのオープン時間を取得する
get_times[0] = times[positions[1]]; // 最後から2番目の値が初めの折れ目として書かれる
get_times[1] = times[positions[2]]; // 最後から3番目の値が2番目の折れ目になる
PrintFormat("%s: first=%s, second=%s", __FUNCTION__, TimeToString(get_times[1]), TimeToString(get_times[0]));
//--- 成功
return true;
}
かなり複雑かつ長いので、小分けにして解説していきたいと思います。
解説1:グローバル領域での定義
#property script_show_inputs
//--- 入力パラメータ
input string symbol = "GBPUSD"; // 新しいチャートのシンボルを指定するパラメータ
input ENUM_TIMEFRAMES period = PERIOD_H3; // 新しいチャートの時間軸を指定するパラメータ
文法要素の解説
- #property script_show_inputs
- このディレクティブは、スクリプトのプロパティを定義します。ここでは、スクリプトの入力パラメータをユーザーに表示する設定を行っています。
- input
- inputキーワードは、スクリプトの外部から設定可能な変数を定義するために使用されます。ユーザーがスクリプトを実行する前に値を設定できるようにします。
- string symbol = “GBPUSD”
- これは、シンボル(特定の通貨ペアなど)を指定するための入力パラメータです。初期値としてGBPUSDが設定されています。
- stringは文字列型を示します。
- ENUM_TIMEFRAMES period = PERIOD_H3
- これは、チャートの時間軸を指定するための入力パラメータです。初期値として3時間足(PERIOD_H3)が設定されています。
- ENUM_TIMEFRAMESは時間軸を示す列挙型です。時間軸には1分足(PERIOD_M1)、1時間足(PERIOD_H1)、日足(PERIOD_D1)など、様々な値が存在します。
このように、グローバル領域でスクリプトのプロパティや入力パラメータを定義することで、スクリプトを実行する際にユーザーが設定を変更できるようにします。
解説2:OnStart関数の中1
void OnStart()
{
//--- 最初のチャートにインジケータを取り付ける
int handle;
//--- インジケータを使用に向けて準備する
if(!PrepareZigzag(NULL,0,handle)) return; // 失敗に続く終了
//--- チャートにインジケータを別ウィンドウで取り付ける
if(!ChartIndicatorAdd(0,1,handle)) return; // 失敗に続く終了
//--- チャートを更新してインジケータを表示する
文法要素の解説
- void OnStart()
- OnStart関数は、スクリプトが実行されたときに最初に呼び出される関数です。MQL5ではスクリプト、インジケータ、エキスパートアドバイザーのエントリーポイントとしてOnStart、OnInit、OnTickなどの関数が用意されています。
- int handle;
- これは整数型の変数handleを宣言しています。handleは、後で作成するインジケータのハンドル(識別子)を格納するために使用されます。
- if(!PrepareZigzag(NULL,0,handle)) return;
- PrepareZigzag関数を呼び出し、ジグザグインジケータの準備を行います。引数のNULLはシンボル、0は時間軸、handleはインジケータのハンドルを示します。
- ジグザグインジケータとは、価格の高低をわかりやすく視覚化するためのツールで、相場の転換点を見つけやすくします。
- この行は、PrepareZigzag関数がfalseを返した場合(インジケータの準備に失敗した場合)にOnStart関数の実行を終了するようにしています。具体的には、ジグザグインジケータの準備が整わなかった場合にスクリプトを中断します。
- if(!ChartIndicatorAdd(0,1,handle))
- ChartIndicatorAdd関数を呼び出し、指定したチャートにインジケータを追加します。0は現在のチャート、1はサブウィンドウのインデックス(通し番号)、handleはインジケータのハンドルを示します。
- ChartIndicatorAdd関数は、指定したインジケータをチャートに追加するために使用されます。この関数を用いることで、チャート上に視覚的なインジケータを表示することができます。
- ChartIndicatorAdd関数がfalseを返した場合(インジケータの追加に失敗した場合)、後続の処理を実行せずに終了します。
これらのコードは、スクリプトが実行された際に最初に行われるインジケータの準備とチャートへの追加を行います。関数や条件分岐を用いることで、処理の成功・失敗に応じた適切な制御を行っています。
解説3:OnStart関数の中2
//--- チャートを更新してインジケータを表示する
ChartRedraw();
//--- ジグザグの最後の2つの切れ目を探す
double two_values[]; // ジグザグの値を格納する配列
datetime two_times[]; // ジグザグの時間を格納する配列
if(!GetLastTwoFractures(two_values,two_times,handle))
{
PrintFormat("Failed to find two last fractures in the Zigzag!"); // エラーメッセージを表示する
//--- プログラム動作を終了する
return;
}
文法要素の解説
- ChartRedraw()
- この関数は、チャートの再描画を行います。インジケータやオブジェクトが追加または変更された後にこの関数を呼び出すことで、チャートにその変更を反映させます。
- double two_values[]
- double型の配列を宣言しています。この配列は、ジグザグインジケータの最後の2つの値を格納するために使用されます。
- dateTime two_times[]
- dateTime型の配列を宣言しています。この配列は、ジグザグインジケータの最後の2つの切れ目の時間を格納するために使用されます。
- if(!GetLastTwoFractures(two_values,two_times,handle))
- GetLastTwoFractures関数を呼び出し、ジグザグインジケータの最後の2つの切れ目を取得します。two_valuesには値、two_timesには時間が格納されます。
- GetLastTwoFractures関数がfalseを返した場合(切れ目の取得に失敗した場合)、エラーメッセージをエキスパートログに表示し、OnStart関数の実行を終了します。
このコードは、ジグザグインジケータの最後の2つの切れ目を取得し、必要な準備が整ったかを確認します。取得したデータは後続の処理で使用されます。各ステップでエラーが発生した場合に適切な対応を行うことで、スクリプトの安定した動作を保証します。
ジグザグインジケータの最後の2つの切れ目について
ジグザグインジケータの最後の2つの切れ目とは、価格の動きが反転したポイントのことです。これらのポイントを特定することで、価格のトレンドの変化を捉えることができます。この情報は、次の価格の動きを予測するために非常に重要です。このコードでは、ジグザグインジケータのデータを取得し、その中から最後の2つの切れ目の位置と値を特定しています。
解説4:OnStart関数の中3
//--- 標準偏差チャンネルを取り付ける
string channel = "StdDeviation Channel"; // 標準偏差チャンネルの名前を指定
if(!ObjectCreate(0, channel, OBJ_STDDEVCHANNEL, 0, two_times[1], 0))
{
PrintFormat("Failed to create object %s. Error code %d",
EnumToString(OBJ_STDDEVCHANNEL), GetLastError()); // エラーメッセージを表示する
return; // エラーが発生した場合はプログラムを終了する
}
文法要素の解説
- stringchannel = “StdDeviation Channel”
- 文字列型の変数channelを宣言し、その値を”StdDeviation Channel”に設定しています。この変数は、標準偏差チャンネルオブジェクトの名前を指定するために使用されます。
- if(!ObjectCreate(0, channel, OBJ_STDDEVCHANNEL, 0, two_times[1], 0))
- ObjectCreate関数を呼び出し、新しいオブジェクト(この場合は標準偏差チャンネル)を作成します。
- 第1引数はチャート識別子で、0は現在のチャートを示します。
- 第2引数はオブジェクトの名前を指定します。ここではchannel変数の値を使用します。
- 第3引数はオブジェクトの種類を指定します。OBJ_STDDEVCHANNELは標準偏差チャンネルを示します。
- 第4引数はシンボルの指定で、0を指定すると現在のシンボルが使用されます。
- 第5引数は時間を指定します。ここではジグザグの最後から2番目の切れ目の時間をtwo_times[1]で指定しています。
- 第6引数は価格の指定ですが、ここでは0を指定しています。
- PrintFormat(“Failed to create object %s. Error code %d”, EnumToString(OBJ_STDDEVCHANNEL), GetLastError())
- ObjectCreate関数がfalseを返した場合、PrintFormat関数を使用してエラーメッセージを表示します。
- EnumToString関数を使用してオブジェクトの種類(OBJ_STDDEVCHANNEL)を文字列に変換し、エラーコードと共に表示します。
- return
- オブジェクトの作成に失敗した場合、return文でOnStart関数の実行を終了します。
標準偏差チャンネルについて
標準偏差チャンネルは、価格の変動範囲を示すために使用されるテクニカル分析ツールです。このチャンネルは、平均価格からの標準偏差を上下に加えた範囲を表示します。標準偏差チャンネルを使用することで、価格が特定の範囲内でどのように変動しているかを視覚的に確認することができます。
解説5:OnStart関数の中4
else
{
//--- チャンネルが作成されたので2 番目の点を定義する
ObjectSetInteger(0, channel, OBJPROP_TIME, 1, two_times[0]);
//--- チャンネルのツールヒントテキストを設定する
ObjectSetString(0, channel, OBJPROP_TOOLTIP, "Demo from MQL5 Help");
//--- チャートを更新する
ChartRedraw();
}
文法要素の解説
- else
- これは、if文の条件がfalseの場合に実行されるブロックを示します。前のif文でオブジェクトの作成に失敗した場合はこの部分がスキップされますが、成功した場合は以下の処理が実行されます。
- ObjectSetInteger(0, channel, OBJPROP_TIME, 1, two_times[0])
- ObjectSetInteger関数を使用して、オブジェクトのプロパティを設定します。
- 第1引数はチャート識別子で、0は現在のチャートを示します。
- 第2引数はオブジェクトの名前を指定します。
- 第3引数はプロパティの識別子で、OBJPROP_TIMEは時間を示します。
- 第4引数はインデックス(通し番号)で、ここでは2番目の点を指定するために1を使用します。
- 第5引数は設定する値で、ここではジグザグの最後の2つの切れ目のうち、最も古い時間をtwo_times[0]で指定しています。
- ObjectSetString(0, channel, OBJPROP_TOOLTIP, “Demo from MQL5 Help”)
- ObjectSetString関数を使用して、オブジェクトの文字列プロパティを設定します。
- 第1引数はチャート識別子で、0は現在のチャートを示します。
- 第2引数はオブジェクトの名前を指定します。
- 第3引数はプロパティの識別子で、OBJPROP_TOOLTIPはツールヒントテキストを示します。
- 第4引数は設定する文字列で、ここでは”Demo from MQL5 Help”というテキストを指定しています。
- ChartRedraw()
- この関数は、チャートの再描画を行います。インジケータやオブジェクトが追加または変更された後にこの関数を呼び出すことで、チャートにその変更を反映させます。
補足説明
この部分のコードは、標準偏差チャンネルが正常に作成された場合に追加の設定を行います。まず、チャンネルの2番目の点をジグザグの最も古い切れ目の時間に設定します。
次に、ツールヒントテキストを設定し、ユーザーがチャート上のオブジェクトにマウスを合わせたときに表示される説明を提供します。最後に、ChartRedraw関数を呼び出してチャートを再描画し、これらの変更を反映させます。
解説6:OnStart関数の中5
//--- テンプレートに結果を保存する
ChartSaveTemplate(0, "StdDevChannelOnZigzag");
//--- 新しいチャートを開いて、保存されたテンプレートを適用する
long new_chart = ChartOpen(symbol, period);
//--- グラフィックオブジェクトのツールヒントを有効にする
ChartSetInteger(new_chart, CHART_SHOW_OBJECT_DESCR, true);
if(new_chart != 0)
{
//--- 保存されたテンプレートをチャートに適用する
ChartApplyTemplate(new_chart, "StdDevChannelOnZigzag");
}
Sleep(10000);
}
文法要素の解説
- ChartSaveTemplate(0, “StdDevChannelOnZigzag”)
- ChartSaveTemplate関数を使用して、現在のチャート設定をテンプレートとして保存します。
- 第1引数はチャート識別子で、0は現在のチャートを示します。
- 第2引数はテンプレートの名前を指定します。この場合は”StdDevChannelOnZigzag”という名前でテンプレートを保存します。
- long new_chart = ChartOpen(symbol, period)
- ChartOpen関数を使用して、新しいチャートを開きます。
- 第1引数はシンボル(例えば通貨ペア)を指定します。ここでは事前に入力されたsymbol変数が使用されます。
- 第2引数は時間軸を指定します。ここでは事前に入力されたperiod変数が使用されます。
- この関数は新しく開かれたチャートの識別子を返します。その値はnew_chart変数に格納されます。
- ChartSetInteger(new_chart,CHART_SHOW_OBJECT_DESCR, true)
- ChartSetInteger関数を使用して、チャートのプロパティを設定します。
- 第1引数はチャート識別子で、新しく開かれたチャートnew_chartを示します。
- 第2引数はプロパティの識別子で、CHART_SHOW_OBJECT_DESCRはグラフィックオブジェクトのツールヒントを有効にするプロパティです。
- 第3引数は設定する値で、ここではtrue(有効)を指定します。
- if(new_chart != 0)
- 新しいチャートが正常に開かれたかどうかを確認します。new_chartが0でない場合は正常に開かれたことを意味します。
- ChartApplyTemplate(new_chart, “StdDevChannelOnZigzag”)
- ChartApplyTemplate関数を使用して、保存されたテンプレートを新しく開いたチャートに適用します。
- 第1引数はチャート識別子で、新しく開かれたチャートnew_chartを示します。
- 第2引数は適用するテンプレートの名前を指定します。この場合は”StdDevChannelOnZigzag”という名前のテンプレートを適用します。
- Sleep(10000)
- Sleep関数は、指定した時間(ミリ秒単位)だけスクリプトの実行を一時停止します。ここでは10000ミリ秒(10秒)だけスクリプトを停止します。
補足説明
この部分のコードは、現在のチャート設定をテンプレートに保存し、そのテンプレートを新しいチャートに適用する手順を実行します。まず、ChartSaveTemplate関数を使用してテンプレートを保存します。次に、新しいチャートを開き、そのチャートのグラフィックオブジェクトのツールヒントを有効にします。新しいチャートが正常に開かれた場合、保存したテンプレートを適用します。最後に、Sleep関数を使用してスクリプトの実行を一時停止し、処理が完了するまでの待機時間を設けます。
解説7:オリジナルの関数PrepareZigzag()の定義1
//+------------------------------------------------------------------+
//| ジグザグのハンドルを作成し、データの準備を整える |
//+------------------------------------------------------------------+
bool PrepareZigzag(string sym, ENUM_TIMEFRAMES tf, int &h)
{
ResetLastError();
//--- ジグザグ指標は terminal_data_folder\MQL5\Examples に位置する必要がある
h = iCustom(sym, tf, "Examples\\Zigzag");
文法要素の解説
- bool PrepareZigzag(string sym, ENUM_TIMEFRAMES tf, int &h)
- PrepareZigzag関数は、ジグザグインジケータを準備するための関数です。
- 戻り値の型はboolで、準備が成功したかどうかを示します。
- 引数にはシンボル(sym)、時間軸(tf)、およびインジケータのハンドルを参照渡しで受け取る変数(h)を取ります。
- ResetLastError()
- この関数は、最後に発生したエラーコードをリセットします。これにより、前回のエラーコードが残っていても、新しいエラーが検出しやすくなります。
- h = iCustom(sym, tf, “Examples\Zigzag”)
- iCustom関数を使用して、ジグザグインジケータを作成し、そのハンドルを取得します。
- 第1引数はシンボルで、準備する対象の通貨ペアや銘柄を指定します。
- 第2引数は時間軸で、インジケータを適用する時間枠を指定します。
- 第3引数はインジケータのパスで、ここではジグザグインジケータがMQL5ディレクトリのExamplesフォルダにあることを示しています。
補足説明
PrepareZigzag関数は、ジグザグインジケータのハンドルを作成し、必要なデータを準備するために使用されます。まず、ResetLastError関数を呼び出してエラーコードをリセットします。次に、iCustom関数を使用してジグザグインジケータを作成し、そのハンドルを取得します。このハンドルは後続の処理で使用され、インジケータの操作を行います。
解説8:オリジナルの関数PrepareZigzag()の定義2
if(h == INVALID_HANDLE)
{
PrintFormat("%s: Failed to create the handle of the Zigzag indicator. Error code %d",
__FUNCTION__, GetLastError());
return false;
}
文法要素の解説
- if(h == INVALID_HANDLE)
- これは条件文で、インジケータのハンドルが無効であるかどうかをチェックします。iCustom関数が失敗した場合、hにはINVALID_HANDLEが設定されます。
- PrintFormat(“%s: Failed to create the handle of the Zigzag indicator. Error code %d”, __FUNCTION_, GetLastError())
- PrintFormat関数を使用してエラーメッセージをフォーマットし、エキスパートログに出力します。
- %sは文字列のフォーマット指定子で、__FUNCTION_は現在の関数名を示します。
- %dは整数のフォーマット指定子で、GetLastError関数は最後に発生したエラーコードを返します。
- このメッセージは、ジグザグインジケータのハンドル作成に失敗したことと、そのエラーコードを示します。
- return false
- この行は、PrepareZigzag関数の実行を終了し、falseを返します。これは、ジグザグインジケータの準備が失敗したことを示します。
補足説明
この部分のコードは、iCustom関数がジグザグインジケータのハンドルを正しく作成できたかどうかを確認します。もしハンドルが無効である場合(INVALID_HANDLE)、エラーメッセージをエキスパートログに出力し、PrepareZigzag関数の実行を終了してfalseを返します。これにより、インジケータの準備が失敗したことを他の部分に伝え、適切なエラーハンドリングを行うことができます。
ジグザグインジケータのハンドルが無効な場合、後続の操作は行えないため、このチェックは重要です。エラーメッセージには関数名とエラーコードが含まれているため、デバッグ時にどの部分で問題が発生したかを特定しやすくなります。
解説9:オリジナルの関数PrepareZigzag()の定義3
int k = 0; // 指標計算を待機する試みの回数
//--- 各ループで50ミリ秒停止して計算を待機する
while(BarsCalculated(h) <= 0)
{
k++;
//--- 試みの回数を表示する
PrintFormat("%s: k=%d", __FUNCTION__, k);
//--- 指標が計算されるまで 50 ミリ秒待機する
Sleep(50);
//--- 100 回以上試みた場合は、何かがおかしい
if(k > 100)
{
//--- 問題を報告する
PrintFormat("Failed to calculate the indicator for %d attempts!", k);
//--- プログラム動作を終了する
return false;
}
}
//--- 指標が作成され、値が計算されて、準備が整う
return true;
}
文法要素の解説
- int k = 0;
- 変数kを初期化しています。この変数は、インジケータの計算が完了するまでの試行回数をカウントするために使用されます。
- while(BarsCalculated(h) <= 0)
- この条件文は、指定したインジケータのハンドルhに関連するバーの計算が完了するまでループを続けます。BarsCalculated関数は、指定したインジケータに対して計算されたバーの数を返します。
- k++;
- 変数kの値を1増やします。これは、各ループの試行回数をカウントするためです。
- PrintFormat(“%s: k=%d”, __FUNCTION_, k);
- PrintFormat関数を使用して、現在の関数名と試行回数をエキスパートログに出力します。__FUNCTION_は現在の関数名を示します。
- Sleep(50);
- Sleep関数は、指定した時間(この場合は50ミリ秒)だけスクリプトの実行を一時停止します。これにより、インジケータが計算を完了するまで待機します。
- if(k > 100)
- もし試行回数が100回を超えた場合、この条件文が真になります。これは、何らかの問題が発生してインジケータの計算が完了しない場合を検出するためのものです。
- PrintFormat(“Failed to calculate the indicator for %d attempts!”, k);
- PrintFormat関数を使用して、試行回数と共にエラーメッセージをエキスパートログに出力します。
- return false;
- インジケータの計算が100回の試行後も完了しない場合、PrepareZigzag関数はfalseを返して実行を終了します。
- return true;
- ループを抜けた場合、つまりインジケータの計算が完了した場合、PrepareZigzag関数はtrueを返します。
補足説明
この部分のコードは、ジグザグインジケータの計算が完了するまで待機する処理を行います。計算が完了するまで、50ミリ秒ごとにスクリプトを一時停止し、試行回数をカウントします。もし100回以上試行しても計算が完了しない場合、エラーメッセージを出力し、falseを返して処理を終了します。計算が正常に完了した場合は、trueを返して次の処理に進みます。これにより、インジケータの準備が正常に完了したかどうかを確認することができます。
解説10:オリジナルの関数GetLastTwoFractures()の定義1
//+------------------------------------------------------------------+
//| ジグザグの最後の 2 つの切れ目を探して配列に書き込む |
//+------------------------------------------------------------------+
bool GetLastTwoFractures(double &get_values[], datetime &get_times[], int handle)
{
double values[]; // ジグザグの値の配列
datetime times[]; // 時間取得の配列
int size = 100; // 配列サイズ
ResetLastError();
//--- 指標の最後の100個の値を複製する
int copied = CopyBuffer(handle, 0, 0, size, values);
文法要素の解説
- bool GetLastTwoFractures(double &get_values[], dateTime &get_times[], int handle)
- GetLastTwoFractures関数は、ジグザグインジケータの最後の2つの切れ目を探し、それらの値と時間を指定した配列に書き込むための関数です。
- 戻り値の型はboolで、処理が成功したかどうかを示します。
- 引数には、ジグザグの値を格納する配列(get_values)、時間を格納する配列(get_times)、およびインジケータのハンドル(handle)を取ります。
- double values[];
- double型の配列valuesを宣言しています。この配列は、ジグザグインジケータの値を格納するために使用されます。
- dateTime times[];
- dateTime型の配列timesを宣言しています。この配列は、ジグザグインジケータの時間を格納するために使用されます。
- int size = 100;
- 配列のサイズを100に設定しています。これは、最後の100個のジグザグの値と時間を取得するためです。
- ResetLastError();
- この関数は、最後に発生したエラーコードをリセットします。これにより、前回のエラーコードが残っていても、新しいエラーが検出しやすくなります。
- int copied = CopyBuffer(handle, 0, 0, size, values);
- CopyBuffer関数を使用して、指定したインジケータのバッファからデータをコピーします。
- 第1引数はインジケータのハンドルを示します。
- 第2引数はバッファの番号を指定します。ここでは、0番目のバッファを示しています。
- 第3引数は開始位置を指定します。0は最新のバーから開始することを意味します。
- 第4引数はコピーする要素の数を指定します。ここでは、size変数(100)を使用しています。
- 第5引数はコピー先の配列を指定します。ここでは、values配列を指定しています。
補足説明
GetLastTwoFractures関数は、ジグザグインジケータの最後の2つの切れ目を取得するために使用されます。まず、配列valuesとtimesを宣言し、コピーするデータのサイズを100に設定します。次に、ResetLastError関数を呼び出してエラーコードをリセットします。その後、CopyBuffer関数を使用して指定したインジケータのバッファからデータをコピーします。このデータは、後続の処理で使用され、ジグザグの切れ目を特定するために用いられます。
解説11:オリジナルの関数GetLastTwoFractures()の定義2
if(copied < 100)
{
PrintFormat("%s: Failed to copy %d values of the indicator with the handle=%d. Error code %d",
__FUNCTION__, size, handle, GetLastError());
return false;
}
//--- 配列へのアクセスの順序を時系列のように定義する
ArraySetAsSeries(values, true);
//--- 切れ目が見つかったバーの数を書く
int positions[];
//--- 配列サイズを設定する
ArrayResize(get_values, 3);
ArrayResize(get_times, 3);
ArrayResize(positions, 3);
文法要素の解説
- if(copied < 100)
- この条件文は、CopyBuffer関数がコピーした要素の数が期待した数(ここでは100)未満であるかどうかを確認します。もし要素が不足している場合、データのコピーが失敗したことを意味します。
- PrintFormat(“%s: Failed to copy %d values of the indicator with the handle=%d. Error code %d”, __FUNCTION_, size, handle, GetLastError())
- PrintFormat関数を使用して、エラーメッセージをエキスパートログに出力します。
- %sは現在の関数名(__FUNCTION_)を示します。
- %dは整数フォーマット指定子で、コピーする要素の数(size)、インジケータのハンドル(handle)、およびエラーコード(GetLastError)を表示します。
- return false
- この行は、GetLastTwoFractures関数の実行を終了し、falseを返します。これは、データのコピーが失敗したことを示します。
- ArraySetAsSeries(values, true)
- ArraySetAsSeries関数を使用して、配列valuesのアクセス順序を時系列のように設定します。この設定により、配列のインデックスが新しい順に並びます。
- int positions[]
- int型の配列positionsを宣言しています。この配列は、切れ目が見つかったバーのインデックス(通し番号)を格納するために使用されます。
- ArrayResize(get_values, 3)
- ArrayResize関数を使用して、配列get_valuesのサイズを3に設定します。これは、ジグザグの切れ目の値を格納するための配列です。
- ArrayResize(get_times, 3)
- ArrayResize関数を使用して、配列get_timesのサイズを3に設定します。これは、ジグザグの切れ目の時間を格納するための配列です。
- ArrayResize(positions, 3)
- ArrayResize関数を使用して、配列positionsのサイズを3に設定します。これは、切れ目が見つかったバーのインデックスを格納するための配列です。
補足説明
この部分のコードは、CopyBuffer関数が期待通りの要素数をコピーできたかどうかを確認し、不足している場合はエラーメッセージを出力して処理を終了します。次に、ジグザグインジケータの値を格納する配列のアクセス順序を時系列のように設定します。その後、ジグザグの切れ目のインデックス、値、および時間を格納するための配列のサイズを設定します。これにより、後続の処理でこれらの配列にデータを格納できるように準備します。
解説12:オリジナルの関数GetLastTwoFractures()の定義3
//---カウンタ
int i = 0, k = 0;
//--- 切れ目を探し始める
while(i < 100)
{
double v = values[i];
//--- 空の値には興味がない
if(v != 0.0)
{
//--- バー番号を覚える
positions[k] = i;
//--- 切れ目でのジグザグの値を覚える
get_values[k] = values[i];
PrintFormat("%s: Zigzag[%d]=%G", __FUNCTION__, i, values[i]);
//--- カウンタを増加する
k++;
//--- 切れ目が 2 つ見つかったら、ループから出る
if(k > 2) break;
}
i++;
}
文法要素の解説
- int i = 0, k = 0;
- 2つの整数型である変数iとkを初期化しています。iはループのカウンタ、kは切れ目が見つかった数をカウントします。
- while(i < 100)
- ループを100回繰り返します。これは、ジグザグインジケータの最後の100個の値をチェックするためです。
- double v = values[i];
- 配列valuesのi番目の要素を変数vに格納します。これは、現在のジグザグの値を表します。
- if(v != 0.0)
- この条件文は、ジグザグの値が0でないことを確認します。ジグザグの値が0でない場合、それは切れ目を示す重要な値です。
- positions[k] = i;
- 切れ目が見つかったバーのインデックス(通し番号)をpositions配列のk番目に格納します。
- get_values[k] = values[i];
- 切れ目のジグザグの値をget_values配列のk番目に格納します。
- PrintFormat(“%s: Zigzag[%d]=%G”, __FUNCTION_, i, values[i]);
- PrintFormat関数を使用して、現在の関数名と切れ目のジグザグの値をエキスパートログに出力します。
- k++;
- 変数kの値を1増やします。これは、次の切れ目を格納するためのインデックスを準備します。
- if(k > 2) break;
- もし切れ目が2つ見つかった場合、ループを終了します。これにより、最初の2つの切れ目だけを処理対象とします。
- i++;
- 変数iの値を1増やします。これは、次の値をチェックするためのインデックスを準備します。
補足説明
この部分のコードは、ジグザグインジケータの最後の100個の値をチェックし、切れ目を探します。切れ目とは、ジグザグの値が0でないポイントのことを指します。ループを使って値を順番にチェックし、切れ目が見つかった場合、そのバーのインデックスとジグザグの値を対応する配列に格納します。最初の2つの切れ目が見つかった時点でループを終了します。これにより、必要なデータが配列に格納され、後続の処理で使用できるようになります。
解説13:オリジナルの関数GetLastTwoFractures()の定義4
//--- 配列へのアクセスの順序を時系列のように定義する
ArraySetAsSeries(times, true);
ArraySetAsSeries(get_times, true);
if(CopyTime(_Symbol, _Period, 0, size, times) <= 0)
{
PrintFormat("%s: Failed to copy %d values from CopyTime(). Error code %d",
__FUNCTION__, size, GetLastError());
return false;
}
//--- 最後の2つの折れ目が発生したバーのオープン時間を取得する
get_times[0] = times[positions[1]]; // 最後から2番目の値が初めの折れ目として書かれる
get_times[1] = times[positions[2]]; // 最後から3番目の値が2番目の折れ目になる
PrintFormat("%s: first=%s, second=%s", __FUNCTION__, TimeToString(get_times[1]), TimeToString(get_times[0]));
//--- 成功
return true;
}
文法要素の解説
- ArraySetAsSeries(times, true);
ArraySetAsSeries(get_times, true); - ArraySetAsSeries関数を使用して、配列timesとget_timesのアクセス順序を時系列のように設定します。この設定により、配列のインデックスが新しい順に並びます。
- if(CopyTime(_Symbol, _Period, 0, size, times) <= 0)
- CopyTime関数を使用して、指定したシンボルと時間枠の時系列データをコピーします。
- 第1引数はシンボルを指定し、_Symbolは現在のシンボルを示します。
- 第2引数は時間枠を指定し、_Periodは現在の時間枠を示します。
- 第3引数は開始位置を指定し、0は最新のバーから開始することを意味します。
- 第4引数はコピーする要素の数を指定し、size変数(100)を使用します。
- 第5引数はコピー先の配列を指定し、times配列を使用します。
- この関数が0以下を返した場合、データのコピーが失敗したことを示します。
- PrintFormat(“%s: Failed to copy %d values from CopyTime(). Error code %d”, __FUNCTION_, size, GetLastError())
- PrintFormat関数を使用して、エラーメッセージをエキスパートログに出力します。
- %sは現在の関数名(__FUNCTION_)を示し、%dは整数フォーマット指定子で、コピーする要素の数(size)およびエラーコード(GetLastError)を表示します。
- return false
- データのコピーが失敗した場合、GetLastTwoFractures関数の実行を終了し、falseを返します。
- get_times[0] = times[positions[1]];
- 最後から2番目の切れ目の時間をget_times配列の最初の要素に格納します。
- get_times[1] = times[positions[2]];
- 最後から3番目の切れ目の時間をget_times配列の2番目の要素に格納します。
- PrintFormat(“%s: first=%s, second=%s”, __FUNCTION_, TimeToString(get_times[1]), TimeToString(get_times[0]));
- PrintFormat関数を使用して、取得した2つの切れ目の時間をエキスパートログに出力します。
- TimeToString関数を使用してdateTime型の時間を文字列に変換します。
- return true
- 最後に、GetLastTwoFractures関数の実行が成功したことを示し、trueを返します。
補足説明
この部分のコードは、ジグザグインジケータの最後の2つの切れ目の時間を取得し、それらを配列に格納します。まず、配列timesとget_timesのアクセス順序を時系列のように設定します。次に、CopyTime関数を使用して、シンボルと時間枠の時系列データをtimes配列にコピーします。データのコピーが失敗した場合、エラーメッセージを出力して処理を終了します。最後に、切れ目の時間をget_times配列に格納し、それらをエキスパートログに出力して、処理の成功を示します。これにより、ジグザグの切れ目の時間を正確に取得し、後続の処理で使用できるようになります。