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

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

MQL4 ファイル操作関数 リファレンスカード
目次

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("Logs2024");

   // 共通フォルダへの書き込み(複数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とほぼ同じで、移植性が高いカテゴリです。実際に試したところ、FileOpen()後のFileClose()を忘れると実行中にファイルハンドルが枯渇します。ポイントは以下の通りです。

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

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

EA本番運用では損失リスクが伴います。十分なバックテストと動作確認を経てから本番口座で稼働させてください。

MQL4ファイル操作 よくある質問

MQL4のファイル操作の基本は?

FileOpen()でファイルを開き、FileWrite()/FileWriteString()で書き込み、FileClose()で閉じる流れが基本です。ファイルはMQL4/Filesフォルダ(データフォルダ内)に保存されます。OnDeinit()でのFileClose()呼び出しを忘れずに行ってください。

MQL4でCSVファイルを書き込む方法は?

FileOpen(name, FILE_CSV|FILE_WRITE, “,”)でCSVモードで開き、FileWrite(handle, col1, col2)で1行書き込みます。FILE_ANSIを追加するとANSIエンコードになります。追記はFILE_READ|FILE_WRITEでFileSeek()してから書き込みます。

MQL4のファイル保存場所はどこですか?

MQL4/Filesフォルダ(MT4データフォルダ内)が標準保存先です。TerminalPath()でMT4インストールフォルダのパスを取得できます。FILE_COMMONフラグ(MQL4.56以降)で共通フォルダへの保存も可能です。

MQL4でファイルが存在するか確認する方法は?

FileIsExist(filename)でファイルの存在確認ができます。FileOpen()で開けたか(戻り値が-1でないか)でも確認できます。ファイルオープン失敗時はGetLastError()でエラーコードを確認し、ハンドルをINVALID_HANDLEと比較してチェックします。

MQL4でEAのトレードログを記録する方法は?

FileOpen()でFILE_WRITE|FILE_TXTモードで開き、FileWriteString()でタイムスタンプ付きログ行を追記します。TimeToStr(TimeCurrent())でタイムスタンプを生成します。ただし頻繁な書き込みはパフォーマンスに影響するため、バッファリングを検討してください。

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

基本的なAPIは同じですが、MQL5ではFileFindFirst()/FileFindNext()によるファイル検索が追加されました。FILE_COMMONフラグはMQL5でより完全にサポートされています。MQL4ではFILE_ANSIとFILE_UNICODEのエンコード指定が重要です。

MQL4リファレンス 関連記事

シストレ.COM編集部|200種類以上のEAをフォワード計測する運営3年の検証メディア。MetaTrader (MT4/MT5) を実運用してきた編集部が監修・執筆しています。

⚠ リスクに関する注意事項

本記事は情報提供を目的としており、特定の金融商品の売買を推奨するものではありません。FX取引はレバレッジ取引の特性上、預託した証拠金以上の損失が生じる可能性があります。取引の際は、ご自身の判断と責任において行ってください。詳しくは特定商取引法に基づく表記をご確認ください。

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

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

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

この記事を書いた人

シストレ.COM編集部は、FX自動売買(EA)とテクニカル分析を専門とするインターネットメディア「シストレ.COM」の編集チームです。200本以上のEAのフォワードテスト結果を公開し、実際の運用データに基づいた客観的な情報を発信しています。記事の執筆・監修はMetaTrader(MT4/MT5)での実運用経験を持つスタッフが担当。

目次