Trying to sometimes look at only closed bars, sometimes calculate every tick.

 

The expert advisor I wrote is very slow in backtesting. Therefore, I attempted to rewrite it to only look at the recent closed bar, unless one of the preconditions for trading was close to being met, in which case it would calculate every tick, as before.

Unfortunately, now the two versions produce different results. Usually the first version enters a trade slightly before the second version, though sometimes the second version enters a trade slightly sooner. This is a huge problem mostly because it means I am misunderstanding how my code runs!

Here is the main function in both versions, abbreviated to only show the important stuff:

//+------------------------------------------------------------------+
//|                                                    Two Loops.mq4 |
//|                        Copyright 2016, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+

// Declare variables

//--Main Function
void Calculate(int index) {

   if (TimeHour(Time[index]) == 22 && TimeMinute(Time[index]) == 0) {                              // New Day

      if (Time[index] != NewDayTime) {                                                             // First Bar of the day
         
         DayOpen = iOpen(Symbol(),0,0);                                                            // Daily Open
         
         //Set some things to zero
         
      } else return;

   } else {
    
      DailyHigh = MathMax(High[index],DailyHighBuffer[index+1]);
      DailyLow  = MathMin(Low[index],DailyLowBuffer[index+1]); 

      DailyHighBuffer[index] = DailyHigh;
      DailyLowBuffer[index]  = DailyLow;
    
      //--Find Spikes
      if (High[index] > DailyHighBuffer[index+1]) SpikeDown = DailyHigh;
      if (Low[index] < DailyLowBuffer[index+1]) SpikeUp = DailyLow;

      if ((iLow(NULL,0,index+1) < iLow(NULL,0,index+2)) && (iLow(NULL,0,index+1) < Low[index]) && 
         (iLow(NULL,0,index+1) < SpikeDown)) 
         SpikeDown = iLow(NULL,0,index+1);

      if ((iHigh(NULL,0,index+1) > iHigh(NULL,0,index+2)) && (iHigh(NULL,0,index+1) > High[index]) && 
         (iHigh(NULL,0,index+1) > SpikeUp)) 
         SpikeUp = iHigh(NULL,0,index+1);

   // If the distance between the DailyOpen and the DailyHigh or DailyLow is big, that is a precondition to being ready to trade.
   // More trading Logic to set ReadytoShort or ReadytoLong to true.   
   }

   //---Take available trades
   if (ReadytoShort == 1) {
      if (Bid > ShortBuffer[index]) {
      ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,3,Bid+StopLoss*Point,Bid-TakeProfit*Point,"",MAGICMA,0,Red);
      GoShort = 1;
      }
   }
   
   if (ReadytoLong == 1) {      
      if (Ask < LongBuffer[index]) {
      ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,3,Ask-StopLoss*Point,Ask+TakeProfit*Point,"",MAGICMA,0,Blue);
      GoLong = 1;
      }
   }    
   // Calculate difference between DayOpen and both DailyHigh and DailyLow
}

Here is the Ontick function in the first version:

//+------------------------------------------------------------------+
//| Expert tick function version #1                                  |
//+------------------------------------------------------------------+
void OnTick()
{
//---
int i=Bars-Counted_bars-1;           // Index of the first uncounted  
   
if (allLoaded == true || (TimeHour(Time[0]) == 22 && TimeMinute(Time[0]) == 0)) {
   
   if (!allLoaded) {
      // Initialize arrays
   }
   while(i >= 0) {                                                                                 // Loop for uncounted bars     
      if (i == 0) {
         if (Time[0] != ArrayResizeTime && allLoaded) {          
            // Advance arrays by 1
            ArrayResizeTime = Time[0];
         }
      }
      if (i < 10000) Calculate(i);
      if (i > 0) Counted_bars++;   
      i--;
   }
   allLoaded = true;
}
}

Here is the second version, which triggers calculating every tick long before either version would enter a trade:

//+------------------------------------------------------------------+
//| Expert tick function version #2                                  |
//+------------------------------------------------------------------+
void OnTick() {
//---
   int i=Bars-Counted_bars-1;                                                                     // Index of the first uncounted
   
   while(i > 0) {                                                                                 // Loop for uncounted bars
      if (i < 10000) Calculate(i);                                                                // ONLY CALCULATE ON CLOSED BARS IF THE RARE 
      Counted_bars++;                                                                             // PRECONDITION TO TRADE IS NOT MET
      i--;
   }
   if (((FarUpfromOpen != 0) || (FarDownfromOpen != 0)) &&                                        // ONLY CALCULATE ON EVERY TICK OF OPEN BAR IF ONE 
      (i == 0)) {                                                                                 // OF THE MANY PRECONDITIONS TO TRADING IS MET.
      Calculate(i);
      Counted_bars++;
   }
}

Please help me understand. The trades should be exactly the same, but they aren't. Thank you for your time.

Reason: