there are no trading operations - page 6

 
If your EA has a Spread parameter in the inputs, and it is set too low, trades may not open on the other end when the file is being validated if the current spread is higher than the Spread max in your inputs. Just a thought.
 
Dominic Poirier #:

Lorentzos Roussos的线程#40 为我解决了这个问题。


他说:“卖家注意:永远不要[永远]使用MQLInfoInteger来检测您是否在测试中。”


可能这里陈述的所有验证都是真实的。但要检查的另一件事是确保不会仅通过检查市场是否开放或交易是否允许而返回

因为它们总是在 MQL5 自动测试器中:


https://www.mql5.com/en/blogs/post/686716&nbsp ;


==>

没有交易操作

此错误仅针对专家顾问。规则是:专家顾问 必须 贸易。如果您的机器人应该只在特定的交易品种时间范围内使用,那么 MetaQuotes 就是这么说的:“产品不能应用限制。所有限制都应在产品说明中标记为建议。”如果您的机器人不是按设计进行交易(例如辅助工具),请在产品属性中选择适当的类别(“实用工具”)。

出现此错误的可能原因之一是您的代码包含这样的检查:

if (! TerminalInfoInteger ( TERMINAL_TRADE_ALLOWED ))
{
   return ERROR_CODE ;
}

此类条件应伴随 IsTesting()/MQLInfoInteger(MQL_TESTER) 调用。自动测试仪未连接账户,测试仪始终被视为允许交易。正确的代码应该是:

if (! TerminalInfoInteger ( TERMINAL_TRADE_ALLOWED ) && !  MQLInfoInteger ( MQL_TESTER ))
{
   return  ERROR_CODE;
}


我的具体检查如下:


if(!IsMarketOpened()) 返回;


改变了


if(!IsMarketOpened() && ! MQLInfoInteger ( MQL_TESTER ) ) 返回;


这解决了我使用 MQL5 自动测试仪的问题。

谢谢你的帮助,你的方法奏效了,解决了我的问题,再次非常感谢!

 

hi everybody., It is the first time that I write in this forum and I hope to contribute my small grain of sand. I have had the same problem that is commented here when publishing the EA on the platform and the only way to solve it has been changing the lot from 0.1 to 0.20, after doing that the EA has been automatically validated by the system.


Best Regards

 
Juan Manuel Mendez Rodriguez #:

hi everybody., It is the first time that I write in this forum and I hope to contribute my small grain of sand. I have had the same problem that is commented here when publishing the EA on the platform and the only way to solve it has been changing the lot from 0.1 to 0.20, after doing that the EA has been automatically validated by the system.


Best Regards

You're right. It seems that the "automatic validation " uses the minimum lot size of 0.2 (at least for now, they might change it).
To be honest, I think it's really bad and I hope they change it to 0.01. These constraints force the developers to implement an automatic conversion to the minimum allowed lot size.
You might ask - so, what is wrong with this? Well, if the client didn't know that the minimum lot is 0.1 instead of the default of 0.01, he'll risk 10x the money! You might say "it's client's responsibility to know these things". Well, I'd say it's the dev's responsibility to make sure the EA follows its input parameters. If it says 0.01, the EA should either use 0.01 lot, or not trade at all. It's safe this way. Yet, the "automatic validation" won't allow such safe EAs to be published.

 

Hello guys,

I'm having the same problem when trying to validate my EA.
So I made a very simple EA, trying to understand what's wrong. And still doesn't work.

Thanks in advance for your help.

//+------------------------------------------------------------------+
//|                                              OfirBasicTrader.mq4 |
//|                                      Copyright 2022, Gad Benisty |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2022, Gad Benisty"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

string OPRX              = ".";
color clrBack=clrWhite;
color clrFont=clrBlack;
color clrBorder= C'255,151,25';/*Panel Border*/
color clrBuy=clrLightBlue;
color clrSell=clrTomato;
color clrDlg=clrWhite;
string FontType = "Calibri";
string bFontType = "Arial Black";
int FontSize = 13;
int sFontSize = 9;
int mFontSize = 11;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- create timer
   EventSetTimer(60);
   DashBoard();
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- destroy timer
   EventKillTimer();

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---

  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
//---

  }
//+------------------------------------------------------------------+
void DashBoard()
  {
   string cb=__FUNCTION__;
   bool rebuild=(ObjectFind(0,OPRX+"BOX")<0);
   int w=300,h=180,h2=100;
   int _x1                       = (int)ChartGetInteger(0,CHART_WIDTH_IN_PIXELS)-w-0;
   int _y1                       = 10;

   int x1=_x1+5;
   int x2;
   int y1=_y1+20;
   color clrBtn=clrBack;
   color clrText=clrFont;
   int hbutton=27;
   ButtonCreate(0,OPRX+"BtnBuy",0,x2+5,y1-5,90,hbutton,CORNER_LEFT_UPPER,"BUY",FontType,FontSize,clrFont,clrBtn,clrNONE,false,false,false,true,1,"Indicator buffers");
//ButtonCreate(0,OPRX+"BtnBufferSell",0,x2+125,y1-5,90,hbutton,CORNER_LEFT_UPPER,StringConcatenateV4((jSet["sellbuffer"].i()==-1)?"Sell not set":("Sell="+(string)jSet["sellbuffer"].i())),FontType,FontSize,clrFont,clrTab,clrNONE,false,false,false,true,1,"Indicator buffers");

  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
   if(sparam==OPRX+"BtnBuy")
     {
      DoTrade(OP_BUY);
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
long DoTrade(int type)
  {
   double volume=0.01;
   double price=getMP(type,Symbol());
   int slippage=5;
   double stoploss=0;
   double takeprofit=0;
   string comment="";
   long ticket=0;
   if(!CheckMoneyForTrade(Symbol(),volume,type))
      return(0);
   string desc="";
   if(!CheckVolumeValue(volume,desc))
      return(0);
   if(!IsNewOrderAllowed()) return(0);
   ticket=OrderSend(Symbol(),type,volume,price,slippage,stoploss,takeprofit,comment,0);
   return(ticket);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double getMP(int type,string symb)
  {
   SymbolSelect(symb,true);
   if(type==-1)
      return((MarketInfo(symb,MODE_ASK)+MarketInfo(symb,MODE_BID))/2);
   return(((isOdd(type))?MarketInfo(symb,MODE_ASK):MarketInfo(symb,MODE_BID)));
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool isOdd(double n)
  {
   return((n/2)==(int)(n/2));
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool ButtonCreate(const long              chart_ID=0,               // chart's ID
                  const string            name="Button",            // button name
                  const int               sub_window=0,             // subwindow index
                  const int               x=0,                      // X coordinate
                  const int               y=0,                      // Y coordinate
                  const int               width=50,                 // button width
                  const int               height=18,                // button height
                  const ENUM_BASE_CORNER  corner=CORNER_LEFT_UPPER, // chart corner for anchoring
                  const string            text="Button",            // text
                  const string            font="Arial",             // font
                  const int               font_size=10,             // font size
                  const color             clr=clrBlack,             // text color
                  const color             back_clr=C'236,233,216',  // background color
                  const color             border_clr=clrNONE,       // border color
                  const bool              state=false,              // pressed/released
                  const bool              back=false,               // in the background
                  const bool              selection=false,          // highlight to move
                  const bool              hidden=true,              // hidden in the object list
                  const long              z_order=0,                // priority for mouse click
                  const string            tooltip="")             // tooltip for mouse hover
  {
//--- reset the error value
   ResetLastError();
   ObjectDelete(chart_ID,name);
//---
   if(ObjectFind(chart_ID,name)!=0)
     {
      if(!ObjectCreate(chart_ID,name,OBJ_BUTTON,sub_window,0,0))
        {
         Print(__FUNCTION__,
               ": failed to create the button! Error code = ",_LastError);
         return(false);
        }
      //--- SetObjects
      ObjectSetInteger(chart_ID,name,OBJPROP_XDISTANCE,x);
      ObjectSetInteger(chart_ID,name,OBJPROP_YDISTANCE,y);
      ObjectSetInteger(chart_ID,name,OBJPROP_XSIZE,width);
      ObjectSetInteger(chart_ID,name,OBJPROP_YSIZE,height);
      ObjectSetInteger(chart_ID,name,OBJPROP_CORNER,corner);
      ObjectSetString(chart_ID,name,OBJPROP_TEXT,text);
      ObjectSetString(chart_ID,name,OBJPROP_FONT,font);
      ObjectSetInteger(chart_ID,name,OBJPROP_FONTSIZE,font_size);
      ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
      ObjectSetInteger(chart_ID,name,OBJPROP_BGCOLOR,back_clr);
      ObjectSetInteger(chart_ID,name,OBJPROP_BORDER_COLOR,border_clr);
      ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
      ObjectSetInteger(chart_ID,name,OBJPROP_STATE,state);
      ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
      ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
      ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
      ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
      ObjectSetString(chart_ID,name,OBJPROP_TOOLTIP,tooltip);
     }
//---
   return(true);
  }
//+------------------------------------------------------------------+
#ifdef __MQL4__
bool CheckMoneyForTrade(string symb, double lots,int type)
  {
   double free_margin=AccountFreeMarginCheck(symb,type, lots);
   //-- if there is not enough money
   if(free_margin<0)
     {
      string oper=(type==OP_BUY)? "Buy":"Sell";
      Print("Not enough money for ", oper," ",lots, " ", symb, " Error code=",GetLastError());
      return(false);
     }
   //--- checking successful
   return(true);
  }
#else
bool CheckMoneyForTrade(string symb,double lots,ENUM_ORDER_TYPE type)
  {
//--- Getting the opening price
   MqlTick mqltick;
   SymbolInfoTick(symb,mqltick);
   double price=mqltick.ask;
   if(type==ORDER_TYPE_SELL)
      price=mqltick.bid;
//--- values of the required and free margin
   double margin,free_margin=AccountInfoDouble(ACCOUNT_MARGIN_FREE);
   //--- call of the checking function
   if(!OrderCalcMargin(type,symb,lots,price,margin))
     {
      //--- something went wrong, report and return false
      Print("Error in ",__FUNCTION__," code=",GetLastError());
      return(false);
     }
   //--- if there are insufficient funds to perform the operation
   if(margin>free_margin)
     {
      //--- report the error and return false
      Print("Not enough money for ",EnumToString(type)," ",lots," ",symb," Error code=",GetLastError());
      return(false);
     }
//--- checking successful
   return(true);
  }
#endif
bool CheckVolumeValue(double volume,string &description)
  {
//--- minimal allowed volume for trade operations
   double min_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MIN);
   if(volume<min_volume)
     {
      description=StringFormat("Volume is less than the minimal allowed SYMBOL_VOLUME_MIN=%.2f",min_volume);
      return(false);
     }

//--- maximal allowed volume of trade operations
   double max_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MAX);
   if(volume>max_volume)
     {
      description=StringFormat("Volume is greater than the maximal allowed SYMBOL_VOLUME_MAX=%.2f",max_volume);
      return(false);
     }

//--- get minimal step of volume changing
   double volume_step=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_STEP);

   int ratio=(int)MathRound(volume/volume_step);
   if(MathAbs(ratio*volume_step-volume)>0.0000001)
     {
      description=StringFormat("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);
     }
   description="Correct volume value";
   return(true);
  }
bool IsNewOrderAllowed()
  {
//--- get the number of pending orders allowed on the account
   int max_allowed_orders=(int)AccountInfoInteger(ACCOUNT_LIMIT_ORDERS);

//--- if there is no limitation, return true; you can send an order
   if(max_allowed_orders==0) return(true);

//--- if we passed to this line, then there is a limitation; find out how many orders are already placed
   int orders=OrdersTotal();

//--- return the result of comparing
   return(orders<max_allowed_orders);
  }
Découvrez de nouvelles opportunités MetaTrader 5 avec la communauté et les services MQL5
Découvrez de nouvelles opportunités MetaTrader 5 avec la communauté et les services MQL5
  • 2022.06.21
  • www.mql5.com
MQL5 : langage de stratégies de trading intégré à la plateforme de trading MetaTrader 5, permet d'écrire vos propres robots de trading, indicateurs techniques, scripts et bibliothèques de fonctions
 
I just met this problem in my first ever EA submission. After adding the volume check as people mentioned above, and converting the decimals into _Point. My EA finally passed the validation.
 
Alexandru Casian #:

You're right. It seems that the "automatic validation " uses the minimum lot size of 0.2 (at least for now, they might change it).
To be honest, I think it's really bad and I hope they change it to 0.01. These constraints force the developers to implement an automatic conversion to the minimum allowed lot size.
You might ask - so, what is wrong with this? Well, if the client didn't know that the minimum lot is 0.1 instead of the default of 0.01, he'll risk 10x the money! You might say "it's client's responsibility to know these things". Well, I'd say it's the dev's responsibility to make sure the EA follows its input parameters. If it says 0.01, the EA should either use 0.01 lot, or not trade at all. It's safe this way. Yet, the "automatic validation" won't allow such safe EAs to be published.

I made that recommendation, and it worked for me to finally upload a new version of my EA.

Thank you very much!

But for that I put this code in the EA, so that in the Test it uses the 0.20 lot.

   if(IsTesting())
      LoteInicial = 0.20;
 

Hi  Rio Purwanggono:

Your suggestion worked like a charm!

Made the code changes you suggested and this time validation passed!

Thank you so much!

Best regards,
Abhi

 
Juan Manuel Mendez Rodriguez #:

hi everybody., It is the first time that I write in this forum and I hope to contribute my small grain of sand. I have had the same problem that is commented here when publishing the EA on the platform and the only way to solve it has been changing the lot from 0.1 to 0.20, after doing that the EA has been automatically validated by the system.


Best Regards

This is the solution that worked for me after trying everything else......................simply changed the lot size to 0.2

Thanks Juan

 

mt4 product validation failed , no trading operations

you can use the following include for opening market orders (not pending) , it passes validation . 

 THIS LIBRARY VERSION IS ONLY FOR MARKET ORDERS BUY/SELL , NOT LIMIT ORDERS
   example of a trade call
   0.you have included this mqh into your code
   a.you define a local result receiver trade_result
   b.and you call the SafeMarketTrade with its parameters 

   trade_result result=SafeMarketTrade(OP_BUY,0.01,10,false,10,false,false,1.5,10,333,1000,23,NULL,clrBlue);
      //if the trade succeeds result.success will be true
           if(result.success==true)
             {
             //the ticket is stored here
               result.ticket;
             //the open price 
               result.open_price
             //the sl and tp
               result.stop_loss
               result.take_profit
             //the lots opened 
               result.lots
             //the margin used
               result.margin_used
             //the time of open
               result.open_time
             //how many tries it took
               result.attempts
             //the time in milliseconds it took to open
               result.time_to_open_ms
             //the slippage you got in points
               result.slippage
             //and the spread 
               result.spread (in price not in points)
             }
      else if(result.success==false)
             {
             Print(result.error_message);
             }

<!>Note the Volume Limit per asset is flawed but it works . 
    Normally the broker provides a limit per market order direction (Long or Short) and
    not as the sum of all trades of the asset .
Files:
Reason: