IndicatorSetInteger関数の働き・役割
IndicatorSetInteger関数は、インジケータの特定のプロパティ値を設定するために使用されます。このプロパティはint型/整数型でなければなりません。
IndicatorSetInteger関数の引数について
IndicatorSetInteger関数には2つの書式があります。それぞれの引数について説明します。
書式1
cppコードをコピーするbool IndicatorSetInteger(
int prop_id, // 識別子
int prop_value // 設定する値
);
第1引数: prop_id
プロパティの識別子を指定します。この識別子はENUM_CUSTOMIND_PROPERTY_INTEGERという列挙型の値のいずれかです。
※ENUM_CUSTOMIND_PROPERTY_INTEGERについての詳細は↓の記事をご参照ください。
第2引数: prop_value
指定したプロパティに設定するint型の値です。
書式2
bool IndicatorSetInteger(
int prop_id, // 識別子
int prop_modifier, // 修飾子
int prop_value // 設定する値
);
第1引数: prop_id
プロパティの識別子を指定します。この識別子はENUM_CUSTOMIND_PROPERTY_INTEGERという列挙型の値のいずれかです。
第2引数: prop_modifier
指定されたプロパティの修飾子です。修飾子は特定のプロパティ(特にレベルプロパティ)で必要です。
第3引数: prop_value
指定したプロパティに設定するint型の値です。
IndicatorSetInteger関数の戻り値について
IndicatorSetInteger関数は、設定が成功した場合にtrueを返し、失敗した場合にfalseを返します。例えば、指定したプロパティや修飾子が存在しない場合、falseが返されます。
IndicatorSetInteger関数を使う際の注意点
propertyディレクティブを使用する場合、プロパティ(修飾子)の番号付けは1から始まりますが、IndicatorSetInteger関数では番号付けが0から始まります。
これにより、レベル番号が正しく設定されていないと、インジケータの表示が意図したものと異なる場合があります。例えば、最初の水平ラインの厚さを設定するには、ゼロインデックスを使用する必要があります。
IndicatorSetInteger(INDICATOR_LEVELWIDTH, 0, 5); // 最初のレベルの厚さを設定するにはインデックス 0 を使用する
IndicatorSetInteger関数を使ったサンプルコード
以下はIndicatorSetInteger関数を使ったサンプルコードになります。
#property indicator_separate_window // 別の指標ウィンドウを使用
#property indicator_minimum 0 // 指標の最小値を0に設定
#property indicator_maximum 100 // 指標の最大値を100に設定
#property indicator_level1 20 // 最初の水平レベルを20に設定
#property indicator_level2 50 // 2番目の水平レベルを50に設定
#property indicator_level3 80 // 3番目の水平レベルを80に設定
#property indicator_levelwidth 5 // 水平レベルの厚さを5に設定
#property indicator_levelcolor clrAliceBlue // 水平レベルの色をAliceBlueに設定
#property indicator_levelstyle STYLE_DOT // 水平レベルのスタイルをドットに設定
//+------------------------------------------------------------------+
//| カスタム指標を初期化する関数 |
//+------------------------------------------------------------------+
int OnInit()
{
// 最初の水平レベルの記述を設定
IndicatorSetString(INDICATOR_LEVELTEXT, 0, "First Level (index 0)");
// 2番目の水平レベルの記述を設定
IndicatorSetString(INDICATOR_LEVELTEXT, 1, "Second Level (index 1)");
// 3番目の水平レベルの記述を設定
IndicatorSetString(INDICATOR_LEVELTEXT, 2, "Third Level (index 2)");
// 指標の短縮名を設定
IndicatorSetString(INDICATOR_SHORTNAME, "IndicatorSetInteger() Demo");
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[]) // スプレッドの配列
{
static int tick_counter = 0; // ティックカウンターを初期化
tick_counter++; // ティックカウンターをインクリメント
// 水平レベルの色をティックカウンターに応じて変更
ChangeLevelColor(0, tick_counter, 3, 6, 10);
ChangeLevelColor(1, tick_counter, 3, 6, 8);
ChangeLevelColor(2, tick_counter, 4, 7, 9);
// 水平レベルのスタイルをティックカウンターに応じて変更
ChangeLevelStyle(0, tick_counter);
ChangeLevelStyle(1, tick_counter + 5);
ChangeLevelStyle(2, tick_counter + 15);
// 水平レベルの厚さをティックカウンターに応じて変更
int width = tick_counter % 5; // ティックカウンターの余りを幅として使用
for (int l = 0; l < 3; l++)
{
// 各水平レベルの厚さを設定
IndicatorSetInteger(INDICATOR_LEVELWIDTH, l, width + 1);
}
return(rates_total); // 計算が成功した場合、全ティック数を返す
}
//+------------------------------------------------------------------+
//| 別の指標ウィンドウにおける水平線の色を設定する関数 |
//+------------------------------------------------------------------+
void ChangeLevelColor(int level, // 水平線のインデックス
int tick_number,// ティックカウンターの数
int f_trigger, // 最初の色変更トリガー
int s_trigger, // 2番目の色変更トリガー
int t_trigger) // 3番目の色変更トリガー
{
static color colors[3] = {clrRed, clrBlue, clrGreen}; // 色の配列
int index = -1; // 色のインデックスを初期化
// tick_numberに基づいて色を決定
if(tick_number % f_trigger == 0)
index = 0; // tick_numberがf_triggerで割り切れる場合
if(tick_number % s_trigger == 0)
index = 1; // tick_numberがs_triggerで割り切れる場合
if(tick_number % t_trigger == 0)
index = 2; // tick_numberがt_triggerで割り切れる場合
// 色が定義されたら設定する
if(index != -1)
IndicatorSetInteger(INDICATOR_LEVELCOLOR, level, colors[index]);
}
//+------------------------------------------------------------------+
//| 別の指標ウィンドウにおける水平線のスタイルを設定する関数 |
//+------------------------------------------------------------------+
void ChangeLevelStyle(int level, // 水平線のインデックス
int tick_number) // ティックカウンターの数
{
static ENUM_LINE_STYLE styles[5] = {STYLE_SOLID, STYLE_DASH, STYLE_DOT, STYLE_DASHDOT, STYLE_DASHDOTDOT}; // スタイルの配列
int index = -1; // スタイルのインデックスを初期化
// tick_numberに基づいてスタイルを決定
if(tick_number % 50 == 0)
index = 4; // tick_numberが50で割り切れる場合スタイルはSTYLE_DASHDOTDOT
if(tick_number % 40 == 0)
index = 3; // tick_numberが40で割り切れる場合スタイルはSTYLE_DASHDOT
if(tick_number % 30 == 0)
index = 2; // tick_numberが30で割り切れる場合スタイルはSTYLE_DOT
if(tick_number % 20 == 0)
index = 1; // tick_numberが20で割り切れる場合スタイルはSTYLE_DASH
if(tick_number % 10 == 0)
index = 0; // tick_numberが10で割り切れる場合スタイルはSTYLE_SOLID
// 定義されたスタイルを設定する
if(index != -1)
IndicatorSetInteger(INDICATOR_LEVELSTYLE, level, styles[index]);
}
少し複雑なので、小分けにして解説していきたいと思います。
解説1:プロパティ命令によるインジケータ設定
【#property indicator_separate_window】
この命令は、インジケータを別ウィンドウに表示することを指定しています。通常の価格チャートとは別の独立したウィンドウにインジケータが表示されます。
【#property indicator_minimum 0】
この命令は、インジケータウィンドウの縦軸の最小値を0に設定しています。インジケータの値がこの範囲内に収まるようにします。
【#property indicator_maximum 100】
この命令は、インジケータウィンドウの縦軸の最大値を100に設定しています。インジケータの値がこの範囲内に収まるようにします。
【#property indicator_level1 20】
この命令は、インジケータウィンドウに表示する最初の水平レベルを20に設定しています。水平レベルは、特定の値に対して水平線を引くために使用されます。
【#property indicator_level2 50】
この命令は、インジケータウィンドウに表示する2番目の水平レベルを50に設定しています。水平レベルは、特定の値に対して水平線を引くために使用されます。
【#property indicator_level3 80】
この命令は、インジケータウィンドウに表示する3番目の水平レベルを80に設定しています。水平レベルは、特定の値に対して水平線を引くために使用されます。
【#property INDICATOR_LEVELWIDTH 5】
この命令は、水平レベルの線の太さを5に設定しています。太さはピクセル(デジタル画像を構成する最小の単位)で指定されます。
【#property indicator_levelcolor clrAliceBlue】
この命令は、水平レベルの線の色をAliceBlueに設定しています。色はMQL5で定義されたカラー定数を使用して指定します。
【#property indicator_levelstyle STYLE_DOT】
この命令は、水平レベルの線のスタイルをドットスタイルに設定しています。スタイルは、連続した線、点線、ドットなどの異なる表示方法を指定するために使用されます。
解説2:OnInit関数
int OnInit()
{
// 最初の水平レベルの記述を設定
IndicatorSetString(INDICATOR_LEVELTEXT, 0, "First Level (index 0)");
// 2番目の水平レベルの記述を設定
IndicatorSetString(INDICATOR_LEVELTEXT, 1, "Second Level (index 1)");
// 3番目の水平レベルの記述を設定
IndicatorSetString(INDICATOR_LEVELTEXT, 2, "Third Level (index 2)");
// 指標の短縮名を設定
IndicatorSetString(INDICATOR_SHORTNAME, "IndicatorSetInteger() Demo");
return(INIT_SUCCEEDED);
}
【IndicatorSetString(INDICATOR_LEVELTEXT, 0, “First Level (index 0)”)】
最初の水平レベルの記述を設定しています。INDICATOR_LEVELTEXTは水平レベルの説明を設定するための識別子です。0
は最初の水平レベルを示し、”First Level (index 0)”はそのレベルの説明です。
【IndicatorSetString(INDICATOR_LEVELTEXT, 1, “Second Level (index 1)”)】
2番目の水平レベルの記述を設定しています。1
は2番目の水平レベルを示し、”Second Level (index 1)”はそのレベルの説明です。
【IndicatorSetString(INDICATOR_LEVELTEXT, 2, “Third Level (index 2)”)】
3番目の水平レベルの記述を設定しています。2
は3番目の水平レベルを示し、”Third Level (index 2)”はそのレベルの説明です。
【IndicatorSetString(INDICATOR_SHORTNAME, “IndicatorSetInteger() Demo”)】
指標の短縮名を設定しています。
INDICATOR_SHORTNAMEは指標の名前を設定するための識別子です。”IndicatorSetInteger() Demo”は指標の短縮名として表示されます。
【return(INIT_SUCCEEDED);】
初期化が成功したことを示す値を返します。INIT_SUCCEEDED
は初期化が正常に完了したことを示す定数です。これにより、指標が正常に動作する準備が整います。
解説3: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[]) // スプレッドの配列
{
static int tick_counter = 0; // ティックカウンターを初期化
tick_counter++; // ティックカウンターをインクリメント
// 水平レベルの色をティックカウンターに応じて変更
ChangeLevelColor(0, tick_counter, 3, 6, 10);
ChangeLevelColor(1, tick_counter, 3, 6, 8);
ChangeLevelColor(2, tick_counter, 4, 7, 9);
// 水平レベルのスタイルをティックカウンターに応じて変更
ChangeLevelStyle(0, tick_counter);
ChangeLevelStyle(1, tick_counter + 5);
【OnCalculate関数】
OnCalculate関数はカスタムインジケ-タの計算ロジックを実装する関数です。引数には、全ティック数、前回計算されたティック数、時間配列、オープン価格、高値、安値、クローズ価格、ティックボリューム、実際のボリューム、スプレッドが含まれます。
【static】
このキーワードは、変数の値が関数の呼び出し間で保持されることを意味します。ここでは、tick_counterがOnCalculate関数の呼び出しごとにリセットされず、前回の値を保持します。
【tick_counter】
ティックごとにインクリメントされるカウンターで、時間の経過を追跡します。
【ChangeLevelColor関数】
ティックカウンターに応じて水平レベルの色を変更します。各水平レベルは異なるタイミングで色を変更します。
引数:
- level: 水平線のインデックスを指定します。
- tick_number: ティックカウンターの数を指定します。
- f_trigger: 色を変更するための最初のトリガー値です。
- s_trigger: 色を変更するための2番目のトリガー値です。
- t_trigger: 色を変更するための3番目のトリガー値です。
【ChangeLevelStyle関数】
ティックカウンターに応じて水平レベルのスタイルを変更します。各水平レベルは異なるタイミングでスタイルを変更します。
引数:
- level: 水平線のインデックスを指定します。
- tick_number: ティックカウンターの数を指定します。
解説4:OnCalculate関数の中2
// 水平レベルの厚さをティックカウンターに応じて変更
int width = tick_counter % 5; // ティックカウンターの余りを幅として使用
for (int l = 0; l < 3; l++)
{
// 各水平レベルの厚さを設定
IndicatorSetInteger(INDICATOR_LEVELWIDTH, l, width + 1);
}
return(rates_total); // 計算が成功した場合、全ティック数を返す
}
【水平レベルの厚さをティックカウンターに応じて変更】
ティックカウンターの値を使って水平レベルの厚さを変更します。ティックカウンターを5で割った余りを厚さの基準として使用します。
【width】
ティックカウンターの値を5で割った余りを幅として設定します。これにより、水平レベルの厚さが周期的に変化します。
【for文】
3つの水平レベルに対してループを行い、各レベルの厚さを設定します。
- なぜ
l < 3
なのか?
これは3つの水平レベル(インデックスが0, 1, 2)のためです。ループカウンタl
を0から始め、l < 3
の条件で3回ループさせることで、各水平レベルの厚さを設定します。 - なぜ
l
を IndicatorSetInteger関数の第2引数に配置することによって、3つの水平レベルに厚さの設定を施すことになるのか?
IndicatorSetInteger関数の第2引数はレベルのインデックスを示します。forループでl
の値を0, 1, 2と変化させることで、それぞれの水平レベルに対して厚さを設定できます。このようにして、3つの水平レベルに対して個別に設定を行います。
【IndicatorSetInteger関数】
各水平レベルの厚さを設定します。引数として、プロパティの識別子(INDICATOR_LEVELWIDTH)、レベルのインデックス、設定する厚さの値を指定します。ここでは、width
に1を加えた値を設定します。
【return(rates_total)】
関数の最後に、計算が成功したことを示すために全ティック数を返します。これにより、次の計算サイクルの開始点が設定されます。
解説5:オリジナル関数ChangeLevelColor()の定義
void ChangeLevelColor(int level, // 水平線のインデックス
int tick_number,// ティックカウンターの数
int f_trigger, // 最初の色変更トリガー
int s_trigger, // 2番目の色変更トリガー
int t_trigger) // 3番目の色変更トリガー
{
static color colors[3] = {clrRed, clrBlue, clrGreen}; // 色の配列
int index = -1; // 色のインデックスを初期化
// tick_numberに基づいて色を決定
if(tick_number % f_trigger == 0)
index = 0; // tick_numberがf_triggerで割り切れる場合
if(tick_number % s_trigger == 0)
index = 1; // tick_numberがs_triggerで割り切れる場合
if(tick_number % t_trigger == 0)
index = 2; // tick_numberがt_triggerで割り切れる場合
// 色が定義されたら設定する
if(index != -1)
IndicatorSetInteger(INDICATOR_LEVELCOLOR, level, colors[index]);
}
【ChangeLevelColor関数】
この関数は、ティックカウンターの値に応じて水平レベルの色を変更します。引数には、水平線のインデックス、ティックカウンターの数、色を変更するためのトリガー値が含まれます。
【level】
水平線のインデックスを指定します。これにより、どの水平線の色を変更するかを決定します。
【tick_number】
ティックカウンターの数を指定します。この値に基づいて、色変更のタイミングを決定します。
【f_trigger、s_trigger、t_trigger】
色を変更するためのトリガー値です。それぞれのトリガー値に基づいて、ティックカウンターの値が特定の条件を満たすと色が変更されます。
【static Color colors[3] = {clrRed, clrBlue, clrGreen};】
関数内で使用される色の配列を定義します。staticキーワードにより、この配列は関数の呼び出し間で値を保持します。ここでは、赤、青、緑の3色が定義されています。
【index】
色のインデックスを初期化します。tick_numberに基づいて、色のインデックスが決定されます。
【if文による色の決定】
tick_numberが各トリガー値で割り切れる場合に、それぞれの条件に従ってindexを設定します。indexが設定されると、そのインデックスに対応する色が使用されます。
- tick_numberがf_triggerで割り切れる場合、indexは0に設定され、色は赤(clrRed)になります。
- tick_numberがs_triggerで割り切れる場合、indexは1に設定され、色は青(clrBlue)になります。
- tick_numberがt_triggerで割り切れる場合、indexは2に設定され、色は緑(clrGreen)になります。
【IndicatorSetInteger関数】
色が定義された場合に、IndicatorSetInteger関数を使用して水平レベルの色を設定します。引数には、プロパティの識別子(INDICATOR_LEVELCOLOR)、水平線のインデックス、設定する色が含まれます。
解説6:オリジナル関数ChangeLevelStyle()の定義
void ChangeLevelStyle(int level, // 水平線のインデックス
int tick_number) // ティックカウンターの数
{
static ENUM_LINE_STYLE styles[5] = {STYLE_SOLID, STYLE_DASH, STYLE_DOT, STYLE_DASHDOT, STYLE_DASHDOTDOT}; // スタイルの配列
int index = -1; // スタイルのインデックスを初期化
// tick_numberに基づいてスタイルを決定
if(tick_number % 50 == 0)
index = 4; // tick_numberが50で割り切れる場合スタイルはSTYLE_DASHDOTDOT
if(tick_number % 40 == 0)
index = 3; // tick_numberが40で割り切れる場合スタイルはSTYLE_DASHDOT
if(tick_number % 30 == 0)
index = 2; // tick_numberが30で割り切れる場合スタイルはSTYLE_DOT
if(tick_number % 20 == 0)
index = 1; // tick_numberが20で割り切れる場合スタイルはSTYLE_DASH
if(tick_number % 10 == 0)
index = 0; // tick_numberが10で割り切れる場合スタイルはSTYLE_SOLID
// 定義されたスタイルを設定する
if(index != -1)
IndicatorSetInteger(INDICATOR_LEVELSTYLE, level, styles[index]);
}
【ChangeLevelStyle関数】
この関数は、ティックカウンターの値に応じて水平レベルのスタイルを変更します。引数には、水平線のインデックスとティックカウンターの数が含まれます。
【level】
水平線のインデックスを指定します。これにより、どの水平線のスタイルを変更するかを決定します。
【tick_number】
ティックカウンターの数を指定します。この値に基づいて、スタイル変更のタイミングを決定します。
【static ENUM_LINE_STYLE styles[5] = {STYLE_SOLID, STYLE_DASH, STYLE_DOT, STYLE_DASHDOT, STYLE_DASHDOTDOT};】
関数内で使用されるスタイルの配列を定義します。staticキーワードにより、この配列は関数の呼び出し間で値を保持します。ここでは、5つの異なるスタイル(連続線、破線、点線、破線と点線の組み合わせ、ダブル破線と点線の組み合わせ)が定義されています。
※staticがない場合、関数が呼び出されるたびにstyles配列が初期化されるため、パフォーマンスの低下やリソースの無駄遣い等の問題が発生する可能性があります。staticキーワードを使用することで、これらの問題を回避し、効率的に動作することができます。
【index】
スタイルのインデックスを初期化します。tick_numberに基づいて、スタイルのインデックスが決定されます。
【if文によるスタイルの決定】
tick_numberが各トリガー値で割り切れる場合に、それぞれの条件に従ってindexを設定します。indexが設定されると、そのインデックスに対応するスタイルが使用されます。
- tick_numberが50で割り切れる場合、indexは4に設定され、スタイルはSTYLE_DASHDOTDOTになります。
- tick_numberが40で割り切れる場合、indexは3に設定され、スタイルはSTYLE_DASHDOTになります。
- tick_numberが30で割り切れる場合、indexは2に設定され、スタイルはSTYLE_DOTになります。
- tick_numberが20で割り切れる場合、indexは1に設定され、スタイルはSTYLE_DASHになります。
- tick_numberが10で割り切れる場合、indexは0に設定され、スタイルはSTYLE_SOLIDになります。
【IndicatorSetInteger関数】
スタイルが定義された場合に、IndicatorSetInteger関数を使用して水平レベルのスタイルを設定します。引数には、プロパティの識別子(INDICATOR_LEVELSTYLE)、水平線のインデックス、設定するスタイルが含まれます。
まとめ:ティックの変化に応じた色、スタイル、および厚さの変化
このインジケータは、ティックの変化に応じて水平レベルの色、スタイル、および厚さを動的に変更します。以下にその動作について説明します。
色の変化
インジケータは、ティックカウンターの値に基づいて水平レベルの色を変更します。関数ChangeLevelColorを使用して、次のように色が決定されます。
- ティックカウンターの値がf_triggerで割り切れる場合、水平レベルの色は赤に変更されます。
- ティックカウンターの値がs_triggerで割り切れる場合、水平レベルの色は青に変更されます。
- ティックカウンターの値がt_triggerで割り切れる場合、水平レベルの色は緑に変更されます。
スタイルの変化
同様に、水平レベルのスタイルもティックカウンターの値に基づいて変更されます。
ChangeLevelStyle関数を使用して、次のようにスタイルが決定されます。
- ティックカウンターの値が10で割り切れる場合、スタイルは連続線に設定されます。
- ティックカウンターの値が20で割り切れる場合、スタイルは破線に設定されます。
- ティックカウンターの値が30で割り切れる場合、スタイルは点線に設定されます。
- ティックカウンターの値が40で割り切れる場合、スタイルは破線と点線の組み合わせに設定されます。
- ティックカウンターの値が50で割り切れる場合、スタイルはダブル破線と点線の組み合わせに設定されます。
厚さの変化
水平レベルの厚さもティックカウンターの値に基づいて変更されます。OnCalculate関数内で次のように厚さが決定されます。
- ティックカウンターの値を5で割った余りを厚さの基準として使用します。
- 3つの水平レベルに対してループを行い、各レベルの厚さを設定します。
このように、ティックの変化に応じて色、スタイル、および厚さが動的に変化することで、チャート上の視覚的な情報が豊かになり、トレーダーにとってより分かりやすくなります。