CopyTicksRange() in tester

 

Testing an EA that has the following function called in OnTrade() event. The goal of the function is to find the highest Ask price for the current bar. Later I want to extend the function so I could get the Ask Price for any bar back in history and use it in an indicator

private:
   double            GetBarMaxPrice(int bar, double defaultPrice)
     {

      datetime start = iTime(GetSymb(), PERIOD_CURRENT, bar);

      MqlTick mqlTick[];
      int copiedTicks=CopyTicksRange(GetSymb(),mqlTick,COPY_TICKS_INFO,(ulong) start * 1000);
      if(copiedTicks < 0)
        {
         CErrorHandler::CheckLastError(false,GetProgramShortName()+"COrderStatus():GetMaxSpread()");
         return defaultPrice;
        }
      else
        {
         double maxAsk;
         for(int a = 0;a<copiedTicks;a++)
           {
            if(maxAsk<mqlTick[a].ask)
              {
               maxAsk=mqlTick[a].ask;
              }
           }
         Print("bar = "+(int)bar+" maxAsk = "+DoubleToString(maxAsk,5)+ " start = "+start+ " copiedTicks = "+copiedTicks);
         return maxAsk;
        }
      return defaultPrice;
     }

Having a Sell order for which stop loss is triggered. Here are the logs:

2026.01.01 20:01:08.708 2025.09.30 09:23:20   bar = 0 maxAsk = 1.17397 start = 2025.09.30 09:00:00 copiedTicks = 1365
2026.01.01 20:01:08.708 2025.09.30 09:23:20   bar = 0 maxAsk = 1.17397 Order.StopLoss = 1.174055080213903
2026.01.01 20:01:08.712 2025.09.30 09:23:20   stop loss triggered #2 sell 0.3 EURUSD 1.17206 sl: 1.17406 [#4 buy 0.3 EURUSD at 1.17406]
2026.01.01 20:01:08.713 2025.09.30 09:23:20   deal #4 buy 0.3 EURUSD at 1.17406 done (based on order #4)
2026.01.01 20:01:08.713 2025.09.30 09:23:20   deal performed [#4 buy 0.3 EURUSD at 1.17406]
2026.01.01 20:01:08.713 2025.09.30 09:23:20   order performed buy 0.3 at 1.17406 [#4 buy 0.3 EURUSD at 1.17406]
2026.01.01 20:01:08.714 2025.09.30 09:23:20   bar = 0 maxAsk = 1.17398 start = 2025.09.30 09:00:00 copiedTicks = 1366

Question: Why is the stoploss triggered at price 1.17406, yet the maxAsks for the current bar is still 1.17398? AFAIK, for sell order, the Ask price shoud be equal or higher the stop loss to trigger it?

Tested both with Modelling : Every tick based on real ticks and Every tick, same results

 
Dimitr Trifonov:
[F]or sell order, the Ask price shoud be equal or higher the stop loss to trigger it?

Yes. A stop order converts to a market order when triggered. Remember, the idea of a stop is to get out urgently. Slippage and delay can be manipulated in the Tester, of course.

In contrast, a limit order does exactly that--limit execution to at or better than... assuming that your limit order can get filled.

As Every tick based on real ticks and Every tick [generated] can't be exactly the same all of the time, I would be interested to see what happens when you demo test your code.
 

I found an Article dedicated to accurate backtesting:

"The pursuit of reliable back-test results in algorithmic trading hinges not only on robust strategy logic but also on the efficiency and precision of the underlying code. Raw code optimization and tweaking are critical to ensuring that Expert Advisors (EAs) perform as intended, minimizing computational overhead while maximizing execution accuracy. Poorly optimized code can distort back-test outcomes through delayed order execution, incorrect signal detection, or resource exhaustion—issues that mask a strategy’s true potential."

"Two MqlTick structures—`CTick` and `PTick`—are employed to track real-time price data, ensuring precision in execution timing and market condition analysis."

Articles

Raw Code Optimization and Tweaking for Improving Back-Test Results

Hlomohang John Borotho, 2025.05.09 11:55

Enhance your MQL5 code by optimizing logic, refining calculations, and reducing execution time to improve back-test accuracy. Fine-tune parameters, optimize loops, and eliminate inefficiencies for better performance.

 
Dimitr Trifonov:
int copiedTicks=CopyTicksRange(GetSymb(),mqlTick,COPY_TICKS_INFO,(ulong) start * 1000);

Did you check that you got the correct ticks for the considered bar ?

Are you this log you posted is using Every ticks (real or generated) ?