Demo version of EA provided mql5.com market not able to write files.

 

To whom it may concern, 

I am facing the issue that apperently demo versions of market EAs (provided via mql5.com market) are incapable of writing files to the common/agent folder. 
To demonstrate the issue I wrote an EA, which I uploaded to the market (https://www.mql5.com/en/market/product/97058).
I am not discussion an EA, this is just to demonstrate the issue. I will delete the EA from the market, after the issue has been resovled.
(I assume it is a bug, because I do not see why a demo EA should have such restrictions.)
Here a video demonstrating the issue :

 

Here the complete code:

//+------------------------------------------------------------------+
//|                                       DemoDoesNotCreateFiles.mq5 |
//|                                    Copyright 2023, Julian Jaeger |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, Julian Jaeger"
#property link      "https://www.mql5.com"
#property version   "1.00"

#include <MT4Orders.mqh>

MqlTick mqltick;
int counter = 0,slippage = 0, m_filehandle;
double AccountBalance,lotStep,_Pips,PipValue,_price,_SL,_TP,ticksize,tickvalue, Ask, _lotsize,vol, _vol;
double atr_array[];
int AtrHandle;

//+------------------------------------------------------------------+
input double RiskPercent = 1;
input double Multiplier = 1.0;//TPSL_multiplier
input string filename = "DemoFile";
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   PipValue = c_PipValue(_Pips);
   lotStep=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_STEP);
   AtrHandle=iATR(_Symbol,PERIOD_D1,7);
   ArraySetAsSeries(atr_array,true);

//---
   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
    if(isNewBar() && !IsOpen() && CheckIfMarketOpen())// && SymbolIsSynchronized(_Symbol))
      {
         SymbolInfoTick(_Symbol,mqltick);
         Ask = mqltick.ask;
         if(!TP_SL_LOT(vol,_SL,_TP))
           {
             Print("TP_SL_LOT false");
             return;
           }
         if(!CheckVolumeValue(vol,_vol))
           {
             Print("CheckVolumeValue false");
             return;
           }
         if(!EnoughMargin(_Symbol,_vol,OP_BUY, _price))
           {
             Print("EnoughMargin false");
             return;
           }
         OrderSend(_Symbol,OP_BUY,_vol,_price,slippage,_SL,_TP,"TestTrade",1);
      }
  }
//+------------------------------------------------------------------+
//| OnTester
//+------------------------------------------------------------------+
double OnTester(void)
 {
   double ret=0.0;
   short Rrow[];
   string row;
   ret = TesterStatistics(STAT_TRADES);
   
//--frames
   row = DoubleToString(ret);
   StringToShortArray(row,Rrow);
   string fram_name = "backtest" ;
   double frame_val = 0; 
   if(MQLInfoInteger(MQL_FORWARD) == 1)
        {
         fram_name = "forward";
         frame_val = 1;
        }
  if(!FrameAdd(fram_name,1,frame_val,Rrow))
  {
    printf("FrameAdd failed with error %i",GetLastError());
  }
  return(ret);
 }
//+------------------------------------------------------------------+
//| TesterDeinit function                                            |
//+------------------------------------------------------------------+
void OnTesterDeinit()
  {
//---
           FileDelete(filename+".csv",FILE_COMMON);
           
           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 = DoubleToString(value,0)+"-";
           StringAdd(datalog,receivedData);

           m_filehandle=FileOpen(filename+".csv" ,FILE_READ|FILE_WRITE|FILE_CSV|FILE_COMMON);
           if(m_filehandle==INVALID_HANDLE) 
                {
                 printf("Error %i creating tester file",GetLastError());
                }
                else
                  {
                        FileSeek(m_filehandle,0,SEEK_END);
                        FileWrite(m_filehandle,datalog);
                  } 

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

          FileClose(m_filehandle);
        }   
//+------------------------------------------------------------------+
bool CheckVolumeValue(double volume, double &c_volume)
  {
//--- minimal lotsize
   double min_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MIN);
   c_volume = volume;
   if(volume<min_volume)
     {
      c_volume=min_volume;
     }

//--- maximal lotsize
   double max_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MAX);
   if(volume>max_volume)
     {
      c_volume=max_volume;
     }

//--- step
   double volume_step=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_STEP);

   int ratio=(int)MathRound(volume/volume_step);
   if(MathAbs(ratio*volume_step-volume)>0.0000001)
     {
      PrintFormat("Volume is not a multiple of the minimal step SYMBOL_VOLUME_STEP=%.2f, the closest correct volume is %.2f",
                               volume_step,ratio*volume_step);
      return(false);
     }
   return(true);
  }
//+------------------------------------------------------------------+
bool EnoughMargin(string symb,double lots,ENUM_ORDER_TYPE type, double &price)
{
   if(!AccBalance(AccountBalance))
    {
      return(false);
    }
   SymbolInfoTick(symb,mqltick);
   price=mqltick.ask;
   if(type==ORDER_TYPE_SELL)
      {
         price=mqltick.bid;
      }
   if(price == 0)
     {
       return(false);
     }
   double margin,free_margin=AccountInfoDouble(ACCOUNT_MARGIN_FREE);
   if(!OrderCalcMargin(type,symb,lots,price,margin))
      {
         Alert("Error in ",__FUNCTION__," code=",GetLastError());
         return(false);
      }
   if(margin>free_margin)
      {
         Alert("Not enough money (max margin reached) for ",EnumToString(type)," ",lots," ",symb," Error code=",GetLastError());
         return(false);
      }
   return(true);
}
//+------------------------------------------------------------------+
        bool AccBalance(double balance)
        {
        balance = AccountInfoDouble(ACCOUNT_BALANCE);
        if(balance > 0)
          {
            return(true);
          }
        else
          {
            return(false);
          }
        }
//+------------------------------------------------------------------+
bool isNewBar()
          {
           static datetime last_time=0;
           datetime lastbar_time=(datetime)SeriesInfoInteger(_Symbol,PERIOD_H1,SERIES_LASTBAR_DATE);
           if(last_time==0)
                 {
                  last_time=lastbar_time;
                  return(false);
                 }
           if(last_time!=lastbar_time)
                 {
                  last_time=lastbar_time;
                  return(true);
                 }
           return(false);
          }
//+------------------------------------------------------------------+
bool IsOpen()
   {
      if(!OrderSelect(OrdersTotal()-1,SELECT_BY_POS))
         {
           return(false);
         }
      return(true);  
   }
//+------------------------------------------------------------------+
double c_PipValue(double &c_Pips)
{       
      ticksize=SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_SIZE);
           tickvalue=SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_VALUE);
           if (_Digits/2 == 1){c_Pips=_Point;}
           else if (_Digits / 2 != 1){c_Pips=_Point*10;}
           double adjContractSize=tickvalue/ticksize;
           return(PipValue = adjContractSize * c_Pips);
}
//+------------------------------------------------------------------+
bool CheckIfMarketOpen()
  {
          if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) && !MQLInfoInteger(MQL_TESTER))
                   {
                         return(false);
                   }
          return(true);  
  }
//+------------------------------------------------------------------+
bool TP_SL_LOT(double &LotSize, double &StopLoss, double &TakeProfit)
{
   if(!AccBalance(AccountBalance))
   {
     return(false);
   }
   //ATR
      CopyBuffer(AtrHandle,0,0,3,atr_array);
      double ATR=atr_array[1];   
      
   //TP  
      double TakeProfitPips = ATR * Multiplier / _Pips;    
   //SL   
      double StopLossPips = ATR * Multiplier / _Pips;
   //lotsize
   if(StopLossPips>0 && PipValue>0 && lotStep>0)
      {
        double Riskvalue = AccountBalance * (RiskPercent / 100);
        double CalclotSize = Riskvalue / StopLossPips / PipValue; //calculate lotSize
        double CalclotSizeFloor=MathFloor(CalclotSize/lotStep)*lotStep;
        LotSize = NormalizeDouble(CalclotSizeFloor,2);
      }
      StopLoss = MathFloor((Ask-(StopLossPips*_Pips))/ticksize)*ticksize;
      TakeProfit = MathFloor((Ask+(TakeProfitPips*_Pips))/ticksize)*ticksize;
   
   return(true);
 }
         

That is a bug right? 

Thanks for any help.

Buy the 'BugNoFilesWritten' Trading Robot (Expert Advisor) for MetaTrader 5 in MetaTrader Market
Buy the 'BugNoFilesWritten' Trading Robot (Expert Advisor) for MetaTrader 5 in MetaTrader Market
  • www.mql5.com
This EA is supposted to act as a demonstration for the following issue. Demo version of EA markets are apperently not able to create Files in the
 
Julian Jaeger: To whom it may concern,I am facing the issue that apperently demo versions of market EAs are incapable of writing files to the common/agent folder. 

To demonstrate the issue I wrote a EA, which I uploaded to the market (https://www.mql5.com/en/market/product/97058) .
I am not discussion an EA, this is just to demonstrate the issue. I will delete the EA from the market, after the issue has been resovled.
(I assume it is a bug, because I do not see why a demo EA should have such restrictions.)
Here a video demonstrating the issue : Attached the .ex5  Here the complete code: That is a bug right?  Thanks for any help.

I understand that this is an issue that you are addressing and I personally will not remove the thread, however I will be removing the ".ex5" file attachment.

Instead, please attach the full ".mq5" file for testing and not the ".ex5".

 
Here the mq5 file and the #include file.
Files:
 
Julian Jaeger: To whom it may concern, I am facing the issue that apperently demo versions of market EAs are incapable of writing files to the common/agent folder. To demonstrate the issue I wrote a EA, which I uploaded to the market (https://www.mql5.com/en/market/product/97058). I am not discussion an EA, this is just to demonstrate the issue. I will delete the EA from the market, after the issue has been resovled. (I assume it is a bug, because I do not see why a demo EA should have such restrictions.) Here a video demonstrating the issue : Here the complete code: That is a bug right? Thanks for any help.

Can you please clarify the following.

Are you saying that when downloaded as an activated product it does work correctly with the "common" folder, but not when it is downloaded as a "demo" version for running in the tester?

When you run the normal source code in the Strategy Tester, does it work as you expect?

 
Fernando Carreiro #:

Can you please clarify the following.

Are you saying that when downloaded as an activated product it does work correctly with the "common" folder, but not when it is downloaded as a "demo" version for running in the tester?

When you run the normal source code in the Strategy Tester, does it work as you expect?

Hi, 
yes I have an EA on the market, with exactly this issue. Activated product and/or source code in Strategy tester works fine. Only the Demo version provided via the mql5.com market has this issue. I was able to reproduce the issue with the EA provided here (, which I wrote to demonstrate the issue).
So yes, you understood correctly.

Best, Julian.

 

I can confirm the issue.

I ran a simple optimisation of the provided source code in the Strategy Tester and a file "DemoFile.csv" was produced in the "%APPDATA%\Roaming\MetaQuotes\Terminal\Common\Files" directory.

I then ran the exact same settings with demo version of the product, but no file was produced.

I now wonder if this is a limitation of Market products as some kind of security measure?

I say this, because I have read that "FILE_COMMON" is not supported in MQL5 Cloud testing. So maybe they applied the same condition to demo downloads.

The question remains however, does this also happen with activated products (instead of demo downloads)?

 
Julian Jaeger #: yes I have an EA on the market, with exactly this issue. Activated product and/or source code in Strategy tester works fine. Only the Demo version provided via the mql5.com market has this issue. I was able to reproduce the issue with the EA provided here (, which I wrote to demonstrate the issue). So yes, you understood correctly.

Ok, I have asked a more experienced moderator (he is currently offline) to have a look at this later and give his input.

Hopefully, he will either offer a solution or report it to the devs/admin if he concludes that it is indeed a bug.

However, even if he does report it, it may be some time before MetaQuotes addresses it.

 
Fernando Carreiro #:

Ok, I have asked a more experienced moderator (he is currently offline) to have a look at this later and give his input.

Hopefully, he will either offer a solution or report it to the devs/admin if he concludes that it is indeed a bug.

However, even if he does report it, it may be some time before MetaQuotes addresses it.

Thanks for the quick answer. I just double checked and it has nothing to do with the common folder. 
For testing I uploaded a second EA that does not write in the common folder, but in the mql5/files folder. https://www.mql5.com/en/market/product/97097
The issue persists. (Please be assured that I will delete those EAs after the issue was addressed/resolved).

By the way it is possible to write to the common folder when using the cloud with the offline version (I just checked).

So I can confirm that demo versions cannot write files, independent of using the common flag or not.

I assume it is a bug, because writing files is already in a sandbox. 

Thanks for helping! Highly appreciated.

Buy the 'BugNoFilesWrittenAgent' Trading Robot (Expert Advisor) for MetaTrader 5 in MetaTrader Market
Buy the 'BugNoFilesWrittenAgent' Trading Robot (Expert Advisor) for MetaTrader 5 in MetaTrader Market
  • www.mql5.com
This EA is supposted to act as a demonstration for the following issue. Demo version of EA markets are apperently not able to create Files in the
 

Could you tell me full path for file ?

Show Experts log messages please.

Did this message appear in the experts log ?

printf("Error %i creating tester file",GetLastError());
 
@Ilyas #: Could you tell me full path for file ? Show Experts log messages please. Did this message appear in the experts log ?

Please note that the OP has provided full source code for the test in his posts which shows the full path ...

input string filename = "DemoFile";
m_filehandle=FileOpen(filename+".csv" ,FILE_READ|FILE_WRITE|FILE_CSV|FILE_COMMON);

In my own tests, there was no error message in the log (both in normal Tester Journal log and the individual Agent logs).

EDIT: There was also no message in the Experts log either.

EDIT: And the "common" directory I was monitoring was ...

%APPDATA%\Roaming\MetaQuotes\Terminal\Common
C:\Users\F.M.I. Carreiro\AppData\Roaming\MetaQuotes\Terminal\Common
EDIT2: And to make extra sure, I also looked at the normal "MQL5\files" and "testing_agent_directory\MQL5\files" too.
 
Fernando Carreiro #:

Please note that the OP has provided full source code for the test in his posts which shows the full path ...

In my own tests, there was no error message in the log (both in normal Tester Journal log and the individual Agent logs).

EDIT: And the "common" directory I was monitoring was ...



Attached the optimization log. 
I just noticed a line that I have overlooked so far:
" Tester OnTesterInit, OnTesterPass and OnTesterDeinit skipped because 'BugNoFilesWritten' is a demo version ".

When OnTesterDeinit is skipped, then obviously the code can not work. 

But now I wonder what is the point in limiting demo versions to such a degree?. A potential customer cannot fully test an EA without OnTesterInit, OnTesterPass and OnTesterDeinit.

Regards, Julian.

Screenshot
Screenshot
  • prnt.sc
Captured with Lightshot
Files:
20230420.log  37 kb
Reason: