【MQL5】FileReadFloat関数について

MQL5リファレンス
スポンサーリンク
スポンサーリンク
  1. FileReadFloat関数の働き・役割
  2. FileReadFloat関数の引数について
  3. FileReadFloat関数の戻り値について
  4. FileReadFloat関数を使ったサンプルコード
  5. サンプルコード解説1:プロパティ命令部分
    1. indicator_separate_window
    2. indicator_buffers
    3. indicator_plots
    4. indicator_label1
    5. indicator_type1
    6. indicator_color1
    7. indicator_style1
    8. indicator_width1
  6. サンプルコード解説2:グローバル領域部分
    1. input 変数
      1. InpFileName
      2. InpDirectoryName
    2. グローバル変数
      1. ind
      2. size
    3. バッファ
      1. close_buff
      2. time_buff
    4. 指標バッファ
      1. buff
      2. color_buff
  7. サンプルコード解説3:OnInit関数部分その1
    1. def_size
    2. ArrayResize
    3. ResetLastError
    4. FileOpen
  8. サンプルコード解説4:OnInit関数部分その2
    1. file_handle != INVALID_HANDLE
    2. PrintFormat
  9. サンプルコード解説5:OnInit関数部分その3
    1. while(!FileIsEnding(file_handle))
    2. time_buff[size] = (datetime)FileReadDouble(file_handle)
    3. close_buff[size] = (double)FileReadFloat(file_handle)
    4. size++
    5. if(size == def_size)
    6. def_size += 100
    7. ArrayResize
  10. サンプルコード解説6:OnInit関数部分その4
    1. FileClose(file_handle)
    2. PrintFormat(“Data is read, %s file is closed”, InpFileName)
    3. elseブロック
    4. PrintFormat(“Failed to open %s file, Error code = %d”, InpFileName, GetLastError())
    5. return(INIT_FAILED)
  11. サンプルコード解説7:OnInit関数部分その5
    1. SetIndexBuffer(0, buff, INDICATOR_DATA)
    2. SetIndexBuffer(1, color_buff, INDICATOR_COLOR_INDEX)
    3. PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, 0)
    4. return(INIT_SUCCEEDED)
  12. サンプルコード解説8:OnCalculate関数部分
    1. ArraySetAsSeries(time, false)
    2. for(int i=prev_calculated; i<rates_total; i++)
    3. buff[i] = 0 と color_buff[i] = 0
    4. if(ind < size)
    5. for(int j = ind; j < size; j++)
    6. if(time[i] == time_buff[j])
      1. 各変数の役割
    7. buff[i] = close_buff[j]
    8. if(buff[i-1] > buff[i])
    9. ind = j + 1
    10. return(rates_total)

FileReadFloat関数の働き・役割

FileReadFloat関数は、バイナリファイルの現在の読み取り位置から単精度浮動小数点数(float)型のデータを読み込むために使用されます。ファイルをバイナリ形式で開いた後、この関数を使うことで、数値データを順番に読み出すことができます。例えば、価格データやインジケータの数値データを格納したファイルから、浮動小数点数の値を取り出す際に役立ちます。

FileReadFloat関数の引数について

float  FileReadFloat(
  int  file_handle    // ファイルハンドル
  );

FileReadFloat関数は1つの引数を取ります。この引数は、ファイルからデータを読み取る際に必要となります。

FileReadFloat関数は、指定されたファイルの現在の読み取り位置から単精度浮動小数点数を取得し、読み取り位置を次のデータに進めます。

FileReadFloat関数の戻り値について

FileReadFloat関数は、バイナリファイルの現在の読み取り位置から読み込まれた単精度浮動小数点数(float型の値)を返します。この値は、ファイルに保存されている数値データであり、例えば価格や取引量、インジケータの値として使われることがあります。

もしファイルの読み込みに失敗した場合や、読み込めるデータがない場合には、不正なデータが返される可能性があります。このような場合は、GetLastError関数を使ってエラーコードを確認し、問題を特定することが推奨されます。

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

#property indicator_separate_window // インジケータを別ウィンドウに表示
#property indicator_buffers 2        // インジケータバッファ数は2
#property indicator_plots   1        // プロットの数は1
//---- Label1 をプロットする
#property indicator_label1 "CloseLine" // プロットにラベル「CloseLine」を設定
#property indicator_type1   DRAW_COLOR_LINE // 色付きラインとして描画
#property indicator_color1 clrRed,clrBlue   // 色は赤と青を設定
#property indicator_style1 STYLE_SOLID      // ラインスタイルは実線
#property indicator_width1  2               // ラインの太さは2
//--- データ読み込みのパラメータ
input string InpFileName="Close.bin";   // 読み込むファイル名(ここでは"Close.bin")
input string InpDirectoryName="Data";   // ファイルの格納ディレクトリ(ここでは"Data")
//--- グローバル変数
int      ind=0;                         // ファイル内のデータ処理用のインデックス
int      size=0;                        // 読み込んだデータの数
double   close_buff[];                  // ファイルから読み取った価格データを格納するバッファ
datetime time_buff[];                   // ファイルから読み取った時間データを格納するバッファ
//--- 指標バッファ
double   buff[];                        // チャートに描画する価格データを格納するバッファ
double   color_buff[];                  // チャート上のラインの色を格納するバッファ
//+------------------------------------------------------------------+
//| カスタム指標を初期化する関数                                      |
//+------------------------------------------------------------------+
int OnInit()
{
  int def_size=100; // データの初期サイズを100に設定
  //--- 配列へメモリを割り当てる(100のサイズで初期化)
  ArrayResize(close_buff,def_size);
  ArrayResize(time_buff,def_size);
  //--- ファイルを開く
  ResetLastError(); // エラーコードをリセット
  int file_handle=FileOpen(InpDirectoryName+"//"+InpFileName,FILE_READ|FILE_BIN); // ファイルをバイナリモードで開く
  if(file_handle!=INVALID_HANDLE) // ファイルが正常に開けたか確認
  {
    PrintFormat("%s file is available for reading",InpFileName); // ファイルが読み込み可能であることを表示
    PrintFormat("File path: %s\\Files\\",TerminalInfoString(TERMINAL_DATA_PATH)); // ファイルのパスを表示
    //--- ファイルからデータを読む
    while(!FileIsEnding(file_handle)) // ファイルの終わりまで繰り返し処理
    {
      //--- ファイルから時間データを読み込み、配列に格納
      time_buff[size]=(datetime)FileReadDouble(file_handle); 
      //--- ファイルから価格データを読み込み、配列に格納
      close_buff[size]=(double)FileReadFloat(file_handle); 
      size++; // データサイズを増加
      //--- 配列がオーバーフローしそうな場合、メモリを追加で割り当てる
      if(size==def_size)
      {
        def_size+=100; // 配列のサイズを100増やす
        ArrayResize(close_buff,def_size); // 価格データ配列のサイズを変更
        ArrayResize(time_buff,def_size);  // 時間データ配列のサイズを変更
      }
    }
    //--- ファイルを閉じる
    FileClose(file_handle); // ファイルを閉じる
    PrintFormat("Data is read, %s file is closed",InpFileName); // ファイルの読み込み完了を表示
  }
  else
  {
    // ファイルが開けなかった場合のエラーメッセージ
    PrintFormat("Failed to open %s file, Error code = %d",InpFileName,GetLastError());
    return(INIT_FAILED); // 初期化失敗を返す
  }
  //--- 配列と指標バッファを関連付ける
  SetIndexBuffer(0,buff,INDICATOR_DATA); // buff配列を指標データバッファとして設定
  SetIndexBuffer(1,color_buff,INDICATOR_COLOR_INDEX); // color_buffをラインの色バッファとして設定
  //--- チャートでは表示されない指標値を設定
  PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0); // チャート上に値がない部分を設定
  //---
  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[])
{
  ArraySetAsSeries(time,false); // time配列を昇順に設定
  //--- まだ処理されてないバーのループ
  for(int i=prev_calculated;i<rates_total;i++)
  {
    //--- デフォルトでは 0を設定
    buff[i]=0; 
    color_buff[i]=0; // デフォルトでは赤色(0は赤)
    //--- まだファイルからのデータがあるかチェック
    if(ind<size)
    {
      for(int j=ind;j<size;j++) // ファイルのデータをループ処理
      {
        //--- チャートの時間とファイルの時間が一致しているかを確認
        if(time[i]==time_buff[j])
        {
          //--- ファイルからの価格データをバッファに設定
          buff[i]=close_buff[j]; 
          //--- 直前の価格が現在の価格より高い場合は青色に変更
          if(buff[i-1]>buff[i])
            color_buff[i]=1; // 色を青に設定(1は青)
          //--- カウンタを進める
          ind=j+1;
          break; // データが一致したらループを抜ける
        }
      }
    }
  }
  //--- 次回呼び出しのために、処理されたバーの数を返す
  return(rates_total);
}

サンプルコード解説1:プロパティ命令部分

#property indicator_separate_window // インジケータを別ウィンドウに表示
#property indicator_buffers 2        // インジケータバッファ数は2
#property indicator_plots   1        // プロットの数は1
//---- Label1 をプロットする
#property indicator_label1 "CloseLine" // プロットにラベル「CloseLine」を設定
#property indicator_type1   DRAW_COLOR_LINE // 色付きラインとして描画
#property indicator_color1 clrRed,clrBlue   // 色は赤と青を設定
#property indicator_style1 STYLE_SOLID      // ラインスタイルは実線
#property indicator_width1  2

MQL5では、プロパティ命令を使って、インジケータスクリプトに関する設定を指定します。これにより、インジケータの表示形式や動作を細かく調整することができます。以下に、サンプルコード内で使用されている各プロパティ命令について解説します。

indicator_separate_window

この設定は、インジケータをチャートとは別のウィンドウに表示することを指定しています。指定することで、インジケータは価格チャートと同じウィンドウではなく、独立したウィンドウに表示されます。価格や取引量以外のデータを視覚化する場合によく使用されます。

indicator_buffers

このプロパティは、インジケータが使用するバッファの数を設定します。このサンプルでは、2つのバッファが使用されています。1つ目のバッファインジケータのデータ自体を保持し、2つ目のバッファインジケータの色を保持するために使用されます。
バッファとは、データを一時的に保存する領域のことです。

indicator_plots

この設定は、インジケータにおけるプロットの数を指定します。プロットとは、チャートに描画されるデータの数を意味します。ここでは、1つのプロットが描画される設定です。

indicator_label1

プロットに付けられるラベルを定義します。このサンプルでは、「CloseLine」というラベルが設定されており、インジケータウィンドウに表示される線の名前として使用されます。ラベルは、インジケータが何を表しているかを示すための名前や説明として機能します。例えば、複数の線やデータを表示する場合、それぞれのラベルを使って、各プロットがどのデータに対応しているのかを視覚的に識別することができます。ラベルは、チャートの凡例に表示され、ユーザーがインジケータの内容を理解するのに役立ちます。

indicator_type1

このプロパティは、インジケータの描画タイプを指定します。このサンプルでは、色付きのラインとしてインジケータが描画される設定です。これは、指定したデータがチャート上に連続したラインとして描かれることを意味します。

indicator_color1

ラインの色を指定します。ここでは、赤と青が指定されています。データの変動に応じて、ラインが赤または青で表示されるようになっています。

indicator_style1

ラインのスタイルを定義します。スタイルは、実線や点線などを指定でき、このサンプルでは実線として描画される設定です。

indicator_width1

描画されるラインの太さを設定します。ここでは、太さが2に設定されており、比較的太めのラインが表示されます。ラインの太さは視覚的な強調に役立ちます。

このプロパティ命令部分では、インジケータの見た目や表示の方法を細かく設定しており、視覚的にわかりやすいインジケータを作成するための基本的な設定が行われています。

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

//--- データ読み込みのパラメータ
input string InpFileName="Close.bin";   // 読み込むファイル名(ここでは"Close.bin")
input string InpDirectoryName="Data";   // ファイルの格納ディレクトリ(ここでは"Data")
//--- グローバル変数
int      ind=0;                         // ファイル内のデータ処理用のインデックス
int      size=0;                        // 読み込んだデータの数
double   close_buff[];                  // ファイルから読み取った価格データを格納するバッファ
datetime time_buff[];                   // ファイルから読み取った時間データを格納するバッファ
//--- 指標バッファ
double   buff[];                        // チャートに描画する価格データを格納するバッファ
double   color_buff[];                  // チャート上のラインの色を格納するバッファ

このセクションでは、グローバル変数や入力パラメータが定義されています。これらはプログラム全体で使用され、カスタムインジケータの動作を制御するための重要な役割を果たしています。

input 変数

InpFileName

この変数は、読み込むファイルの名前を指定します。ここでは「Close.bin」という名前のファイルを指定しており、インジケータが価格データを読み取るファイルとなっています。この変数は「input」として定義されているため、チャート上でインジケータを適用する際に、ユーザーが変更可能なパラメータです。

InpDirectoryName

この変数は、読み込むファイルが保存されているディレクトリ名を指定しています。ここでは「Data」というディレクトリが指定されています。ファイル名と同様に、「input」として定義されているため、ユーザーが設定を変更することが可能です。

グローバル変数

ind

この変数は、ファイル内のデータを処理するためのインデックスとして使用されます。ファイルからデータを順次読み取る際に、このインデックスがデータの位置を示し、データの処理が進むたびに更新されます。

size

ファイルから読み込んだデータの数を保持します。この変数は、読み込んだ価格データや時間データの個数を追跡し、次のデータを読み込む際に配列のサイズ管理に利用されます。

バッファ

close_buff

この配列は、ファイルから読み取った価格データを一時的に保持します。ファイルから価格情報が読み込まれると、この配列にデータが格納され、その後チャートに描画されます。

time_buff

この配列は、ファイルから読み取った時間データを格納します。ファイルに記録されている各データポイントに対する時間情報が、この配列に格納されます。価格データと時間データは対応しており、同じインデックスで管理されています。

指標バッファ

buff

この配列は、チャート上に描画する価格データを保持します。価格データはインジケータとして視覚的に表示されるため、この配列にデータが保持されます。

color_buff

この配列は、ラインの色を管理するためのバッファです。チャート上に表示されるラインの色(赤や青)が、このバッファに格納されます。価格の変動に応じて、色が変わるように設定されています。

このグローバル領域では、プログラム全体で使用される主要な変数が定義され、価格データや時間データの管理、ラインの描画と色の制御が可能になっています。

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

//+------------------------------------------------------------------+
//| カスタム指標を初期化する関数                                      |
//+------------------------------------------------------------------+
int OnInit()
{
  int def_size=100; // データの初期サイズを100に設定
  //--- 配列へメモリを割り当てる(100のサイズで初期化)
  ArrayResize(close_buff,def_size);
  ArrayResize(time_buff,def_size);
  //--- ファイルを開く
  ResetLastError(); // エラーコードをリセット
  int file_handle=FileOpen(InpDirectoryName+"//"+InpFileName,FILE_READ|FILE_BIN); 
// ファイルをバイナリモードで開く

OnInit関数は、カスタム指標が初期化される際に一度だけ実行される関数です。この関数内では、インジケータの初期設定やファイルの読み込み準備が行われます。以下はその詳細な解説です。

def_size

この変数は、配列に割り当てる初期サイズを指定します。ここでは、100という値が設定されており、ファイルから読み込むデータの数を格納するための配列の初期サイズが100に設定されています。このサイズは後で動的に変更することができるため、必要に応じて増加されることがあります。

ArrayResize

ArrayResize関数は、指定した配列メモリを割り当てるために使用されます。この場合、close_buffとtime_buffの2つの配列に対して、それぞれdef_sizeで指定された100のサイズでメモリが割り当てられています。これにより、ファイルから読み込む価格データと時間データを格納するための領域が確保されます。

ResetLastError

ResetLastError関数は、前回のエラー情報をリセットするために使用されます。この関数を呼び出すことで、以前に発生したエラーコードが消去され、ファイル操作などで新たなエラーが発生した場合に正確にエラーを取得できるようになります。ここでは、ファイルを開く前にエラー状態をクリアしておくために使用されています。

FileOpen

FileOpen関数は、指定したファイルを開くための関数です。第1引数にはファイルのパス情報が指定されます。ここでは、InpDirectoryNameとInpFileNameを組み合わせることで、ファイルのディレクトリと名前を指定しています。例えば、「Data」ディレクトリ内にある「Close.bin」というファイルを開くために、このパスが使われます。

第2引数には、ファイルの開き方を指定する情報が含まれます。ここでは、FILE_READとFILE_BINが指定されています。FILE_READはファイルを「読み込み専用」で開くことを示し、FILE_BINは「バイナリ形式」でファイルを開くことを意味します。これらの2つの指定は、パイプ記号(|)で繋がれています。パイプ記号は、複数のオプションを同時に指定するためのものです。この場合、「読み込み専用」で「バイナリ形式」のファイルを開くという2つの条件を組み合わせていることになります。

端的に言うと、FileOpen関数では、指定したパスのバイナリファイルを読み込み専用で開くという動作を行っています。

この部分では、データを格納するための配列を初期化し、ファイルを正しく読み込むための準備が整えられています。続くコードでは、ファイルが正常に開けたかどうかのチェックやデータの読み取りが行われます。

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

 if(file_handle!=INVALID_HANDLE) // ファイルが正常に開けたか確認
  {
    PrintFormat("%s file is available for reading",InpFileName); // ファイルが読み込み可能であることを表示
    PrintFormat("File path: %s\\Files\\",TerminalInfoString(TERMINAL_DATA_PATH)); // ファイルのパスを表示
    //--- ファイルからデータを読む

この部分では、ファイルが正常に開けたかどうかを確認し、開けた場合にファイルのパス情報を表示し、ファイルからデータを読み込む準備を進める処理が行われています。

file_handle != INVALID_HANDLE

file_handleは、FileOpen関数が返すファイルハンドル(ファイルを操作するための識別子)です。このハンドルが有効であればファイルは正常に開けたことを示し、無効な場合はINVALID_HANDLEが返されます。この条件式では、file_handleがINVALID_HANDLEと等しくないかどうかを確認し、ファイルが正常に開けた場合のみ次の処理を実行します。これにより、エラーが発生していないことをチェックしています。

PrintFormat

PrintFormat関数は、指定した形式でメッセージを作成し、エキスパートログに出力します。最初のPrintFormat関数では、ファイル名が読み込み可能であることを表示します。ここでは、ファイル名を指定された変数InpFileNameに置き換えて表示しています。

2つ目のPrintFormat関数は、ファイルのパスを表示します。TerminalInfoString関数を使って、ターミナルのデータディレクトリパスを取得し、そのパス情報と固定された「\Files\」という部分を組み合わせて表示しています。これにより、ファイルがどこに存在しているのかを確認することができます。

この部分では、ファイルが正常に開けた場合に、読み込みが可能であることとファイルのパスをエキスパートログに表示しています。

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

 while(!FileIsEnding(file_handle)) // ファイルの終わりまで繰り返し処理
    {
      //--- ファイルから時間データを読み込み、配列に格納
      time_buff[size]=(datetime)FileReadDouble(file_handle); 
      //--- ファイルから価格データを読み込み、配列に格納
      close_buff[size]=(double)FileReadFloat(file_handle); 
      size++; // データサイズを増加
      //--- 配列がオーバーフローしそうな場合、メモリを追加で割り当てる
      if(size==def_size)
      {
        def_size+=100; // 配列のサイズを100増やす
        ArrayResize(close_buff,def_size); // 価格データ配列のサイズを変更
        ArrayResize(time_buff,def_size);  // 時間データ配列のサイズを変更
      }
    }

この部分では、ファイルの終わりまでデータを読み込み、それを対応する配列に格納する処理が行われています。ファイルの読み取りが完了するまでループ処理を実行し、価格と時間のデータを順次バッファに保存していきます。

while(!FileIsEnding(file_handle))

この条件式は、ファイルの終わりに到達するまでループ処理を続けるためのものです。FileIsEnding関数は、ファイルの読み込みが終わったかどうかを判定する関数で、終わりに到達していない場合はfalseを返します。whileループは、この条件がtrueになるまで繰り返し実行されます。

time_buff[size] = (datetime)FileReadDouble(file_handle)

この行では、ファイルから時間データを読み込み、その値をtime_buff配列の現在のインデックス(size)に格納します。FileReadDouble関数はファイルから倍精度浮動小数点数を読み込みますが、dateTime型キャストして、日時データとして配列に保存しています。

close_buff[size] = (double)FileReadFloat(file_handle)

この行では、ファイルから価格データを読み込み、その値をclose_buff配列の同じインデックスに格納します。FileReadFloat関数を使用して単精度浮動小数点数(float型)のデータを読み込み、double型キャストして価格データとして保存しています。

size++

この行では、データが1つ読み込まれるたびにsize変数が1つ増加します。これにより、次のデータを格納する配列インデックスが更新されていきます。

if(size == def_size)

この条件式は、配列のサイズが現在の定義サイズ(def_size)に達したかどうかを確認します。もし配列がいっぱいになった場合には、新たに100個分のメモリを追加で確保する必要があります。

def_size += 100

この行では、配列のサイズを100増やしています。これにより、次に配列が必要となるデータが保存できるよう、メモリ領域が拡張されます。

ArrayResize

ArrayResize関数は、指定された配列のサイズを変更するために使用されます。ここでは、close_buffとtime_buffの両方の配列サイズが、100ずつ増加されます。この処理により、読み込むデータ量が増えても問題なくデータを格納できるようになります。

この部分では、ファイルの終わりまで価格と時間データを順次読み込み、バッファに保存しつつ、必要に応じて配列のサイズを拡張する処理が行われています。

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

   //--- ファイルを閉じる
    FileClose(file_handle); // ファイルを閉じる
    PrintFormat("Data is read, %s file is closed",InpFileName); // ファイルの読み込み完了を表示
  }
  else
  {
    // ファイルが開けなかった場合のエラーメッセージ
    PrintFormat("Failed to open %s file, Error code = %d",InpFileName,GetLastError());
    return(INIT_FAILED); // 初期化失敗を返す
  }

この部分では、ファイルの読み込みが完了した後の処理や、ファイルが開けなかった場合のエラーハンドリングについて説明します。

FileClose(file_handle)

ファイル操作が完了した後、FileClose関数を使用してファイルを閉じます。ファイルを開いたままにすると、システムのリソースを消費するため、必ずファイルを閉じる必要があります。ここでは、file_handle(ファイルハンドル)を指定し、開いていたファイルを正常に閉じる処理を行っています。

PrintFormat(“Data is read, %s file is closed”, InpFileName)

この行は、ファイルが正常に閉じられたことをエキスパートログに出力するためのものです。PrintFormat関数を使用して、指定されたファイル名を含むメッセージが表示されます。これにより、ファイルの読み込みと閉じる処理が正常に完了したことを確認できます。

elseブロック

この部分は、ファイルが開けなかった場合のエラーハンドリングです。

PrintFormat(“Failed to open %s file, Error code = %d”, InpFileName, GetLastError())

ファイルを開けなかった場合、PrintFormat関数を使ってエラーメッセージをエキスパートログに出力します。ファイル名(InpFileName)と、GetLastError関数が返すエラーコードを含む形式でエラーメッセージが表示されます。GetLastError関数は、最後に発生したエラーの詳細を返すため、問題の原因を特定するのに役立ちます。

return(INIT_FAILED)

ファイルが開けなかった場合、関数はINIT_FAILEDを返し、指標の初期化に失敗したことを示します。これにより、指標は実行されず、エラーが発生したことを他の部分で確認できます。

この部分では、ファイルを正常に閉じる処理と、ファイルが開けなかった場合のエラーメッセージの表示と初期化失敗を処理しています。

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

//--- 配列と指標バッファを関連付ける
  SetIndexBuffer(0,buff,INDICATOR_DATA); // buff配列を指標データバッファとして設定
  SetIndexBuffer(1,color_buff,INDICATOR_COLOR_INDEX); // color_buffをラインの色バッファとして設定
  //--- チャートでは表示されない指標値を設定
  PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0); // チャート上に値がない部分を設定
  //---
  return(INIT_SUCCEEDED); // 初期化成功を返す
}

この部分では、配列インジケータバッファに関連付ける処理や、インジケータが表示するデータの初期設定を行っています。最後に、初期化が成功したことを示す値を返します。

SetIndexBuffer(0, buff, INDICATOR_DATA)

SetIndexBuffer関数は、指定した配列インジケータバッファに関連付けます。最初の引数「0」は、バッファインデックス(通し番号)を指定しています。ここでは「buff」配列インジケータのデータバッファとして設定され、チャート上に表示されるデータがこの配列に基づいて描画されます。「INDICATOR_DATA」は、このバッファインジケータのデータを保持するものであることを示しています。

SetIndexBuffer(1, color_buff, INDICATOR_COLOR_INDEX)

この行は、2番目のバッファ「color_buff」を色インデックス用のバッファとして設定しています。これにより、ラインの色が「color_buff」配列のデータに基づいて変更されます。例えば、価格が上昇している場合は青、下降している場合は赤といったように、価格変動に応じた色の変化を表示することが可能です。

PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, 0)

PlotIndexSetDouble関数は、チャート上に値が表示されない場合の値を設定します。ここでは「PLOT_EMPTY_VALUE」を使って、データがない場所や表示する値がない場合に、何も表示しないように設定しています。この設定により、データが存在しない部分にはラインが描画されなくなります。

return(INIT_SUCCEEDED)

この行は、初期化が成功したことを示す値を返します。INIT_SUCCEEDEDは、インジケータの初期化が正しく行われた場合に返される定数であり、これが返されると、インジケータは正常に動作を開始します。

この部分では、価格データや色データを保持するバッファを設定し、値がない部分の処理を行い、最後に初期化成功を返しています。

サンプルコード解説8:OnCalculate関数部分

//+------------------------------------------------------------------+
//| カスタム指標の反復関数                                            |
//+------------------------------------------------------------------+
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[])
{
  ArraySetAsSeries(time,false); // time配列を昇順に設定
  //--- まだ処理されてないバーのループ
  for(int i=prev_calculated;i<rates_total;i++)
  {
    //--- デフォルトでは 0を設定
    buff[i]=0; 
    color_buff[i]=0; // デフォルトでは赤色(0は赤)
    //--- まだファイルからのデータがあるかチェック
    if(ind<size)
    {
      for(int j=ind;j<size;j++) // ファイルのデータをループ処理
      {
        //--- チャートの時間とファイルの時間が一致しているかを確認
        if(time[i]==time_buff[j])
        {
          //--- ファイルからの価格データをバッファに設定
          buff[i]=close_buff[j]; 
          //--- 直前の価格が現在の価格より高い場合は青色に変更
          if(buff[i-1]>buff[i])
            color_buff[i]=1; // 色を青に設定(1は青)
          //--- カウンタを進める
          ind=j+1;
          break; // データが一致したらループを抜ける
        }
      }
    }
  }
  //--- 次回呼び出しのために、処理されたバーの数を返す
  return(rates_total);

OnCalculate関数は、インジケータの計算を繰り返し実行するための関数です。チャートのバーが更新されるたびに、この関数が呼び出され、データの処理や表示が行われます。このセクションでは、ファイルから読み込んだデータとチャートのバーを比較し、データをチャート上に表示するための処理が行われています。

ArraySetAsSeries(time, false)

ArraySetAsSeries関数は、time配列の順序を設定します。ここでは、time配列を昇順に設定することで、チャート上のデータが古い順から新しい順に並ぶようにしています。MQL5では、配列が降順(新しいデータが先頭)か昇順(古いデータが先頭)に設定でき、ここでは昇順で処理を進めます。

for(int i=prev_calculated; i<rates_total; i++)

このループでは、まだ処理されていないバーに対して処理を行います。prev_calculatedは前回までに処理されたバーの数を表しており、それ以降のバー(新しいバー)を対象にループが進みます。rates_totalは、チャート全体のバーの数を表します。

buff[i] = 0 と color_buff[i] = 0

各バーのデフォルト値を設定しています。buff配列はチャートに描画される価格データを保持し、color_buff配列はラインの色を管理します。ここでは、デフォルトで価格データを0に、色を赤色(0は赤)に設定しています。

if(ind < size)

ファイルからのデータがまだ存在するかどうかをチェックします。indは、ファイル内のデータを順次処理するためのインデックスであり、sizeは読み込んだデータの数です。まだ未処理のデータが残っている場合、この条件が真になります。

if(ind < size) が真のとき、まだデータが残っているといえる理由は、ind は現在処理されているデータのインデックス(位置)を示し、size は読み込まれたデータの総数を表すからです。

indsize より小さい場合、それは現在の位置(ind)が読み込まれたデータの総数(size)に達していないことを示しています。したがって、まだ未処理のデータが残っていると判断でき、次のデータを処理することができます。

逆に、indsize に達すると、すべてのデータが処理済みであり、それ以上データは存在しないことになります。

for(int j = ind; j < size; j++)

ファイル内のデータをループ処理し、time_buff配列に格納された時間データを順次チェックします。

if(time[i] == time_buff[j])

チャートの現在のバーの時間(time[i])と、ファイルから読み込んだ時間(time_buff[j])が一致しているかを確認します。この一致が確認されると、ファイルから読み込んだ価格データをチャートに反映することができます。

if(time[i] == time_buff[j])は、チャートの時間データとファイルから読み込んだ時間データが一致するかどうかを確認するための条件式です。この記述は、ファイル内のデータが、チャート上のどのバー(時点)に対応しているのかを判断する重要な役割を果たします。

各変数の役割

  • time[i]
    チャート上のバー(ローソク足)に対応する時間を保持する配列time の、i 番目の要素を指します。i は現在のバーのインデックスです。time[i] は、現在のチャート上での特定のバーの時刻を示しています。
  • time_buff[j]
    ファイルから読み込んだ時間データを保持している配列time_buff の、j 番目の要素です。j はファイルから読み込んだデータのインデックスで、ファイルに記録されている各データに対応する時刻を保持しています。

buff[i] = close_buff[j]

ファイルから読み込んだ価格データ(close_buff[j])を、チャートの価格データバッファ(buff[i])に設定します。これにより、チャート上にファイルのデータが反映されます。

if(buff[i-1] > buff[i])

現在の価格が前の価格よりも低い場合、色を青色に変更する処理です。この条件が満たされた場合、color_buff[i]に1を設定し、これによってラインが青色で表示されます。

ind = j + 1

インデックスindを更新します。これにより、次回のループでファイルの次のデータを処理することができます。

return(rates_total)

関数の最後では、チャート全体のバー数(rates_total)を返します。これにより、次回呼び出された際に前回の処理状況を保持しつつ、未処理のバーだけを対象に処理を続けることができます。

この部分では、ファイルから読み込んだデータをチャートの時間データと照合し、価格データを表示しつつ、その変動に応じてラインの色を変更する処理が実行されています。

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