Why do i got "failed instant buy 0.01 XAUUSD at 1810.70 [Invalid volume]" message when doing EA validation

 

Why do i got "failed instant buy 0.01 XAUUSD at 1810.70 [Invalid volume]" message when doing EA validation ?


My product needs user to select the forex pair before it can trade.

 
Ka Yiu Wong:

Why do i got "failed instant buy 0.01 XAUUSD at 1810.70 [Invalid volume]" message when doing EA validation ?


My product needs user to select the forex pair before it can trade.

for starters, see reply i made to you previous thread.

Forum on trading, automated trading systems and testing trading strategies

Validation of EA failed before publish to Market for selling

Michael Charles Schefe, 2025.03.10 03:35

search for the rules of market products. One rule is that the product must not be limited to specific symbols.


 
Ka Yiu Wong:

Why do i got "failed instant buy 0.01 XAUUSD at 1810.70 [Invalid volume]" message when doing EA validation ?


My product needs user to select the forex pair before it can trade.

You are probably not normalizing lots in the correct way, which means you are not considering Volume MIN, Volume STEP, Volume MAX and Volume Limit.

Even if you have an input for "Static lots", which may be set by default to 0.01, you need to check this value before triggering a trade, because if on the symbol you want to trade, the Volume MIN is 0.1, your 0.01 value is invalid.
 
Ka Yiu Wong: My product needs user to select the forex pair before it can trade.

Therefor it is not an EA, it is a utility.

 
Ka Yiu Wong:

Why do i got "failed instant buy 0.01 XAUUSD at 1810.70 [Invalid volume]" message when doing EA validation ?

It is a Margin and Lot size calculation issue. Sample code given below for your verification.

#include <Trade\Trade.mqh>
CTrade trade;

// Function to adjust the lot size based on symbol settings
double FixLot(double requestedLot)
{
   double minLot  = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
   double maxLot  = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
   double lotStep = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);

   // Ensure the requested lot is not below the minimum
   double fixedLot = requestedLot < minLot ? minLot : requestedLot;
   // Adjust fixedLot to be a multiple of the lot step
   fixedLot = MathFloor(fixedLot / lotStep) * lotStep;

   // Make sure we didn't fall below the minimum or exceed maximum allowed
   if(fixedLot < minLot)
      fixedLot = minLot;
   if(fixedLot > maxLot)
      fixedLot = maxLot;

   return(fixedLot);
}

void OnTick()
{
   // Sample entry price (for a buy, use BID price)
   double entry = SymbolInfoDouble(_Symbol, SYMBOL_BID);
   // Example stop loss and take profit values (50 points away)
   double sl    = entry - 50 * _Point;
   double tp    = entry + 50 * _Point;
   
   double requestedLot = 0.01;  // The desired lot size
   double validLot = FixLot(requestedLot);
   
   // Calculate the margin required for a BUY order with the given parameters
   double marginRequired = OrderCalcMargin(ORDER_TYPE_BUY, _Symbol, validLot, entry);
   double freeMargin     = AccountInfoDouble(ACCOUNT_FREEMARGIN);
   
   // Check if the account has enough free margin
   if(marginRequired > freeMargin)
   {
      Print("Not enough free margin. Required: ", marginRequired, 
            " | Free Margin: ", freeMargin);
      return;  // Exit if margin is insufficient
   }
   
   // Attempt to place the buy order
   if(!trade.Buy(validLot, _Symbol, entry, sl, tp, NULL))
      Print("Buy order failed. Error: ", GetLastError());
   else
      Print("Buy order placed with lot size: ", validLot);
}