MQL4 ファイル操作リファレンス|FileOpen・FileWrite・CSV・バイナリ・設定ファイル読み書き

MQL4のファイル操作関数を体系的にまとめました。FileOpen()によるファイルオープン、FileClose()によるクローズ、FileWrite()/FileWriteString()による書き込み、FileReadString()/FileReadNumber()による読み込み、FileDelete()によるファイル削除、CSV/テキスト/バイナリの各モード、FileIsExist()によるファイル存在確認、トレードログの保存、設定ファイルの読み込みまで、MT4 EA開発に必要なファイル操作のすべてをコード付きで解説します。

目次

MQL4とMQL5のファイル操作の違い

機能MQL4MQL5
基本関数ほぼ同じほぼ同じ
ファイルパスMQL4/Files/フォルダMQL5/Files/フォルダ
共通フォルダFILE_COMMON フラグFILE_COMMON フラグ
UnicodeFILE_ANSI / FILE_UNICODE同じ
フォルダ操作FolderCreate/Delete(ビルド600+)FolderCreate/Delete/Clean

MQL4のファイル操作はセキュリティ上、MQL4/Files/フォルダ(またはテスター使用時はtester/files/)内でのみ実行できます。このサンドボックスの外にはアクセスできません。

FileOpen — ファイルを開く

int FileOpen(
   string file_name,    // ファイル名(Files/フォルダ内の相対パス)
   int    open_flags,   // オープンフラグの組み合わせ
   short  delimiter = '\t',  // CSVの区切り文字
   uint   codepage = CP_ACP   // コードページ
);
// 戻り値: ファイルハンドル(失敗時はINVALID_HANDLE)

オープンフラグ

フラグ説明
FILE_READ読み込み用
FILE_WRITE書き込み用
FILE_BINバイナリモード
FILE_CSVCSVモード(区切り文字対応)
FILE_TXTテキストモード
FILE_ANSIANSIエンコーディング
FILE_UNICODEUnicodeエンコーディング
FILE_COMMON共通フォルダを使用
ファイルパスの制約
  • 通常: MQL4/Files/ フォルダ内のみアクセス可能
  • テスター: tester/files/ フォルダにリダイレクトされる
  • FILE_COMMON: ターミナル共通フォルダ(AppData/Roaming/MetaQuotes/Terminal/Common/Files/
  • サブフォルダの作成: FolderCreate("subfolder")(ビルド600+)
  • 絶対パスは指定できない(セキュリティ上の制約)
ファイルパスの制約
  • 通常: MQL4/Files/ フォルダ内のみアクセス可能
  • テスター: tester/files/ フォルダにリダイレクトされる
  • FILE_COMMON: ターミナル共通フォルダ(AppData/Roaming/MetaQuotes/Terminal/Common/Files/
  • 絶対パスは指定できない(セキュリティ上の制約)

CSVファイルの書き込み

void WriteTradeLog(int ticket, string action, double lots, double price)
  {
   string filename = "TradeLog_" + Symbol() + ".csv";

   int handle = FileOpen(filename, FILE_READ|FILE_WRITE|FILE_CSV, ',');

   if(handle == INVALID_HANDLE)
     {
      Print("ファイルオープン失敗: ", GetLastError());
      return;
     }

   // ファイル末尾に移動
   FileSeek(handle, 0, SEEK_END);

   // ファイルが空ならヘッダーを書く
   if(FileTell(handle) == 0)
      FileWrite(handle, "DateTime", "Action", "Symbol", "Ticket",
                "Lots", "Price", "Balance", "Equity");

   // データ行を書き込み
   FileWrite(handle,
      TimeToStr(TimeCurrent(), TIME_DATE|TIME_SECONDS),
      action,
      Symbol(),
      ticket,
      DoubleToStr(lots, 2),
      DoubleToStr(price, Digits),
      DoubleToStr(AccountBalance(), 2),
      DoubleToStr(AccountEquity(), 2)
   );

   FileClose(handle);
  }

CSVファイルの読み込み

void ReadTradeLog()
  {
   string filename = "TradeLog_" + Symbol() + ".csv";

   int handle = FileOpen(filename, FILE_READ|FILE_CSV, ',');

   if(handle == INVALID_HANDLE)
     {
      Print("ファイルが見つかりません");
      return;
     }

   // ヘッダー行をスキップ
   string header = FileReadString(handle);

   int lineCount = 0;
   while(!FileIsEnding(handle))
     {
      string dateTime = FileReadString(handle);
      string action   = FileReadString(handle);
      string symbol   = FileReadString(handle);
      int    ticket   = (int)FileReadNumber(handle);
      double lots     = FileReadNumber(handle);
      double price    = FileReadNumber(handle);
      double balance  = FileReadNumber(handle);
      double equity   = FileReadNumber(handle);

      if(StringLen(dateTime) > 0)
        {
         Print(dateTime, " ", action, " ", symbol,
               " ticket=", ticket, " lots=", lots);
         lineCount++;
        }
     }

   FileClose(handle);
   Print("読み込み完了: ", lineCount, "行");
  }

FILE_READ|FILE_WRITEを同時に指定すると、既存ファイルを開いて読み書きできます。FILE_WRITEのみだとファイルが空になります。既存ファイルに追記する場合は、必ずFILE_READ|FILE_WRITEで開いてからFileSeek(handle, 0, SEEK_END)でファイル末尾に移動してください。

FILE_READ|FILE_WRITEを同時に指定すると、既存ファイルを開いて読み書きできます。FILE_WRITEのみだとファイルが空になります。既存ファイルに追記する場合は、必ずFILE_READ|FILE_WRITEで開いてからFileSeek(handle, 0, SEEK_END)でファイル末尾に移動してください。

テキストファイル操作

// テキストファイルへの書き込み
void WriteTextLog(string message)
  {
   string filename = "EA_Log.txt";
   int handle = FileOpen(filename, FILE_READ|FILE_WRITE|FILE_TXT|FILE_ANSI);

   if(handle == INVALID_HANDLE) return;

   FileSeek(handle, 0, SEEK_END);
   FileWriteString(handle,
      TimeToStr(TimeCurrent(), TIME_DATE|TIME_SECONDS) + " " + message + "\n");
   FileClose(handle);
  }

// テキストファイルの全文読み込み
string ReadTextFile(string filename)
  {
   int handle = FileOpen(filename, FILE_READ|FILE_TXT|FILE_ANSI);

   if(handle == INVALID_HANDLE)
      return "";

   int size = (int)FileSize(handle);
   string content = FileReadString(handle, size);

   FileClose(handle);
   return content;
  }

バイナリファイル操作

// 構造体をバイナリで保存
struct TradeRecord
  {
   int      ticket;
   int      type;
   double   lots;
   double   openPrice;
   datetime openTime;
  };

void SaveTradeRecords(TradeRecord &records[], int count)
  {
   int handle = FileOpen("trades.bin", FILE_WRITE|FILE_BIN);
   if(handle == INVALID_HANDLE) return;

   // レコード数を最初に保存
   FileWriteInteger(handle, count);

   for(int i = 0; i < count; i++)
     {
      FileWriteInteger(handle, records[i].ticket);
      FileWriteInteger(handle, records[i].type);
      FileWriteDouble(handle, records[i].lots);
      FileWriteDouble(handle, records[i].openPrice);
      FileWriteInteger(handle, (int)records[i].openTime);
     }

   FileClose(handle);
  }

int LoadTradeRecords(TradeRecord &records[])
  {
   int handle = FileOpen("trades.bin", FILE_READ|FILE_BIN);
   if(handle == INVALID_HANDLE) return 0;

   int count = FileReadInteger(handle);
   ArrayResize(records, count);

   for(int i = 0; i < count; i++)
     {
      records[i].ticket    = FileReadInteger(handle);
      records[i].type      = FileReadInteger(handle);
      records[i].lots      = FileReadDouble(handle);
      records[i].openPrice = FileReadDouble(handle);
      records[i].openTime  = (datetime)FileReadInteger(handle);
     }

   FileClose(handle);
   return count;
  }

ファイルユーティリティ関数

関数説明
FileIsExist(filename)ファイルの存在確認
FileDelete(filename)ファイルの削除
FileMove(src, dst, flag)ファイルの移動/リネーム
FileCopy(src, flag, dst, flag)ファイルのコピー
FileSize(handle)ファイルサイズ(バイト)
FileTell(handle)現在のファイル位置
FileSeek(handle, offset, origin)ファイル位置の移動
FileFlush(handle)バッファのフラッシュ
FileIsEnding(handle)ファイル末尾かどうか
FileIsLineEnding(handle)行末かどうか
FolderCreate(path)フォルダの作成(ビルド600+)
FolderDelete(path)フォルダの削除(ビルド600+)
void FileUtilityExample()
  {
   string filename = "test.txt";

   // 存在確認
   if(FileIsExist(filename))
      Print("ファイルが存在します");
   else
      Print("ファイルが存在しません");

   // ファイル削除
   if(FileIsExist("old_log.txt"))
      FileDelete("old_log.txt");

   // フォルダ作成(ビルド600+)
   FolderCreate("Logs");
   FolderCreate("Logs\\2024");

   // 共通フォルダへの書き込み(複数EAで共有)
   int handle = FileOpen("shared_data.txt",
                          FILE_WRITE|FILE_TXT|FILE_COMMON);
   if(handle != INVALID_HANDLE)
     {
      FileWriteString(handle, "共有データ");
      FileClose(handle);
     }
  }

実践: 設定ファイルの読み書き

// key=value形式の設定ファイル読み込み
string ReadSetting(string filename, string key, string defaultValue = "")
  {
   int handle = FileOpen(filename, FILE_READ|FILE_TXT|FILE_ANSI);
   if(handle == INVALID_HANDLE)
      return defaultValue;

   string result = defaultValue;

   while(!FileIsEnding(handle))
     {
      string line = FileReadString(handle);
      int eqPos = StringFind(line, "=");

      if(eqPos > 0)
        {
         string k = StringSubstr(line, 0, eqPos);
         string v = StringSubstr(line, eqPos + 1);
         StringTrimLeft(k); StringTrimRight(k);
         StringTrimLeft(v); StringTrimRight(v);

         if(k == key)
           {
            result = v;
            break;
           }
        }
     }

   FileClose(handle);
   return result;
  }

// 使用例
void LoadSettings()
  {
   double riskPercent = StrToDouble(ReadSetting("ea_config.ini", "RiskPercent", "2.0"));
   int    maxPositions = StrToInteger(ReadSetting("ea_config.ini", "MaxPositions", "3"));
   string allowedPairs = ReadSetting("ea_config.ini", "AllowedPairs", "USDJPY,GBPJPY");

   Print("Risk: ", riskPercent, "% MaxPos: ", maxPositions, " Pairs: ", allowedPairs);
  }

ファイル操作関数一覧(MQL5対応表)

MQL4関数MQL5対応説明
FileOpen()FileOpen()ファイルを開く
FileClose()FileClose()ファイルを閉じる
FileWrite()FileWrite()CSVフィールド書き込み
FileWriteString()FileWriteString()文字列書き込み
FileWriteInteger()FileWriteInteger()整数書き込み
FileWriteDouble()FileWriteDouble()浮動小数点書き込み
FileReadString()FileReadString()文字列読み込み
FileReadNumber()FileReadNumber()数値読み込み
FileReadInteger()FileReadInteger()整数読み込み
FileReadDouble()FileReadDouble()浮動小数点読み込み
FileDelete()FileDelete()ファイル削除
FileIsExist()FileIsExist()存在確認
FileSize()FileSize()サイズ取得
FileSeek()FileSeek()位置移動
FileTell()FileTell()現在位置取得

まとめ

MQL4のファイル操作関数はMQL5とほぼ同じで、移植性が高いカテゴリです。重要なポイントは以下の通りです。

  • ファイルはMQL4/Files/フォルダ内でのみ操作可能 — セキュリティサンドボックス
  • FileOpen()後は必ずFileClose()する — ファイルハンドルのリークを防ぐ
  • FILE_COMMONで複数EA間のデータ共有が可能
  • CSVモードはFileWrite()、テキストモードはFileWriteString()を使い分ける

次のステップとして、MQLリファレンス総合ガイドで他のカテゴリも学習しましょう。

シストレ.COMで実績のあるEAが使い放題!/
無料会員登録はこちら
FX自動売買でEAを探すなら
シストレ.COM
実績あるEAが無料
厳格な審査を乗り越えた実績のあるEAが無料で使えます!
自由な口座選び
有料版を購入し柔軟な口座選びが可能!
フォワードテスト公開
全EAのフォワードテスト結果を公開中!
FX初心者も安心
初心者の方も安心して取引を始められます。
多様なEA選択肢
様々な種別のEAをご用意!自分の手法にあった取引が可能です。
信頼のFX会社と提携
人気のFX会社と提携中!様々なFX会社から選べます。
1分で登録完了!EA探すならシストレ.COM!/
無料会員登録はこちら
【FX自動売買】システムトレード完全ガイド|Forex Guide

この記事が気に入ったら
フォローしてね!

お役立ち情報をシェアする
  • URLをコピーしました!
目次