MQL4/MQL5 File Operations: Read & Write Data Like a Pro

Master MQL4/MQL5 file operations with expert guidance on FileOpen, CSV handling, sandbox rules, and common pitfalls for persistent EA data storage.

mql4-mql5-file-operations-read-write-data-like-a

Every serious algorithmic trader eventually needs their Expert Advisor or indicator to remember something between runs — trade history, market regime data, custom symbol lists, or optimization results. The built-in MQL4/MQL5 file operations give you that persistence. This guide walks you through reading from and writing to files in both MQL4 and MQL5, covering the exact function calls, the file sandbox rules, CSV handling, and the gotchas that trip up even experienced developers.

What You Will Learn

By the end of this guide you will be able to:

  • Open and close files safely using FileOpen and FileClose
  • Write structured trade data to CSV files from your EA
  • Read back that data and parse it into usable variables
  • Handle the MetaTrader file sandbox (the Files folder) correctly
  • Avoid common pitfalls like unclosed handles and wrong file flags

Prerequisites

Before you begin, ensure you have:

  • MetaTrader 4 or 5 (build 600+ for MT4; MT5 is fine as-is)
  • MetaEditor installed (comes with the terminal)
  • An MQL4 or MQL5 project open (EA, script, or indicator)
  • Basic familiarity with MQL syntax — variables, functions, if statements

Understanding the File Sandbox

MetaTrader restricts file access to a specific sandbox folder to protect your system. In MT4, the default path is \MQL4\Files\; in MT5, it is \MQL5\Files\. You can verify this by navigating in MetaEditor to File > Open Data Folder, then looking for the Files subdirectory. Any file operation using a relative filename (e.g., "trades.csv") will resolve inside this sandbox. To access a shared folder across multiple terminal instances (useful for multi-chart EAs), use the FILE_COMMON flag, which places files in \AppData\Roaming\MetaQuotes\Terminal\Common\Files\ (Windows) or the equivalent on other OSes.

Sandbox Limitations and Workarounds

  • No absolute paths: You cannot use paths like C:\Users\...\trades.csv. MQL will reject them.
  • File size limits: While not enforced by MQL, large files (over 100 MB) can slow down terminal performance. Keep files lean.
  • Concurrent access: Multiple EAs on the same chart share the same sandbox. Use unique filenames or the FILE_COMMON flag to avoid conflicts.

Step-by-Step Instructions: Writing to a File

Step 1: Choose the Right File Flags

Every file operation in MQL begins with FileOpen. You must supply the correct combination of flags. The most common ones are:

Flag Value Purpose
FILE_TXT 0 Opens file in text mode (CR+LF line endings)
FILE_CSV 0 Opens file in CSV mode (comma-delimited, same as FILE_TXT in MQL4)
FILE_BIN 0 Opens file in binary mode (no line-ending conversion)
FILE_READ 1 Allows reading from the file
FILE_WRITE 2 Allows writing to the file
FILE_COMMON 4096 Uses the common Files folder shared between terminals

Combine flags with the bitwise OR operator |. For example, to open a CSV file for both reading and writing: FILE_CSV|FILE_READ|FILE_WRITE.

Step 2: Write Data with FileWrite

Here is a complete MQL4 snippet that writes trade data to a CSV file. The same code works in MQL5 with one difference: in MQL5 you must include #include .

// MQL4 example — writes a trade record to "trades.csv"
int fileHandle = FileOpen("trades.csv", FILE_CSV|FILE_WRITE|FILE_READ, ",");
if(fileHandle != INVALID_HANDLE)
  {
   FileSeek(fileHandle, 0, SEEK_END);  // append to end
   FileWrite(fileHandle, TimeToString(TimeCurrent()), Symbol(),
             DoubleToString(OrderProfit(), 2), "EURUSD");
   FileClose(fileHandle);
   Print("Trade recorded successfully.");
  }
else
   Print("Failed to open file. Error: ", GetLastError());

Key points:

  • FileOpen returns INVALID_HANDLE (-1) on failure — always check this.
  • The third parameter to FileOpen is the separator character (comma in this case).
  • FileSeek with SEEK_END positions the write cursor at the end so you append, not overwrite.
  • FileWrite automatically adds a newline after each call.

Step 3: Write Binary Data for Efficiency

For high-frequency trading or large datasets, binary mode is faster and more compact. Here is an example writing integer and double values:

// MQL4 example — writes binary trade data
int fileHandle = FileOpen("trades.bin", FILE_BIN|FILE_WRITE|FILE_READ);
if(fileHandle != INVALID_HANDLE)
  {
   FileSeek(fileHandle, 0, SEEK_END);
   FileWriteInteger(fileHandle, (int)TimeCurrent(), INT_VALUE);
   FileWriteDouble(fileHandle, OrderProfit());
   FileWriteInteger(fileHandle, OrderType(), SHORT_VALUE);
   FileClose(fileHandle);
  }

When reading binary data, you must read in the exact same order and with matching types. Use FileReadInteger, FileReadDouble, etc. Binary files are not human-readable but are ideal for internal EA state storage.

Step 4: Read Data with FileReadString and FileIsEnding

To read back the data, open the file with FILE_READ and loop until you hit the end:

// MQL4 example — reads all lines from "trades.csv"
int fileHandle = FileOpen("trades.csv", FILE_CSV|FILE_READ, ",");
if(fileHandle != INVALID_HANDLE)
  {
   while(!FileIsEnding(fileHandle))
     {
      string timestamp = FileReadString(fileHandle);
      string symbol    = FileReadString(fileHandle);
      string profit    = FileReadString(fileHandle);
      string pair      = FileReadString(fileHandle);
      Print("Trade: ", timestamp, " | ", symbol, " | ", profit, " | ", pair);
     }
   FileClose(fileHandle);
  }
else
   Print("Failed to open file. Error: ", GetLastError());

Notice that FileReadString reads one field at a time, delimited by the separator you specified in FileOpen. For numeric fields, use FileReadNumber instead.

Advanced Techniques

Handling Large Files with FileTell and FileSize

When dealing with files that may grow large (e.g., logging every tick), use FileSize to check the file size before opening, and FileTell to track your position. This prevents accidental overwrites and helps with partial reads:

int fileHandle = FileOpen("biglog.txt", FILE_TXT|FILE_READ);
if(fileHandle != INVALID_HANDLE)
  {
   ulong fileSize = FileSize(fileHandle);
   if(fileSize > 1048576) // 1 MB limit
     {
      Print("File too large, truncating...");
      FileClose(fileHandle);
      FileDelete("biglog.txt");
      fileHandle = FileOpen("biglog.txt", FILE_TXT|FILE_WRITE);
     }
   FileClose(fileHandle);
  }

Using FileWriteStruct for Complex Data

MQL5 supports writing entire structures to binary files using FileWriteStruct. This is powerful for saving EA state (e.g., open orders, indicators). Define a struct and write it atomically:

// MQL5 example
struct TradeRecord
  {
   long   ticket;
   double price;
   int    type;
   string symbol;
  };
// In EA
TradeRecord rec;
rec.ticket = OrderTicket();
rec.price  = OrderOpenPrice();
rec.type   = OrderType();
rec.symbol = OrderSymbol();
int fileHandle = FileOpen("state.bin", FILE_BIN|FILE_WRITE);
if(fileHandle != INVALID_HANDLE)
  {
   FileWriteStruct(fileHandle, rec);
   FileClose(fileHandle);
  }

To read back, use FileReadStruct with the same struct definition.

Tips and Best Practices from Experience

  • Always close file handles. Every FileOpen must have a matching FileClose. Use a try-finally pattern in MQL4 by putting the close inside OnDeinit or a cleanup function.
  • Use FILE_COMMON for multi-instance sharing. If you run the same EA on multiple charts and want them to share one file, add the FILE_COMMON flag. Otherwise each chart gets its own sandboxed Files folder.
  • Check the file sandbox path. In MT4, files go to \MQL4\Files\. In MT5, it is \MQL5\Files\. You cannot access files outside this folder unless you use FILE_COMMON.
  • Handle errors gracefully. GetLastError() returns the error code after a failed operation. Common codes: 5003 (file not found), 5004 (file already open), 5006 (disk full).
  • Use FILE_TXT for human-readable logs. CSV mode is fine, but if you only need plain text, FILE_TXT works identically and makes the file easier to open in Notepad.
  • Backup your files regularly. MetaTrader does not automatically backup the Files folder. Copy important CSVs to an external location periodically.

Common Mistakes and Troubleshooting

Mistake 1: Forgetting to Close the File

If your EA crashes or you forget FileClose, the file handle remains locked. The next call to FileOpen will fail with error 5004. Fix: Always call FileClose in a cleanup section, and consider using a global variable to track the handle. For example:

int fileHandle = INVALID_HANDLE;
void OnTick()
  {
   if(fileHandle == INVALID_HANDLE)
      fileHandle = FileOpen("data.csv", FILE_CSV|FILE_WRITE|FILE_READ, ",");
   // ... use fileHandle ...
  }
void OnDeinit(const int reason)
  {
   if(fileHandle != INVALID_HANDLE)
      FileClose(fileHandle);
  }

Mistake 2: Wrong File Flags

Opening a file with FILE_WRITEFrequently Asked Questions

Can I write to a file in the Experts folder instead of Files?

No. MetaTrader restricts file writes to the Files subdirectory of your MQL4/MQL5 folder. Use FILE_COMMON to access a shared folder that all terminals can see.

Why does my file keep getting overwritten instead of appended?

You likely opened the file with FILE_WRITE only. Add FILE_READ to the flags and call FileSeek(fileHandle, 0, SEEK_END) before writing.

How do I read a CSV file with a semicolon delimiter?

Pass the semicolon as the separator in FileOpen: FileOpen("data.csv", FILE_CSV|FILE_READ, ";"). MQL treats the separator literally.

What is the maximum file size MQL can handle?

MQL4/MQL5 can handle files up to 2 GB in practice, but performance degrades with very large files. For logging, consider rotating files daily or weekly.

Community

Clap for the article and open comments only when you want to read them.

0 claps0 comments

Related articles