Almost done creating my EA and then this...

 

Hello MT5 Community,

I am developing an Expert Advisor (EA) for MT5 that reads trade alerts from a file and executes trades based on those alerts. The EA is supposed to check for a trigger file, and if the trigger file indicates a new alert, it reads the alert file and processes the trade. However, I am encountering some issues that I hope some experienced developers can help me resolve.

Here are the specifics of the EA:

  • Alert File Path: C:\Users\optim\Desktop\EA_MT5\Auto_Scripts_MT5\alert.txt
  • Trigger File Path: C:\Users\optim\Desktop\EA_MT5\Auto_Scripts_MT5\trigger.txt

Issues:

  1. File Access Error: I consistently get an error message indicating the EA cannot open the alert file for reading. The error code is 5002, which suggests a file access issue. The EA's logs show the following message:

    2024.06.27 10:27:10.277 Auto_Scripts_v2 (XAUUSD,M5) Failed to open file for reading: C:\Users\optim\Desktop\EA_MT5\Auto_Scripts_MT5\alert.txt, error code: 5002

    I've given MT5 permission and access to the file and the file is not read-only.

  2. Frequent File Access: The EA seems to be checking the files every second instead of only when an HTTP request indicates a new alert. I set the timer to trigger every 60 seconds, but it doesn't seem to help. Here is the current MQ5 source code:#include <Trade\Trade.mqh>


// Input parameters

input string alertFilePath = "C:\\Users\\optim\\Desktop\\EA_MT5\\Auto_Scripts_MT5\\alert.txt";

input string triggerFilePath = "C:\\Users\\optim\\Desktop\\EA_MT5\\Auto_Scripts_MT5\\trigger.txt";



// Global variables

CTrade trade;



int OnInit()

{

    Print("Auto_Scripts_EA initialized.");

    EventSetTimer(60); // Set timer to trigger every 60 seconds (1 minute)

    return(INIT_SUCCEEDED);

}



void OnDeinit(const int reason)

{

    Print("Auto_Scripts_EA deinitialized.");

    EventKillTimer(); // Kill the timer when deinitializing

}



void OnTimer()

{

    Print("Timer triggered, checking for new alerts.");

    // Only read the file when there is a request

    if (CheckForRequest())

    {

        Print("Request found, reading alert file.");

        ReadAndProcessAlertFile();

        ClearTriggerFile();

    }

    else

    {

        Print("No request found, not reading alert file.");

    }

}



bool CheckForRequest()

{

    Print("Checking for request.");

    if (!FileExists(triggerFilePath))

    {

        Print("Trigger file does not exist: ", triggerFilePath);

        return false; // No request if the file does not exist

    }



    int handle = FileOpen(triggerFilePath, FILE_READ | FILE_TXT);

    if (handle < 0)

    {

        Print("Trigger file not found or inaccessible: ", triggerFilePath);

        return false; // No request if the file cannot be read

    }



    string content = FileReadString(handle);

    FileClose(handle);

    

    Print("Trigger file content: ", content);

    return (content == "1");

}



void ClearTriggerFile()

{

    Print("Clearing trigger file.");

    if (!FileExists(triggerFilePath))

    {

        Print("Trigger file does not exist, creating new: ", triggerFilePath);

    }



    int handle = FileOpen(triggerFilePath, FILE_WRITE | FILE_TXT);

    if (handle >= 0)

    {

        FileWrite(handle, "0");

        FileClose(handle);

        Print("Trigger file cleared.");

    }

    else

    {

        Print("Failed to clear trigger file: ", triggerFilePath);

    }

}



void ReadAndProcessAlertFile()

{

    Print("Attempting to read alert file.");

    if (!FileExists(alertFilePath))

    {

        Print("Alert file does not exist: ", alertFilePath);

        return;

    }



    int handle = FileOpen(alertFilePath, FILE_READ | FILE_TXT);

    if (handle < 0)

    {

        int error_code = GetLastError();

        Print("Failed to open file for reading: ", alertFilePath, ", error code: ", error_code);

        if (error_code == 5002)

        {

            Print("Error 5002: File access denied. Please check permissions and ensure the file is not locked by another application.");

        }

        return;

    }



    string alertContent = FileReadString(handle);

    FileClose(handle);

    Print("File read successfully, content: ", alertContent);



    ProcessAlert(alertContent);

}



void ProcessAlert(string alertContent)

{

    Print("Processing alert: ", alertContent);



    string symbol = GetJsonValue(alertContent, "symbol");

    string action = GetJsonValue(alertContent, "action");

    double entry = StringToDouble(GetJsonValue(alertContent, "entry"));

    double stop = StringToDouble(GetJsonValue(alertContent, "stop"));

    double profit_target = StringToDouble(GetJsonValue(alertContent, "profit_target"));



    if (action == "buy")

    {

        trade.Buy(1.0, symbol, entry, stop, profit_target);

        Print("Buy order placed: Symbol=", symbol, " Entry=", entry, " Stop=", stop, " Profit Target=", profit_target);

    }

    else if (action == "sell")

    {

        trade.Sell(1.0, symbol, entry, stop, profit_target);

        Print("Sell order placed: Symbol=", symbol, " Entry=", entry, " Stop=", stop, " Profit Target=", profit_target);

    }

    else

    {

        Print("Invalid action: ", action);

    }

}



string GetJsonValue(string json, string key)

{

    string result = "";

    int keyPos = StringFind(json, "\"" + key + "\"");

    if (keyPos != -1)

    {

        int valueStart = StringFind(json, ":", keyPos) + 1;

        int valueEnd = StringFind(json, ",", valueStart);

        if (valueEnd == -1) // Last item, no comma

        {

            valueEnd = StringFind(json, "}", valueStart);

        }

        result = StringTrim(StringSubstr(json, valueStart, valueEnd - valueStart));

        result = StringTrim(result, "\"");

    }

    return result;

}



string StringTrim(string str, string chars = " \t\n\r")

{

    int start = 0;

    int end = StringLen(str) - 1;



    while (start <= end && StringFind(chars, StringSubstr(str, start, 1)) != -1)

    {

        start++;

    }



    while (end >= start && StringFind(chars, StringSubstr(str, end, 1)) != -1)

    {

        end--;

    }



    return StringSubstr(str, start, end - start + 1);

}



bool FileExists(string filename)

{

    int handle = FileOpen(filename, FILE_READ | FILE_TXT);

    if (handle < 0)

    {

        return false;

    }

    FileClose(handle);

    return true;

}


Request for Assistance:

  • File Access Issues: Any advice on how to resolve the file access error (error code 5002)?
  • Trigger Handling: Suggestions on how to ensure the EA only checks for new alerts based on an HTTP request and not every second?
  • General Improvements: Any other recommendations for improving the code or handling file operations more efficiently?

Thank you in advance for your help!

Best regards,

DF (OptimalVentures)

Documentation on MQL5: Constants, Enumerations and Structures / Trade Constants / Order Properties
Documentation on MQL5: Constants, Enumerations and Structures / Trade Constants / Order Properties
  • www.mql5.com
Requests to execute trade operations are formalized as orders. Each order has a variety of properties for reading. Information on them can be...
 
Documentation on MQL5: File Functions
Documentation on MQL5: File Functions
  • www.mql5.com
This is a group of functions for working with files. For security reasons, work with files is strictly controlled in the MQL5 language. Files with...
 

Thank you!