【MQL5】FileWrite関数について

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

FileWrite関数の働き・役割

FileWrite関数は、指定したファイルにデータをCSV形式で書き込むために使用されます。この関数を使うと、ファイルに数値や文字列などのデータを効率的に書き込むことができます。書き込まれたデータは、カンマ区切りの形式で保存され、さらにデータの最後には改行文字が自動的に挿入されます。

FileWrite関数の特徴として、数値データが自動的にテキスト形式に変換されて書き込まれる点があります。例えば、double型やfloat型の数値は適切な精度でテキストに変換されます。また、bool型はtrueまたはfalseという文字列で書き込まれ、dateTime型は「年.月.日 時:分:秒」の形式で保存されます。

CSVファイルにデータを保存する際には、最大63個までのパラメータを一度に書き込むことができます。また、FileWrite関数は、ファイルに書き込んだバイト数を戻り値として返すため、データが正しく書き込まれたかどうかを確認することが可能です。

FileWrite関数の引数について

uint  FileWrite(
  int  file_handle,  // ファイルハンドル
  ...                 // 記録されたパラメータのリスト
  );

FileWrite関数は、2つの主な引数を取ります。

  1. file_handle
    この引数は、FileOpen関数によって返されるファイルハンドル(ファイル記述子)を指定します。このファイルハンドルは、ファイルへのアクセス権を示すもので、FileOpen関数を使用してファイルを開いた際に取得されます。FileWrite関数は、このハンドルを使用して、どのファイルに書き込むかを判断します。
  2. …(可変長引数
    この引数は、ファイルに書き込むデータのリストを指定します。複数のパラメータをカンマで区切って指定でき、最大63個までのデータを一度に書き込むことが可能です。このリストには、文字列、数値(int型double型など)、bool型dateTime型などさまざまなデータ型を指定できます。指定したデータは、カンマ区切りでCSV形式のファイルに保存されます。

データが書き込まれる際には、数値は自動的にテキスト形式に変換され、適切な精度でファイルに記録されます。double型の数値は小数点以下16桁、float型の数値は小数点以下5桁で記録されます。また、dateTime型の値は「YYYY.MM.DD HH:MI:SS」の形式でファイルに書き込まれます。

例として、ファイルハンドルが有効な場合、FileWrite関数に複数のデータを渡して書き込むことが可能です。

FileWrite関数の戻り値について

FileWrite関数戻り値は、ファイルに実際に書き込まれたバイト数です。この戻り値を使用することで、データが正しく書き込まれたかを確認することができます。書き込まれたバイト数が0の場合、何も書き込まれていないことを意味し、ファイルハンドルが無効であったり、書き込み操作に問題が発生した可能性があります。

エラーチェックを行いたい場合、FileWrite関数の後にGetLastError関数を使用して、エラーコードを取得し、適切なエラーハンドリングを実装することが推奨されます。

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

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

//--- 書き込みするファイル名を設定(入力パラメータとして扱う)
input string InpFileName="example.csv"; // 保存するファイル名

//--- スクリプトのメイン関数(スクリプトが実行されるとOnStartが呼び出される)
void OnStart()
{
  //--- エラーコードをリセットして、直前のエラー情報をクリアする
  ResetLastError();
  
  //--- ファイルを開く(読み書きとCSV形式でファイルを扱う)
  int file_handle = FileOpen(InpFileName, FILE_READ | FILE_WRITE | FILE_CSV);
  
  //--- ファイルが正常に開けたかどうかをチェック
  if (file_handle != INVALID_HANDLE)  // ファイルが正常に開けた場合
  {
    //--- 1000回ループして、ファイルにデータを書き込む処理を行う
    for (int i = 0; i < 1000; i++)
    {
      //--- 現在の時刻とシンボル(通貨ペアなど)のBidとAsk価格を書き込む
      FileWrite(file_handle, TimeCurrent(), SymbolInfoDouble(Symbol(), SYMBOL_BID), SymbolInfoDouble(Symbol(), SYMBOL_ASK));
      
      //--- 128回書き込みごとにバッファのデータをディスクに書き込む
      //--- (i & 127) == 127 という条件は、iが128の倍数の時にtrueになる
      if ((i & 127) == 127)
      {
        //--- FileFlushを呼び出し、バッファ内のデータをディスクに書き込む
        FileFlush(file_handle);
        
        //--- データが書き込まれたことを確認するためにエキスパートログに出力する
        PrintFormat("i = %d, データがディスクに保存されました", i);
      }
      
      //--- プログラムが急に負荷をかけないように、0.01秒(10ミリ秒)休止する
      Sleep(10);
    }
    
    //--- すべての書き込みが完了したら、ファイルを閉じる
    FileClose(file_handle);
  }
  else  // ファイルが開けなかった場合
  {
    //--- ファイルを開く際にエラーが発生したことをエキスパートログに表示する
    PrintFormat("ファイルを開けませんでした。エラーコード = %d", GetLastError());
  }
}

このサンプルコードは、指定したファイルに対して現在のサーバー時刻やシンボルのBid・Ask価格を1000回書き込み、128回ごとにバッファ内のデータをディスクに強制的に保存するものです。さらに、書き込みの進行状況をエキスパートログに出力し、最後にファイルを閉じて処理を終了します。

サンプルコードの解説

script_show_inputsプロパティは、スクリプトを実行する際に入力パラメータのウィンドウを表示させるための設定です。これにより、スクリプトを実行する前にユーザーが入力するパラメータを変更できるようになります。

input型のInpFileName変数は、ユーザーが変更できるパラメータを設定するために使われます。ここでは、書き込むファイルの名前を入力パラメータとして指定しています。InpFileNameは”example.csv”という初期値を持ちます。プログラムが動作する際、このファイルにデータが書き込まれます。

OnStart関数は、スクリプトが実行されたときに最初に呼び出される関数です。MQL5では、スクリプトが開始された際に必ずこの関数が自動的に実行され、プログラムのメインロジックがここに記述されます。今回のサンプルコードでも、ファイルのオープン、データの書き込み、ファイルのクローズなどの一連の処理がOnStart関数内にまとめられています。

ResetLastError関数は、前回のエラー情報をリセットします。これにより、次にエラーが発生した場合に、正しいエラーコードを取得できるようにします。

FileOpen関数は、ファイルを開くための関数です。この関数を使用することで、指定されたファイル名を、読み書き可能な状態かつCSV形式で開きます。ここで使用されているFILE_READ、FILE_WRITE、FILE_CSVの各識別子にはそれぞれ役割があります。

  • FILE_READは、ファイルを読み込み専用で開くための識別子です。ファイルの内容をプログラム内で読み取ることができます。
  • FILE_WRITEは、ファイルにデータを書き込むための識別子です。この識別子が指定されている場合、ファイルに対してデータの書き込みが可能になります。
  • FILE_CSVは、ファイルをCSV(カンマ区切りのテキスト形式)として扱うための識別子です。この識別子を使うと、ファイル内のデータが自動的にカンマで区切られた形式で処理されます。

また、これらの識別子の間にあるパイプ記号はビット演算子で、複数のフラグを組み合わせるために使われます。この場合、FILE_READ、FILE_WRITE、FILE_CSVという構文は、ファイルを「読み込み」「書き込み」「CSV形式」という3つのモードで同時に開くことを意味します。

if文は、条件式が真である場合にブロック内の処理を実行します。ここでは、file_handleが有効な値かどうかを確認し、無効でなければファイル操作を進めます。else文if文の条件が偽の場合に実行されます。つまり、ファイルが開けなかった場合の処理が記述されています。

for文は、指定した回数だけ繰り返し処理を実行するループ構文です。ここでは、iの値が0から999になるまでループを回し、1000回データを書き込む処理を行っています。

FileWrite関数は、ファイルにデータを書き込むための関数です。FileWrite関数には、書き込み対象となるファイルハンドルと、書き込むデータを引数として指定します。サンプルコードでは、以下の3つのデータがFileWrite関数に渡され、CSV形式でファイルに保存されます。

  1. TimeCurrent関数
  • TimeCurrent関数は、サーバーの現在時刻を取得するための関数です。この関数戻り値は、dateTime型(日時情報を表す型)で、現在のサーバー時刻を返します。これにより、データが書き込まれたタイミングの時刻を記録することができます。
  1. SymbolInfoDouble関数(SYMBOL_BID)
  • SymbolInfoDouble関数は、指定したシンボル(通貨ペアや銘柄)の情報を取得するための関数です。ここでは、SYMBOL_BIDというパラメータを渡すことで、シンボルのBid価格(買い価格)を取得しています。この価格は、データの一部としてファイルに書き込まれます。
  1. SymbolInfoDouble関数(SYMBOL_ASK)
  • 同様に、SymbolInfoDouble関数にSYMBOL_ASKというパラメータを渡すことで、シンボルのAsk価格(売り価格)を取得しています。このデータもBid価格と一緒に書き込まれます。

これらの関数を使用することで、FileWrite関数に対して現在のサーバー時刻、シンボルのBid価格とAsk価格を引数として渡し、それらをファイルに書き込むことができます。結果として、ファイルには時刻と価格情報が逐次的に保存されていきます。

「(i & 127) == 127という条件式」はビット演算によって、iが128の倍数の時に真になります。128回ごとにFileFlush関数を呼び出し、バッファ内のデータをディスクに書き込むタイミングを決めています。

FileFlush関数は、バッファに蓄えられているデータを即座にディスクに書き込む関数です。通常、データは一時的にメモリ上に保存されますが、FileFlush関数を使うことで途中でディスクにデータを反映させることができます。これにより、データが失われるリスクを減らします。

PrintFormat関数は、指定された書式に従って文字列を作成し、その文字列をエキスパートログ(プログラムの実行状況を表示するウィンドウ)に出力します。ここでは、ループの進行状況をエキスパートログに表示して、データが保存されたことを確認しています。※ミリ秒とは1/1000秒を意味します。

Sleep関数は、指定した時間(ここでは10ミリ秒)の間、プログラムの実行を一時的に停止します。これにより、急激な負荷がかからないようにしながら処理を続けます。

FileClose関数は、最後にファイル操作が終わったらファイルを閉じます。FileClose関数を呼び出すことで、ファイルに対するすべての操作を終了し、システムリソースを解放します。

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