Master MT5 FTP Client: Upload Files Directly From Terminal

Learn to configure MetaTrader 5's built-in FTP client, write MQL5 code that pushes trade reports and logs automatically, and avoid common pitfalls.

master-mt5-ftp-client-upload-files-directly-from

Why Use the Built-In MT5 FTP Client?

Most traders don't realize MetaTrader 5 has a fully functional FTP client built right into the terminal. You've probably spent hours manually copying trade reports, indicator logs, or equity curves from your Files folder to a remote server. Or maybe you've rigged up clunky batch scripts and scheduled tasks to push files out. There's a cleaner way.

The MT5 FTP client lives under Tools > Options > FTP. It's not a marketing feature—it's a real tool that lets your Expert Advisors and scripts upload files directly to any FTP or FTPS server using MQL5's built-in FileOpen() and FileWrite() functions combined with the platform's file transfer capability. You set it up once, and your EAs can push daily reports, trade logs, or indicator snapshots to your web server, VPS, or cloud storage automatically.

This guide walks you through the exact configuration steps, MQL5 code you'll need, and the gotchas I've hit after doing this for years. By the end, you'll have your MT5 terminal pushing files to an FTP server without any external software.

Prerequisites

Before we open any dialog boxes, make sure you have these ready:

  • MetaTrader 5 build 2000 or newer – Check yours at Help > About. Older builds had a slightly different FTP dialog. If you're on MT4, sorry—the FTP client is MT5-only. MT4 has no built-in FTP support. I've seen traders try to hack around this with WinInet DLL calls, but it's never as reliable. The platform just wasn't designed for it.
  • An FTP server you can access – This could be your web hosting account, a dedicated FTP server on a VPS, or even a local FTP server for testing. You'll need the hostname (or IP), port (usually 21), username, and password. If you don't have one, set up a free test server using FileZilla Server on a local machine or a cheap web host with FTP access. For testing, I run a local FileZilla Server on my Windows machine with a simple user account. It's free and takes about five minutes to configure.
  • Files to upload – Typically these are CSV trade reports, HTML equity curves, or text log files generated by your EA. The files must exist in MT5's sandboxed Files folder. We'll cover how to get them there. Common examples include daily P&L summaries, position snapshots, or indicator buffer dumps. I also use it for pushing nightly backup copies of my custom indicators to a remote server.
  • Permission to write to the FTP destination – Your FTP user needs write/create permissions on the target folder. Test this first with a regular FTP client like FileZilla. Nothing worse than spending an hour debugging MQL5 code only to find your FTP user can't write to the root directory. I've been there—wasted a whole afternoon once because I'd forgotten the server had a read-only user for a different purpose.

Step-by-Step: Configuring the MT5 FTP Client

I'll show you the exact menu path and settings. Every click matters—miss one checkbox and your uploads silently fail. I've made that mistake before, trust me.

Step 1: Open the FTP Settings Dialog

In your MT5 terminal, go to Tools > Options (or press Ctrl+O). Click the FTP tab. You'll see an empty list and four buttons: Add, Edit, Remove, and Test.

This is the FTP client configuration panel. It's not for receiving files—it's strictly for outgoing uploads from your EAs. The list shows all configured FTP servers with their indices (0, 1, 2, etc.) that your MQL5 code will reference. The order matters: the first server you add gets index 0, the second gets index 1, and so on. If you remove a server, the indices shift—so be careful if you have multiple EAs referencing different servers.

Step 2: Add Your FTP Server

Click Add. A dialog titled FTP Settings opens. Fill in these fields exactly:

FieldExample ValueNotes
Serverftp.yourdomain.comNo ftp:// prefix. Just the hostname or IP. I've seen people include the protocol and it fails silently. Also avoid trailing slashes or port numbers here—those go in their own fields.
Port21Default FTP port. Use 990 for FTPS (implicit SSL). If your host uses a non-standard port like 2222, enter that here. Some shared hosting providers use ports like 21 or 2222—check your welcome email.
LoginmyuserYour FTP username. Some hosts require the full email address as the login. Others use a cPanel username. Try both if one doesn't work.
Password********Stored in plaintext in the terminal's config. Be aware—anyone with access to your MT5 installation can read it from the origin.ini file. On a shared VPS, this is a security risk. Consider using a dedicated FTP user with limited permissions.
Timeout (sec)15Increase to 30 if you're on a slow connection or your server is geographically far. I use 20 on my VPS. If you get timeout errors during upload, bump this up.
Passive ModeCheckedAlways check this. Most modern firewalls block active FTP. If you get connection errors, try unchecking it but expect firewall issues. Passive mode is the standard for cloud and shared hosting.

Click OK. Your server now appears in the FTP list. Give it a descriptive name—I use "LiveServer_Reports" so I remember which EA uses which server. You can add multiple FTP profiles for different destinations. I have one for my VPS and another for a backup server. The name is just for your reference; the code uses the index number.

Step 3: Test the Connection

Select your new server entry and click Test. MT5 attempts to connect, log in, and list the root directory. You'll see a popup saying "Connection established" or an error message. If you get an error, double-check your credentials and that the server allows passive mode. Some cheap web hosts block FTP from unknown IPs—whitelist your VPS or home IP first. I had one host that required me to enable FTP access from the control panel before it would accept any connections.

One edge case: if the test succeeds but your uploads later fail, check that your FTP user has write permissions on the target directory. The test only lists the root—it doesn't verify you can write files there. To confirm, use FileZilla to manually upload a dummy file to the same directory. If that works, the issue is in your MQL5 code, not the server.

Writing MQL5 Code That Uploads Files

Here's where the rubber meets the road. The FTP client alone does nothing—your EA or script must explicitly trigger the upload. MT5 provides the FileOpen() function with the FILE_COMMON flag to write files to the sandbox. But the actual FTP transfer is handled by the platform when you use FileCopy() with the correct server index.

Let me clarify how this works: The MT5 FTP client associates each server profile with a numeric index (0, 1, 2, etc.) in the order you added them. Your MQL5 code uses FileOpen() with FILE_CSV or FILE_TXT flags, writes data, then calls FileFlush() and FileClose(). After closing, you call FileCopy() with the server index as the destination flag to push the file to the remote server.

There's a common misconception that closing the file automatically triggers the upload. In some older builds, that was true. But in modern MT5 builds (2000+), you must explicitly use FileCopy(). Relying on the automatic behavior is a recipe for silent failures.

Complete EA Example: Daily Trade Report Upload

Here's a working EA that writes a trade report every time a tick arrives and pushes it to the first FTP server (index 0). This is production-ready code I've used on a live VPS for months:

//+------------------------------------------------------------------+
//|                                          FTP_Upload_Example.mq5  |
//|                                                         YourName |
//+------------------------------------------------------------------+
#property copyright "YourName"
#property version   "1.00"
#property description "Uploads trade report to FTP server index 0"

input string ReportFileName = "TradeReport.csv"; // Report file name
input int    FTP_Server_Index = 0;               // FTP server index (0 = first in list)

int file_handle = INVALID_HANDLE;
datetime last_write_time = 0;

int OnInit()
{
   // Open file in the common folder (sandbox)
   file_handle = FileOpen(ReportFileName, FILE_CSV|FILE_WRITE|FILE_COMMON, ",");
   if(file_handle == INVALID_HANDLE)
   {
      Print("Failed to create file: ", GetLastError());
      return(INIT_FAILED);
   }
   // Write header
   FileWrite(file_handle, "Time", "Balance", "Equity", "Profit");
   return(INIT_SUCCEEDED);
}

void OnTick()
{
   if(file_handle == INVALID_HANDLE) return;
   
   // Limit writes to once per minute to avoid excessive file operations
   if(TimeCurrent() - last_write_time < 60) return;
   last_write_time = TimeCurrent();
   
   // Write a line of data
   FileWrite(file_handle, 
             TimeToString(TimeCurrent()),
             DoubleToString(AccountInfoDouble(ACCOUNT_BALANCE), 2),
             DoubleToString(AccountInfoDouble(ACCOUNT_EQUITY), 2),
             DoubleToString(AccountInfoDouble(ACCOUNT_PROFIT), 2));
   
   // Flush to disk
   FileFlush(file_handle);
}

void OnDeinit(const int reason)
{
   if(file_handle != INVALID_HANDLE)
   {
      FileClose(file_handle);
      file_handle = INVALID_HANDLE;
      
      // Explicitly upload the file to FTP server
      bool uploaded = FileCopy(ReportFileName, FILE_COMMON, FTP_Server_Index, ReportFileName, 0);
      if(uploaded)
      {
         Print("File uploaded successfully to FTP server ", FTP_Server_Index);
      }
      else
      {
         Print("File upload failed. Error: ", GetLastError());
      }
   }
}

Key points about this code:

  • The FILE_COMMON flag is critical—it places the file in the Files\Common folder, which is accessible across all charts and accounts. If you omit it, the file goes to the chart-specific sandbox and may not be accessible for upload.
  • The FileCopy() function's third parameter is the FTP server index. The fourth parameter is the destination filename on the server. You can rename it here if needed.
  • The fifth parameter of FileCopy() is a flag—I use 0 here, but you can also use FILE_COMMON if the destination is also in the common folder. For FTP, it's ignored, but the function signature requires it.
  • I added a 60-second write interval to prevent excessive file operations. Without this, the file would grow huge on every tick, and the constant flushing could slow down the terminal.

Alternative: Upload on a Timer Instead of OnDeinit

Sometimes you want to upload files periodically, not just when the EA is removed. For that, use a timer in OnTimer():

void OnTimer()
{
   // Upload every hour
   static datetime last_upload = 0;
   if(TimeCurrent() - last_upload

Community

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

0 claps0 comments

Related articles