This code has been slowing down my strategy tester drastically

 

Any leads on how do i make this much more efficient and not make my strategy tester load slowly, i don't know where to start.

void breakEvenStopLoss(double inputAsk,double inputBid) {

   ulong inpMagic = 0;
   string inpSymbol = _Symbol;
   double orderOpenPrice = PositionGetDouble(POSITION_PRICE_OPEN);
   double orderStopLoss = PositionGetDouble(POSITION_SL);
   ulong orderTicket = PositionGetInteger(POSITION_TICKET);
   double orderTakeProfit = PositionGetDouble(POSITION_TP);
   
      for(int i=PositionsTotal()-1; i>=0; i--)
      {
         if(PositionGetTicket(i)==0) continue;
         if(PositionGetTicket(i)>0)
         {
            if(
            PositionGetString(POSITION_SYMBOL)==inpSymbol 
            && PositionGetInteger(POSITION_MAGIC)==inpMagic
            ) {
               //ORDER TYPE MUST BE THE SAME
               if ((PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)) 
               {  
                  // PRICE REACHED 1:1 MOVE SL TO BREAKEVEN     
                  if (Ask>(orderOpenPrice - orderStopLoss + orderOpenPrice) && 
                  //SINCE WE MOVE THE SL TO BREAKEVEN + ADD HALF PIP TO ACCOUNT FOR SPREAD,
                  //MEANING THIS COULD ONLY TRIGGER IF PRICE WASN'T MODIFIED YET,
                  //THUS PREVENTING ORDERMODIFY ERROR 1
                  //ORDERMODIFY ERROR 1: DOING THE SAME THING OVER & OVER AGAIN WITHOUT CHANGING ANYTHING
                  (orderStopLoss < orderOpenPrice))
                  {
                     trade.PositionModify(
                     orderTicket //CHOOSE THE CORRECT TICKET
                     ,(orderOpenPrice + (Ask-Bid)) // SL HAS BEEN CHANGED
                     ,orderTakeProfit); // TAKE PROFIT NOT CHANGED, ONLY THE STOPLOSS
                     Comment("the OrderGetTicket Value is ",orderTicket);
                     }
                   }
                 }
               }                     
            }
         
      for(int i=PositionsTotal()-1; i>=0; i--)
      {
         if(PositionGetTicket(i)==0) continue;
         if(PositionGetTicket(i)>0)
         {
            if(
            PositionGetString(POSITION_SYMBOL)==inpSymbol 
            && PositionGetInteger(POSITION_MAGIC)==inpMagic
            ) {
               //ORDER TYPE MUST BE THE SAME
               if ((PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)) 
               {  
                  // PRICE REACHED 1:1 MOVE SL TO BREAKEVEN
                  if (Bid < (((orderStopLoss - orderOpenPrice)- orderOpenPrice)*(-1))
                  //SINCE WE MOVE THE SL TO BREAKEVEN + ADD HALF PIP TO ACCOUNT FOR SPREAD,
                  //MEANING THIS COULD ONLY TRIGGER IF PRICE WASN'T MODIFIED YET,
                  //THUS PREVENTING ORDERMODIFY ERROR 1
                  //ORDERMODIFY ERROR 1: DOING THE SAME THING OVER & OVER AGAIN WITHOUT CHANGING ANYTHING
                  && (orderStopLoss > orderOpenPrice))
                  Comment("the OrderGetTicket Value is ",orderTicket);
                  {
                     trade.PositionModify(
                     orderTicket //CHOOSE THE CORRECT TICKET
                     ,(orderOpenPrice - (Ask-Bid)) // SL HAS BEEN CHANGED
                     ,orderTakeProfit); // TAKE PROFIT NOT CHANGED, ONLY THE STOPLOSS
                     }
                   }
                 }
               }                     
            }
         }
 
                  Comment("the OrderGetTicket Value is ",orderTicket);
                  {

Comment() should be below the brace.

 
Renz Carillo:

Any leads on how do i make this much more efficient and not make my strategy tester load slowly, i don't know where to start.

don't assign a variable to  _Symbol  just use  _Symbol it is what it is there for.

don't do your position loop twice (buy and then sell)  just do everything you want from the first loop, you are doubling the amount of processing.

are you calling this every tick?   if so it will consume a lot of processing time,  

store what you need about your positions and just check the latest tick price and then take action if required, getting all positions data every tick is a drain on processing.

You can use OnTrade() to update your positions data only when a trade event occurs.

The Fundamentals of Testing in MetaTrader 5
The Fundamentals of Testing in MetaTrader 5
  • www.mql5.com
What are the differences between the three modes of testing in MetaTrader 5, and what should be particularly looked for? How does the testing of an EA, trading simultaneously on multiple instruments, take place? When and how are the indicator values calculated during testing, and how are the events handled? How to synchronize the bars from different instruments during testing in an "open prices only" mode? This article aims to provide answers to these and many other questions.
 
Renz Carillo:

Any leads on how do i make this much more efficient and not make my strategy tester load slowly, i don't know where to start.

Use the profiler (Editor => Debug Profiling..) - it is exactly meant for that.
 
Paul Anscombe:

don't assign a variable to  _Symbol  just use  _Symbol it is what it is there for.

don't do your position loop twice (buy and then sell)  just do everything you want from the first loop, you are doubling the amount of processing.

are you calling this every tick?   if so it will consume a lot of processing time,  

store what you need about your positions and just check the latest tick price and then take action if required, getting all positions data every tick is a drain on processing.

You can use OnTrade() to update your positions data only when a trade event occurs.

Yes it is placed in OnTick() function, i'm going to look for clues about ontrade(), thank you!
 
Carl Schreiber:
Use the profiler (Editor => Debug Profiling..) - it is exactly meant for that.
I'll try this one, thank you!
 
The Comment() function is slow by itself You are calling it multiple times inside a loop. Do not use Comment() for logging, use Print() for that. 
 

The problem is that the second PositionModify() function is called on every tick because it's outside the scope of the expression (only Comment() is called when the condition is met).

      for(int i=PositionsTotal()-1; i>=0; i--)
      {
         if(PositionGetTicket(i)==0) continue;
         if(PositionGetTicket(i)>0)
         {
            if(
            PositionGetString(POSITION_SYMBOL)==inpSymbol 
            && PositionGetInteger(POSITION_MAGIC)==inpMagic
            ) {
               //ORDER TYPE MUST BE THE SAME
               if ((PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)) 
               {  
                  // PRICE REACHED 1:1 MOVE SL TO BREAKEVEN     
                  if (Ask>(orderOpenPrice - orderStopLoss + orderOpenPrice) && 
                  //SINCE WE MOVE THE SL TO BREAKEVEN + ADD HALF PIP TO ACCOUNT FOR SPREAD,
                  //MEANING THIS COULD ONLY TRIGGER IF PRICE WASN'T MODIFIED YET,
                  //THUS PREVENTING ORDERMODIFY ERROR 1
                  //ORDERMODIFY ERROR 1: DOING THE SAME THING OVER & OVER AGAIN WITHOUT CHANGING ANYTHING
                  (orderStopLoss < orderOpenPrice))
                  {
                     trade.PositionModify(
                     orderTicket //CHOOSE THE CORRECT TICKET
                     ,(orderOpenPrice + (Ask-Bid)) // SL HAS BEEN CHANGED
                     ,orderTakeProfit); // TAKE PROFIT NOT CHANGED, ONLY THE STOPLOSS
                     Print("the OrderGetTicket Value is ",orderTicket);
                     }
                   }
               //ORDER TYPE MUST BE THE SAME
               if ((PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)) 
               {  
                  // PRICE REACHED 1:1 MOVE SL TO BREAKEVEN
                  if (Bid < (((orderStopLoss - orderOpenPrice)- orderOpenPrice)*(-1))
                  //SINCE WE MOVE THE SL TO BREAKEVEN + ADD HALF PIP TO ACCOUNT FOR SPREAD,
                  //MEANING THIS COULD ONLY TRIGGER IF PRICE WASN'T MODIFIED YET,
                  //THUS PREVENTING ORDERMODIFY ERROR 1
                  //ORDERMODIFY ERROR 1: DOING THE SAME THING OVER & OVER AGAIN WITHOUT CHANGING ANYTHING
                  && (orderStopLoss > orderOpenPrice))
                  {
                     trade.PositionModify(
                     orderTicket //CHOOSE THE CORRECT TICKET
                     ,(orderOpenPrice - (Ask-Bid)) // SL HAS BEEN CHANGED
                     ,orderTakeProfit); // TAKE PROFIT NOT CHANGED, ONLY THE STOPLOSS
                     Print("the OrderGetTicket Value is ",orderTicket);
                     }
                   }
                 }
               }                     
            }
         }