Discussion of article "The checks a trading robot must pass before publication in the Market"

 

New article The checks a trading robot must pass before publication in the Market has been published:

Before any product is published in the Market, it must undergo compulsory preliminary checks in order to ensure a uniform quality standard. This article considers the most frequent errors made by developers in their technical indicators and trading robots. An also shows how to self-test a product before sending it to the Market.

The strategy tester integrated into the platform allows not only to backtest trading systems, but also to identify logical and algorithmic errors made at the development stage of the trading robot. During testing, all messages about trade operations and identified errors are output to the tester Journal. It is convenient to analyze those messages in a special log Viewer, which can be called using a context menu command.

Author: MetaQuotes Software Corp.

 

In the function  

bool CheckMoneyForTrade(string symb, double lots,int type)

you have to change the free margin check function from,

double free_margin=AccountFreeMarginCheck(symb,lots,type);

to,

double free_margin=AccountFreeMarginCheck(symb,type,lots);

to let it work properly.

 
Article fixed on all languages, thank you.
 

That's an interesting article, unfortunately there are too much errors (typo or even logical errors in the proposed code), and it will probably confuse more people than help them at some points.

//+------------------------------------------------------------------+
//| Return the maximum allowed volume for an order on the symbol     |
//+------------------------------------------------------------------+
double NewOrderAllowedVolume(string symbol)
  {
   double allowed_volume=0;
//--- get the limitation on the maximal volume of an order
   double symbol_max_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MAX);
//--- get the limitation on the volume by a symbol
   double max_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_LIMIT);

//--- get the volume of the open position by a symbol
   double opened_volume=PositionVolume(symbol);
   if(opened_volume>=0)
     {
      //--- if we have exhausted the volume
      if(max_volume-opened_volume<=0)
         return(0);

      //--- volume of the open position doesn't exceed max_volume
      double orders_volume_on_symbol=PendingsVolume(symbol);
      allowed_volume=max_volume-opened_volume-orders_volume_on_symbol;
      if(allowed_volume>symbol_max_volume) allowed_volume=symbol_max_volume;
     }
   return(allowed_volume);
  }

Logical error. If there is no position yet, you still have to check the pendings volume and calculate allowed volume. This code returns allowed_volume=0 if there is no position already opened without taking pendings into account.

bool OrderModifyCheck(ulong ticket,double price,double sl,double tp)
  {
//--- select order by ticket
   if(orderinfo.Select(ticket))
     {
      //--- point size and name of the symbol, for which a pending order was placed
      string symbol=orderinfo.Symbol();
      double point=SymbolInfoDouble(symbol,SYMBOL_POINT);
      int digits=(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS);
      //--- check if there are changes in the Open price
      bool PriceOpenChanged=(MathAbs(orderinfo.PriceOpen()-price)>point);
      //--- check if there are changes in the StopLoss level
      bool StopLossChanged=(MathAbs(orderinfo.StopLoss()-sl)>point);
      //--- check if there are changes in the Takeprofit level
      bool TakeProfitChanged=(MathAbs(orderinfo.TakeProfit()-sl)>tp);
      //--- if there are any changes in levels
      if(PriceOpenChanged || StopLossChanged || TakeProfitChanged)
         return(true);  // order can be modified      
      //--- there are no changes in the Open, StopLoss and Takeprofit levels
      else
      //--- notify about the error
         PrintFormat("Order #%d already has levels of Open=%.5f SL=.5f TP=%.5f",
                     ticket,orderinfo.StopLoss(),orderinfo.TakeProfit());
     }
//--- came to the end, no changes for the order
   return(false);       // no point in modifying 
  }

An other logical error. Changing a SL/TP by 1 point is allowed. It should be >=

+ typo error, should be "-tp)>=point);"

+ missing parameter (PrintFormat has for %, but only 3 parameters are provided).

bool PositionModifyCheck(ulong ticket,double sl,double tp)

Similar error as point 2° above.

And same errors also in OrderModifyCheck() mql4 version.

Thanks for fixing these errors, please note I didn't check all the article in depth, so maybe there is more.

 

Some other comments about this article, but not related to errors this time, but more on my personal opinion :

Access violation

This error occurs when trying to address memory, the access to which is denied. In each such case, it is necessary to contact the developers via the Service Desk in your Profile or via the Contacts page.
  • Funnily enough, this has nothing to do in an article about users (coders) errors. An access violation means it's an error in Metaquotes code 

This type of errors is relatively rare, many of them have ready codes, that are designed to help in finding the cause.

Constant Value Description
ERR_INTERNAL_ERROR 4001 Unexpected internal error
ERR_WRONG_INTERNAL_PARAMETER 4002 Wrong parameter in the inner call of the client terminal function
  • Error codes are there to help, but "Unexpected internal error" is completely useless and "Wrong parameter in the inner call of the client terminal function" is really cryptic (at least to me).

Newcomers are recommended to read all the articles about error handling, as well as ask questions on the forum and in the article comments. Other more experienced members of the MQL5.community will help you figure out any unclear points. We hope that the information gathered in the article will help you create more reliable trading robots and in a shorter time.

  • I completely disagree with such practice, the Market is a commercial service proposed by Metaquotes, they should assume the support and don't rely on the community. That's not a professional approach following my view.

Despite the critics, I would like to thank Metaquotes for their great work on MT4/MT5, and encourage them to continue to increase their level of quality and professionalism.

 

Is it possible for MetaQuotes to generate a template for developers? It will make it easier for developers and also save MetaQuotes tons of money and resources on checking submitted EAs. 

‌Have the template for developer in the code base

https://www.mql5.com/en/code/mt4/experts/best‌

 
Alain Verleyen:

That's an interesting article, unfortunately there are too much errors (typo or even logical errors in the proposed code), and it will probably confuse more people than help them at some points.

//+------------------------------------------------------------------+
//| Return the maximum allowed volume for an order on the symbol     |
//+------------------------------------------------------------------+
double NewOrderAllowedVolume(string symbol)
  {
   double allowed_volume=0;
//--- get the limitation on the maximal volume of an order
   double symbol_max_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MAX);
//--- get the limitation on the volume by a symbol
   double max_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_LIMIT);

//--- get the volume of the open position by a symbol
   double opened_volume=PositionVolume(symbol);
   if(opened_volume>=0)  There is no opened positions
     {
      //--- if we have exhausted the volume
      if(max_volume-opened_volume<=0)
         return(0);

      //--- volume of the open position doesn't exceed max_volume
      double orders_volume_on_symbol=PendingsVolume(symbol);
      allowed_volume=max_volume-opened_volume-orders_volume_on_symbol;
      if(allowed_volume>symbol_max_volume) allowed_volume=symbol_max_volume;
     }
   return(allowed_volume);
  }

Logical error. If there is no position yet, you still have to check the pendings volume and calculate allowed volume. This code returns allowed_volume=0 if there is no position already opened without taking pendings into account.

Why?  In this cace we check pending orders volume too
 
Alain Verleyen:


+ missing parameter (PrintFormat has for %, but only 3 parameters are provided).

Thank you! Fixed

bool OrderModifyCheck(ulong ticket,double price,double sl,double tp)
  {
//--- select order by ticket
   if(orderinfo.Select(ticket))
     {
      //--- point size and name of the symbol, for which a pending order was placed
      string symbol=orderinfo.Symbol();
      double point=SymbolInfoDouble(symbol,SYMBOL_POINT);
      int digits=(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS);
      //--- check if there are changes in the Open price
      bool PriceOpenChanged=(MathAbs(orderinfo.PriceOpen()-price)>point);
      //--- check if there are changes in the StopLoss level
      bool StopLossChanged=(MathAbs(orderinfo.StopLoss()-sl)>point);
      //--- check if there are changes in the Takeprofit level
      bool TakeProfitChanged=(MathAbs(orderinfo.TakeProfit()-sl)>tp);
      //--- if there are any changes in levels
      if(PriceOpenChanged || StopLossChanged || TakeProfitChanged)
         return(true);  // order can be modified      
      //--- there are no changes in the Open, StopLoss and Takeprofit levels
      else
      //--- notify about the error
         PrintFormat("Order #%d already has levels of Open=%.5f SL=%.5f TP=%.5f",
                     ticket,orderinfo.PriceOpen(),orderinfo.StopLoss(),orderinfo.TakeProfit());
     }
//--- came to the end, no changes for the order
   return(false);       // no point in modifying 
  }
 
Alain Verleyen:

Similar error as point 2° above.

And same errors also in OrderModifyCheck() mql4 version.


All fixed, thank you!

 
Alain Verleyen:

bool OrderModifyCheck(ulong ticket,double price,double sl,double tp)
  {
//--- select order by ticket
   if(orderinfo.Select(ticket))
     {
      //--- point size and name of the symbol, for which a pending order was placed
      string symbol=orderinfo.Symbol();
      double point=SymbolInfoDouble(symbol,SYMBOL_POINT);
      int digits=(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS);
      //--- check if there are changes in the Open price
      bool PriceOpenChanged=(MathAbs(orderinfo.PriceOpen()-price)>point);
      //--- check if there are changes in the StopLoss level
      bool StopLossChanged=(MathAbs(orderinfo.StopLoss()-sl)>point);

An other logical error. Changing a SL/TP by 1 point is allowed. It should be >=

As far as I remember we use such practice just in order to do not get refusion from trade sercver due the price changing for the time while our trade request reaches to server

It is just more secure approach.

 
Alain Verleyen:

bool OrderModifyCheck(ulong ticket,double price,double sl,double tp)
  {
//--- select order by ticket
   if(orderinfo.Select(ticket))
     {
      //--- point size and name of the symbol, for which a pending order was placed
      string symbol=orderinfo.Symbol();
      double point=SymbolInfoDouble(symbol,SYMBOL_POINT);
      int digits=(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS);
      //--- check if there are changes in the Open price
      bool PriceOpenChanged=(MathAbs(orderinfo.PriceOpen()-price)>point);
      //--- check if there are changes in the StopLoss level
      bool StopLossChanged=(MathAbs(orderinfo.StopLoss()-sl)>point);
      //--- check if there are changes in the Takeprofit level
      bool TakeProfitChanged=(MathAbs(orderinfo.TakeProfit()-sl)>tp);
      //--- if there are any changes in levels
      if(PriceOpenChanged || StopLossChanged || TakeProfitChanged)

+ typo error, should be "-tp)>=point);"

Thank you! fixed
Reason: