EA fails to place limit orders while testing without visualization

 
I am currently testing an EA I built that places pending limit orders. Everything works fine when I test with visualization enabled, but I receive an 'invalid request' error when testing without visualization. Could this be a limitation of the tester, or is there an issue in my code that I need to address? thanks.
bool              PlaceLimitOrder(int signalType, double limitPrice)
     {
      Print("placing limit order");

      // Check if a limit order should be a buy or sell
      int orderType;
      if(signalType == SIGNAL_BUY)
        {
         orderType = ORDER_TYPE_BUY_LIMIT;
        }
      else
         if(signalType == SIGNAL_SELL)
           {
            orderType = ORDER_TYPE_SELL_LIMIT;
           }
         else
           {
            Print("Invalid signal type: ", signalType);
            return false; // Invalid signal type
           }

      // Define trade request structure
      MqlTradeRequest request;
      MqlTradeResult result;
      double stopLoss = 0;

      // Calculate stop loss based on the entry and risk percentage
      if(orderType == ORDER_TYPE_BUY_LIMIT)
        {
         stopLoss = calculateExit(ExtLevelPrices[2], ExtLevelPrices[1], limitPrice, 0.20, true);
        }
      else
         if(orderType == ORDER_TYPE_SELL_LIMIT)
           {
            stopLoss = calculateExit(ExtLevelPrices[2], ExtLevelPrices[1], limitPrice, 0.20, false);
           }
      Print("Calculated stop loss: ", stopLoss);

      // Default parameters
      double baseLotSize = 0.01; // Base lot size for scaling
      double newLotSize = 0.01;
      double slPoints = MathAbs(limitPrice - stopLoss); // Calculate SL in points
      Print("Calculated SL in points: ", slPoints);

      // Calculate the risk amount for a given lot size
      double riskAmount = calculateRiskAmount(slPoints, baseLotSize);
      Print("Risk amount: ", riskAmount);

      // Scale lot size based on max allowable risk
      int lotSizeScaling = int(maxRisk / riskAmount);
      double scaledLotSize = newLotSize * lotSizeScaling;
      Print("Scaled lot size: ", scaledLotSize);

      // Portfolio handling: ensure risk is within acceptable limits
      if(!handlePortfolio(riskAmount, scaledLotSize))
        {
         Print("Portfolio handling failed. Exiting.");
         return false;
        }

      // Initialize trade request
      request.action = TRADE_ACTION_PENDING;
      request.symbol = _Symbol;
      request.volume = scaledLotSize;
      request.price = limitPrice;
      request.type = (ENUM_ORDER_TYPE)orderType;
      request.type_filling = ORDER_FILLING_RETURN;
      request.type_time = ORDER_TIME_GTC;
      request.sl = stopLoss;
      request.deviation = 5;
      Print("Order details - Symbol: ", request.symbol, ", Volume: ", request.volume,
            ", Price: ", request.price, ", Type: ", request.type, ", Stop Loss: ", request.sl);

      // Set take profit to 0
      request.tp = 0;

      // Send trade request
      if(!OrderSend(request, result))
        {
         int errorCode = GetLastError();
         Print("OrderSend failed. Error: ", errorCode);
         return false;
        }

      // Check result of the trade operation
      if(result.retcode == TRADE_RETCODE_DONE)
        {
         Print("Limit order placed successfully. Ticket: ", result.order);
         return true;
        }
      else
        {
         Print("Order placement failed. Retcode: ", result.retcode);
         return false;
        }
     }
 
Your topic has been moved to the section: Expert Advisors and Automated Trading
Please consider which section is most appropriate — https://www.mql5.com/en/forum/172166/page6#comment_49114893
 

Are you perhaps basing your calculations on data obtained from graphical objects?

If yes, then know that graphical objects are not simulated during non-visual testing.

 
Fernando Carreiro #:

Are you perhaps basing your calculations on data obtained from graphical objects?

If yes, then know that graphical objects are not simulated during non-visual testing.

Thanks for the response, Fernando. I'm not using graphical objects in my calculations. I retrieve data like this:
      ExtCopiedData = CopyRates(symbol,
                                ExtPeriod,
                                fromTime,
                                toTime,
                                ExtChartData);

      int copiedZigzagData = CopyBuffer(ExtZigzagHandle,
                                        0,
                                        0,
                                        ExtCopiedData,
                                        ExtZigzagData);
I'm working directly with CopyRates and CopyBuffer functions for data acquisition. Could there be any specific considerations for these functions in non-visual testing that might trigger an 'invalid request' error?
 

It depends on how the Indicators are implemented.

However, even if the Indicators are the cause for miscalculations, your EA should be checking those values and preventing invalid values from being applied to the trade request.

Your code does not seem to have any checks in place for price alignment or verification of limits set in the contract specifications.

Articles

The checks a trading robot must pass before publication in the Market

MetaQuotes, 2016.08.01 09:30

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.
 
Fernando Carreiro #:

It depends on how the Indicators are implemented.

However, even if the Indicators are the cause for miscalculations, your EA should be checking those values and preventing invalid values from being applied to the trade request.

Your code does not seem to have any checks in place for price alignment or verification of limits set in the contract specifications.

Okay, I'll check it out. thanks!