【MQL5】ArrayBsearch関数について

MQL5リファレンス
スポンサーリンク
スポンサーリンク
  1. ArrayBsearch関数の働き・役割
  2. ArrayBsearch関数の引数について
    1. double型の配列の検索
    2. float型の配列の検索
    3. long型の配列の検索
    4. int型の配列の検索
    5. short型の配列の検索
    6. char型の配列の検索
    7. 引数の説明(全データ型共通)
  3. ArrayBsearch関数の戻り値について
    1. 戻り値の詳細
  4. ArrayBsearch関数を使ったサンプルコード
  5. サンプルコード解説1:グローバル領域部分
    1. スクリプトの起動時に入力パラメータのウィンドウを表示する設定
    2. 入力パラメータの定義
  6. サンプルコード解説2:OnStart関数部分その1
    1. RSIの値を格納するための配列とサイズを定義
    2. RSIインジケータのハンドルを取得
    3. エラーハンドリング
  7. サンプルコード解説3:OnStart関数部分その2
    1. RSIのデータ計算完了を待機
    2. RSI値を配列にコピー
    3. エラーハンドリング
  8. サンプルコード解説4:OnStart関数部分その3
    1. 配列のサイズを取得
    2. 配列を昇順にソート
    3. 売りすぎ領域にあった期間の計算
    4. 買われすぎ領域にあった期間の計算
  9. サンプルコード解説5:OnStart関数部分その4
    1. 結果を表示するための文字列の形成
  10. サンプルコード解説6:OnStart関数部分その5
    1. ラベルの作成と表示
    2. チャートの再描画
    3. スクリプトの休止
    4. 結果の表示とフィードバック
  11. サンプルコード解説7:CreateLabel関数(オリジナル関数)部分
    1. CreateLabel関数の引数について
    2. 関数内で使用されるMQL5関数の解説
    3. 識別子とプロパティの解説
    4. 関数全体の流れ

ArrayBsearch関数の働き・役割

ArrayBsearch関数は、昇順(小さい値から大きい値へと並んでいる状態)にソート(並べ替え)された多次元数値配列(複数の行や列を持つ配列)内の指定された値を検索するために使用されます。

この関数は、配列の最初の次元の要素配列内の個々のデータ)に基づいて検索を行い、二分探索アルゴリズムを使用して高速な検索結果を提供します。二分探索アルゴリズムは、配列の中央の要素と検索値を比較し、値が小さい場合は左半分、大きい場合は右半分に検索範囲を絞り込む方法です。これを繰り返すことで、効率的に目的の値を見つけることができます。

この関数は、ソートされた配列を前提としているため、効率的に検索が行えることが特徴です。また、もし検索値が正確に見つからなかった場合でも、最も近い値を持つ要素インデックスを返すため、近似的なデータを活用するシナリオにも役立ちます。

ArrayBsearch関数の引数について

ArrayBsearch関数は、異なる数値型の配列を検索するために、それぞれのデータ型に対応する書式を持っています。以下に、double型、float型、long型int型Short型char型配列を対象とする書式を順に示します。

double型の配列の検索

int ArrayBsearch(
   const double&   array[],   // 検索対象の配列
   double          value      // 検索される値
);

float型の配列の検索

int ArrayBsearch(
   const float&   array[],  // 検索対象の配列
   float          value      // 検索される値
);

long型の配列の検索

int ArrayBsearch(
   const long&   array[],  // 検索対象の配列
   long          value      // 検索される値
);

int型の配列の検索

int ArrayBsearch(
   const int&   array[],  // 検索対象の配列
   int          value      // 検索される値
);

short型の配列の検索

int ArrayBsearch(
   const short&   array[],  // 検索対象の配列
   short          value      // 検索される値
);

char型の配列の検索

int ArrayBsearch(
   const char&   array[],  // 検索対象の配列
   char          value      // 検索される値
);

引数の説明(全データ型共通)

  1. array[]
    検索対象の数値配列を指定します。この配列は昇順(小さい値から大きい値へ)にソートされている必要があります。配列がソートされていない場合、正しい結果を得ることができません。
  2. value
    配列内で検索する数値を指定します。指定された値が配列内に存在しない場合、最も近い値を持つ要素が検索されます。

配列が適切にソートされていることを保証するためには、ArraySort関数を使用することが推奨されます。

ArrayBsearch関数の戻り値について

ArrayBsearch関数は、指定された配列内で検索された値に対応する要素インデックス(通し番号)を返します。このインデックスは、配列の最初の要素を0とする位置を示します。

戻り値の詳細

  1. 検索値が配列に存在する場合
    検索された値が配列内に見つかった場合、その値が存在する位置(インデックス)が返されます。
  2. 検索値が配列に存在しない場合
    検索値が配列内に正確には存在しない場合、配列内で検索値に最も近い値を持つ要素インデックスが返されます。この場合、値が存在しないものの、近い値を参照する際に有効です。
  3. 検索結果が0未満の場合
    この関数は整数型の値を返しますが、エラーが発生したり、配列が不適切な形式であった場合には、正しいインデックスが返されないこともあります。そのため、戻り値が0以上であることを確認することが重要です。

たとえば、検索値が見つかった場合は、インデックスを使用してその位置のデータを利用できますが、見つからなかった場合には適切なハンドリングが必要です。

ArrayBsearch関数を使ったサンプルコード

//--- スクリプトの起動時に入力パラメータのウィンドウを表示する設定
#property script_show_inputs

//--- 入力パラメータの定義
input int               InpMAPeriod=14;                   // RSIの計算に使用する移動平均線の期間
input ENUM_APPLIED_PRICE InpAppliedPrice=PRICE_CLOSE;     // RSIを計算する際に使用する価格の種類(終値)
input double             InpOversoldValue=30.0;           // 売りすぎと判断するRSIの値(30.0を下回ると売りすぎ)
input double             InpOverboughtValue=70.0;         // 買われすぎと判断するRSIの値(70.0を超えると買われすぎ)
input datetime           InpDateStart=D'2012.01.01 00:00'; // 分析を開始する日付
input datetime           InpDateFinish=D'2013.01.01 00:00'; // 分析を終了する日付

//+------------------------------------------------------------------+
//| スクリプトプログラムを開始する関数                                |
//+------------------------------------------------------------------+
void OnStart()
 {
  double rsi_buff[]; // RSIの値を格納するための配列
  int    size=0;     // 配列のサイズを保持する変数

  //--- RSIインジケータのハンドルを取得
  ResetLastError();
  int rsi_handle=iRSI(Symbol(),Period(),InpMAPeriod,InpAppliedPrice);
  
  //--- ハンドルが無効な場合(RSIの計算に失敗した場合)、エラーメッセージを表示して処理を終了する
  if(rsi_handle==INVALID_HANDLE)
    {
    PrintFormat("RSIインジケータのハンドル取得エラー。エラーコード = %d",GetLastError());
    return;
    }

  //--- RSIが全てのデータを計算し終えるまで待機
  while(BarsCalculated(rsi_handle)==-1)
    {
    //--- スクリプトが強制終了される場合は処理を中止
    if(IsStopped())
        return;
    //--- 計算が完了するまで小休止
    Sleep(10);
    }

  //--- RSI値を指定された期間のデータとしてコピーして配列に格納
  ResetLastError();
  if(CopyBuffer(rsi_handle, 0, InpDateStart, InpDateFinish, rsi_buff) == -1)
    {
    PrintFormat("RSI値のコピーに失敗。エラーコード = %d", GetLastError());
    return;
    }

  //--- 配列のサイズを取得
  size = ArraySize(rsi_buff);

  //--- 配列を昇順にソート(小さい値から大きい値に並び替え)
  ArraySort(rsi_buff);

  //--- 市場が売りすぎ領域にあった期間を百分率で計算
  double ovs = (double)ArrayBsearch(rsi_buff, InpOversoldValue) * 100 / (double)size;

  //--- 市場が買われすぎ領域にあった期間を百分率で計算
  double ovb = (double)(size - ArrayBsearch(rsi_buff, InpOverboughtValue)) * 100 / (double)size;

  //--- 結果を表示するための文字列を形成
  string str = "期間: " + TimeToString(InpDateStart, TIME_DATE) + " から "
               + TimeToString(InpDateFinish, TIME_DATE) + " の間、";
  string str_ovb = "市場は " + DoubleToString(ovb, 2) + "% の時間で買われすぎ領域にあった";
  string str_ovs = "市場は " + DoubleToString(ovs, 2) + "% の時間で売りすぎ領域にあった";

  //--- チャート上に計算結果を表示するラベルを作成
  CreateLabel("top", 5, 60, str, clrDodgerBlue);  // 期間情報を表示
  CreateLabel("overbought", 5, 35, str_ovb, clrDodgerBlue);  // 買われすぎ領域の情報を表示
  CreateLabel("oversold", 5, 10, str_ovs, clrDodgerBlue);  // 売りすぎ領域の情報を表示

  //--- チャートを再描画する
  ChartRedraw(0);

  //--- 10秒間休止する
  Sleep(10000);
 }

//+------------------------------------------------------------------+
//| チャートの左下隅にコメントを表示するための関数                    |
//+------------------------------------------------------------------+
void CreateLabel(const string name, const int x, const int y,
                const string str, const color clr)
 {
  //--- 指定した名前のラベルを作成する
  ObjectCreate(0, name, OBJ_LABEL, 0, 0, 0);

  //--- ラベルをチャートの左下隅に配置
  ObjectSetInteger(0, name, OBJPROP_CORNER, CORNER_LEFT_LOWER);

  //--- ラベルのアンカーポイントを左下に設定
  ObjectSetInteger(0, name, OBJPROP_ANCHOR, ANCHOR_LEFT_LOWER);

  //--- X軸方向のアンカーポイントからの距離を設定
  ObjectSetInteger(0, name, OBJPROP_XDISTANCE, x);

  //--- Y軸方向のアンカーポイントからの距離を設定
  ObjectSetInteger(0, name, OBJPROP_YDISTANCE, y);

  //--- ラベルに表示するテキストを設定
  ObjectSetString(0, name, OBJPROP_TEXT, str);

  //--- テキストの色を設定
  ObjectSetInteger(0, name, OBJPROP_COLOR, clr);

  //--- テキストサイズを設定
  ObjectSetInteger(0, name, OBJPROP_FONTSIZE, 12);
 }

このコードは、RSI(相対力指数)を使って市場の売りすぎ(RSIが30以下)や買われすぎ(RSIが70以上)の状態を分析し、その期間をパーセンテージで計算して、チャート上に表示するスクリプトです。

具体的には、指定された期間のRSI値を取得し、それを昇順にソートした後、売りすぎおよび買われすぎの時間が市場全体の何パーセントを占めていたかを計算します。その結果を、チャートの左下にテキストラベルとして表示します。

サンプルコード解説1:グローバル領域部分

//--- スクリプトの起動時に入力パラメータのウィンドウを表示する設定
#property script_show_inputs

//--- 入力パラメータの定義
input int               InpMAPeriod=14;                   // RSIの計算に使用する移動平均線の期間
input ENUM_APPLIED_PRICE InpAppliedPrice=PRICE_CLOSE;     // RSIを計算する際に使用する価格の種類(終値)
input double             InpOversoldValue=30.0;           // 売りすぎと判断するRSIの値(30.0を下回ると売りすぎ)
input double             InpOverboughtValue=70.0;         // 買われすぎと判断するRSIの値(70.0を超えると買われすぎ)
input datetime           InpDateStart=D'2012.01.01 00:00'; // 分析を開始する日付
input datetime           InpDateFinish=D'2013.01.01 00:00'; // 分析を終了する日付

このセクションでは、スクリプトのグローバル領域に定義されたコードについて説明します。この部分は、スクリプトが実行される際に必要となる設定や入力パラメータの定義を行う役割を担っています。

スクリプトの起動時に入力パラメータのウィンドウを表示する設定

スクリプトを実行する際に、入力パラメータのウィンドウが自動的に表示されるように設定しています。これにより、ユーザーはスクリプトを実行する前に、必要なパラメータを指定できるようになります。

入力パラメータの定義

この部分では、スクリプトで使用する入力パラメータを定義しています。input修飾子がついている変数は、スクリプト実行前にユーザーが設定できるパラメータです。

  • InpMAPeriod
    RSI(相対力指数)の計算に使用する移動平均線の期間を指定します。初期値は14です。ユーザーはこの値を変更することで、RSIの感度を調整することができます。
  • InpAppliedPrice
    RSI計算の際に使用する価格の種類を指定します。初期値は終値ですが、始値や高値など他の価格も指定可能です。ENUM_APPLIED_PRICEは価格の種類を指定するための列挙型です。
  • InpOversoldValue
    市場が売りすぎと判断されるRSIの値を設定します。デフォルトでは30.0が指定されており、この値を下回ると売りすぎと判断されます。
  • InpOverboughtValue
    市場が買われすぎと判断されるRSIの値を設定します。デフォルトでは70.0が設定されており、この値を上回ると買われすぎと判断されます。
  • InpDateStart
    RSIの分析を開始する日付を指定します。初期値は2012年1月1日です。この日付から指定した終了日までのデータを対象にRSIが計算されます。
  • InpDateFinish
    RSIの分析を終了する日付を指定します。初期値は2013年1月1日です。開始日からこの終了日までの期間におけるRSIの値を計算し、後続の処理に使用します。

これらの入力パラメータにより、ユーザーはスクリプトの動作を柔軟に調整でき、分析対象の期間や売買の過熱感を設定できます。この入力パラメータを設定することで、スクリプトは対象期間内で市場の状態を把握し、過剰な売りや買いが行われていた時間を測定します。

サンプルコード解説2:OnStart関数部分その1

//+------------------------------------------------------------------+
//| スクリプトプログラムを開始する関数                                |
//+------------------------------------------------------------------+
void OnStart()
 {
  double rsi_buff[]; // RSIの値を格納するための配列
  int    size=0;     // 配列のサイズを保持する変数

  //--- RSIインジケータのハンドルを取得
  ResetLastError();
  int rsi_handle=iRSI(Symbol(),Period(),InpMAPeriod,InpAppliedPrice);
  
  //--- ハンドルが無効な場合(RSIの計算に失敗した場合)、エラーメッセージを表示して処理を終了する
  if(rsi_handle==INVALID_HANDLE)
    {
    PrintFormat("RSIインジケータのハンドル取得エラー。エラーコード = %d",GetLastError());
    return;
    }

ここでは、スクリプトが実行される際に最初に呼び出されるOnStart関数の一部について説明します。この関数は、RSIインジケータの値を取得し、スクリプトのメイン処理を開始するための重要な役割を担っています。

RSIの値を格納するための配列とサイズを定義

まず、RSI(相対力指数)の値を格納するための配列と、配列のサイズを保持する変数が定義されています。

  • rsi_buff[]
    RSIの値を保存するための配列です。後ほど、この配列RSIの計算結果が格納されます。
  • size
    配列のサイズ(要素数)を保持するための変数です。後にRSI値を取得した後、その数値データがどれだけ存在するかをこの変数で確認します。

RSIインジケータのハンドルを取得

次に、iRSI関数を使用して、指定されたパラメータ(シンボル、時間足、移動平均線の期間、価格の種類)に基づきRSIインジケータを計算するハンドルを取得します。ハンドルとは、MQL5プログラムにおいてインジケータやオブジェクトにアクセスするための識別子です。

  • ResetLastError関数
    この関数は、直前に発生したエラーコードをリセットします。これにより、後で発生したエラーを正確に判断できるようにします。
  • iRSI関数
    この関数は、指定された条件(シンボル、時間足、RSIの期間、価格の種類)に基づいてRSIインジケータを生成し、そのハンドルを返します。Symbol関数は現在のシンボル(通貨ペアなど)を表し、Period関数は現在のチャートの時間足を表します。InpMAPeriodとInpAppliedPriceは、ユーザーが入力した値が使用されます。

エラーハンドリング

もし、RSIインジケータハンドルを取得できなかった場合(rsi_handleが無効である場合)、エラーメッセージをエキスパートログに出力し、スクリプトの実行を終了します。

  • INVALID_HANDLE
    iRSI関数が失敗した場合、ハンドルには無効な値が設定され、INVALID_HANDLEとして扱われます。
  • PrintFormat関数
    この関数は、指定されたフォーマットに従ってエラーメッセージを出力します。ここでは、取得したエラーコードをメッセージとして表示し、問題の詳細を確認できるようにしています。

これにより、インジケータハンドルが正しく取得できない場合でも、エラーの原因を把握し、スクリプトの実行を安全に中止できるようにしています。

サンプルコード解説3:OnStart関数部分その2

  //--- RSIが全てのデータを計算し終えるまで待機
  while(BarsCalculated(rsi_handle)==-1)
    {
    //--- スクリプトが強制終了される場合は処理を中止
    if(IsStopped())
        return;
    //--- 計算が完了するまで小休止
    Sleep(10);
    }

  //--- RSI値を指定された期間のデータとしてコピーして配列に格納
  ResetLastError();
  if(CopyBuffer(rsi_handle, 0, InpDateStart, InpDateFinish, rsi_buff) == -1)
    {
    PrintFormat("RSI値のコピーに失敗。エラーコード = %d", GetLastError());
    return;
    }

ここでは、RSIインジケータのデータを取得し、その計算結果を配列に格納するための処理について説明します。この部分では、計算が完了するまでの待機処理とデータのコピーが行われます。

RSIのデータ計算完了を待機

最初に、RSIインジケータがすべてのデータを計算し終えるまで待機する処理が実行されます。

  • BarsCalculated関数
    この関数は、指定されたインジケータの計算が完了しているかどうかを確認します。指定したインジケータのバー(価格データの単位)数が返され、計算が完了していない場合は-1を返します。このため、whileループ内で、BarsCalculated関数が-1を返している間は計算が完了するまで待機します。
  • IsStopped関数
    この関数は、スクリプトが強制終了されるかどうかを確認します。例えば、ユーザーがスクリプトを手動で停止した場合、この関数がtrueを返し、スクリプトの処理を中止するためにreturnが呼ばれます。
  • Sleep関数
    スクリプトを一時的に停止させるために使用されます。ここでは、10ミリ秒ごとに一時停止し、計算が完了するのを待ちます。この短い休止を繰り返すことで、計算が終わるのを待ちながらスクリプトが過度にシステムリソースを消費しないようにしています。

RSI値を配列にコピー

RSIインジケータの計算が完了したら、その値を配列にコピーします。この部分では、指定した期間のRSI値を取得してrsi_buff配列に格納します。

  • ResetLastError関数
    先ほどと同様、エラーコードをリセットするために使用されます。これにより、CopyBuffer関数で新たに発生したエラーを正確に判断できます。
  • CopyBuffer関数
    この関数は、指定されたインジケータバッファのデータをコピーするために使用されます。ここでは、RSIハンドルバッファ番号、開始日と終了日の期間を指定し、取得したRSIの値をrsi_buff配列に格納しています。InpDateStartとInpDateFinishはユーザーが入力した分析期間で、その期間内のデータを対象にします。

エラーハンドリング

もし、CopyBuffer関数が失敗した場合、エラーメッセージをエキスパートログに出力し、スクリプトを終了します。

  • PrintFormat関数
    再度、フォーマット付きでエラーメッセージを出力し、問題の詳細を確認できるようにしています。ここでは、RSI値のコピーに失敗した場合のエラーコードを表示しています。エラーハンドリング
  • もし、CopyBuffer関数が失敗した場合、エラーメッセージをエキスパートログに出力し、スクリプトを終了します。
  • PrintFormat関数
    フォーマット付きでエラーメッセージを出力し、問題の詳細を確認できるようにしています。ここでは、RSI値のコピーに失敗した場合のエラーコードを表示しています。
  • GetLastError関数
    この関数は、直近に発生したエラーコードを返します。CopyBuffer関数が失敗した場合、GetLastError関数を使用してエラーの原因を確認できます。このエラーコードをPrintFormat関数でエキスパートログに表示することで、何が問題であるかをユーザーに知らせ、適切な対応を行えるようにしています。

この処理により、指定された期間のRSI値を正しく取得し、それらの値を後の処理に活用できるように配列に格納しています。

サンプルコード解説4:OnStart関数部分その3

  //--- 配列のサイズを取得
  size = ArraySize(rsi_buff);

  //--- 配列を昇順にソート(小さい値から大きい値に並び替え)
  ArraySort(rsi_buff);

  //--- 市場が売りすぎ領域にあった期間を百分率で計算
  double ovs = (double)ArrayBsearch(rsi_buff, InpOversoldValue) * 100 / (double)size;

  //--- 市場が買われすぎ領域にあった期間を百分率で計算
  double ovb = (double)(size - ArrayBsearch(rsi_buff, InpOverboughtValue)) * 100 / (double)size;

ここでは、RSI値を格納した配列の操作と、それを元に市場の売りすぎ・買われすぎの領域にあった期間を計算する処理について説明します。

配列のサイズを取得

まず、取得したRSI値が格納された配列のサイズを取得します。

  • ArraySize関数
    この関数は、指定した配列要素数を返します。ここでは、RSI値が格納された配列rsi_buffの要素数(サイズ)を取得し、size変数に格納しています。このsize変数は、後の計算で市場が売りすぎや買われすぎの状態にあった期間を百分率で求める際に使用されます。

配列を昇順にソート

次に、取得したRSI値の配列を昇順にソートします。

  • ArraySort関数
    この関数は、配列要素を小さい値から大きい値へと昇順に並び替えます。RSI値を昇順にソートすることで、ArrayBsearch関数を使った二分探索が可能になります。ソートが行われていない配列に対して二分探索を行うと、正確な結果が得られないため、必ずこの段階でソートを行います。

売りすぎ領域にあった期間の計算

市場が売りすぎと判断されるRSI値以下の期間を、全期間に対する百分率で計算します。

  • ArrayBsearch関数
    この関数は、指定された値を配列の中から探し、そのインデックスを返します。ここでは、売りすぎを判断する閾値として指定されたInpOversoldValueに基づき、RSI値が30以下の部分のインデックスを取得しています。このインデックス値に配列全体のサイズ(size)を掛けることで、市場が売りすぎ状態にあった期間を百分率で計算します。

買われすぎ領域にあった期間の計算

市場が買われすぎと判断されるRSI値以上の期間を、全期間に対する百分率で計算します。

  • ArrayBsearch関数
    同様に、InpOverboughtValueに基づき、買われすぎ状態を判断するRSI値70以上の部分のインデックスを取得します。そのインデックスと全体のサイズの差を使って、買われすぎの期間を百分率で求めます。

このようにして、市場が売りすぎまたは買われすぎの領域にあった期間を計算し、それぞれの割合を求めることができます。この結果は後の処理でチャート上に表示されます。

サンプルコード解説5:OnStart関数部分その4

  //--- 結果を表示するための文字列を形成
  string str = "期間: " + TimeToString(InpDateStart, TIME_DATE) + " から "
               + TimeToString(InpDateFinish, TIME_DATE) + " の間、";
  string str_ovb = "市場は " + DoubleToString(ovb, 2) + "% の時間で買われすぎ領域にあった";
  string str_ovs = "市場は " + DoubleToString(ovs, 2) + "% の時間で売りすぎ領域にあった";

このセクションでは、売りすぎおよび買われすぎ領域にあった市場の期間を計算した結果を、ユーザーが理解しやすい形で文字列に変換して出力する処理について説明します。

結果を表示するための文字列の形成

計算された結果(市場が売りすぎ・買われすぎの領域にあった時間の割合)を表示するために、いくつかの文字列を形成しています。

  • str
    分析対象期間を表す文字列です。TimeToString関数を使って、InpDateStartとInpDateFinishの日時を指定されたフォーマット(ここでは日付のみ)で文字列に変換しています。これにより、結果がどの期間に基づいて計算されたかをユーザーに知らせます。
  • str_ovb
    市場が買われすぎ領域にあった時間の割合を表す文字列です。DoubleToString関数を使用して、計算されたovb(買われすぎ領域にあった期間の割合)を2桁の小数点でフォーマットしています。この結果を文字列に組み込み、「市場は〇〇%の時間で買われすぎ領域にあった」と表示します。
  • str_ovs
    市場が売りすぎ領域にあった時間の割合を表す文字列です。同じくDoubleToString関数を使用して、ovs(売りすぎ領域にあった期間の割合)を2桁の小数点でフォーマットしています。この結果を文字列に組み込み、「市場は〇〇%の時間で売りすぎ領域にあった」と表示します。

これらの文字列は、単に数値を出力するのではなく、ユーザーにとって直感的に理解しやすい形式で結果を表示するために作成されています。日付の形式やパーセンテージを含めることで、分析期間や市場の状態をより明確に伝えることができます。この情報は後にチャート上で表示され、視覚的なフィードバックとしても役立ちます。

サンプルコード解説6:OnStart関数部分その5

 //--- チャート上に計算結果を表示するラベルを作成
  CreateLabel("top", 5, 60, str, clrDodgerBlue);  // 期間情報を表示
  CreateLabel("overbought", 5, 35, str_ovb, clrDodgerBlue);  // 買われすぎ領域の情報を表示
  CreateLabel("oversold", 5, 10, str_ovs, clrDodgerBlue);  // 売りすぎ領域の情報を表示

  //--- チャートを再描画する
  ChartRedraw(0);

  //--- 10秒間休止する
  Sleep(10000);
 }

このセクションでは、計算結果をチャート上に表示するための処理について説明します。ここでは、ラベルを作成し、売りすぎおよび買われすぎの情報を視覚的にユーザーに伝える役割を果たします。

ラベルの作成と表示

まず、CreateLabel関数を使用して、計算結果をチャート上に表示するラベルを作成しています。

  • CreateLabel関数
    この関数は、指定された位置にラベルを作成し、文字列を表示するために使用されます。ここでは、3つのラベルを作成しています。
  • “top”
    期間情報を表示するためのラベルです。ここでは、画面の上部に「期間: 日付から日付まで」の情報を表示します。
  • “overbought”
    買われすぎ領域にあった期間を表示するラベルです。チャート上では、少し下の位置にこの情報が表示されます。
  • “oversold”
    売りすぎ領域にあった期間を表示するラベルです。チャートのさらに下の位置にこの情報が表示されます。

各ラベルは、それぞれの位置(x座標5、y座標60, 35, 10)に配置され、str、str_ovb、str_ovsで作成した文字列が表示されます。また、clrDodgerBlueは、文字の色として指定されています。

チャートの再描画

次に、ChartRedraw関数を使用して、チャートを再描画します。

  • ChartRedraw関数
    この関数は、チャートの表示内容を更新し、ラベルなどの新たに追加されたオブジェクトを反映させるために使用されます。ここでは、計算結果を表示したラベルがチャート上に反映されるようにしています。

スクリプトの休止

最後に、Sleep関数スクリプトを10秒間一時停止させます。

  • Sleep関数
    スクリプトを指定されたミリ秒単位で一時的に停止させます。ここでは10,000ミリ秒(10秒間)スクリプトを休止させることで、表示された結果を一定時間チャート上に保持します。この後、スクリプトが再開され、処理が終了します。

結果の表示とフィードバック

この処理により、計算結果がチャート上にわかりやすく表示され、ユーザーは分析の結果を視覚的に確認できます。また、期間の情報とともに、市場が売りすぎや買われすぎの状態にあった時間の割合が表示されるため、取引の判断材料として利用可能です。

サンプルコード解説7:CreateLabel関数(オリジナル関数)部分

//+------------------------------------------------------------------+
//| チャートの左下隅にコメントを表示するための関数                    |
//+------------------------------------------------------------------+
void CreateLabel(const string name, const int x, const int y,
                const string str, const color clr)
 {
  //--- 指定した名前のラベルを作成する
  ObjectCreate(0, name, OBJ_LABEL, 0, 0, 0);

  //--- ラベルをチャートの左下隅に配置
  ObjectSetInteger(0, name, OBJPROP_CORNER, CORNER_LEFT_LOWER);

  //--- ラベルのアンカーポイントを左下に設定
  ObjectSetInteger(0, name, OBJPROP_ANCHOR, ANCHOR_LEFT_LOWER);

  //--- X軸方向のアンカーポイントからの距離を設定
  ObjectSetInteger(0, name, OBJPROP_XDISTANCE, x);

  //--- Y軸方向のアンカーポイントからの距離を設定
  ObjectSetInteger(0, name, OBJPROP_YDISTANCE, y);

  //--- ラベルに表示するテキストを設定
  ObjectSetString(0, name, OBJPROP_TEXT, str);

  //--- テキストの色を設定
  ObjectSetInteger(0, name, OBJPROP_COLOR, clr);

  //--- テキストサイズを設定
  ObjectSetInteger(0, name, OBJPROP_FONTSIZE, 12);
 }

このセクションでは、オリジナルのCreateLabel関数について詳しく解説します。この関数は、指定されたパラメータに基づいて、チャート上にテキストラベルを作成し、表示するために使用されます。さらに、引数や内部で使用されているMQL5関数識別子についても詳しく説明します。

CreateLabel関数の引数について

  • name
    ラベルの名前を指定する引数です。文字列型で、作成するラベルを一意(一つしか存在しない)に識別するために使用されます。この名前を使って後からラベルを操作することも可能です。
  • x
    ラベルのX軸方向(水平)の位置を指定する引数です。数値型で、左下隅を基準にして、どれだけの距離を離して配置するかを決めます。
  • y
    ラベルのY軸方向(垂直)の位置を指定する引数です。数値型で、左下隅を基準にして、どれだけの距離を離して配置するかを決めます。
  • str
    ラベルに表示するテキストを指定する引数です。文字列型で、実際に表示される内容がこの引数で渡されます。
  • clr
    ラベルのテキストの色を指定する引数です。色の定数RGB値で指定できます。ここでは、例えばclrDodgerBlueなどの定義済みの色が使われています。

関数内で使用されるMQL5関数の解説

  1. ObjectCreate関数
  • 用途: 新しいオブジェクト(この場合はラベル)をチャート上に作成します。
  • 引数の説明:
    • 第1引数: チャートの識別子。0は現在アクティブなチャートを意味します。
    • 第2引数: オブジェクトの名前。ここでは、引数として渡されたnameが使用されます。
    • 第3引数: オブジェクトの種類。OBJ_LABELはラベルを意味します。
    • 第4~6引数: オブジェクトの時間・価格位置を設定するための引数ですが、ラベルには不要なため0を指定しています。
  1. ObjectSetInteger関数
  • 用途: オブジェクトのプロパティを整数型で設定します。この関数が複数回使用されており、ラベルの位置や色などのプロパティが設定されます。
  • 引数の説明:
    • 第1引数: チャートの識別子。ここでも0は現在のチャートを意味します。
    • 第2引数: 設定するオブジェクトの名前。CreateLabel関数内では、ラベル名が指定されます。
    • 第3引数: 設定するプロパティ。以下で具体的なプロパティの種類を説明します。
    • 第4引数: プロパティに対して設定する値。例えば、位置や色、フォントサイズなどが指定されます。
  1. ObjectSetString関数
  • 用途: オブジェクトのプロパティを文字列型で設定します。この場合、ラベルに表示するテキストを設定します。
  • 引数の説明:
    • 第1引数: チャートの識別子。0で現在のチャート。
    • 第2引数: オブジェクトの名前。
    • 第3引数: 設定するプロパティ。ここではOBJPROP_TEXTが指定され、表示するテキストを意味します。
    • 第4引数: 実際に表示するテキスト内容。strで渡された文字列がここで設定されます。

識別子とプロパティの解説

  1. OBJPROP_CORNER
  • 意味: オブジェクトが配置されるチャートの角を指定します。ここではCORNER_LEFT_LOWERが使用されており、これはチャートの左下隅を意味します。
  1. OBJPROP_ANCHOR
  • 意味: オブジェクトのアンカーポイントを設定します。アンカーポイントとは、オブジェクトのどの部分を基準に配置するかを決定するものです。ANCHOR_LEFT_LOWERは、ラベルの左下が基準となることを意味します。
  1. OBJPROP_XDISTANCE
  • 意味: X軸方向(水平)のアンカーポイントからの距離を指定します。ここでは、x引数の値が設定され、左下隅からの水平距離が決定されます。
  1. OBJPROP_YDISTANCE
  • 意味: Y軸方向(垂直)のアンカーポイントからの距離を指定します。y引数がここで使われ、左下隅からの垂直距離を決定します。
  1. OBJPROP_TEXT
  • 意味: ラベルに表示するテキストを指定します。str引数で渡された文字列がこのプロパティに設定されます。
  1. OBJPROP_COLOR
  • 意味: ラベルのテキストの色を設定します。clr引数で指定された色がここで使われます。
  1. OBJPROP_FONTSIZE
  • 意味: ラベルのテキストのフォントサイズを設定します。ここでは、サイズ12が固定で指定されていますが、必要に応じて変更することも可能です。

関数全体の流れ

CreateLabel関数は、指定された名前、位置、テキスト、色をもとにチャート上にラベルを作成します。ラベルはチャートの左下隅に配置され、テキストの表示内容や色、サイズなどが細かく設定されます。この関数により、簡単にカスタマイズ可能なラベルを作成でき、ユーザーに重要な情報を視覚的に提供することが可能になります。

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