- iFractals関数の働き・役割
- iFractals関数の引数について
- iFractals関数の戻り値について
- iFractals関数を使う際の注意点
- 公式リファレンスのiFractals関数を使ったサンプルコードについて解説
- 解説1:プロパティ命令によるインジケータ設定
- #property indicator_chart_window
- #property indicator_buffers
- #property indicator_plots
- #property indicator_label1 “FractalUp”
- #property indicator_type1 DRAW_ARROW
- #property indicator_color1 clrBlue
- #property indicator_label2 “FractalDown”
- #property indicator_type2 DRAW_ARROW
- #property indicator_color2 clrRed
- 解説2:グローバル領域での各種定義
- 解説3:OnInit関数の中1
- 解説4:OnInit関数の中2
- 解説5:OnInit関数の中3
- 解説6:OnCalculate関数の中1
- 解説7:OnCalculate関数の中2
- 解説8:OnCalculate関数の中3
- 解説9:オリジナル関数FillArraysFromBuffers()についてその1
- 解説10:オリジナル関数FillArraysFromBuffers()についてその2
- 解説11:オリジナル関数FillArraysFromBuffers()についてその3
- 解説12:OnDeinit関数
- 解説1:プロパティ命令によるインジケータ設定
iFractals関数の働き・役割
iFractals関数は、フラクタル(Fractals)のハンドルを返します。フラクタルは、チャート上の高値と安値の特定のパターンを示し、トレンドの反転点や相場の転換点を見つけるのに役立ちます。
iFractals関数の引数について
iFractals関数の引数構成は以下の通りです。
int iFractals(
string symbol, // 銘柄名
ENUM_TIMEFRAMES period // 期間
);
各引数の説明
- symbol
- period
- 期間を指定します。ENUM_TIMEFRAMES列挙の値の一つで、0を指定すると現在の時間軸を意味します。
iFractals関数の戻り値について
iFractals関数は、指定されたテクニカルインジケータのハンドルを返します。失敗した場合はINVALID_HANDLEを返します。取得したハンドルは、IndicatorRelease関数を使用して解放することができます。
iFractals関数を使う際の注意点
iFractals関数を使用して取得したハンドルを用いて、フラクタルのデータにアクセスします。フラクタルのバッファ番号は以下の通りです:
公式リファレンスのiFractals関数を使ったサンプルコードについて解説
以下は公式リファレンスのiFractals関数を使ったサンプルコードについての記述になります。
※コメントアウトは解説用にこちらで付与したものが含まれています。
//+------------------------------------------------------------------+
//| Demo_iFractals.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 description "The indicator demonstrates how to obtain data" // インジケータの説明
#property description "of indicator buffers for the iFractals technical indicator."
#property description "A symbol and timeframe used for calculation of the indicator,"
#property description "are set by the symbol and period parameters."
#property description "The method of creation of the handle is set through the 'type' parameter (function type)."
#property indicator_chart_window // インジケータをチャートウィンドウに表示
#property indicator_buffers 2 // インジケータバッファの数を指定
#property indicator_plots 2 // インジケータプロットの数を指定
//--- FractalUp プロット
#property indicator_label1 "FractalUp" // プロット1のラベル
#property indicator_type1 DRAW_ARROW // プロット1の描画タイプ
#property indicator_color1 clrBlue // プロット1の色
//--- FractalDown プロット
#property indicator_label2 "FractalDown" // プロット2のラベル
#property indicator_type2 DRAW_ARROW // プロット2の描画タイプ
#property indicator_color2 clrRed // プロット2の色
//+------------------------------------------------------------------+
//| 入力パラメータ |
//+------------------------------------------------------------------+
input string symbol = "EURUSD"; // シンボル(銘柄名)
input ENUM_TIMEFRAMES period = PERIOD_H1; // 時間軸
//--- インジケータバッファ
double FractalUpBuffer[];
double FractalDownBuffer[];
//--- iFractals インジケータハンドルを格納する変数
int FractalsHandle;
//+------------------------------------------------------------------+
//| カスタムインジケータを初期化する関数 |
//+------------------------------------------------------------------+
int OnInit()
{
//--- 配列のインジケータバッファへの割り当て
SetIndexBuffer(0, FractalUpBuffer, INDICATOR_DATA);
SetIndexBuffer(1, FractalDownBuffer, INDICATOR_DATA);
//--- PLOT_ARROWプロパティのコードを Wingdings 文字セットからの記号を使用して設定
PlotIndexSetInteger(0, PLOT_ARROW, 217); // 上矢印
PlotIndexSetInteger(1, PLOT_ARROW, 218); // 下矢印
//--- フラクタルインジケータのハンドルを作成
FractalsHandle = iFractals(symbol, period);
//--- ハンドルが無効な場合
if (FractalsHandle == INVALID_HANDLE)
{
//--- エラーメッセージを出力
Print("フラクタルインジケータのハンドル取得に失敗しました。エラーコード: ", GetLastError());
return (INIT_FAILED);
}
return (INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| カスタムインジケータの反復関数 |
//+------------------------------------------------------------------+
int OnCalculate(
const int rates_total, // 全てのレート数
const int prev_calculated, // 以前に計算されたレート数
const datetime &time[], // 時刻配列
const double &open[], // 始値配列
const double &high[], // 高値配列
const double &low[], // 安値配列
const double &close[], // 終値配列
const long &tick_volume[], // ティックボリューム配列
const long &volume[], // 取引量配列
const int &spread[] // スプレッド配列
)
{
//--- フラクタルインジケータの上矢印データをコピー
int copied = CopyBuffer(FractalsHandle, 0, 0, rates_total, FractalUpBuffer);
if (copied <= 0)
{
//--- エラーメッセージを出力
Print("フラクタルインジケータのデータコピーに失敗しました。エラーコード: ", GetLastError());
return (0);
}
//--- フラクタルインジケータの下矢印データをコピー
copied = CopyBuffer(FractalsHandle, 1, 0, rates_total, FractalDownBuffer);
if (copied <= 0)
{
//--- エラーメッセージを出力
Print("フラクタルインジケータのデータコピーに失敗しました。エラーコード: ", GetLastError());
return (0);
}
return (rates_total);
}
//+------------------------------------------------------------------+
//| インジケータ初期化解除関数 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- インジケータハンドルを解放
if (FractalsHandle != INVALID_HANDLE)
{
IndicatorRelease(FractalsHandle);
}
}
いくつのブロックに分けてコード内容を解説していきたいと思います。
解説1:プロパティ命令によるインジケータ設定
#property indicator_chart_window // インジケータをチャートウィンドウに表示
#property indicator_buffers 2 // インジケータバッファの数を指定
#property indicator_plots 2 // インジケータプロットの数を指定
//--- FractalUp プロット
#property indicator_label1 "FractalUp" // プロット1のラベル
#property indicator_type1 DRAW_ARROW // プロット1の描画タイプ
#property indicator_color1 clrBlue // プロット1の色
//--- FractalDown プロット
#property indicator_label2 "FractalDown" // プロット2のラベル
#property indicator_type2 DRAW_ARROW // プロット2の描画タイプ
#property indicator_color2 clrRed // プロット2の色
#property indicator_chart_window
この命令は、インジケータをチャートウィンドウに表示することを指定します。これにより、インジケータの描画がメインチャートウィンドウに行われます。
#property indicator_buffers
この命令は、インジケータが使用するバッファの数を指定します。この例では、2つのバッファを使用します。バッファは、インジケータがデータを保持するためのメモリ領域です。
#property indicator_plots
この命令は、インジケータが描画するプロット(線やシンボル)の数を指定します。この例では、2つのプロットを使用します。
#property indicator_label1 “FractalUp”
この命令は、最初のプロットのラベルを指定します。
ラベルとは、プロットを識別するための名前です。ここでは、「FractalUp」という名前をプロット1のラベルとして設定しています。
このラベルは、MT5上でインジケータのプロパティウィンドウやデータウィンドウで視認することができます。具体的には、インジケータをチャートに適用した後、プロパティウィンドウの「パラメータ」タブや「データウィンドウ」に表示されます。
#property indicator_type1 DRAW_ARROW
この命令は、最初のプロットの描画タイプを指定します。ここでは、DRAW_ARROW(矢印)を使用しています。これは、インジケータが矢印を描画することを意味します。
#property indicator_color1 clrBlue
この命令は、最初のプロットの色を指定します。ここでは、青色(clrBlue)を使用しています。
#property indicator_label2 “FractalDown”
この命令は、2つ目のプロットのラベルを指定します。ここでは、「FractalDown」という名前をプロット2のラベルとして設定しています。
#property indicator_type2 DRAW_ARROW
この命令は、2つ目のプロットの描画タイプを指定します。ここでは、DRAW_ARROW(矢印)を使用しています。これは、インジケータが矢印を描画することを意味します。
#property indicator_color2 clrRed
この命令は、2つ目のプロットの色を指定します。ここでは、赤色(clrRed)を使用しています。
これらのプロパティ命令により、インジケータの基本的な設定が行われ、インジケータの描画方法や表示形式が指定されます。
解説2:グローバル領域での各種定義
//+------------------------------------------------------------------+
//| 作成を処理する方法の列挙 |
//+------------------------------------------------------------------+
enum Creation
{
Call_iFractals, // iFractals を使用する
Call_IndicatorCreate // IndicatorCreateを使用する
};
//--- 入力パラメータ
input Creation type = Call_iFractals; // 関数の種類
input string symbol = " "; // シンボル
input ENUM_TIMEFRAMES period = PERIOD_CURRENT; // 時間軸
//--- インジケータバッファ
double FractalUpBuffer[];
double FractalDownBuffer[];
//--- iFractals インジケータハンドルを格納する変数
int handle;
//--- 格納に使用される変数
string name = symbol;
//--- チャートでのインジケータ名
string short_name;
//--- フラクタルインジケータに値の数を保存
int bars_calculated = 0;
enum Creation
Creation列挙型は、インジケータの作成方法を指定します。ここでは、iFractals関数を使用するかIndicatorCreate関数を使用するかを選択できます。
- Call_iFractals:iFractals関数を使用してインジケータを作成します。
- Call_IndicatorCreate:IndicatorCreate関数を使用してインジケータを作成します。
input Creation type = Call_iFractals;
この入力パラメータは、インジケータの作成方法を指定します。デフォルトではiFractals関数を使用するように設定されています。
input string symbol = ” “;
この入力パラメータは、インジケータ計算に使用する銘柄名を指定します。デフォルトでは空白文字が設定されていますが、NULL(現在のシンボル)を指定することもできます。
input ENUM_TIMEFRAMES period = PERIOD_CURRENT;
この入力パラメータは、インジケータ計算に使用する時間軸を指定します。デフォルトでは現在の時間軸が設定されています。
double FractalUpBuffer[];
フラクタルの上矢印データを格納するためのバッファを定義します。このバッファは、インジケータの計算結果を保持します。
double FractalDownBuffer[];
フラクタルの下矢印データを格納するためのバッファを定義します。このバッファは、インジケータの計算結果を保持します。
int handle;
iFractals関数やIndicatorCreate関数で作成されたインジケータのハンドルを格納するための変数です。ハンドルは、インジケータを一意(1つしか存在しない)に識別するためのIDです。
string name = symbol;
シンボル名を格納するための変数です。入力パラメータとして指定されたシンボル名を初期値として設定します。
string short_name;
チャート上で表示するインジケータ名を格納するための変数です。この名前は、インジケータの短縮名として使用されます。
int bars_calculated = 0;
フラクタルで計算されたバーの数を保存するための変数です。インジケータの計算状態を追跡するために使用されます。
解説3:OnInit関数の中1
int OnInit()
{
//--- 配列のインジケータバッファへの割り当て
SetIndexBuffer(0, FractalUpBuffer, INDICATOR_DATA);
SetIndexBuffer(1, FractalDownBuffer, INDICATOR_DATA);
//--- PLOT_ARROWプロパティのコードを Wingdings 文字セットからの記号を使用して設定
PlotIndexSetInteger(0, PLOT_ARROW, 217); // 上矢印
PlotIndexSetInteger(1, PLOT_ARROW, 218); // 下矢印
//--- インジケータが描画するシンボルを決める
name = symbol;
//--- 左右のスペースを削除する
StringTrimRight(name);
StringTrimLeft(name);
int OnInit()
OnInit関数は、カスタムインジケ-タの初期化を行う関数です。この関数内でインジケータの設定を行います。
配列のインジケータバッファへの割り当て
SetIndexBuffer関数は、配列をインジケータのバッファに割り当てます。ここでは、FractalUpBufferとFractalDownBufferがそれぞれ上矢印と下矢印のデータを保持するために割り当てられます。
PLOT_ARROWプロパティのコードを Wingdings 文字セットからの記号を使用して設定
PlotIndexSetInteger関数は、インジケータの描画プロパティを設定します。ここでは、上矢印と下矢印の表示に使用する記号を設定します。217は上矢印、218は下矢印のWingdingsフォントコードです。
※Wingdingsフォントコードとは、特殊な記号やシンボルを表示するためのフォントセットで、ここでは矢印記号を描画するために使用されています。
インジケータが描画するシンボルを決める
この行は、インジケータが描画するシンボル名を決定します。入力パラメータとして指定されたシンボル名をname変数に設定します。
左右のスペースを削除する
StringTrimRight関数とStringTrimLeft関数は、指定された文字列の右端と左端からスペースを削除します。これにより、シンボル名の前後に不要なスペースが含まれている場合、それを取り除くことができます。
このセクションでは、インジケータの基本的な設定を行い、表示するシンボルや描画するプロパティを設定しています。次に、インジケータのハンドルを取得し、その他の初期化処理を行う部分に進みます。
解説4:OnInit関数の中2
//---「name」文字列の長さがゼロになった場合
if(StringLen(name) == 0)
{
//--- インジケータが接続されているチャートのシンボルを取る
name = _Symbol;
}
//--- インジケータハンドルを作成する
if(type == Call_iFractals)
handle = iFractals(name, period);
else
handle = IndicatorCreate(name, period, IND_FRACTALS);
//--- ハンドルが作成されなかった場合
if(handle == INVALID_HANDLE)
{
//--- 失敗した事実とエラーコードを出力する
PrintFormat("Failed to create handle of the iFractals indicator for the symbol %s/%s, error code %d",
name,
EnumToString(period),
GetLastError());
//--- インジケータが早期に中止された
return(INIT_FAILED);
}
「name」文字列の長さがゼロになった場合
if(StringLen(name) == 0)
{
name = _Symbol;
}
StringLen関数は、指定された文字列の長さを返します。もしname文字列の長さがゼロの場合、つまりシンボル名が指定されていない場合には、_Symbolを使用して現在のチャートのシンボル名を取得し、name変数に設定します。
インジケータハンドルを作成する
if(type == Call_iFractals)
handle = iFractals(name, period);
else
handle = IndicatorCreate(name, period, IND_FRACTALS);
この部分では、インジケータの作成方法に応じてハンドルを取得します。typeがCall_iFractalsの場合はiFractals関数を使用してハンドルを取得し、そうでない場合はIndicatorCreate関数を使用してハンドルを取得します。
なぜ「そうでない場合はIndicatorCreate関数を使用してハンドルを取得」するのか?
このスクリプトは、柔軟性を持たせるために2つの方法でフラクタルを作成することができます。Call_iFractalsが選択されている場合、iFractals関数を使用してインジケータを作成します。これに対して、IndicatorCreate関数はより一般的なインジケータ作成関数で、インジケータの種類や設定を指定して作成することができます。このようにして、どちらの方法でもインジケータを作成できるようにしています。
ハンドルが作成されなかった場合
if(handle == INVALID_HANDLE)
{
PrintFormat("Failed to create handle of the iFractals indicator for the symbol %s/%s, error code %d",
name,
EnumToString(period),
GetLastError());
return(INIT_FAILED);
}
取得したハンドルがINVALID_HANDLE(無効なハンドル)である場合、インジケータのハンドル取得に失敗したことを意味します。PrintFormat関数を使用してエラーメッセージとエラーコードをエキスパートログに出力し、初期化を失敗として終了します。
PrintFormat関数のフォーマット指定子と対応する値
PrintFormat関数は、フォーマット指定子を使用して文字列をフォーマットし、エキスパートログに出力します。この例では以下のように使用されています:
PrintFormat("Failed to create handle of the iFractals indicator for the symbol %s/%s, error code %d",
name,
EnumToString(period),
GetLastError());
%s
:文字列をフォーマットする指定子です。ここでは、nameとEnumToString(period)が対応します。%d
:整数をフォーマットする指定子です。ここでは、GetLastError()が対応します。
EnumToString関数
EnumToString関数は、列挙型の値を文字列に変換します。ここでは、periodの値を文字列に変換してエラーメッセージに表示しています。
GetLastError関数
GetLastError関数は、最後に発生したエラーコードを返します。ここでは、ハンドル取得に失敗した場合のエラーコードを取得してエラーメッセージに表示しています。
このセクションでは、指定されたシンボル名や時間軸に基づいてハンドルを作成し、ハンドル取得に失敗した場合には適切なエラーメッセージを出力して初期化を終了する処理を行っています。これにより、インジケータの作成が確実に成功するかどうかを確認し、問題が発生した場合にはその原因を特定できるようにしています。
解説5:OnInit関数の中3
//--- フラクタルインジケータが計算された銘柄/時間軸を表示
short_name = StringFormat("iFractals(%s/%s)", name, EnumToString(period));
IndicatorSetString(INDICATOR_SHORTNAME, short_name);
//--- 通常のインジケータの初期化
return(INIT_SUCCEEDED);
}
フラクタルインジケータが計算された銘柄/時間軸を表示
StringFormat関数は、指定された形式に従って文字列を作成します。この場合、フラクタルの短縮名を作成しています。%s
は文字列を挿入するためのフォーマット指定子で、nameとEnumToString(period)がそれぞれ対応します。これにより、「iFractals(銘柄名/時間軸)」という形式の短縮名が生成されます。
短縮名とは、インジケータを識別するための簡略化された名前のことです。これにより、チャート上でインジケータがどの銘柄と時間軸に対して計算されたかを一目で確認できるようになります。
INDICATOR_SHORTNAMEとは、インジケータの短縮名を設定するための識別子です。このプロパティを設定することで、インジケータの情報がチャート上に表示されます。具体的には、インジケータの名前がチャートウィンドウやデータウィンドウに表示され、ユーザーがインジケータの設定や結果を簡単に確認できるようになります。
IndicatorSetString関数
IndicatorSetString関数は、インジケータのプロパティを設定します。ここでは、INDICATOR_SHORTNAMEプロパティに対して、先ほど作成したshort_nameを設定しています。これにより、チャート上でインジケータの短縮名が表示されます。
通常のインジケータの初期化
この行は、OnInit関数の正常な終了を示します。INIT_SUCCEEDEDを返すことで、インジケータの初期化が成功したことを示します。
このセクションでは、フラクタルの短縮名を作成し、それをチャート上に表示するための設定を行います。これにより、インジケータの情報が視覚的にわかりやすくなります。また、初期化が正常に完了したことを示すために、INIT_SUCCEEDEDを返しています。
解説6:OnCalculate関数の中1
//+------------------------------------------------------------------+
//| カスタム指標の反復関数 |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
//--- iFractals インジケータから複製された値の数
int values_to_copy;
//--- インジケータで計算された値の数を決める
int calculated = BarsCalculated(handle);
if(calculated <= 0)
{
PrintFormat("BarsCalculated() returned %d, error code %d", calculated, GetLastError());
return(0);
}
OnCalculate関数
OnCalculate関数は、カスタムインジケ-タの計算を行う関数です。この関数は、新しいデータが追加されるたびに呼び出され、インジケータの計算を更新します。各引数は以下の通りです:
- rates_total:全てのレート数
- prev_calculated:以前に計算されたレート数
- time:時刻配列
- open:始値配列
- high:高値配列
- low:安値配列
- close:終値配列
- tick_volume:ティックボリューム配列
- volume:取引量配列
- spread:スプレッド配列
iFractalsインジケータから複製された値の数
int values_to_copy;
values_to_copy変数は、後でコピーする値の数を格納するために使用されます。
インジケータで計算された値の数を決める
int calculated = BarsCalculated(handle);
if(calculated <= 0)
{
PrintFormat("BarsCalculated() returned %d, error code %d", calculated, GetLastError());
return(0);
}
BarsCalculated関数は、指定されたハンドルに対して計算されたバーの数を返します。もしcalculatedが0以下の場合、計算がまだ行われていないことを意味します。この場合、エラーメッセージをエキスパートログに出力し、関数を終了します。
PrintFormat関数の詳細
PrintFormat関数は、フォーマット指定子を使用して文字列をフォーマットし、エキスパートログに出力します。この例では以下のように使用されています:
PrintFormat("BarsCalculated() returned %d, error code %d", calculated, GetLastError());
%d
:整数をフォーマットする指定子です。ここでは、calculatedとGetLastError()が対応します。
GetLastError関数
GetLastError関数は、最後に発生したエラーコードを返します。ここでは、BarsCalculated関数の呼び出しに失敗した場合のエラーコードを取得してエラーメッセージに表示しています。
このセクションでは、インジケータの計算状態を確認し、必要に応じてエラーメッセージを出力して処理を終了する機能を実装しています。これにより、インジケータの計算が正常に行われているかどうかを確認できます。
解説7:OnCalculate関数の中2
//--- これがインジケータ計算の初めであるか iFractals インジケータの値の数が変更した
//---または、2つ以上のバーのインジケータの計算が必要である場合(価格履歴で何かが変更された)
if(prev_calculated == 0 || calculated != bars_calculated || rates_total > prev_calculated + 1)
{
//--- もし FractalUpBuffer 配列が銘柄/期間で iFractalsインジケータの値の数より大きい場合、全体のコピーはしない
//--- 他の場合、インジケータバッファサイズより少ない量をコピーをする
if(calculated > rates_total)
values_to_copy = rates_total;
else
values_to_copy = calculated;
}
else
{
//--- これは初回の計算ではなく、
//--- 前回の OnCalculate() から、一以上のバーが加えられてない。
values_to_copy = (rates_total - prev_calculated) + 1;
}
これがインジケータ計算の初めであるか iFractals インジケータの値の数が変更した
if(prev_calculated == 0 || calculated != bars_calculated || rates_total > prev_calculated + 1)
この条件文は、以下の3つの状況を確認しています:
- prev_calculatedが0である場合、つまりインジケータ計算が初めて行われる場合。
- calculatedとbars_calculatedが異なる場合、つまりインジケータの計算されたバーの数が変更された場合。
- rates_totalがprev_calculatedより2つ以上多い場合、つまり価格履歴で何かが変更され、2つ以上のバーで再計算が必要な場合。
インジケータバッファのサイズを決定
if(calculated > rates_total)
values_to_copy = rates_total;
else
values_to_copy = calculated;
条件が真である場合、FractalUpBuffer配列のサイズを決定します。calculatedがrates_totalより大きい場合、values_to_copyにはrates_totalを設定します。そうでない場合は、calculatedの値を設定します。これにより、インジケータのバッファサイズを適切に設定し、必要なデータ量だけをコピーするようにします。
初回の計算ではなく、前回のOnCalculate()から新しいバーが追加されていない場合
else
{
values_to_copy = (rates_total - prev_calculated) + 1;
}
この部分は、初回の計算ではなく、前回のOnCalculate()から新しいバーが1つ以上追加されていない場合の処理です。values_to_copyには、今回の計算で必要なデータ量を設定します。これにより、インジケータの再計算が効率的に行われ、無駄なデータのコピーが避けられます。
このセクションでは、インジケータの初期計算や再計算の際に必要なデータ量を適切に決定し、効率的にデータを処理する方法を説明しています。これにより、インジケータの計算が正確かつ効率的に行われるようになります。
解説8:OnCalculate関数の中3
//--- フラクタルインジケータの値で FractalUpBuffer 及び FractalDownBuffer 配列を記入する
//--- FillArrayFromBuffer が false を返した場合、情報の準備が終わっていないので操作を終了する
if(!FillArraysFromBuffers(FractalUpBuffer, FractalDownBuffer, handle, values_to_copy))
return(0);
//--- メッセージを形成する
string comm = StringFormat("%s ==> Updated value in the indicator %s: %d",
TimeToString(TimeCurrent(), TIME_DATE | TIME_SECONDS),
short_name,
values_to_copy);
//--- チャートにサービスメッセージを表示する
Comment(comm);
//--- フラクタルインジケータの値の数を覚える
bars_calculated = calculated;
//--- prev_calculated 値を次の関数呼び出しのために返す
return(rates_total);
}
フラクタルインジケータの値で FractalUpBuffer 及び FractalDownBuffer 配列を記入する
if(!FillArraysFromBuffers(FractalUpBuffer, FractalDownBuffer, handle, values_to_copy))
return(0);
FillArraysFromBuffers関数は、フラクタルの値をFractalUpBufferおよびFractalDownBuffer配列にコピーします。この関数がfalseを返す場合、インジケータのデータがまだ準備されていないことを意味するため、操作を終了します。
メッセージを形成する
string comm = StringFormat("%s ==> Updated value in the indicator %s: %d",
TimeToString(TimeCurrent(), TIME_DATE | TIME_SECONDS),
short_name,
values_to_copy);
StringFormat関数を使用して、メッセージを作成します。このメッセージには、現在の時刻、インジケータの短縮名、および更新された値の数が含まれます。
- TimeToString関数:現在の時刻を文字列に変換します。
- TIME_DATE | TIME_SECONDS:日付と秒を含む形式で時刻をフォーマットします。
チャートにメッセージを表示する
Comment(comm);
Comment関数は、指定されたメッセージをチャート上に表示します。この場合、インジケータが更新されたことを示すメッセージを表示します。
フラクタルインジケータの値の数を覚える
bars_calculated = calculated;
bars_calculated変数に、今回計算されたバーの数を保存します。これにより、次回の計算時に前回の計算結果と比較することができます。
prev_calculated 値を次の関数呼び出しのために返す
return(rates_total);
OnCalculate関数の最後に、現在のレート数を返します。この値は、次回の関数呼び出し時にprev_calculatedとして渡されます。
このセクションでは、インジケータの計算結果をバッファにコピーし、その結果をチャート上に表示する処理を行っています。また、計算されたバーの数を保存し、次回の計算時に使用するための準備を行っています。これにより、インジケータの計算結果が正確に反映され、視覚的に確認できるようになります。
解説9:オリジナル関数FillArraysFromBuffers()についてその1
//+------------------------------------------------------------------+
//| iFractals インジケータからインジケータバッファを記入する |
//+------------------------------------------------------------------+
bool FillArraysFromBuffers(double &up_arrows[], // 上矢印のインジケータバッファ
double &down_arrows[], // 下矢印のインジケータバッファ
int ind_handle, // iFractals インジケータハンドル
int amount // 複製された値の数
)
関数の目的
FillArraysFromBuffers関数は、iFractals関数のデータを指定されたバッファにコピーするために使用されます。この関数は、上矢印と下矢印のデータをそれぞれ対応するバッファに格納します。
引数の説明
- double &up_arrows[]
- double &down_arrows[]
- 下矢印のバッファ。iFractals関数の下矢印データを格納するための配列です。この配列も、呼び出し元の関数で定義されており、FillArraysFromBuffers関数内でデータがコピーされます。
- int ind_handle
- iFractals関数のハンドル。このハンドルは、インジケータを一意に識別するためのもので、iFractals関数やIndicatorCreate関数によって取得されます。このハンドルを使用して、インジケータのデータにアクセスします。
- int amount
この関数の主な役割は、指定されたハンドルを使用して、上矢印と下矢印のデータを対応するバッファにコピーすることです。次の部分では、具体的なデータコピーの処理について説明します。
解説10:オリジナル関数FillArraysFromBuffers()についてその2
{
//--- エラーコードをリセットする
ResetLastError();
//--- インデックス0 を持つインジケータバッファの値で FractalUpBuffer 配列の一部を記入する
if(CopyBuffer(ind_handle, 0, 0, amount, up_arrows) < 0)
{
//--- 複製が失敗したら、エラーコードを出す
PrintFormat("Failed to copy data from the iFractals indicator to the FractalUpBuffer array, error code %d",
GetLastError());
//--- ゼロ結果で終了。 インジケータは計算されていないと見なされる
return(false);
}
エラーコードをリセットする
ResetLastError();
ResetLastError関数は、最後に発生したエラーコードをリセットします。これにより、新しい操作を開始する前にエラー状態をクリアします。次の操作でエラーが発生した場合に正確なエラーコードを取得するために重要です。
インジケータバッファの値で FractalUpBuffer 配列の一部を記入する
if(CopyBuffer(ind_handle, 0, 0, amount, up_arrows) < 0)
CopyBuffer関数は、指定されたハンドルからデータをコピーします。ここでは、次の引数が使用されています:
ind_handle
:ハンドル。0
:バッファのインデックス。0は上矢印データを示します。0
:コピー開始位置。0は最新のデータからコピーを開始することを意味します。amount
:コピーするデータの数。up_arrows
:データをコピーする配列。
この関数が負の値を返す場合、データのコピーに失敗したことを意味します。
複製が失敗した場合の処理
if(CopyBuffer(ind_handle, 0, 0, amount, up_arrows) < 0)
{
PrintFormat("Failed to copy data from the iFractals indicator to the FractalUpBuffer array, error code %d",
GetLastError());
return(false);
}
データのコピーに失敗した場合、PrintFormat関数を使用してエラーメッセージをエキスパートログに出力します。このエラーメッセージには、GetLastError関数で取得したエラーコードが含まれます。エラーコードは、最後に発生したエラーを特定するために使用されます。
その後、関数はfalseを返し、操作を終了します。これにより、インジケータが正しく計算されていないと見なされます。
このセクションでは、インジケータのデータを指定されたバッファにコピーし、エラーが発生した場合には適切なエラーメッセージを出力して処理を終了する方法を説明しています。これにより、データのコピーが正確に行われているかどうかを確認できます。
解説11:オリジナル関数FillArraysFromBuffers()についてその3
//--- インデックス 1 を持つインジケータバッファの値で FractalDownBuffer 配列の一部を記入する
if(CopyBuffer(ind_handle, 1, 0, amount, down_arrows) < 0)
{
//--- 複製が失敗したら、エラーコードを出す
PrintFormat("Failed to copy data from the iFractals indicator to the FractalDownBuffer array, error code %d",
GetLastError());
//--- ゼロ結果で終了。 インジケータは計算されていないと見なされる
return(false);
}
//--- 全てが成功
return(true);
}
インデックス 1 を持つインジケータバッファの値で FractalDownBuffer 配列の一部を記入する
if(CopyBuffer(ind_handle, 1, 0, amount, down_arrows) < 0)
この行は、インジケータの下矢印データをコピーします。CopyBuffer関数の引数は次の通りです:
ind_handle
:ハンドル。1
:バッファのインデックス。1は下矢印データを示します。0
:コピー開始位置。0は最新のデータからコピーを開始することを意味します。amount
:コピーするデータの数。down_arrows
:データをコピーする配列。
この関数が負の値を返す場合、データのコピーに失敗したことを意味します。
複製が失敗した場合の処理
if(CopyBuffer(ind_handle, 1, 0, amount, down_arrows) < 0)
{
PrintFormat("Failed to copy data from the iFractals indicator to the FractalDownBuffer array, error code %d",
GetLastError());
return(false);
}
データのコピーに失敗した場合、PrintFormat関数を使用してエラーメッセージをエキスパートログに出力します。このエラーメッセージには、GetLastError関数で取得したエラーコードが含まれます。エラーコードは、最後に発生したエラーを特定するために使用されます。
その後、関数はfalseを返し、操作を終了します。これにより、インジケータが正しく計算されていないと見なされます。
全てが成功
return(true);
データのコピーが正常に完了した場合、関数はtrueを返します。これにより、インジケータのデータが正しくバッファにコピーされたことを示します。
このセクションでは、インジケータのデータを指定されたバッファにコピーし、エラーが発生した場合には適切なエラーメッセージを出力して処理を終了する方法を説明しています。これにより、データのコピーが正確に行われているかどうかを確認できます。最後に、データのコピーが成功した場合にtrueを返すことで、インジケータの計算が正常に完了したことを示しています。
解説12:OnDeinit関数
//+------------------------------------------------------------------+
//| インジケータ初期化解除関数 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
if(handle != INVALID_HANDLE)
IndicatorRelease(handle);
//--- インジケータの削除後チャートをクリアする
Comment("");
}
OnDeinit関数の役割
OnDeinit関数は、インジケータの初期化解除時に呼び出される関数です。この関数は、インジケータがチャートから削除されるときやプログラムが終了するときに実行され、インジケータが使用していたリソースを解放します。
引数の説明
インジケータハンドルの解放
if(handle != INVALID_HANDLE)
IndicatorRelease(handle);
この部分では、ハンドルが有効であるかどうかを確認しています。ハンドルがINVALID_HANDLEでない場合、IndicatorRelease関数を使用してハンドルを解放します。IndicatorRelease関数は、インジケータが使用していたメモリを解放し、リソースをクリーンアップします。
チャートのクリア
//--- インジケータの削除後チャートをクリアする
Comment("");
インジケータが削除された後、チャートに表示されていたコメントをクリアします。Comment関数を使用して空の文字列を設定することで、以前に表示されていたメッセージを消去します。これにより、チャートがクリーンな状態に戻ります。
このセクションでは、インジケータのリソースを適切に解放し、チャートをクリーンアップする方法について説明しました。これにより、インジケータの削除時にシステムリソースが無駄に消費されることを防ぎ、チャート上の表示を整理することができます。