- FileReadInteger関数の働き・役割
- FileReadInteger関数の引数について
- FileReadInteger関数の戻り値について
- FileReadInteger関数を使う際の注意点
- FileReadInteger関数を使ったサンプルコード
- サンプルコード解説1:プロパティ命令
- サンプルコード解説2:グローバル領域部分
- サンプルコード解説3:OnInit関数部分その1
- int OnInit
- int def_size=100
- 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)
- int arr_size
- uchar arr[]
- サンプルコード解説4:OnInit関数部分その2
- サンプルコード解説5:OnInit関数部分その3
- サンプルコード解説6:OnInit関数部分その4
- サンプルコード解説7:OnCalculate関数部分
FileReadInteger関数の働き・役割
FileReadInteger関数は、ファイルポインタの現在位置から整数型のデータを読み込むために使用されます。この関数は、指定されたバイト数に応じて、int型、Short型、char型のいずれかの形式の整数を読み取ることができます。
FileReadInteger関数は、バイナリファイルからデータを効率的に読み出す際に利用されるため、EA(エキスパートアドバイザー)やカスタムインジケータの開発において、過去のトレードデータやカスタムフォーマット(ユーザーや開発者が独自に定義したデータの形式や構造)のファイルを扱う場合に特に有用です。
FileReadInteger関数の引数について
int FileReadInteger(
int file_handle, // ファイルハンドル
int size=INT_VALUE // バイト単位での整数のサイズ
);
FileReadInteger関数の引数は以下の通りです。
file_handle
最初の引数は、ファイルハンドルを指定します。これは、FileOpen関数で取得されるファイル識別子を使用します。ファイルが正しく開かれていない場合、この引数の値は無効であり、FileReadInteger関数は失敗します。ファイルがバイナリ形式で開かれている必要があります。
size=INT_VALUE
第二引数は、読み込むデータのサイズをバイト単位で指定します。この引数には、以下の定数を使用します。
- CHAR_VALUE (1):1バイト(char型のデータ)を読み込みます。
- SHORT_VALUE (2):2バイト(Short型のデータ)を読み込みます。
- INT_VALUE (4):4バイト(int型のデータ)を読み込みます。
sizeの指定によって、FileReadInteger関数は適切なサイズのデータをバイト単位で読み込みます。sizeに3を指定して3バイトのデータを読み込むことは可能ですが、符号の扱いが難しくなる点に注意が必要です。
FileReadInteger関数の戻り値について
FileReadInteger関数の戻り値は、指定されたバイト数に応じたint型の値です。戻り値は、次のようにして扱われます。
- int型: 4バイト(32ビット)のデータが読み込まれた場合、戻り値はint型の値になります。
- Short型 2バイト(16ビット)のデータが読み込まれた場合、戻り値はShort型にキャストして使用します。
- char型: 1バイト(8ビット)のデータが読み込まれた場合、戻り値はchar型にキャストして使用します。
戻り値としては常にint型が返されますが、読み込んだデータの正確な型に基づいて明示的にキャストする必要があります。また、ファイルから読み込まれたバイト数に応じて、ファイルポインタが自動的に移動します。
たとえば、char型やShort型のデータを読み込む場合は、それぞれ(char)や(Short)のようにキャストして使用することが推奨されます。
FileReadInteger関数を使う際の注意点
FileOpen関数でファイルを正しく開けなかった場合、FileReadInteger関数は動作しません。そのため、ファイルハンドルが無効でないか確認することが大切です。
size引数で指定するバイト数は1、2、4のいずれかにすることが基本です。3バイトのデータを読み込むことも可能ですが、その場合は符号の扱いが難しくなるため、特別な処理が必要となります。
FileReadInteger関数を使用すると、ファイルポインタは自動的に読み込んだバイト数分だけ移動します。そのため、複数回の読み込みを行う場合には、前回の読み込み位置を正確に把握することが重要です。
FileReadInteger関数は常にint型で戻り値を返しますが、読み込んだデータがchar型やShort型の場合、それに応じてキャストを行わないと正しい値を取得できません。
FileReadInteger関数を使ったサンプルコード
#property indicator_chart_window // インジケータをチャートウィンドウに表示する
#property indicator_buffers 1 // インジケータのバッファを1つ使用する
#property indicator_plots 1 // インジケータのプロット数を1つ指定する
//---- ラベル1をプロットする設定
#property indicator_label1 "Trends" // インジケータの名前を"Trends"に設定
#property indicator_type1 DRAW_SECTION // 描画の種類をセクションに設定
#property indicator_color1 clrRed // 描画の色を赤色に設定
#property indicator_style1 STYLE_SOLID // 線のスタイルを実線に設定
#property indicator_width1 1 // 線の幅を1ピクセル(デジタル画像を構成する最小の単位)に設定
//--- データ読み込みのパラメータ
input string InpFileName="Trend.bin"; // 読み込むファイルの名前を"Trend.bin"に設定
input string InpDirectoryName="Data"; // 読み込むディレクトリの名前を"Data"に設定
//--- グローバル変数
int ind=0; // インデックスを保持する変数
int size=0; // 読み込んだデータのサイズを保持する変数
datetime time_buff[]; // 読み込んだ時間データを格納する配列
//--- 指標バッファ
double buff[]; // インジケータのデータを格納するバッファ
//+------------------------------------------------------------------+
//| カスタム指標を初期化する関数 |
//+------------------------------------------------------------------+
int OnInit()
{
int def_size=100; // デフォルトの配列サイズを100に設定
//--- 配列にメモリを割り当てる
ArrayResize(time_buff,def_size); // time_buff配列のサイズを100にリサイズ
//--- ファイルを開く
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));
// ファイルのパスをエキスパートログに出力
//--- 追加の変数
int arr_size; // 配列サイズを保持する変数
uchar arr[]; // 読み込んだバイトデータを格納する配列
//--- ファイルからデータを読み取る
while(!FileIsEnding(file_handle)) // ファイルの末尾に達していない間、読み込みを続ける
{
//--- 時間情報を格納するためのバイト数を読み取る
arr_size=FileReadInteger(file_handle,INT_VALUE);
// 4バイト(int型)を読み取ってサイズを取得
ArrayResize(arr,arr_size); // 読み込むデータ用に配列arrのサイズをリサイズ
for(int i=0;i<arr_size;i++)
arr[i]=(char)FileReadInteger(file_handle,CHAR_VALUE);
// 1バイト(char型)を1つずつ読み込み、arr配列に格納
//--- 読み取ったデータを時間に変換し、time_buffに保存
time_buff[size]=StringToTime(CharArrayToString(arr));
// 文字配列arrを文字列に変換し、それを時間データとしてtime_buffに格納
size++; // 読み込んだデータ数をカウント
//--- 配列がいっぱいになった場合、配列サイズを100ずつ増やす
if(size==def_size)
{
def_size+=100; // 配列サイズを100増加
ArrayResize(time_buff,def_size); // time_buff配列のサイズを再調整
}
}
//--- ファイルを閉じる
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); // インジケータバッファにデータを設定する
//---- チャートには表示されない指標値を設定する
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配列を非時系列モードに設定
ArraySetAsSeries(close,false); // close配列を非時系列モードに設定
//--- 前回計算されていないバーから現在のバーまでループ
for(int i=prev_calculated;i<rates_total;i++)
{
//--- バッファの初期値を0に設定
buff[i]=0; // buffバッファの初期化
//--- 読み込んだデータがまだ存在するかを確認
if(ind<size)
{
for(int j=ind;j<size;j++)
{
//--- 時間が一致する場合、ファイルのデータを使用
if(time[i]==time_buff[j]) // ファイル内の時間とチャートの時間が一致する場合
{
//--- ファイルから得たデータを終値に設定
buff[i]=close[i]; // 終値データをbuffバッファに保存
//--- 次のデータに進むためにインデックスを増やす
ind=j+1; // indをインクリメントして次のデータへ移動
break; // ループを抜けて次のバーに進む
}
}
}
}
//--- 計算されたバーの数を返す
return(rates_total); // 処理したバーの総数を戻り値として返す
}
サンプルコード解説1:プロパティ命令
#property indicator_chart_window // インジケータをチャートウィンドウに表示する
#property indicator_buffers 1 // インジケータのバッファを1つ使用する
#property indicator_plots 1 // インジケータのプロット数を1つ指定する
//---- ラベル1をプロットする設定
#property indicator_label1 "Trends" // インジケータの名前を"Trends"に設定
#property indicator_type1 DRAW_SECTION // 描画の種類をセクションに設定
#property indicator_color1 clrRed // 描画の色を赤色に設定
#property indicator_style1 STYLE_SOLID // 線のスタイルを実線に設定
#property indicator_width1 1 // 線の幅を1ピクセル(デジタル画像を構成する最小の単位)に設定
#property indicator_chart_window
この命令は、インジケータをチャートウィンドウに表示することを指定します。MQL5では、インジケータをチャートウィンドウ(価格の動きが表示される領域)に直接表示するか、別のサブウィンドウに表示するかを指定できます。このコードでは、インジケータがメインのチャートウィンドウに描画されるように設定されています。
#property indicator_buffers 1
インジケータで使用するバッファの数を設定しています。このバッファは、インジケータが表示するデータを格納するための領域です。この場合、1つのデータバッファのみを使用して、1つのラインやプロットを表示します。※バッファとは、データを一時的に保存しておくメモリ領域のことです。
#property indicator_plots 1
インジケータのプロット数を指定しています。プロットとは、チャート上に描画されるデータの系列を意味します。この設定では、1つのプロットのみが表示されることを示しています。
#property indicator_label1 “Trends”
インジケータのラベル(名前)を「Trends」と指定しています。チャート上に表示されるインジケータの名前として使用されます。このラベルは、トレーダーがチャート上でインジケータを視覚的に識別するために役立ちます。
#property indicator_type1 DRAW_SECTION
インジケータの描画スタイルをセクションに設定しています。DRAW_SECTIONは、チャート上のデータポイント間を直線で結ぶ描画方式です。データが不連続な場合でも、その間に線を描画することが特徴です。
#property indicator_color1 clrRed
インジケータの描画色を赤色に設定しています。clrRedはMQL5で定義された標準的な色の1つです。この指定によって、インジケータのラインが赤色で表示されるようになります。
#property indicator_style1 STYLE_SOLID
インジケータの線のスタイルを「実線」に設定しています。STYLE_SOLIDは、連続した実線を描画する設定です。線のスタイルには、点線や破線などのオプションもありますが、このコードでは実線が使用されています。
#property indicator_width1 1
インジケータの線の幅を1ピクセル(デジタル画像を構成する最小の単位)に設定しています。値が大きいほど、線の幅が太くなります。ここでは細い実線として描画される設定です。
サンプルコード解説2:グローバル領域部分
//--- データ読み込みのパラメータ
input string InpFileName="Trend.bin"; // 読み込むファイルの名前を"Trend.bin"に設定
input string InpDirectoryName="Data"; // 読み込むディレクトリの名前を"Data"に設定
//--- グローバル変数
int ind=0; // インデックスを保持する変数
int size=0; // 読み込んだデータのサイズを保持する変数
datetime time_buff[]; // 読み込んだ時間データを格納する配列
//--- 指標バッファ
double buff[]; // インジケータのデータを格納するバッファ
input string InpFileName=”Trend.bin”
この行は、読み込むファイルの名前を指定するための変数を定義しています。デフォルト値として”Trend.bin”という名前のファイルを読み込むように設定されています。ユーザーが別のファイルを読み込みたい場合、この値を変更できます。
input string InpDirectoryName=”Data”
この行では、読み込むファイルが存在するディレクトリの名前を指定しています。デフォルト値は”Data”で、このディレクトリ内にファイルがあると想定されます。これもユーザーが任意に設定できます。
int ind=0
ind
はインデックスを保持するための変数です。この変数は、ファイルから読み込んだデータの位置を追跡するために使用されます。
int size=0
size
は、読み込んだデータのサイズ(つまり、読み込まれたデータの総数)を保持する変数です。この変数は、ファイルから何バイトのデータが読み込まれたかを管理します。
datetime time_buff[]
time_buff
は、読み込んだ時間データを格納するための配列です。ファイルから読み込まれた時間情報(例えば、トレードのタイムスタンプなど)がこの配列に保存されます。
double buff[]
buff
は、インジケータのデータを格納するためのバッファです。このバッファに、ファイルから読み込んだデータやインジケータの計算結果が保存され、チャートに表示される際に使用されます。バッファとは、一時的にデータを保存しておくメモリ領域のことです。
サンプルコード解説3:OnInit関数部分その1
//+------------------------------------------------------------------+
//| カスタム指標を初期化する関数 |
//+------------------------------------------------------------------+
int OnInit()
{
int def_size=100; // デフォルトの配列サイズを100に設定
//--- 配列にメモリを割り当てる
ArrayResize(time_buff,def_size); // time_buff配列のサイズを100にリサイズ
//--- ファイルを開く
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));
// ファイルのパスをエキスパートログに出力
//--- 追加の変数
int arr_size; // 配列サイズを保持する変数
uchar arr[]; // 読み込んだバイトデータを格納する配列
int OnInit
OnInit関数は、カスタムインジケータの初期化を行う関数です。この関数はインジケータが最初に呼び出されたときに実行され、必要なデータの初期設定やファイルの読み込みなどを行います。
int def_size=100
この行では、配列のデフォルトサイズを100に設定しています。ここで設定されたdef_sizeは、time_buff配列の初期サイズとして使用され、後で必要に応じてサイズを動的に変更することが可能です。
ArrayResize(time_buff, def_size)
ArrayResize関数を使って、time_buff配列のサイズを100にリサイズしています。これは、インジケータが初期化される際に、time_buff配列にメモリ領域を割り当てるための操作です。この配列には、ファイルから読み込む時間データが格納されます。
ResetLastError
ResetLastError関数は、前回のエラーコードをリセットするために使用されます。この操作により、次のエラーチェックが正確に行えるようになります。特にファイル操作の前には、エラーステータスをクリアすることが重要です。
int file_handle=FileOpen(InpDirectoryName+”//”+InpFileName, FILE_READ|FILE_BIN)
この行で、ファイルを読み込み専用のバイナリモードで開きます。FileOpen関数は、指定されたファイルを開くために使用され、ファイルハンドルが返されます。InpDirectoryNameとInpFileNameは、外部から指定されたディレクトリ名とファイル名です。ファイルが正しく開かれると、後でその内容を読み込むことができます。
if (file_handle != INVALID_HANDLE)
この条件文では、ファイルが正しく開かれたかどうかを確認しています。FileOpen関数が有効なハンドルを返した場合、ファイルが正常に開かれたことを意味し、次の処理に進みます。
PrintFormat(“%s file is available for reading”, InpFileName)
この行は、ファイルが正常に開かれた場合に、指定されたファイル名とともにその情報をエキスパートログに出力します。PrintFormat関数を使用して、フォーマットされた文字列をログに記録します。
PrintFormat(“File path: %s\Files\”, TerminalInfoString(TERMINAL_DATA_PATH)
この行では、読み込んでいるファイルのパス情報をエキスパートログに出力します。TerminalInfoString関数は、ターミナル(取引プラットフォーム)のデータディレクトリのパスを返す関数です。この情報は、ファイルがどこに保存されているかを確認するために役立ちます。
int arr_size
arr_sizeは、ファイルから読み込んだデータサイズを保持するための変数です。後で読み込むバイト数を格納するために使用します。
uchar arr[]
arrは、ファイルから読み込んだバイトデータを格納するための配列です。uchar型は1バイトの符号なし整数型であり、ファイルから読み取られたバイナリデータを保持するのに適しています。
サンプルコード解説4:OnInit関数部分その2
//--- ファイルからデータを読み取る
while(!FileIsEnding(file_handle)) // ファイルの末尾に達していない間、読み込みを続ける
{
//--- 時間情報を格納するためのバイト数を読み取る
arr_size=FileReadInteger(file_handle,INT_VALUE);
// 4バイト(int型)を読み取ってサイズを取得
ArrayResize(arr,arr_size); // 読み込むデータ用に配列arrのサイズをリサイズ
for(int i=0;i<arr_size;i++)
arr[i]=(char)FileReadInteger(file_handle,CHAR_VALUE);
// 1バイト(char型)を1つずつ読み込み、arr配列に格納
//--- 読み取ったデータを時間に変換し、time_buffに保存
time_buff[size]=StringToTime(CharArrayToString(arr));
// 文字配列arrを文字列に変換し、それを時間データとしてtime_buffに格納
size++; // 読み込んだデータ数をカウント
//--- 配列がいっぱいになった場合、配列サイズを100ずつ増やす
if(size==def_size)
{
def_size+=100; // 配列サイズを100増加
ArrayResize(time_buff,def_size); // time_buff配列のサイズを再調整
}
}
while (!FileIsEnding(file_handle))
FileIsEnding関数を使用して、ファイルの末尾に達していない限り、whileループ内でファイルの読み込みを続けます。
arr_size = FileReadInteger(file_handle, INT_VALUE)
4バイト(int型)のデータを読み取り、その値をarr_size
に格納します。この値は次に読み込むデータのサイズを示しています。
ArrayResize(arr, arr_size)
ArrayResize関数を使い、読み込むデータのサイズに合わせて、arr
配列のサイズを動的に変更します。これにより、読み込むバイト数に応じたメモリ領域が確保されます。
arr[i] = (char) FileReadInteger(file_handle, CHAR_VALUE)
FileReadInteger関数を使って1バイトずつデータを読み込み、arr
配列に格納します。この処理は、指定されたバイト数分だけ繰り返されます。
time_buff[size] = StringToTime(CharArrayToString(arr))
StringToTime関数とCharArrayToString関数を使い、読み込んだバイトデータを文字列に変換し、さらに時間データとして変換してtime_buff
配列に保存します。この操作により、ファイルから読み込んだ文字列データを正しい時間形式に変換します。
size++
データを読み込むごとに、size
変数を1つインクリメントし、現在のデータ数を追跡します。
if (size == def_size)
もしsize
がdef_size
と等しくなった場合、つまり配列がいっぱいになった場合、次の処理が実行されます。
def_size += 100
配列のサイズを100バイト増加させます。これにより、次のデータが読み込まれる際に、配列に十分な領域が確保されます。
ArrayResize(time_buff, def_size)
time_buff
配列のサイズを100バイト分追加してリサイズします。これで、データを引き続き格納できるようになります。
サンプルコード解説5:OnInit関数部分その3
//--- ファイルを閉じる
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でファイルを閉じる
FileClose関数を使って、開いたファイルを閉じます。これは、ファイルの操作が完了した後に必ず行うべき操作です。
PrintFormatでログにファイルが閉じられたことを出力
PrintFormat関数を使用して、ファイルが正しく読み込まれ閉じられたことをエキスパートログに出力します。これにより、処理の進行状況を確認できます。
elseでファイルが開けなかった場合の処理
もしファイルが開けなかった場合、このelseブロックが実行されます。
PrintFormatでエラーとファイル名をログに出力
PrintFormat関数を使って、ファイルが開けなかったことと、そのエラーコードをエキスパートログに出力します。エラーの原因を確認するのに役立ちます。
returnで初期化失敗を返す
ファイルが開けなかった場合、INIT_FAILEDを返して初期化が失敗したことを示します。
サンプルコード解説6:OnInit関数部分その4
//--- 配列とインジケータバッファを関連付ける
SetIndexBuffer(0,buff,INDICATOR_DATA); // インジケータバッファにデータを設定する
//---- チャートには表示されない指標値を設定する
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0); // 指定したプロットには表示されない値を設定
//---
return(INIT_SUCCEEDED); // 初期化が成功した場合の戻り値を返す
}
SetIndexBufferで配列とインジケータバッファを関連付ける
SetIndexBuffer関数を使用して、配列とインジケータバッファを関連付けます。ここでは、バッファのインデックス0にデータを設定しています。これにより、インジケータバッファがデータを保持し、チャート上に表示されます。
PlotIndexSetDoubleで表示されない指標値を設定する
PlotIndexSetDouble関数を使用して、指定したプロットに対して表示されない値を設定します。この操作により、特定の条件でデータがチャートに表示されないようにすることができます。
初期化が成功した場合の戻り値を返す
INIT_SUCCEEDEDを返すことで、初期化が正常に完了したことを示します。これは、OnInit関数の最後に呼ばれ、初期化が成功したかどうかを確認するために使用されます。
サンプルコード解説7: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配列を非時系列モードに設定
ArraySetAsSeries(close,false); // close配列を非時系列モードに設定
//--- 前回計算されていないバーから現在のバーまでループ
for(int i=prev_calculated;i<rates_total;i++)
{
//--- バッファの初期値を0に設定
buff[i]=0; // buffバッファの初期化
//--- 読み込んだデータがまだ存在するかを確認
if(ind<size)
{
for(int j=ind;j<size;j++)
{
//--- 時間が一致する場合、ファイルのデータを使用
if(time[i]==time_buff[j]) // ファイル内の時間とチャートの時間が一致する場合
{
//--- ファイルから得たデータを終値に設定
buff[i]=close[i]; // 終値データをbuffバッファに保存
//--- 次のデータに進むためにインデックスを増やす
ind=j+1; // indをインクリメントして次のデータへ移動
break; // ループを抜けて次のバーに進む
}
}
}
}
//--- 計算されたバーの数を返す
return(rates_total); // 処理したバーの総数を戻り値として返す
}
OnCalculate関数
OnCalculate関数は、カスタムインジケータの反復計算を行う関数です。この関数は、新しいデータがチャートに追加されるたびに呼び出され、インジケータの計算を行います。関数内では、過去に計算されたバーのデータを参照し、まだ処理されていないバーに対して新しい計算を行います。
ArraySetAsSeriesで配列のモードを設定
ArraySetAsSeries関数を使用して、time配列とclose配列を非時系列モードに設定します。このモードでは、配列のインデックスが最新のデータから順に割り当てられ、通常の時系列配列とは逆の順序になります。
forループで未計算のバーを処理
forループを使用して、前回の計算が終了していないバーから最新のバーまでの処理を行います。prev_calculated
は以前に計算されたバーの数であり、それ以降のバーに対して計算が行われます。
buffバッファの初期化
buffバッファの各要素を0に設定し、初期化を行います。このバッファは、各バーのインジケータデータを保存するための領域です。
読み込んだデータの存在を確認
ファイルから読み込んだデータがまだ存在するかを確認し、条件に従って処理を進めます。この部分では、ind変数がファイルからのデータを追跡し、データが利用可能かをチェックします。
ファイルの時間とチャートの時間が一致する場合の処理
ファイルから読み込んだ時間データ(time_buff)とチャート上のバーの時間(time配列)が一致する場合、ファイル内のデータを使用して処理を行います。時間が一致すれば、ファイルから得たデータを終値としてバッファに設定します。
インデックスを増やして次のデータへ
一致したデータを処理した後、ind変数をインクリメントして次のデータへ移動します。この操作により、次のバーに対して処理が進むようになります。
計算されたバーの数を返す
処理が完了したバーの総数を戻り値として返します。これにより、次回呼び出されたときにどこから再計算すればよいかを把握できるようになります。