【MQL5】FileWriteFloat関数について

MQL5リファレンス
スポンサーリンク
スポンサーリンク

FileWriteFloat関数の働き・役割

FileWriteFloat関数は、バイナリファイルにfloat型の値を書き込むために使用されます。この関数は、指定されたファイルポインタの現在位置から書き込みを開始し、データをファイルに追加していきます。ファイルは、ファイルハンドルと呼ばれる識別子を通じて管理され、ファイルの位置は自動的に進行します。主にデータの保存やバックアップのために使われ、float型のデータを効率的にバイナリ形式で格納することができます。

FileWriteFloat関数の引数について

uint  FileWriteFloat(
  int    file_handle,    // ファイルハンドル
  float  value            // 書かれる値
  );

FileWriteFloat関数には、次の2つの引数があります。

file_handle
この引数は、FileOpen関数から戻されたファイルハンドルを指定します。ファイルハンドルは、開かれたファイルを操作するための識別子です。ファイルが正しく開かれていない場合、この値はINVALID_HANDLEを返します。

value
この引数には、バイナリファイルに書き込むfloat型の値を指定します。float型は小数点以下の値を扱うため、主に価格データやその他の数値データを格納する際に使用されます。

この関数では、ファイルハンドルと値の両方を正しく指定することで、バイナリファイルにfloatデータを書き込むことができます。

FileWriteFloat関数の戻り値について

FileWriteFloat関数は、操作が成功すると、書き込まれたバイト数を戻り値として返します。float型のデータは4バイトで表されるため、正常に書き込まれた場合は常に4が返されます。

操作が失敗した場合、戻り値として0が返されます。この場合、エラーコードを取得するためにGetLastError関数を使用することが推奨されます。

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

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

//--- ユーザーからデータを受け取るパラメータの宣言
input string         InpSymbolName="EURUSD";           // 通貨ペア(例: EURUSD)
input ENUM_TIMEFRAMES InpSymbolPeriod=PERIOD_M15;      // 時間軸(例: 15分足)
input datetime       InpDateStart=D'2013.01.01 00:00'; // データコピーの開始日

//--- データを書き込むファイルの設定
input string         InpFileName="Close.bin";          // 書き込むファイル名
input string         InpDirectoryName="Data";          // 書き込むディレクトリ名

//+------------------------------------------------------------------+
//| スクリプトプログラムが開始された時に呼び出される関数                |
//+------------------------------------------------------------------+
void OnStart()
{
  //--- サーバーの現在時刻を取得し、date_finishに格納
  datetime date_finish=TimeCurrent();

  //--- 終値データを保存するための配列を宣言
  double close_buff[];
  
  //--- 時間データを保存するための配列を宣言
  datetime time_buff[];
  
  //--- データのサイズを格納する変数を宣言
  int size;

  //--- エラー状態をリセットする
  ResetLastError();

  //--- 指定されたシンボルと時間軸で、指定された期間の終値データをコピー
  if(CopyClose(InpSymbolName, InpSymbolPeriod, InpDateStart, date_finish, close_buff) == -1)
  {
    //--- 終値データのコピーが失敗した場合、エラーコードを表示して終了
    PrintFormat("終値データのコピーに失敗しました。エラーコード = %d", GetLastError());
    return;
  }

  //--- 指定されたシンボルと時間軸で、指定された期間の時間データをコピー
  if(CopyTime(InpSymbolName, InpSymbolPeriod, InpDateStart, date_finish, time_buff) == -1)
  {
    //--- 時間データのコピーが失敗した場合、エラーコードを表示して終了
    PrintFormat("時間データのコピーに失敗しました。エラーコード = %d", GetLastError());
    return;
  }

  //--- コピーした終値データの配列のサイズを取得
  size = ArraySize(close_buff);

  //--- ファイルを読み書きモードで開く(存在しない場合は作成される)
  ResetLastError();  // エラー状態をリセット
  int file_handle = FileOpen(InpDirectoryName + "//" + InpFileName, FILE_READ | FILE_WRITE | FILE_BIN);
  
  //--- ファイルが正常に開かれた場合
  if (file_handle != INVALID_HANDLE)
  {
    //--- ファイルが開かれたことを確認するメッセージを出力
    PrintFormat("%s ファイルを開きました。", InpFileName);
    
    //--- ファイルのパスを出力
    PrintFormat("ファイルパス: %s\\Files\\", TerminalInfoString(TERMINAL_DATA_PATH));

    //--- 配列のデータをファイルに書き込む
    for (int i = 0; i < size; i++)
    {
      //--- 時間データをファイルに書き込む
      FileWriteDouble(file_handle, (double)time_buff[i]);

      //--- 終値データをfloat型でファイルに書き込む
      FileWriteFloat(file_handle, (float)close_buff[i]);
    }

    //--- ファイルの書き込みが完了したらファイルを閉じる
    FileClose(file_handle);
    
    //--- 書き込みが完了し、ファイルを閉じたことを確認するメッセージを出力
    PrintFormat("データが書き込まれ、%s ファイルを閉じました。", InpFileName);
  }
  else
  {
    //--- ファイルが開けなかった場合、エラーコードを表示
    PrintFormat("%s ファイルを開けませんでした。エラーコード = %d", InpFileName, GetLastError());
  }
}

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

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

//--- ユーザーからデータを受け取るパラメータの宣言
input string         InpSymbolName="EURUSD";           // 通貨ペア(例: EURUSD)
input ENUM_TIMEFRAMES InpSymbolPeriod=PERIOD_M15;      // 時間軸(例: 15分足)
input datetime       InpDateStart=D'2013.01.01 00:00'; // データコピーの開始日

//--- データを書き込むファイルの設定
input string         InpFileName="Close.bin";          // 書き込むファイル名
input string         InpDirectoryName="Data";          // 書き込むディレクトリ名

このセクションでは、スクリプト全体で使用するグローバル変数などを宣言しています。これらの設定はスクリプトの動作に大きく影響を与えるため、ユーザーが実行時にカスタマイズできるようになっています。

#property script_show_inputs

スクリプトの実行時に、入力パラメータのウィンドウを表示するためのプロパティです。この設定があると、スクリプト起動時にユーザーがパラメータを変更できるインターフェースが表示されます。

input string InpSymbolName=”EURUSD”;

ユーザーが使用する通貨ペアを指定するためのパラメータです。ここでは「EURUSD」が初期値として設定されていますが、ユーザーは別の通貨ペア(例えば「USDJPY」など)に変更できます。

input ENUM_TIMEFRAMES InpSymbolPeriod=PERIOD_M15;

このパラメータでは、指定する時間軸(タイムフレーム)を決定します。初期値は15分足(PERIOD_M15)ですが、他の時間軸(1時間足、日足など)も指定可能です。

input datetime InpDateStart=D’2013.01.01 00:00′;

取得するデータの開始日を指定するパラメータです。初期値として2013年1月1日の0時からのデータが指定されています。ユーザーはこの日付を変更して、別の日からデータを取得することができます。

input string InpFileName=”Close.bin”;

書き込むファイル名を指定するパラメータです。初期値は「Close.bin」となっており、この名前のファイルに終値データがバイナリ形式で保存されます。ユーザーはこの名前を変更して、別のファイル名を指定することもできます。

input string InpDirectoryName=”Data”;

データを書き込むディレクトリ名を指定するパラメータです。初期値は「Data」となっており、指定されたディレクトリにデータが保存されます。ディレクトリが存在しない場合は自動的に作成されます。

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

//+------------------------------------------------------------------+
//| スクリプトプログラムが開始された時に呼び出される関数                |
//+------------------------------------------------------------------+
void OnStart()
{
  //--- サーバーの現在時刻を取得し、date_finishに格納
  datetime date_finish=TimeCurrent();

  //--- 終値データを保存するための配列を宣言
  double close_buff[];
  
  //--- 時間データを保存するための配列を宣言
  datetime time_buff[];
  
  //--- データのサイズを格納する変数を宣言
  int size;

  //--- エラー状態をリセットする
  ResetLastError();

OnStart関数は、スクリプトが実行された際に自動的に呼び出される関数で、ここではデータの取得や配列の初期化など、主要な処理が行われます。このセクションでは、OnStart関数の最初の部分に焦点を当てて解説します。

サーバーの現在時刻を取得し、date_finishに格納

この行では、サーバーの現在時刻を取得し、それをdate_finishという変数に格納しています。TimeCurrent関数は、サーバーの最新の時刻を返すため、スクリプト実行時点での正確なタイムスタンプを取得できます。この時刻は後に、データのコピー範囲を指定する際に使用されます。

終値データを保存するための配列を宣言

この行では、終値データを保存するための配列を宣言しています。この配列は後に、CopyClose関数を使用して通貨ペアの終値データを取得し、データを格納するために使用されます。配列のサイズは後で決定されますが、ここでは配列の宣言のみ行われています。

時間データを保存するための配列を宣言

こちらは、各バーの時間データを保存するための配列です。close_buffと同様に、CopyTime関数を使用して指定された範囲のバーの時間情報を取得します。この時間情報は、終値データとともにファイルに保存するために使用されます。

データのサイズを格納する変数を宣言

データのサイズを格納するための変数sizeを宣言しています。これは、取得した終値データや時間データの総数を後で保持するために使用され、データの書き込みやループ処理で利用されます。

エラー状態をリセットする

ResetLastError関数はエラー状態をリセットするための関数です。この関数を呼び出すことで、以前に発生したエラーコードがクリアされ、次に発生するエラーを正確に把握できるようにします。特にファイル操作やデータコピーなど、エラーが発生しやすい処理の前にこの関数を呼び出すことは重要です。


OnStart関数のこの部分では、データの取得や処理に必要な変数配列を準備し、初期化するための重要なステップが実行されています。

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

 //--- 指定されたシンボルと時間軸で、指定された期間の終値データをコピー
  if(CopyClose(InpSymbolName, InpSymbolPeriod, InpDateStart, date_finish, close_buff) == -1)
  {
    //--- 終値データのコピーが失敗した場合、エラーコードを表示して終了
    PrintFormat("終値データのコピーに失敗しました。エラーコード = %d", GetLastError());
    return;
  }

  //--- 指定されたシンボルと時間軸で、指定された期間の時間データをコピー
  if(CopyTime(InpSymbolName, InpSymbolPeriod, InpDateStart, date_finish, time_buff) == -1)
  {
    //--- 時間データのコピーが失敗した場合、エラーコードを表示して終了
    PrintFormat("時間データのコピーに失敗しました。エラーコード = %d", GetLastError());
    return;

このセクションでは、OnStart関数の中でデータを取得する重要な部分について解説します。ここでは、指定された通貨ペアと時間軸に基づいて、終値データと時間データをコピーしています。

終値データの取得

最初に、CopyClose関数を使用して指定されたシンボル(通貨ペア)と時間軸で、指定された期間の終値データを取得します。CopyClose関数は、指定したシンボル、時間軸、開始日、終了日をもとに、該当する終値データを取得し、配列に格納します。

この場合、InpSymbolNameが通貨ペア、InpSymbolPeriodが時間軸(例えば、15分足)、InpDateStartがデータ取得の開始日、date_finishが取得終了日となります。データはclose_buff配列に格納されます。

もし終値データのコピーが失敗した場合、CopyClose関数は-1を返し、GetLastError関数を使用してエラーコードを取得し、エラーメッセージを表示した後、スクリプトを終了します。このように、エラーハンドリングを適切に行うことで、予期せぬエラー発生時にも対処できるようになっています。

時間データの取得

次に、CopyTime関数を使用して同様の条件で時間データを取得します。CopyTime関数は、指定したシンボル、時間軸、開始日、終了日をもとに、該当するバーの時間データを取得し、time_buff配列に格納します。

こちらも、もしCopyTime関数がデータ取得に失敗した場合には、-1を返します。その際には、GetLastError関数を用いてエラーコードを表示し、スクリプトの処理を中断します。


この部分では、CopyClose関数CopyTime関数がデータ取得の中心的な役割を担っています。CopyClose関数は終値データを取得し、CopyTime関数はバーの時間データを取得します。両関数とも、エラーが発生した場合には適切なメッセージを出力し、処理を中断する設計がなされています。これにより、データ取得の失敗に対する堅牢な対策が組み込まれています。

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

  //--- コピーした終値データの配列のサイズを取得
  size = ArraySize(close_buff);

  //--- ファイルを読み書きモードで開く(存在しない場合は作成される)
  ResetLastError();  // エラー状態をリセット
  int file_handle = FileOpen(InpDirectoryName + "//" + InpFileName, FILE_READ | FILE_WRITE | FILE_BIN);
  
  //--- ファイルが正常に開かれた場合
  if (file_handle != INVALID_HANDLE)
  {
    //--- ファイルが開かれたことを確認するメッセージを出力
    PrintFormat("%s ファイルを開きました。", InpFileName);
    
    //--- ファイルのパスを出力
    PrintFormat("ファイルパス: %s\\Files\\", TerminalInfoString(TERMINAL_DATA_PATH));

    //--- 配列のデータをファイルに書き込む
    for (int i = 0; i < size; i++)
    {
      //--- 時間データをファイルに書き込む
      FileWriteDouble(file_handle, (double)time_buff[i]);

      //--- 終値データをfloat型でファイルに書き込む
      FileWriteFloat(file_handle, (float)close_buff[i]);
    }

このセクションでは、OnStart関数の残りの部分について解説します。ここでは、終値データと時間データをバイナリファイルに書き込むための処理が行われています。

配列のサイズ取得

まず、ArraySize関数を使用して、コピーした終値データの配列サイズを取得しています。ArraySize関数は、指定した配列要素数を返します。ここでは、終値データが格納されたclose_buff配列のサイズをsize変数に格納し、ループ処理で使用します。このサイズは、ファイルに書き込むデータの量を決定するために使われます。

ファイルのオープン

次に、FileOpen関数を使用して、指定されたディレクトリおよびファイルを読み書きモードで開きます。FileOpen関数は、ファイルのパス、操作モード、およびバイナリ書き込みかどうかを指定してファイルを開く関数です。

ここでは、ディレクトリ名とファイル名を結合し、FILE_READ | FILE_WRITE | FILE_BINというモードでファイルを開いています。FILE_READはファイルを読み込み可能に、FILE_WRITEはファイルへの書き込みを可能にし、FILE_BINはバイナリモードで開くことを意味します。もしファイルが存在しない場合は、新しく作成されます。

ファイルハンドルのチェック

FileOpen関数が正常にファイルを開くと、ファイルハンドルが返されます。このハンドルは、ファイルを操作するための識別子です。もし、ファイルハンドルINVALID_HANDLEであった場合は、ファイルのオープンに失敗していることを示します。正常にファイルが開かれた場合は、メッセージを出力してファイルが開かれたことを確認します。

データのファイルへの書き込み

次に、forループを使って、コピーした終値データと時間データをファイルに書き込む処理が行われます。

時間データの書き込み

FileWriteDouble関数を使って、time_buff配列に格納された時間データをバイナリ形式でファイルに書き込んでいます。この関数は、double型のデータをバイナリファイルに書き込むためのものです。

終値データの書き込み

FileWriteFloat関数を使って、close_buff配列に格納された終値データをバイナリ形式でファイルに書き込んでいます。この関数は、float型のデータをバイナリファイルに書き込むために使用されます。バイナリ形式での保存は、データの容量を効率的に管理するために有効です。


この部分では、配列のサイズを取得し、ファイルをオープンした後、時間データと終値データを順次ファイルに書き込む処理が行われています。FileWriteDouble関数FileWriteFloat関数を使用することで、double型およびfloat型のデータを効率的にバイナリファイルに書き込むことができます。

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

//--- ファイルの書き込みが完了したらファイルを閉じる
    FileClose(file_handle);
    
    //--- 書き込みが完了し、ファイルを閉じたことを確認するメッセージを出力
    PrintFormat("データが書き込まれ、%s ファイルを閉じました。", InpFileName);
  }
  else
  {
    //--- ファイルが開けなかった場合、エラーコードを表示
    PrintFormat("%s ファイルを開けませんでした。エラーコード = %d", InpFileName, GetLastError());
  }
}

このセクションでは、OnStart関数の最後の部分について解説します。ここでは、ファイルにデータを書き込んだ後の処理とエラーハンドリングが行われています。

ファイルのクローズ処理

すべてのデータの書き込みが完了した後、FileClose関数を使用してファイルを閉じます。ファイルを正しく閉じることで、書き込まれたデータが確実に保存され、他のアプリケーションやプロセスがそのファイルにアクセスできるようになります。ファイルが正しく閉じられないと、データが破損する可能性があるため、重要な処理です。

書き込み完了のメッセージ表示

ファイルの書き込みが正常に完了し、ファイルが閉じられたことを確認するために、PrintFormat関数を使用してメッセージを出力しています。このメッセージには、書き込まれたファイル名が表示され、スクリプトが正常に終了したことを示しています。

エラーハンドリング

もしFileOpen関数がファイルを開くことができなかった場合、FileHandleがINVALID_HANDLEを返すため、この場合はelseブロックに入り、ファイルを開けなかったことを示すエラーメッセージを出力します。この際、GetLastError関数を使用してエラーコードを取得し、エラーメッセージとして表示します。これにより、エラーの原因を特定しやすくなります。


この部分では、ファイル操作における終了処理とエラーハンドリングが行われています。FileClose関数を使ってファイルを正しく閉じ、スクリプトが正常に完了したことを確認するメッセージを出力しています。また、ファイルのオープンに失敗した場合のエラー処理も行い、適切なメッセージで問題の発生を知らせる設計がなされています。

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