MQL5 - When using Local Network Farm, OnTester() doesn't run

 

Hi,


I am in the optimisation phase on my EA.  The below code is my OnTester function which will produce a CSV file of the results which is saved to the common data folder.  This works both during single tests and optimisations.  However, it appears OnTester() doesn't run when you disable local agents and enable the Local Network Farm.  For completeness, I also ran an optimisation with both Local agents and Local Network Farm enabled and the only results that get written into the CSV file are the tests completed on the local side.  Things I've tried so far include:  
Created 2 brand new virtual machines, disabled the window firewalls on both, enabled the agents to be shared locally on one VM and installed a demo MT5 account on the other VM. Ran my test again and results are the same, only the agents which were local wrote results into the CVS file.


Please help, I'm not sure what else to try or if anyone can shed any light on the issue, I tried searching the forums but only found topics about general issues setting up the local network farm and nothing about the issue i'm facing.


Thanks for reading

double OnTester() {
   string Stat_Log;

   ENUM_TIMEFRAMES EnumPeriod = Period();
   string StrPeriod = EnumToString(EnumPeriod);
   string period = StringSubstr(StrPeriod, StringFind(StrPeriod, "_") + 1, StringLen(StrPeriod) - StringFind(StrPeriod, "_"));


   int m_filehandle = FileOpen(MQLInfoString(MQL_PROGRAM_NAME) + ".csv",FILE_WRITE|FILE_READ|FILE_CSV|FILE_COMMON);
   Stat_Log = _Symbol + "," +
              period + "," +
              DoubleToString(TesterStatistics(STAT_PROFIT_TRADES),0) + "," +
              DoubleToString(TesterStatistics(STAT_LOSS_TRADES),0) + "," +
              DoubleToString(TesterStatistics(STAT_PROFIT),2);
   if(m_filehandle!=INVALID_HANDLE) {
      FileSeek(m_filehandle,0,SEEK_SET);
      FileWriteString(m_filehandle,"SEP=,\nSymbol,Period,Wins,Losses,Profit\n");

      FileSeek(m_filehandle,0,SEEK_END);
      FileWrite(m_filehandle,Stat_Log);
      FileClose(m_filehandle);
   }

   return(0);
}
 
andreafxtrading:
Hi Jamie, 

the problem is that the FILE_COMMON flag is compatible only with local agents. 

It would be nice if MT5 tester would return an error in such a case but apparently is a silent error. 


 

Solution:  Use frames.  Ensure the correct functions are used to process the data into a frame.  Ensure correct function is used to retrieve the frame of data.  Loops through the frames at the end and write them to a CSV.  Add ExpertRemove() to end of OnTester() as a just-in-case fix for an older issue where it could miss out results.

double OnTester() {

   short SStat_Log[];
   string Stat_Log;

   ENUM_TIMEFRAMES EnumPeriod = (ENUM_TIMEFRAMES)mPeriod;
   string StrPeriod = EnumToString(EnumPeriod);
   string period = StringSubstr(StrPeriod, StringFind(StrPeriod, "_") + 1, StringLen(StrPeriod) - StringFind(StrPeriod, "_"));

   Stat_Log = _Symbol + "," +
              period + "," +
              DoubleToString(TesterStatistics(STAT_PROFIT_TRADES),0) + "," +
              DoubleToString(TesterStatistics(STAT_LOSS_TRADES),0) + "," +
              DoubleToString(TesterStatistics(STAT_PROFIT),2);

   StringToShortArray(Stat_Log,SStat_Log);

   if(!FrameAdd("Statistics",1,0,SStat_Log))
      printf("FrameAdd failed with error %i",GetLastError());

   ExpertRemove();


//ExpertRemove();

   return(0);
}

void OnTesterPass() {

   ulong pass;
   string name;
   long id;
   double value;
   ushort data[];

   if(!FrameNext(pass,name,id,value,data))
      printf("Error #%i with FrameNext",GetLastError());


}

int m_filehandle;

void OnTesterDeinit() {

   FrameFirst();

   ulong pass;
   string name;
   long id;
   double value;
   ushort data[];

   if(!FrameNext(pass,name,id,value,data))
      printf("Error #%i with FrameNext",GetLastError());

   string receivedData=ShortArrayToString(data);

   string datalog = IntegerToString(pass)+",";
   StringAdd(datalog, receivedData);

   m_filehandle = FileOpen(MQLInfoString(MQL_PROGRAM_NAME) + ".csv",FILE_CSV|FILE_READ|FILE_WRITE|FILE_ANSI|FILE_COMMON);

   if(m_filehandle==INVALID_HANDLE) {
      printf("Error %i creating tester file",GetLastError());
   } else {
      FileSeek(m_filehandle,0,SEEK_SET);
      FileWriteString(m_filehandle,"SEP=,\n#,Symbol,Period,Wins,Losses,Profit\n");

      FileSeek(m_filehandle,0,SEEK_END);
      FileWrite(m_filehandle,datalog);

      while(FrameNext(pass,name,id,value,data)) {
         receivedData=ShortArrayToString(data);
         datalog = IntegerToString(pass)+",";
         StringAdd(datalog, receivedData);
         FileSeek(m_filehandle,0,SEEK_END);
         FileWrite(m_filehandle,datalog);
      }
   }

   FileClose(m_filehandle);

}
//+------------------------------------------------------------------+
 

And a final update.  Turns out RemoveExpert() wasn't needed, however it seems to be important to use the same currency in testing as the symbol you are testing on as for some reason sometimes the exchange rate is not applied or applied incorrectly to only some of the results, making them incomparable.   Simply using the same currency as the symbol you are optimizing on solves this issue.


I think I can officially say that I'm now getting consistent reliable results for very large sets of inputs when optimizing over both local agents, remote agents (local farm or cloud) and both at the same time.  And the correct number of results are written to CSV in the common data folder.


I hope the above info helps someone at some point :)

Reason: