Reading from a file during testing

 

Reading from a file during testing is not easy to solve.

I am getting error:

2024.08.18 18:29:50.988 Core 1  2024.01.01 00:00:00   Initializing Expert Advisor...
2024.08.18 18:29:50.988 Core 1  2024.01.01 00:00:00   Current working directory: C:\Program Files\MetaTrader5\Tester\Agent-127.0.0.1-3000
2024.08.18 18:29:50.988 Core 1  2024.01.01 00:00:00   Source file does not exist: C:\Program Files\MetaTrader5\MQL5\Files\trading_signals.csv
2024.08.18 18:29:50.988 Core 1  tester stopped because OnInit returns non-zero code 1

Here is my code:

#property tester_file "\\trading_signals.csv" //+------------------------------------------------------------------+
//| Expert initialization function                                   | //+------------------------------------------------------------------+ int OnInit() {     Print("Initializing Expert Advisor...");     string current_directory = TerminalInfoString(TERMINAL_DATA_PATH);     Print("Current working directory: ", current_directory);     // Define source and destination paths     string source_file = TerminalInfoString(TERMINAL_PATH) + "\\MQL5\\Files\\trading_signals.csv";     string destination_file = current_directory + "\\MQL5\\Files\\trading_signals.csv";     // Check if the source file exists     if (FileIsExist(source_file)) {         Print("Source file exists: ", source_file);     } else {         Print("Source file does not exist: ", source_file);         return INIT_FAILED;     }     // Copy the file     if (FileCopy(source_file, FILE_COMMON, destination_file, FILE_COMMON)) {         Print("File copied successfully from ", source_file, " to ", destination_file);     } else {         Print("Failed to copy file from ", source_file, " to ", destination_file, ". Error code: ", GetLastError());         return INIT_FAILED;     }     // List files in the Tester/Files directory     string files_directory = current_directory + "\\MQL5\\Files";     ListFilesInDirectory(files_directory);     ea = new ExpertAdvisor(100.0, 2.0); // Example parameters: 100% balance, 2 pips cost     string file_path = files_directory + "\\trading_signals.csv";     Print("Constructed file path: ", file_path);     Print("Attempting to open file: ", file_path);     if (!ea.LoadSignals(file_path)) { // Ensure the path is correct         Print("Failed to load trading signals.");         return INIT_FAILED;     }     Print("Expert Advisor initialized successfully.");     return INIT_SUCCEEDED; }

Any idea how to solve it?

 
Hi, using File function on Metatrader have file access restrictions because the sandbox environment in MetaTrader often restricts access to the file system, especially when it comes to accessing directories outside the allowed areas (like TERMINAL_PATH ). For security reasons, the sandbox environment limits file read/write access to certain areas, such as the MQL5/Files or Terminal/Files directories. If you attempt to access or copy files from other directories, this action may be blocked.

Solution: You need to use Kernel32, I will include it here (Working with Metatrader 5 64bit)

#import "kernel32.dll"
   long CreateFileW(
       string               lpFileName,
       uint                 dwDesiredAccess,
       uint                 dwShareMode,
       uint                 lpSecurityAttributes,
       uint                 dwCreationDisposition,
       uint                 dwFlagsAndAttributes,
       uint                 hTemplateFile
   );

   bool WriteFile(
       long                 hFile,
       uchar&               lpBuffer[],
       uint                 nNumberOfBytesToWrite,
       uint&                lpNumberOfBytesWritten,
       long                 lpOverlapped
   );
   
   bool ReadFile(
       long                 hFile,
       uchar&               lpBuffer[],
       uint                 nNumberOfBytesToRead,
       uint&                lpNumberOfBytesRead,
       long                 lpOverlapped
   );

   bool CloseHandle(long hObject);
   long GetFileSize(int hFile, long lpFileSizeHigh);
   void CopyMemory(string &dest, uchar &src[], int length);
#import

string ReadFromFile(string fileName) {
   // Open the file with read permissions
   long hFile = CreateFileW(fileName, GENERIC_READ, _FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
   
   if(hFile == -1) {
     // Print("Failed to open the file.");
      return("");
   }

   // Define a buffer to read the file contents
   uchar wideBuffer[];
   ArrayResize(wideBuffer,(int)GetFileSize((int)hFile,0));
   uint bytesRead;
   if(!ReadFile(hFile, wideBuffer, ArraySize(wideBuffer), bytesRead, 0)) {
     // Print("Failed to read from the file.");
      CloseHandle(hFile);
      return("");
   }

   CloseHandle(hFile);

   return CharArrayToString(wideBuffer);
}

void WriteData(char &data[],string path){

   long hFile = CreateFileW(path, GENERIC_WRITE, _FILE_SHARE_READ | _FILE_SHARE_WRITE, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
   if(hFile != -1)
   {
     if(WriteFile(hFile, data, ArraySize(data), bytesWritten, 0))
      {
         //Do something when write file successfully
      }
      CloseHandle(hFile);
   }
   
   ZeroMemory(data);
   ArrayFree(data);
   
}
Hope you can find it useful.
 
Petr Janata:

Reading from a file during testing is not easy to solve.

I am getting error:

Here is my code:

Any idea how to solve it?

Why did you comment out the property tester_file? This would be the easiest way to access the file by short name just in the agent directory, because such files are transferred to agents automatically.

Also you can open local files in the common MQL folder.

 
    string source_file = TerminalInfoString(TERMINAL_PATH) + "\\MQL5\\Files\\trading_signals.csv";
    string destination_file = current_directory + "\\MQL5\\Files\\trading_signals.csv";
Stop specifying a path. File Write Problem (Error: 5002) - Expert Advisors and Automated Trading - MQL5 programming forum #1-2 (2020)
and FolderDelete using TERMINAL_DATA_PATH - General - MQL5 programming forum (2017)
 
Finally, this was achieved by placing the csv file in a common path and setting a flag FILE_COMMON to open the file.
 
Petr Janata #:
Finally, this was achieved by placing the csv file in a common path and setting a flag FILE_COMMON to open the file.

the property tester directive works but you have to compile then restart mt5 first.