How to Send my personal trades from mt4 to mt5

 

Hello everyone,
I intend to copy my personal trades from MetaTrader 4 to my MetaTrader 5. To achieve this, I have written two codes:

  1. The first code is for MQL4, which saves the necessary trade data in a TXT file whenever I make a trade.
  2. The second code is for MQL5, which reads the file, analyzes the trades, and executes them accordingly.

But I have encountered some issues. One of them was that the file created in MQL4 is in UTF-8, and MQL5 couldn't read it properly. So, I had to create a function in my MQL5 code to convert UTF-8 to UTF-9. For now, this part seems to be working fine, but I am facing a few other issues:

  1. If there are multiple trades in the file, only the first trade is copied.
  2. The trade keeps repeating continuously.
  3. If I modify a trade in MetaTrader 4, the modification does not reflect in MetaTrader 5.
I will place both MQL4 and MQL5 codes below. I would appreciate it if someone could provide guidance.

mql4 Code

#include <stderror.mqh>

// File name for saving
string fileName = "ActiveOrders.txt";

// Function to save trade information
void SaveActiveOrders()
{
   // Open the file for reading previous data
   int fileHandle = FileOpen(fileName, FILE_COMMON | FILE_TXT | FILE_READ);
   string ordersData = "";
   string currentLine;  // Renaming variable to avoid conflict

   // If the file is opened, read previous orders data
   if (fileHandle >= 0)
   {
      // Read all existing lines in the file
      while (!FileIsEnding(fileHandle))
      {
         currentLine = FileReadString(fileHandle);  // Using currentLine instead of line
         ordersData += currentLine + "\n";
      }
      // Close the file after reading
      FileClose(fileHandle);
   }

   // Now we need to save the open orders
   string updatedOrdersData = "";
   
   // Iterate through all open orders
   for (int i = OrdersTotal() - 1; i >= 0; i--)
   {
      if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
         // Only save open orders
         if (OrderType() == OP_BUY || OrderType() == OP_SELL)
         {
            // Retrieve required values
            string ticket = IntegerToString(OrderTicket());
            string symbol = OrderSymbol();
            double volume = OrderLots();
            double stopLoss = OrderStopLoss();
            double takeProfit = OrderTakeProfit();
            string orderType = (OrderType() == OP_BUY) ? "BUY" : "SELL";
            
            // Append order information to the new string
            string line = ticket + ";" + orderType + ";" + symbol + ";" + DoubleToString(volume, 2) + ";" + DoubleToString(stopLoss, 5) + ";" + DoubleToString(takeProfit, 5);
            updatedOrdersData += line + "\n";
         }
      }
   }

   // Now open the file and write new data into it
   fileHandle = FileOpen(fileName, FILE_COMMON | FILE_TXT | FILE_WRITE);
   
   if (fileHandle >= 0)
   {
      // Write open orders data to the file
      if (updatedOrdersData != "")  // If there is data to write
      {
         FileWriteString(fileHandle, updatedOrdersData);
      }
      // Close the file
      FileClose(fileHandle);
   }
   else
   {
      Print("Error opening file: ", GetLastError());
   }
}

// Function to check for changes in trades and save updated information
void OnTick()
{
   static datetime lastUpdate = 0;
   
   // Update time every 5 seconds
   if (TimeCurrent() - lastUpdate >= 5)
   {
      SaveActiveOrders();
      lastUpdate = TimeCurrent();
   }
}

MQL5 Code

#define FILE_NAME "ActiveOrders.txt"  // File name created in MT4
#include <trade\trade.mqh>
#include <arrays\arraylong.mqh>

CTrade trade;  // Create an object for trading operations
CArrayLong arr;  // Array to store trade tickets

datetime lastCheckTime = 0;  // Last file check time

// Function to process file data and perform operations
void ProcessFile()
{
    // Open the file as binary from the Common folder
    int fileHandle = FileOpen(FILE_NAME, FILE_READ | FILE_BIN | FILE_COMMON);
    if (fileHandle == INVALID_HANDLE)
    {
        Print("⚠ Error opening file: ", FILE_NAME);
        return;
    }

    // Read file data as binary
    uchar fileData[];
    int fileSize = FileReadArray(fileHandle, fileData);
    FileClose(fileHandle);  // Close the file after reading

    // Convert data to UTF-16
    string fileContent = UTF8ToUTF16(fileData);

    // Print file content for debugging
    Print("File content: ", fileContent);

    // Process each line of file data
    string lines[];
    StringSplit(fileContent, "\n", lines);  // Split lines

    // Process each line
    for (int i = 0; i < ArraySize(lines); i++)
    {
        string line = lines[i];
        
        // If the line is empty, continue
        if (StringLen(line) == 0)
        {
            continue;
        }

        // Split string into different parts using ';'
        string values[];
        StringSplit(line, ';', values);  // Separate values

        // Check if there are enough values
        if (ArraySize(values) < 6)
        {
            Print("Incorrect line format, skipping: ", line);
            continue;
        }

        // Extract values from the array
        string ticketStr = values[0];
        string positionTypeStr = values[1];
        string symbol = values[2];
        string volumeStr = values[3];
        string stopLossStr = values[4];
        string takeProfitStr = values[5];

        // Convert values to appropriate types
        ulong ticket = StringToInteger(ticketStr);  // Convert ticket to number
        ENUM_POSITION_TYPE positionType = (positionTypeStr == "BUY") ? POSITION_TYPE_BUY : POSITION_TYPE_SELL;
        double volume = StringToDouble(volumeStr);  // Convert volume to number
        double stopLoss = StringToDouble(stopLossStr);  // Convert stop loss to number
        double takeProfit = StringToDouble(takeProfitStr);  // Convert take profit to number

        // Validate data
        if (ticket == 0 || volume <= 0 || stopLoss < 0 || takeProfit < 0 || symbol == "")
        {
            Print("Invalid data, skipping: ", line);
            continue;  // If data is invalid, move to the next line
        }

        // Check for an existing trade with the same ticket
        bool isPositionExist = false;
        for (int j = PositionsTotal() - 1; j >= 0; j--)
        {
            CPositionInfo pos;
            if (pos.SelectByIndex(j))
            {
                if (pos.Ticket() == ticket)  // If ticket matches
                {
                    isPositionExist = true;

                    // Modify stop loss or take profit if changed
                    if (pos.StopLoss() != stopLoss || pos.TakeProfit() != takeProfit)
                    {
                        if (!trade.PositionModify(pos.Ticket(), stopLoss, takeProfit))  // Modify trade
                        {
                            Print("Error modifying trade: ", GetLastError());
                        }
                    }
                    break;
                }
            }
        }

        // If no existing trade with the given ticket is found, open a new trade
        if (!isPositionExist)
        {
            if (positionType == POSITION_TYPE_BUY)
            {
                if (!trade.Buy(volume, symbol, 0, stopLoss, takeProfit, IntegerToString(ticket)))  // Open buy trade
                {
                    Print("Error opening buy trade: ", GetLastError());
                }
            }
            else if (positionType == POSITION_TYPE_SELL)
            {
                if (!trade.Sell(volume, symbol, 0, stopLoss, takeProfit, IntegerToString(ticket)))  // Open sell trade
                {
                    Print("Error opening sell trade: ", GetLastError());
                }
            }
        }
    }
}

// Function to convert UTF-8 data to UTF-16
string UTF8ToUTF16(uchar &utf8Data[])
{
    int len = ArraySize(utf8Data);
    string result = "";
    int i = 0;

    while (i < len)
    {
        uchar byte1 = utf8Data[i];

        if (byte1 < 0x80)
        {
            // One-byte character (ASCII)
            result += CharToString(byte1);
            i++;
        }
        else if (byte1 < 0xE0)
        {
            // Two-byte character
            uchar byte2 = utf8Data[i + 1];
            result += CharToString((byte1 << 8) | byte2);
            i += 2;
        }
        else if (byte1 < 0xF0)
        {
            // Three-byte character
            uchar byte2 = utf8Data[i + 1];
            uchar byte3 = utf8Data[i + 2];
            result += CharToString((byte1 << 16) | (byte2 << 8) | byte3);
            i += 3;
        }
        else
        {
            // Four-byte character
            uchar byte2 = utf8Data[i + 1];
            uchar byte3 = utf8Data[i + 2];
            uchar byte4 = utf8Data[i + 3];
            result += CharToString((byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4);
            i += 4;
        }
    }

    return result;
}

// Function to check for changes in the file and perform operations
void OnTick()
{
    static datetime lastCheckTime = 0;
    
    // Check the file only every 10 seconds
    if (TimeCurrent() - lastCheckTime >= 10)
    {
        ProcessFile();  // Process file to copy and modify trades
        lastCheckTime = TimeCurrent();
    }
}
 

What if you write for each trade an individual file which is deleted by the mt5 app after reading?

To be faster (some msec) use the Windows functions to write and read files and a RAM-Disk.