【MQL5】FileReadLong関数の使い方と自動売買実装コード

1. FileReadLong関数の概要と実務での活用法

FileReadLongは、MQL5で開いたバイナリファイルから「long型(8バイトの整数)」のデータを読み出すための関数です。

実務レベルのEA(エキスパートアドバイザー)開発において、この関数は単なる数値の読み込み以上の重要な役割を果たします。例えば、「最後に約定したポジションのチケット番号」「特定ロジックで計算されたユニークなID(マジックナンバー)」、あるいは「マイクロ秒単位のタイムスタンプ」などを、ターミナルが終了しても消えないようにローカルディスクに保存し、再起動時に復元する際によく利用されます。

開発者が特につまずきやすいポイントは、「バイナリモード」と「テキストモード」の混同です。FileReadLongはバイナリ形式で書き込まれたデータに対して使用するものであり、CSVファイルのように人間がメモ帳で読める形式のファイルを読み込むためのものではありません。この区別を誤ると、予期せぬ巨大な数値が読み込まれるといったバグの原因になります。

2. 構文と戻り値

FileReadLong関数の仕様は非常にシンプルです。

long  FileReadLong(
   int  file_handle    // ファイルハンドル
   );

パラメーター

  • file_handle: FileOpen() 関数によって返されたファイルハンドルを指定します。このハンドルを通じて、どのファイルからデータを読み出すかを決定します。

戻り値

  • 正常に読み取れた場合、ファイルポインタの現在位置から8バイト分のデータをlong型として返します。
  • 読み取りに失敗した場合やファイルの終端(EOF)に達した場合は0を返しますが、0自体が有効なデータである可能性もあるため、正確なエラー判定には GetLastError() を併用するのが一般的です。

3. 具体的な使い方・実践サンプルコード

以下のサンプルは、EAが停止しても「最後に処理したチケット番号」を記憶しておき、初期化時(OnInit)にその番号をファイルから読み込む実用的なコード例です。

//--- ファイル名の定義
const string fileName = "last_ticket.dat";

//+------------------------------------------------------------------+
//| EAの初期化関数                                                     |
//+------------------------------------------------------------------+
int OnInit()
{
    long lastTicket = LoadLastTicket();

    if(lastTicket > 0)
    {
        Print("前回の終了時の最終チケット番号を読み込みました: ", lastTicket);
    }
    else
    {
        Print("保存されたチケット番号はありません。");
    }

    return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| バイナリファイルからlong型の値を読み込む関数                          |
//+------------------------------------------------------------------+
long LoadLastTicket()
{
    // ファイルをバイナリ読み込みモードで開く
    int fileHandle = FileOpen(fileName, FILE_READ|FILE_BIN);
    long result = 0;

    if(fileHandle != INVALID_HANDLE)
    {
        // ファイルサイズがlong型(8バイト)以上あるか確認
        if(FileSize(fileHandle) >= sizeof(long))
        {
            // long型のデータを読み込む
            result = FileReadLong(fileHandle);
        }
        else
        {
            Print("ファイルサイズが不足しています。");
        }

        // ファイルを閉じる
        FileClose(fileHandle);
    }
    else
    {
        Print("ファイルを開けませんでした。エラーコード: ", GetLastError());
    }

    return result;
}

4. 使用上の注意点とよくあるエラー

  1. ファイルモードの一致: FileWriteLongで書き込んだファイルに対してのみFileReadLongを使ってください。CSVファイル(FILE_CSV)に対して実行すると、型変換が正しく行われず支離滅裂な数値が返されます。
  2. ファイルポインタの意識: FileReadLongを実行すると、ファイルポインタ(読み込み位置)が自動的に8バイト進みます。連続して読み込む場合は問題ありませんが、同じ箇所を何度も読み直したい場合は FileSeek 関数でポインタを戻す必要があります。
  3. エラーハンドリング: 戻り値が 0 の場合、それが「保存された値が 0 だった」のか「読み込みに失敗した」のかを区別できません。ファイルを開く際に INVALID_HANDLE をチェックし、FileSize で読み込めるデータが存在するかを事前に確認するロジックを組むのがプロの書き方です。

5. 【重要】自動売買における約定スピードと環境の罠

アルゴリズムトレードにおいて、FileReadLongなどを用いたデータの整合性維持は重要ですが、それ以上に収益を左右するのが「約定スピード」です。自宅のPCや一般的な光回線でEAを稼働させることは、プロのクオンツから見れば極めてリスクの高い行為と言わざるを得ません。家庭用回線は常に不安定な遅延(レイテンシ)を抱えており、相場急変時に注文を出しても、ブローカーのサーバーに届くまでに価格が滑り(スリッページ)、本来得られるはずだった利益が消失、あるいは損失が拡大する致命的な原因となります。

特にMQL5でミリ秒単位のロジックを組むエンジニアにとって、物理的な距離によるネットワーク遅延はコードの最適化では克服不可能な壁です。この問題を解決し、極限まで約定スピードを高めるには、ブローカーの取引サーバーと同じデータセンター、あるいは極めて近い距離に設置された自動売買専用のVPS(仮想専用サーバー)の利用が必須条件となります。24時間365日、安定した低レイテンシ環境を維持することこそが、システムトレーダーが最初に投資すべき「インフラ」であり、勝率に直結するテクニカルな最適化なのです。

💡 この記事の内容を実運用で活かすには?

この記事の内容を実運用で活かすには、正しい環境が必要です。
特にVPSを使わないと、このロジックは再現できません。

コメント

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