Raphael Tunji
Raphael Tunji

Reputation: 138

How can I make two mql4 trade copier EAs on different laptops but on same wifi network communicate?

Below is Server EA that will send trades to client EA

#property strict

#define SOCKET_LIBRARY_USE_EVENTS
#include <socket-library-mt4-mt5.mqh>

input ushort   ServerPort = 6000;

#define TIMER_FREQUENCY_MS    1000

ServerSocket * glbServerSocket = NULL;

ClientSocket * glbClients[];

bool glbCreatedTimer = false;

void OnInit()
{
   if (glbServerSocket) {
      Print("Reloading EA with existing server socket");
   } else {
      // Create the server socket
      glbServerSocket = new ServerSocket(ServerPort, false);
      if (glbServerSocket.Created()) {
         Print("Server socket created");
   
         glbCreatedTimer = EventSetMillisecondTimer(TIMER_FREQUENCY_MS);
      } else {
         Print("Server socket FAILED - is the port already in use?");
      }
   }
}

void OnDeinit(const int reason)
{
   switch (reason) {
      case REASON_CHARTCHANGE:
         break;
         
      default:
         glbCreatedTimer = false;
         
         for (int i = 0; i < ArraySize(glbClients); i++) {
            delete glbClients[i];
         }
         ArrayResize(glbClients, 0);
      
         delete glbServerSocket;
         glbServerSocket = NULL;
         Print("Server socket terminated");
         break;
   }
}

void OnTimer()
{
   AcceptNewConnections();
   
   for (int i = ArraySize(glbClients) - 1; i >= 0; i--) {
      HandleSocketIncomingData(i);
   }
}

void AcceptNewConnections()
{
   ClientSocket * pNewClient = NULL;
   do {
      pNewClient = glbServerSocket.Accept();
      if (pNewClient != NULL) {
         int sz = ArraySize(glbClients);
         ArrayResize(glbClients, sz + 1);
         glbClients[sz] = pNewClient;
         Print("New client connection");
         
         pNewClient.Send("Hello\r\n");
      }
      
   } while (pNewClient != NULL);
}

void HandleSocketIncomingData(int idxClient)
{
   ClientSocket * pClient = glbClients[idxClient];

   bool bForceClose = false;
   string strCommand;
   do {
      strCommand = pClient.Receive("\r\n");
      if (strCommand == "quote") {
         //Alert("Jesus is Lord");
         string msg = "Symbol: "+ Symbol() + " Bid: " + DoubleToString(SymbolInfoDouble(Symbol(), SYMBOL_BID), Digits()) + " Ask: " + DoubleToString(SymbolInfoDouble(Symbol(), SYMBOL_ASK), Digits());
         pClient.Send(msg + "\r\n");

      } else if (strCommand == "close") {
         bForceClose = true;

      } else if (StringFind(strCommand, "FILE:") == 0) {
         string strFileData = StringSubstr(strCommand, 5);
         uchar arrBase64[];
         StringToCharArray(strFileData, arrBase64, 0, StringLen(strFileData));
         
         // Do base64 decoding on the data, converting it to the zipped data 
         uchar arrZipped[], dummyKey[];
         if (CryptDecode(CRYPT_BASE64, arrBase64, dummyKey, arrZipped)) {
            
            // Unzip the data 
            uchar arrOriginal[];
            if (CryptDecode(CRYPT_ARCH_ZIP, arrZipped, dummyKey, arrOriginal)) {
               int f = FileOpen("receive.dat", FILE_BIN | FILE_WRITE);
               if (f == INVALID_HANDLE) {
                  Print("Unable to open receive.dat for writing");
               } else {
                  FileWriteArray(f, arrOriginal);
                  FileClose(f);
                  
                  Print("Created receive.dat file");
               }
            } else {
               Print("Unzipping of file data failed");               
            }
         } else {
            Print("Decoding from base64 failed");
         }
         
      } else if (strCommand != "") {
         Print("<- ", strCommand);
      }
   } while (strCommand != "");

   if (!pClient.IsSocketConnected() || bForceClose) {
      Print("Client has disconnected");

      delete pClient;
      
      int ctClients = ArraySize(glbClients);
      for (int i = idxClient + 1; i < ctClients; i++) {
         glbClients[i - 1] = glbClients[i];
      }
      ctClients--;
      ArrayResize(glbClients, ctClients);
   }
}

void OnTick()
{
   if (!glbCreatedTimer) glbCreatedTimer = EventSetMillisecondTimer(TIMER_FREQUENCY_MS);
}

void OnChartEvent(const int id, const long& lparam, const double& dparam, const string& sparam)
{
   if (id == CHARTEVENT_KEYDOWN) {
         
      if (lparam == glbServerSocket.GetSocketHandle()) {
         Print("New server socket event - incoming connection");
         AcceptNewConnections();

      } else {
         for (int i = 0; i < ArraySize(glbClients); i++) {
            if (lparam == glbClients[i].GetSocketHandle()) {
               HandleSocketIncomingData(i);
               return;
            }
         }
        
      }
   }
}

Below is Client EA that will receive and copy trades from server EA

#property strict

#include <socket-library-mt4-mt5.mqh>

input string   Hostname = "localhost";
input ushort   ServerPort = 6000;

ClientSocket * glbClientSocket = NULL;

void OnInit() {}

void OnDeinit(const int reason)
{
   if (glbClientSocket) {
      delete glbClientSocket;
      glbClientSocket = NULL;
   }
}

void OnTick()
{
   if (!glbClientSocket) {
      glbClientSocket = new ClientSocket(Hostname, ServerPort);
      if (glbClientSocket.IsSocketConnected()) {
         Print("Client connection succeeded");
      } else {
         Print(__LINE__,": Client connection failed: Error code = ", GetLastError());
      }
  }

   if (glbClientSocket.IsSocketConnected()) {
      string strMsg ="quote\r\n";// "Symbol: " + Symbol() + " Bid: " + DoubleToString(SymbolInfoDouble(Symbol(), SYMBOL_BID), Digits()) + " Ask: " + DoubleToString(SymbolInfoDouble(Symbol(), SYMBOL_ASK), Digits()) + "\r\n";
      glbClientSocket.Send(strMsg);
      
      // Receive a message from the server
      string serverMessage = glbClientSocket.Receive("\r\n");

      // Print the server message in the client log
      if (serverMessage != "") {
         Print("Received from server: ", serverMessage);
      }
      
   } else {
      Print(__LINE__,": Client connection failed: Error code = ", GetLastError());
   }
   
   if (!glbClientSocket.IsSocketConnected()) {
      Print(__LINE__,": Client disconnected. Will retry.Error code = ", GetLastError());
      delete glbClientSocket;
      glbClientSocket = NULL;
   }
}

Let me explain what I have tried

  1. Both EA worked/communicated when attached to the same mt4 terminals (one broker mt4 terminal) but different currency chart on same laptop.
  2. Both EA worked/communicated when attached to the different mt4 terminals (mt4 of different brokers) on same laptop.
  3. Both did not work/communicate when attached to different mt4 on different laptops. server EA was on laptop A, client EA was on laptop B, but both laptops are on connected to the same WIFI network.

I tried so many things in solving this problem, I enabled File and Printer Sharing (Echo Request - ICMPv4-In) on my laptop A by doing this I was able to use command prompt (CMD) ping IPV4 address of laptop A on laptop B which confirms both laptop are the same network and can communicate but the client EA on laptop B could not still talk to/communicate with server EA that is on laptop A.

Please help me.

Upvotes: 0

Views: 37

Answers (0)

Related Questions