help with strategy tester

 
I made an EA that compiled without problems... but when I tried to test it, no sells or sales were made. How can I solve this problem?


//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"   
#property version   "1.13"

//+------------------------------------------------------------------+
//| Parâmetros de entrada                                            |
//+------------------------------------------------------------------+
input double   RiskPercent     = 5.0;     // % do saldo para risco (ajustado)
input int      TrailingHours   = 6;       // Horas para trailing stop
input double   TrailingPips    = 10.0;    // Pips para trailing
input int      MagicNumber     = 12345;   // Número mágico
input int      RSI_Upper_Level = 70;      // Nível superior do RSI
input int      RSI_Lower_Level = 30;      // Nível inferior do RSI

//+------------------------------------------------------------------+
//| Declaração global dos handles dos indicadores                    |
//+------------------------------------------------------------------+
int rsi_handle, stoch_handle, bb_handle;

//+------------------------------------------------------------------+
//| Função de inicialização do EA                                    |
//+------------------------------------------------------------------+
int OnInit()
{
   // Cria handles dos indicadores
   rsi_handle = iRSI(_Symbol, PERIOD_CURRENT, 24, PRICE_CLOSE);
   stoch_handle = iStochastic(_Symbol, PERIOD_CURRENT, 24, 24, 1, MODE_SMA, STO_LOWHIGH);
   bb_handle = iBands(_Symbol, PERIOD_CURRENT, 6, 0, 2.0, PRICE_CLOSE);

   // Verifica se os handles foram criados com sucesso
   if(rsi_handle == INVALID_HANDLE || stoch_handle == INVALID_HANDLE || bb_handle == INVALID_HANDLE)
   {
      Print("Erro ao criar indicadores!");
      return(INIT_FAILED);
   }

   // Cria objetos gráficos para os níveis do RSI
   ObjectCreate(0, "RSI Upper Level", OBJ_HLINE, 0, 0, RSI_Upper_Level);
   ObjectSetInteger(0, "RSI Upper Level", OBJPROP_COLOR, clrRed);
   ObjectSetInteger(0, "RSI Upper Level", OBJPROP_STYLE, STYLE_DOT);
   ObjectSetInteger(0, "RSI Upper Level", OBJPROP_WIDTH, 1);
   ObjectSetInteger(0, "RSI Upper Level", OBJPROP_RAY, false);
   ObjectSetString(0, "RSI Upper Level", OBJPROP_TEXT, "RSI "+IntegerToString(RSI_Upper_Level));
   
   ObjectCreate(0, "RSI Lower Level", OBJ_HLINE, 0, 0, RSI_Lower_Level);
   ObjectSetInteger(0, "RSI Lower Level", OBJPROP_COLOR, clrBlue);
   ObjectSetInteger(0, "RSI Lower Level", OBJPROP_STYLE, STYLE_DOT);
   ObjectSetInteger(0, "RSI Lower Level", OBJPROP_WIDTH, 1);
   ObjectSetInteger(0, "RSI Lower Level", OBJPROP_RAY, false);
   ObjectSetString(0, "RSI Lower Level", OBJPROP_TEXT, "RSI "+IntegerToString(RSI_Lower_Level));
   
   ChartRedraw();
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Função de desinicialização do EA                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   // Remove objetos gráficos ao desinicializar
   ObjectDelete(0, "RSI Upper Level");
   ObjectDelete(0, "RSI Lower Level");
}

//+------------------------------------------------------------------+
//| Função principal do EA                                           |
//+------------------------------------------------------------------+
void OnTick()
{
   static datetime lastBarTime = 0;
   datetime currentTime = iTime(_Symbol, PERIOD_CURRENT, 0);
   
   if(lastBarTime != currentTime)
   {
      lastBarTime = currentTime;
      CheckForSignal();
   }
   
   ManageTrailingStop();
}

//+------------------------------------------------------------------+
//| Verifica condições de entrada                                    |
//+------------------------------------------------------------------+
void CheckForSignal()
{
   double rsi_prev = 0;
   double stochK_prev = 0, stochD_prev = 0;
   double bbLower = 0, bbUpper = 0;
   
   // Arrays para armazenar os valores
   double rsi_buffer[1];
   double stochK_buffer[1], stochD_buffer[1];
   double bbLower_buffer[1], bbUpper_buffer[1];
   
   // Copia os valores dos indicadores
   if(CopyBuffer(rsi_handle, 0, 1, 1, rsi_buffer) != 1 || 
      CopyBuffer(stoch_handle, 0, 1, 1, stochK_buffer) != 1 ||
      CopyBuffer(bb_handle, 1, 0, 1, bbLower_buffer) != 1)
   {
      Print("Dados dos indicadores não disponíveis ainda.");
      return;
   }

   rsi_prev = rsi_buffer[0];
   stochK_prev = stochK_buffer[0];
   stochD_prev = CopyBuffer(stoch_handle, 1, 1, 1, stochD_buffer) == 1 ? stochD_buffer[0] : 50.0;
   bbLower = bbLower_buffer[0];
   bbUpper = CopyBuffer(bb_handle, 2, 0, 1, bbUpper_buffer) == 1 ? bbUpper_buffer[0] : 0.0;

   double currentPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);
   
   // Calcula níveis SL/TP
   double prevRange = GetYesterdayRange();
   double stopLoss = prevRange * 0.25;
   double takeProfit = prevRange;
   
   // Calcula tamanho do lote
   double lotSize = CalculateLotSize(stopLoss);
   
   if(PositionsTotal() > 0) return;
   
   // Depuração: imprime valores intermediários
   PrintFormat("Time: %s | RSI: %.2f | Stoch K: %.2f | Stoch D: %.2f | Price: %.5f | BB Lower: %.5f | BB Upper: %.5f | SL: %.5f | TP: %.5f | Lot: %.2f", 
               TimeToString(TimeCurrent()), rsi_prev, stochK_prev, stochD_prev, currentPrice, bbLower, bbUpper, stopLoss, takeProfit, lotSize);

   // Condição de COMPRA (relaxada)
   if(currentPrice < bbLower && rsi_prev > RSI_Upper_Level - 5 && stochK_prev > stochD_prev)
   {
      double sl = currentPrice - stopLoss;
      double tp = currentPrice + takeProfit;
      PlaceOrder(ORDER_TYPE_BUY, lotSize, sl, tp);
   }
   // Condição de VENDA (relaxada)
   else if(currentPrice > bbUpper && rsi_prev < RSI_Lower_Level + 5 && stochK_prev < stochD_prev)
   {
      double sl = currentPrice + stopLoss;
      double tp = currentPrice - takeProfit;
      PlaceOrder(ORDER_TYPE_SELL, lotSize, sl, tp);
   }
}

//+------------------------------------------------------------------+
//| Calcula o range do dia anterior                                  |
//+------------------------------------------------------------------+
double GetYesterdayRange()
{
   MqlRates rates[1];
   if(CopyRates(_Symbol, PERIOD_D1, 1, 1, rates) == 1)
   {
      double range = rates[0].high - rates[0].low;
      if(range <= 0)
      {
         Print("Range diário inválido (zero ou negativo): ", range);
         return 0.0001; // Valor mínimo seguro
      }
      return range;
   }
   Print("Erro ao copiar dados diários.");
   return 0.0001; // Valor mínimo seguro
}

//+------------------------------------------------------------------+
//| Calcula tamanho do lote baseado no risco                         |
//+------------------------------------------------------------------+
double CalculateLotSize(double slPoints)
{
   double accountBalance = AccountInfoDouble(ACCOUNT_BALANCE);
   double riskAmount = accountBalance * (RiskPercent / 100);
   double tickValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
   double pointValue = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
   
   if(slPoints <= 0 || tickValue == 0 || pointValue == 0)
   {
      Print("Erro no cálculo do lote: valores inválidos!");
      return 0.01; // Valor mínimo seguro
   }
   
   double lotSize = (riskAmount / (slPoints / pointValue)) / tickValue;
   return MathMax(NormalizeDouble(lotSize, 2), SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN));
}

//+------------------------------------------------------------------+
//| Executa ordens                                                  |
//+------------------------------------------------------------------+
void PlaceOrder(ENUM_ORDER_TYPE orderType, double lot, double sl, double tp)
{
   MqlTradeRequest request = {};
   MqlTradeResult result = {};
   
   request.action = TRADE_ACTION_DEAL;
   request.symbol = _Symbol;
   request.volume = lot;
   request.type = orderType;
   request.price = (orderType == ORDER_TYPE_BUY) ? SymbolInfoDouble(_Symbol, SYMBOL_ASK) : SymbolInfoDouble(_Symbol, SYMBOL_BID);
   request.sl = sl;
   request.tp = tp;
   request.deviation = 50;
   request.magic = MagicNumber;
   
   if(!OrderSend(request, result))
   {
      Print("Erro ao enviar ordem: ", GetLastError());
   }
}

//+------------------------------------------------------------------+
//| Gerencia trailing stop                                           |
//+------------------------------------------------------------------+
void ManageTrailingStop()
{
   for(int i = PositionsTotal()-1; i >= 0; i--)
   {
      ulong ticket = PositionGetTicket(i);
      if(PositionSelectByTicket(ticket) && PositionGetInteger(POSITION_MAGIC) == MagicNumber)
      {
         datetime positionTime = (datetime)PositionGetInteger(POSITION_TIME);
         datetime currentTime = TimeCurrent();
         double newSl = 0;
         double currentSl = PositionGetDouble(POSITION_SL);
         
         if(currentTime - positionTime >= TrailingHours * 3600)
         {
            if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
            {
               newSl = PositionGetDouble(POSITION_PRICE_OPEN) + TrailingPips * _Point;
               if(newSl > currentSl) ModifySL(ticket, newSl);
            }
            else if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
            {
               newSl = PositionGetDouble(POSITION_PRICE_OPEN) - TrailingPips * _Point;
               if(newSl < currentSl) ModifySL(ticket, newSl);
            }
         }
      }
   }
}

//+------------------------------------------------------------------+
//| Modifica Stop Loss                                              |
//+------------------------------------------------------------------+
void ModifySL(ulong ticket, double newSl)
{
   MqlTradeRequest request = {};
   MqlTradeResult result = {};
   
   request.action = TRADE_ACTION_SLTP;
   request.position = ticket;
   request.symbol = _Symbol;
   request.sl = newSl;
   request.tp = PositionGetDouble(POSITION_TP);
   
   if(!OrderSend(request, result))
   {
      Print("Erro ao modificar SL: ", GetLastError());
   }
}
//+------------------------------------------------------------------+
Discover new MetaTrader 5 opportunities with MQL5 community and services
Discover new MetaTrader 5 opportunities with MQL5 community and services
  • 2025.06.10
  • www.mql5.com
MQL5: language of trade strategies built-in the MetaTrader 5 Trading Platform, allows writing your own trading robots, technical indicators, scripts and libraries of functions
 
Samuel Cornelio:

please edit your msg and add your code via the CODE S button in the msg editor.

But just a quick look and i can not see any fill type which could be your issue, or if your code is done by an AI or online generator, then, there could be other issues. If this is obvious to other readers, you will not get any responses. But no one can read it if you do not use the CODE S button that formats and makes pretty colours so we can read it.

I do not see any ArrayAsSeries in your code either. And your Copy lines == 1? whats that? i imagine there is another issue. It seems that i was correct. It is made by an AI or online generator, right?
 
Samuel Cornelio:
I made an EA that compiled without problems... but when I tried to test it, no sells or sales were made. How can I solve this problem?


thanks for formatting the code. it is much easier to read, however, the issues i mention are more obvious now. If you fix those 3 issues, i think that it will work. But i wont respond after this as it is clear to me that you did not code it yourself.