Backtest too slow

Pak Hong Poon  
maybe you modify orders by tick
Rafael Magalhaes Souza  
Vladimir Karputov:
Conecte seu código MQL5. Mostre as configurações do Testadorde Estratégia MQL5 .

I did a test here by adding a reading after a new candle, but it hurts my operational. My setup needs to be updated at least every 1 minute and even I put the function for each new 1 minute candle the backtest is slow.

void OnTick()

{

   CopyRates(_Symbol,_Period,0,5,velas);}
   
    ArraySetAsSeries(velas,true);       


      if(GetData())     //Here loads the data of my indicators.

       {

          if(CheckPositionsAndOrders()) // check for open position

           {

            if( !TradeLogic() ) //Here is the function of my operational logic, that is, my setup

             {

              Print("Lógica operacional não realizada com sucesso!");

             }

           }

         }

}


GET DATA FUNCTION

bool GetData()
  {
   int barsToCopy = 5;
   int barsToCopy2 = 5; 
   
   int copied1 = CopyBuffer(ma1_handler,0,0,barsToCopy,ma1_buffer);
   int copied2 = CopyBuffer(ma2_handler,0,0,barsToCopy,ma2_buffer);
   
   int copied3 = CopyBuffer(ifr_handler,0,0,barsToCopy,ifr_buffer);
   int copied4 = (CalcMode==MODE_ATR) ? CopyBuffer(atr_handler,0,0,barsToCopy,atr_buffer) : barsToCopy;
   
   int copied5 = CopyBuffer(bb_handler,1,0,barsToCopy,bb_Cima);
   int copied6 = CopyBuffer(bb_handler,0,0,barsToCopy,bb_meio);
   int copied7 = CopyBuffer(bb_handler,2,0,barsToCopy,bb_baixo);
   
   int copied8 = CopyBuffer(hilo_handler,0,0,barsToCopy,hilo_buffer);
   
   int copied10 = CopyBuffer(SilverTrend_handler,0,0,barsToCopy2,SilverTrend_sell_buffer);
   int copied11 = CopyBuffer(SilverTrend_handler,1,0,barsToCopy2,SilverTrend_buy_buffer);
   
   int copied12 = CopyBuffer(SuperTrend_handler,0,0,barsToCopy2,SuperTrend_UP_buffer);
   int copied13 = CopyBuffer(SuperTrend_handler,1,0,barsToCopy2,SuperTrend_DOWN_buffer);
   int copied14 = CopyBuffer(SuperTrend_handler,2,0,barsToCopy2,SuperTrend_BUY_buffer);
   int copied15 = CopyBuffer(SuperTrend_handler,3,0,barsToCopy2,SuperTrend_SELL_buffer);
   
   int copied16 = CopyBuffer(Parabolic_handler,0,0,barsToCopy,Parabolic_Buffer);
   
   int copied17 = CopyBuffer(FiboCandle_handler,0,0,barsToCopy,FiboCandle_Open);
   int copied18 = CopyBuffer(FiboCandle_handler,1,0,barsToCopy,FiboCandle_High);
   int copied19 = CopyBuffer(FiboCandle_handler,2,0,barsToCopy,FiboCandle_Low);
   int copied20 = CopyBuffer(FiboCandle_handler,3,0,barsToCopy,FiboCandle_Close);
   int copied21 = CopyBuffer(FiboCandle_handler,4,0,barsToCopy,FiboCandle_Color);
   
   int copied22 = CopyBuffer(Estocastico_handler, 0, 0, barsToCopy, Estocastico_Buffer);
   int copied23 = CopyBuffer(Estocastico_handler, 1, 0, barsToCopy, EstocasticoSinal_Buffer);
   
 
   
   
   
      
   //
   if(copied1!=barsToCopy   || copied2!=barsToCopy   || copied3!=barsToCopy   || copied4!=barsToCopy   || copied5!=barsToCopy   || 
      copied6!=barsToCopy   || copied7!=barsToCopy   || copied8!=barsToCopy                            || copied10!=barsToCopy2 || 
      copied11!=barsToCopy2 || copied12!=barsToCopy2 || copied13!=barsToCopy2 || copied14!=barsToCopy2 || copied15!=barsToCopy2 ||
      copied16!=barsToCopy  || copied17!=barsToCopy  || copied18!=barsToCopy  || copied19!=barsToCopy  || copied20!=barsToCopy  ||
      copied21!=barsToCopy  || copied22!=barsToCopy  || copied23!=barsToCopy )
     {
      Print("ERRO -> Dados de indicadores não foram copiados corretamente");
      return(false);
     }
   
   //
   if( !SymbolInfoTick(_Symbol,tick) )
     {
      Print("ERRO -> Dados de ticks não foram copiados corretamente");
      return(false);
     }
   
   //
   return(true);
  }


FUNCTION CHECKS POSITION

// 2) CheckPositionsAndOrders() -> função para verificação de ordens e posições
bool CheckPositionsAndOrders()
  {
   // variáveis para controle de posições
   comprado = false;
   vendido  = false;
   ticketComprado = 0;
   ticketVendido = 0;
   
   // variáveis para controle de ordens
   compraPendente = false;
   vendaPendente = false;
   ticketCompraPendente = 0;
   ticketVendaPendente = 0;
   
   //+------------------------------------------------------------------+
   //| LOOP NAS POSIÇÕES                                                |
   //+------------------------------------------------------------------+
   // caso não tenha posição -> compra a mercado
   int positionsTotal = PositionsTotal();
   for(int i=0;i<positionsTotal;i++)
     {
      ulong posTicket = PositionGetTicket(i);
      //
      if(PositionSelectByTicket(posTicket))
        {
         ulong posMagic = PositionGetInteger(POSITION_MAGIC);
         string posSymbol = PositionGetString(POSITION_SYMBOL);
         ENUM_POSITION_TYPE posType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
         
         // já tenho posição com meu magic number
         if(posSymbol==_Symbol && posMagic==MagicNumber)
           {
            if(posType==POSITION_TYPE_BUY)
              {
               comprado = true;
               ticketComprado = posTicket;
              }
            //
            if(posType==POSITION_TYPE_SELL)
              {
               vendido  = true;
               ticketVendido = posTicket;
              }
           }
        }
      else
        {
         Print("ERRO -> Posição não selecionada com sucesso");
         return(false);
        }
     }
   
   //+------------------------------------------------------------------+
   //| LOOP NAS ORDENS                                                  |
   //+------------------------------------------------------------------+
   int ordersTotal = OrdersTotal();
   for(int i=0;i<ordersTotal;i++)
     {
      ulong orderTicket = OrderGetTicket(i);
      
      // caso a ordem tenha sido selecionada com sucesso
      if(OrderSelect(orderTicket))
        {
         ulong orderMagic = OrderGetInteger(ORDER_MAGIC);
         string orderSymbol = OrderGetString(ORDER_SYMBOL);
         ENUM_ORDER_TYPE orderType = (ENUM_ORDER_TYPE)OrderGetInteger(ORDER_TYPE);
         
         //
         if(orderSymbol==_Symbol && orderMagic==MagicNumber)
           {
            if(orderType==ORDER_TYPE_BUY_LIMIT)
              {
               compraPendente = true;
               ticketCompraPendente = orderTicket;
              }
            if(orderType==ORDER_TYPE_SELL_LIMIT)
              {
               vendaPendente = true;
               ticketVendaPendente = orderTicket;
              }
           }
        }
      else
        {
         Print("ERRO -> Ordem não selecionada com sucesso");
         return(false);
        }
     }
   
   // returna verdadeiro depois de atualizadas as variáveis de controle
   return(true);
  }


TRADE LOGIC FUNCTION

bool TradeLogic()
  {
   
   sinalCompra  = false;
   sinalVenda   = false;
   filtroCompra = false;
   filtroVenda  = false;
   Indicador1_compra   = false;
   Indicador1_venda    = false;
   Indicador2_compra   = false;
   Indicador2_venda    = false;

  
      Painel();
      
        if(Funcao_Janeiro(TimeCurrent())   != Janeiro)
        {
        if(Funcao_Fevereiro(TimeCurrent()) != Fevereiro)
        {
        if(Funcao_Marco(TimeCurrent())     != Marco)
        {
        if(Funcao_Abril(TimeCurrent())     != Abril)
        {
        if(Funcao_Maio(TimeCurrent())      != Maio)
        {
        if(Funcao_Junho(TimeCurrent())     != Junho)
        {
        if(Funcao_Julho(TimeCurrent())     != Julho)
        {
        if(Funcao_Agosto(TimeCurrent())    != Agosto)
        {
        if(Funcao_Setembro(TimeCurrent())  != Setembro)
        {
        if(Funcao_Outubro(TimeCurrent())   != Outubro)
        {
        if(Funcao_Novembro(TimeCurrent())  != Novembro)
        {
        if(Funcao_Dezembro(TimeCurrent())  != Dezembro)
        {
        //-------------------------------------
        if(Funcao_Segunda(TimeCurrent())   != Segunda)
        {
        if(Funcao_Terca(TimeCurrent())     != Terca)
        {
        if(Funcao_Quarta(TimeCurrent())    != Quarta)
        {
        if(Funcao_Quinta(TimeCurrent())    != Quinta)
        {
        if(Funcao_Sexta(TimeCurrent())     != Sexta)
        {
         //----------------------------------------------
            if(Limite_TakeProfit(LimiteTake)==false)
              {
               if(Limite_StopLoss(LimiteLoss)==false)
                 {
                  if(Limite_Operacoes(LimiteOp)==false)
                    {
                      if(CheckTradePause(1, MagicNumber))
                      {
                  
      
                        ////////////////////////////////////////////////////////////////////////////
                        ////+------------------------------------------------------------------+////
                        ////|                                                                  |////
                        ////|                         INDICADORES                              |////
                        ////|                                                                  |////
                        ////+------------------------------------------------------------------+////
                        ////////////////////////////////////////////////////////////////////////////
    
      
//------------------------ BANDA DE BOLLINGER ------------------------------------
           
      // ROMPIMENTO BANDA DE BOLLINGER - PARA FORA 
      if(EstrategiaBB==Rompimento)
        {
         //------ INDICADOR 1
         if(Indicador1==BandaBollinger)
           {         
            if((velas[1].close > bb_Cima[1])) 
              {Funcao_compra_1();}
           
            if((velas[1].close < bb_baixo[1])) 
              {Funcao_venda_1();} 
            }
          }
William Roeder  
Rafael Magalhães:  My setup needs to be updated at least every 1 minute and even I put the function for each new 1 minute candle the backtest is slow.
  1. You are doing all that, every tick.
  2. Test for a new M1 bar.

    For a new bar test, Bars is unreliable (a refresh/reconnect can change number of bars on chart), volume is unreliable (miss ticks), Price is unreliable (duplicate prices and The == operand. - MQL4 programming forum.) Always use time.
              New candle - MQL4 programming forum #3 (2014.04.04)

    I disagree with making a new bar function, because it can only be called once per tick. A variable can be tested multiple times.
              Running EA once at the start of each bar - MQL4 programming forum (2011.05.06)

    detecting a new bar without removing ability to detect tick in multiple timeframe - Easy Trading Strategy - MQL4 programming forum #8 (2021.08.24)

Reason: