How to resolve "no trading operations" validation failure?

 
I tried updating the MT4 version of the EA that was listed on MQL5, but it kept failing validation with a "no trading operations" message.



I tested it by:
1. Re-uploading the old EA that had passed validation and was already listed.
2. Creating a simple EA that ensured "trading operations" for various pairs and various time frames (from M1 to Daily).

The result was the same: the EA failed validation and continued to display the "no trading operations" message.
Below, I've included the code for the simple EA I used for testing. I'd like to ask my fellow admins and more experienced coders to help me identify the error in the code that causes validation to fail and always display the "no trading operations" message.

Thank you in advance.

//+------------------------------------------------------------------+
//|                                                    MinimalEA.mq4 |
//|                                       Copyright 2026, Test26.com |
//|                                           https://www.Test26.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, Test26.com"
#property link      "https://www.Test26.com"
#property version   "2.03"
#property strict
#define   EAName       "EA_Test_V2"
#property description   EAName
//---------------------------------------------------------
input int      Mgc   = 12345;//Magic Number
input double   Lots  = 0.01;
input double   TP    = 400;
input double   SL    = 200;

int Cb = _Digits==3?10:1;//Calibration for 3 Digits Price
string   myDes = "";//Volume Value Description
//+------------------------------------------------------------------+
//| Expert initialization & deinitialization function                |
//+------------------------------------------------------------------+
int  OnInit(){
if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED)) return(INIT_FAILED);
                                                 return(INIT_SUCCEEDED);
}
//-------------------------------
void OnDeinit(const int reason){}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick(){
//----------------------------- check everything -----
if(Bars<100 || !TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) || OrdersTotal()>0 ||
                  !CheckMoneyForTrade(_Symbol,Lots,OP_BUY)  ||
                  !CheckMoneyForTrade(_Symbol,Lots,OP_SELL) ||
                  !CheckVolumeValue(Lots,myDes)){Print(myDes); return;
}
//------------------------------------ BUY -----------------------
if(OrderSend(_Symbol,OP_BUY,Lots,Ask,3,SL==0?0:Ask-SL*_Point*Cb,//Set SL Value
                                       TP==0?0:Ask+TP*_Point*Cb,//Set TP Value
                                       "",Mgc,0,Lime)!=-1)      //Return Value
                                       Print("New Position Opened");
                                       else Print("Error ",GetLastError());
//------------------------------------ SELL ----------------------
if(OrderSend(_Symbol,OP_SELL,Lots,Bid,3,SL==0?0:Bid+SL*_Point*Cb,//Set SL Value
                                        TP==0?0:Bid-TP*_Point*Cb,//Set TP Value
                                        "",Mgc,0,Red)!=-1)       //Return Value
                                        Print("New Position Opened");
                                        else Print("Error ",GetLastError());
}
//+------------------------------------------------------------------+
//| Check the correctness of the order volume                        |
//+------------------------------------------------------------------+
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); }
//+------------------------------------------------------------------+
//| Check sufficient funds to perform trade operation                |
//+------------------------------------------------------------------+
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); }
//------------------------------------- Test26.com 19/06/2026 -----------------------------




 

You've set a fixed lot size of 0.01, but if the trading account doesn't accept this micro-lot, the EA simply won't open a position. This needs improvement. I did a very basic implementation in your code just to confirm this theory, and the EA passed the automatic validation:

//+------------------------------------------------------------------+
//|                                                    MinimalEA.mq4 |
//|                                       Copyright 2026, Test26.com |
//|                                           https://www.Test26.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, Test26.com"
#property link      "https://www.Test26.com"
#property version   "2.03"
#property strict
#define   EAName       "EA_Test_V2"
#property description   EAName
//---------------------------------------------------------
input int      Mgc   = 12345;//Magic Number
input double   Lots  = 0.01;
input double   TP    = 400;
input double   SL    = 200;

int Cb = _Digits==3?10:1;//Calibration for 3 Digits Price
string   myDes = "";//Volume Value Description
double g_lot = Lots;
//+------------------------------------------------------------------+
//| Expert initialization & deinitialization function                |
//+------------------------------------------------------------------+
int  OnInit()
  {
   if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
      return(INIT_FAILED);
   return(INIT_SUCCEEDED);
  }
//-------------------------------
void OnDeinit(const int reason) {}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//----------------------------- check everything -----
   if(Bars<100 || !TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) || OrdersTotal()>0 ||
      !CheckMoneyForTrade(_Symbol,g_lot,OP_BUY)  ||
      !CheckMoneyForTrade(_Symbol,g_lot,OP_SELL) ||
      !CheckVolumeValue(g_lot,myDes))
     {
      Print(myDes);
      return;
     }
//------------------------------------ BUY -----------------------
   if(OrderSend(_Symbol,OP_BUY,g_lot,Ask,3,SL==0?0:Ask-SL*_Point*Cb,//Set SL Value
                TP==0?0:Ask+TP*_Point*Cb,//Set TP Value
                "",Mgc,0,Lime)!=-1)      //Return Value
      Print("New Position Opened");
   else
      Print("Error ",GetLastError());
//------------------------------------ SELL ----------------------
   if(OrderSend(_Symbol,OP_SELL,g_lot,Bid,3,SL==0?0:Bid+SL*_Point*Cb,//Set SL Value
                TP==0?0:Bid-TP*_Point*Cb,//Set TP Value
                "",Mgc,0,Red)!=-1)       //Return Value
      Print("New Position Opened");
   else
      Print("Error ",GetLastError());
  }
//+------------------------------------------------------------------+
//| Check the correctness of the order volume                        |
//+------------------------------------------------------------------+
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);
      volume = min_volume;
      return(true);
     }
//--- 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);
      volume = max_volume;
      return(true);
     }
//--- 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);
  }
//+------------------------------------------------------------------+
//| Check sufficient funds to perform trade operation                |
//+------------------------------------------------------------------+
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);
  }
//------------------------------------- Test26.com 19/06/2026 -----------------------------
//+------------------------------------------------------------------+


But please, this was just a test example, don't take it seriously. 😁 See the following code for how to properly validate the volume (and other important validations):

Code Base

V1N1 LONNY MT4

Vinicius Pereira De Oliveira, 2017.01.25 09:12

Asian Range Breakout day-trading EA. Multi-symbol, M15/M30/H1. Places pending stop orders during the London session outside the pre-London Asian range, using PSAR + MACD + Stochastic signals, with automatic London/NY DST handling, structural stops, trailing and break-even.

 
Vinicius Pereira De Oliveira #:

You've set a fixed lot size of 0.01, but if the trading account doesn't accept this micro-lot, the EA simply won't open a position. This needs improvement. I did a very basic implementation in your code just to confirm this theory, and the EA passed the automatic validation:


But please, this was just a test example, don't take it seriously. 😁 See the following code for how to properly validate the volume (and other important validations):




Thank you for your reply and answer to my question.
I've modified the EA and re-uploaded it as per your suggestion, but the result is always the same: validation failed, with a "no trading operations" notification.

I've also tried using your EA (just for validation testing), and the result is the same: validation failed, with the same notification.

Nevertheless, I still appreciate your reply, and thank you again.
 
Nino Guevara Ruwano #Thank you for your reply and answer to my question. I've modified the EA and re-uploaded it as per your suggestion, but the result is always the same: validation failed, with a "no trading operations" notification. I've also tried using your EA (just for validation testing), and the result is the same: validation failed, with the same notification. Nevertheless, I still appreciate your reply, and thank you again.
So, something strange is happening on your end, and I don't know why. Please see below:

1. Test result of your example code:




2. Test result of your example code with the edits I suggested:




3. Test result of the CodeBase code I recommended as an example, which failed for you:


 
Vinicius Pereira De Oliveira #:
1. Test result of your example code:

Thank you for your kind reply sir.
Just like you said, there is something strange is happening on my end, this what I got, please see below:

1. Test result of my example code (the first one before edited):



2. I'm using edited code, that fully copy from your answer:



3. Test result of my example code (after edited by you):



4. Test result of your recommended EA (just for testing purpose):



I really don't understand why this problem keeps happening, after I've tried various solutions to fix the problem.
Nevertheless, I still appreciate your reply, and thank you again.


 
 
Nino Guevara Ruwano #Thank you for your kind reply sir. Just like you said, there is something strange is happening on my end, this what I got, please see below: 1. Test result of my example code (the first one before edited): 2. I'm using edited code, that fully copy from your answer: 3. Test result of my example code (after edited by you): 4. Test result of your recommended EA (just for testing purpose): I really don't understand why this problem keeps happening, after I've tried various solutions to fix the problem. Nevertheless, I still appreciate your reply, and thank you again.

Okay, @Nino Guevara Ruwano, all right, we'll manage to solve this. Note that in the following test, what prevented the EA from uploading wasn't the "no trading operations" error (since it opened 312 trades in EURUSD/H1), it was "error 130" (if I read correctly):




So, with just the corrections I suggested earlier, the EA would already overcome the "no trading operations" error. What you will need to do now:

1. Based on this guideline I've given you, you will work to make your volume validation much more robust, so that the EA trades with any volume specifications from any broker/symbol;

2. You will work to include robust validation in your EA to overcome this "error 130", that is, before trying to include a new position, close or modify an existing position, perform the following check (example):

//+--------------------------------------------------------------------------------------------------------------------+
//| Validate stops level
//+--------------------------------------------------------------------------------------------------------------------+
bool CheckStopsLevel(string symbol, ENUM_ORDER_TYPE type, double sl, double tp)
  {
   if(g_cache.stopsLevel == 0)
      return true;

   RefreshRates();
   double price = (type == OP_BUY) ? MarketInfo(symbol, MODE_BID) : MarketInfo(symbol, MODE_ASK);
   double minDistance = g_cache.stopsLevel * g_cache.point;

   if(type == OP_BUY)
     {
      if(price - sl <= minDistance)
         return false;
      if(tp - price <= minDistance)
         return false;
     }
   else
     {
      if(sl - price <= minDistance)
         return false;
      if(price - tp <= minDistance)
         return false;
     }

   return true;
  }

 
Vinicius Pereira De Oliveira #:

Okay, @Nino Guevara Ruwano, all right, we'll manage to solve this. Note that in the following test, what prevented the EA from uploading wasn't the "no trading operations" error (since it opened 312 trades in EURUSD/H1), it was "error 130" (if I read correctly):




So, with just the corrections I suggested earlier, the EA would already overcome the "no trading operations" error. What you will need to do now:

1. Based on this guideline I've given you, you will work to make your volume validation much more robust, so that the EA trades with any volume specifications from any broker/symbol;

2. You will work to include robust validation in your EA to overcome this "error 130", that is, before trying to include a new position, close or modify an existing position, perform the following check (example):



Thank you for your reply.
The problem was resolved with some additional code adjustments.
I'm sharing my code and experience so that it can be useful for other members that may facing similar issues.

Here are the results of the Minimalist EA that I used for testing, which finally passed the validation process:



Here's the code that passed validation.
I've included a stop level test based on my friend De Oliveira's suggestion:

//+------------------------------------------------------------------+
//|                                                    MinimalEA.mq4 |
//|                                       Copyright 2026, Test26.com |
//|                                           https://www.Test26.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, Test26.com"
#property link      "https://www.Test26.com"
#property version   "2.03"
#property strict
#define   EAName       "EA_Test_V2"
#property description   EAName
//---------------------------------------------------------
input int      Mgc   = 12345;//Magic Number
input double   Lots  = 0.01;
input double   TP    = 50;
input double   SL    = 0;

int Cb = _Digits==3?10:1;//Calibration for 3 Digits Price
string myDes  = "";      //Volume Value Description
double myLots = Lots;    //Lots Variable
//+------------------------------------------------------------------+
//| Expert initialization & deinitialization function                |
//+------------------------------------------------------------------+
int  OnInit(){
if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED)) return(INIT_FAILED);
                                                 return(INIT_SUCCEEDED);
}
//-------------------------------
void OnDeinit(const int reason){}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick(){
if(Volume[0]>1) return;//Go trading only for first tiks of new bar
//----------------------------- check everything -----
if(Bars<100 || !TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) || OrdersTotal()>0 ||
                !CheckMoneyForTrade(_Symbol,myLots,OP_BUY)  ||
                !CheckMoneyForTrade(_Symbol,myLots,OP_SELL) ||
                !CheckVolumeValue(myLots,myDes)){Print(myDes); return;
}
long StopLevel=SymbolInfoInteger(_Symbol,SYMBOL_TRADE_STOPS_LEVEL);
double nTP=TP<StopLevel?StopLevel:TP;
double nSL=SL<StopLevel?StopLevel:SL;
//------------------------------------ BUY -----------------------
if(OrderSend(_Symbol,OP_BUY,myLots,Ask,3,SL==0?0:Ask-nSL*_Point*Cb,//Set SL Value
                                         TP==0?0:Ask+nTP*_Point*Cb,//Set TP Value
                                         "",Mgc,0,Lime)!=-1)       //Return Value
                                         Print("New Position Opened");
                                         else Print("Error ",GetLastError());
//------------------------------------ SELL ----------------------
if(OrderSend(_Symbol,OP_SELL,myLots,Bid,3,SL==0?0:Bid+nSL*_Point*Cb,//Set SL Value
                                          TP==0?0:Bid-nTP*_Point*Cb,//Set TP Value
                                          "",Mgc,0,Red)!=-1)        //Return Value
                                          Print("New Position Opened");
                                          else Print("Error ",GetLastError());
}
//+------------------------------------------------------------------+
//| Check the correctness of the order volume                        |
//+------------------------------------------------------------------+
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);
 volume = min_volume;
 return(true);}
//--- 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);
 volume = max_volume;
 return(true);}
//--- 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);}
//+------------------------------------------------------------------+
//| Check sufficient funds to perform trade operation                |
//+------------------------------------------------------------------+
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);}
//------------------------------------- Test26.com 19/06/2026 -----------------------------

Here are some important notes to keep in mind:
1. Lots must be assigned to a variable so that their values ​​can be adjusted to the minimum and maximum lots.
2. TP and SL must also be assigned to variables so that their values ​​can be adjusted to ensure they are not lower than the stop level.
3. Set the default TP value to a low value (I use 50 as the default). If this value is too high, the validation result will display "not enough money" and the validation will fail.
4. Set the default SL value to 0. As like the TP, if the SL value is set to a specific value, the validation result will display "not enough money" and the validation will fail.
5. I added "if(Volume[0]>1) return;" to the code before OrderSend so that orders are sent only at the beginning of the tick. Without this addition, the order frequency would be too high, resulting in too many open positions, so the validation result would display "not enough money" and the validation would fail. Note: This means that there is a possibility that in the future HFT type EAs will fail to be validated.

Special thanks to my friend, moderator Vinicius Pereira De Oliveira, who took the time to answer and share his experience as a useful solution.

I hope this explanation is helpful to our friends on our beloved forum.
Happy coding and happy trading, have a nice day :-)

 
The “no trading operations” validation error usually means that the EA did not open any trade during the automatic Market validation test.

It is not necessarily a trading server error. In most cases, the entry conditions are too strict, the symbol/timeframe does not produce a signal during the validation period, or the EA blocks trading because of spread, time filters, margin checks, or input parameters.

Check these points:

1. Make sure the EA can open at least one valid trade under default input parameters.
2. Do not depend on a very specific symbol, timeframe, broker suffix, or rare market condition.
3. Avoid overly strict filters during validation, such as fixed trading hours, very low spread limits, or large minimum balance requirements.
4. Always check trade result codes after Buy/Sell/OrderSend.
5. Print the exact reason when the EA skips trading.

For Market validation, the default settings should be able to produce trading activity on common symbols and standard tester conditions. If the EA only trades under rare conditions, the validator may report “no trading operations” even if the code itself has no compilation errors.
#include <Trade/Trade.mqh>
CTrade trade;

void OnTick()
{
   static bool traded = false;
   if(traded)
      return;

   if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
   {
      Print("Trading is not allowed in terminal.");
      return;
   }

   if(!MQLInfoInteger(MQL_TRADE_ALLOWED))
   {
      Print("Trading is not allowed for this program.");
      return;
   }

   double volume = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);

   if(volume <= 0.0)
   {
      Print("Invalid minimum volume for symbol: ", _Symbol);
      return;
   }

   double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);

   if(ask <= 0.0)
   {
      Print("Invalid Ask price for symbol: ", _Symbol);
      return;
   }

   if(trade.Buy(volume, _Symbol))
   {
      Print("Test trade opened successfully.");
      traded = true;
   }
   else
   {
      Print("Buy failed. Retcode: ", trade.ResultRetcode(),
            " Description: ", trade.ResultRetcodeDescription());
   }
}