This code makes Strategy Tester extremely slow

 

So I ran this, even in not visual mode, and it took approx 3 hours for 1 month of data on a Daily chart.. insane. 

//Custom indicator values

extern int Price = 0;
extern int Length = 52;
extern int Displace = 0; //DispLace or Shift
extern double PctFilter = 0; //Dynamic filter in decimal
extern int Color = 1; //Switch of Color mode (1-color)
extern int ColorBarBack = 1; //Bar back for color mode
extern double Deviation = 0; //Up/down deviation
extern int AlertMode = 0; //Sound Alert switch (0-off,1-on)
extern int WarningMode = 0; //Sound Warning switch(0-off,1-on)
extern int Shift = 1;
extern string CrossSignal = "";
extern string ColorSignal = "";


void OnTick()
  {

// Signal cross
double macurrent = iCustom(NULL, 0, "NonLagMA_v7.1",Price,Length,Displace, PctFilter, Color, ColorBarBack, Deviation, AlertMode, WarningMode, 0,Shift);
double maprevious = iCustom(NULL, 0, "NonLagMA_v7.1",Price,Length,Displace, PctFilter, Color, ColorBarBack, Deviation, AlertMode, WarningMode, 0,Shift+1);

double close_current = iClose (NULL,0,Shift);
double close_previous = iClose (NULL,0,Shift+1);

// Signal color 
double buy_macurrent = iCustom(NULL, 0, "NonLagMA_v7.1",Price,Length,Displace, PctFilter, Color, ColorBarBack, Deviation, AlertMode, WarningMode, 1,Shift);
double buy_maprevious = iCustom(NULL, 0, "NonLagMA_v7.1",Price,Length,Displace, PctFilter, Color, ColorBarBack, Deviation, AlertMode, WarningMode, 1,Shift+1);
double sell_macurrent = iCustom(NULL, 0, "NonLagMA_v7.1",Price,Length,Displace, PctFilter, Color, ColorBarBack, Deviation, AlertMode, WarningMode, 2,Shift);
double sell_maprevious = iCustom(NULL, 0, "NonLagMA_v7.1",Price,Length,Displace, PctFilter, Color, ColorBarBack, Deviation, AlertMode, WarningMode, 2,Shift+1);

   if (close_previous <= maprevious && close_current >= macurrent){
      CrossSignal = "BUY";
         //Comment("BUY");
   }
   if (close_previous >= maprevious && close_current <= macurrent){
      CrossSignal = "SELL";
         //Comment("SELL");
   }
   if (sell_maprevious!=EMPTY_VALUE && sell_macurrent==EMPTY_VALUE && buy_macurrent!=EMPTY_VALUE){
      ColorSignal = "BUY";
   }
   if (buy_maprevious!=EMPTY_VALUE && buy_macurrent==EMPTY_VALUE && sell_macurrent!=EMPTY_VALUE){
      ColorSignal = "SELL";
   }
   
   if (OrdersTotal()==0 && (CrossSignal == "BUY" && ColorSignal == "BUY")) {
      int buyticket = OrderSend(
         Symbol(),
         OP_BUY,
         0.01,
         Ask,
         10,
         Ask-100*_Point,
         Ask+300*_Point,
         NULL,
         0,
         0,
         Green
      );
   }
 }

I'm a newb but I think the reason it's so slow is because on every tick it's calculating those variables. 

I tried moving them to or above int OnInit() but that makes the buy order not working. 

I'm hoping someone could advise me on how to handle this because I want to run the EA with a lot of different indicator values and it's hard to do that while the EA takes 3 hours for 1 month of data only. 

 

EDIT: 

I read some and tried to do the following but unfortunately didn't help a lot. 

      if (close_previous <= maprevious) {
         if (close_current >= macurrent) {
            if (sell_maprevious!=EMPTY_VALUE){
               if (sell_macurrent==EMPTY_VALUE) {
                  if (buy_macurrent!=EMPTY_VALUE) {
                     int buyticket = OrderSend(
                        Symbol(),
                        OP_BUY,
                        0.01,
                        Ask,
                        10,
                        Ask-100*_Point,
                        Ask+300*_Point,
                        NULL,
                        0,
                        0,
                        CLR_NONE
                     );
                  }
               }
            }
         }
      }
 
pipsortreat:

So I ran this, even in not visual mode, and it took approx 3 hours for 1 month of data on a Daily chart.. insane. 

I'm a newb but I think the reason it's so slow is because on every tick it's calculating those variables. 

I tried moving them to or above int OnInit() but that makes the buy order not working. 

I'm hoping someone could advise me on how to handle this because I want to run the EA with a lot of different indicator values and it's hard to do that while the EA takes 3 hours for 1 month of data only. 

First of all, you have to think about whether it is necessary to run the code every tick.

extern int Shift = 1;

if Shift is 1 then you really only need to run the code when there is a new bar opened.

if (OrdersTotal()==0 && (CrossSignal == "BUY" && ColorSignal == "BUY"))

If OrdersTotal is >0, there is no need to run all the preceding code


   if (close_previous <= maprevious && close_current >= macurrent){
      CrossSignal = "BUY";
         //Comment("BUY");
   }
   if (close_previous >= maprevious && close_current <= macurrent){
      CrossSignal = "SELL";
         //Comment("SELL");
   }
   if (sell_maprevious!=EMPTY_VALUE && sell_macurrent==EMPTY_VALUE && buy_macurrent!=EMPTY_VALUE){
      ColorSignal = "BUY";
   }
   if (buy_maprevious!=EMPTY_VALUE && buy_macurrent==EMPTY_VALUE && sell_macurrent!=EMPTY_VALUE){
      ColorSignal = "SELL";
   }

You don't need the string variables

   if (close_previous <= maprevious && close_current >= macurrent)
      if (sell_maprevious!=EMPTY_VALUE && sell_macurrent==EMPTY_VALUE && buy_macurrent!=EMPTY_VALUE)
        {
         int buyticket = OrderSend(
                            Symbol(),
                            OP_BUY,
                            0.01,
                            Ask,
                            10,
                            Ask-100*_Point,
                            Ask+300*_Point,
                            NULL,
                            0,
                            0,
                            Green
                         );
        }
 

@ Keith Watford

Thanks for the reply! I will adjust according to your suggestions. 

In order for the EA to trigger a trade only bar data is needed so that means that I could set Model to Open Price. 

But, in order for TP and SL to be as precise as possible, I would need the tick value. e.g. if the TP/SL of an open trade has been set, this level might be triggered on tick level but might be away from close price and thus will not be triggered. 

Or is there something that I'm not seeing correctly? 

 
pipsortreat:

In order for the EA to trigger a trade only bar data is needed so that means that I could set Model to Open Price. 

You should test in every tick mode

if Shift is 1 then you really only need to run the code when there is a new bar opened.

Check for a new bar before running the code.
 

That's genius, I set it so that all calculations are made once there's a new candle. 

Made the script 1000 times faster. Thank you. Will include this way of thinking in future scripts. 

 

For anyone that is searching the same, here's the code improvement: 


// check for new candle

datetime NewCandleTime=TimeCurrent();
bool IsNewCandle(){
   if(NewCandleTime==iTime(Symbol(),0,0)) return false;
   else{
      NewCandleTime=iTime(Symbol(),0,0);
      return true;
   }
}

// ontick

if(IsNewCandle()){
      if (OrdersTotal()==0) {
         // Signal cross
         double macurrent = iCustom(NULL, 0, "NonLagMA_v7.1",Price,Length,Displace, PctFilter, Color, ColorBarBack, Deviation, AlertMode, WarningMode, 0,Shift);
         double maprevious = iCustom(NULL, 0, "NonLagMA_v7.1",Price,Length,Displace, PctFilter, Color, ColorBarBack, Deviation, AlertMode, WarningMode, 0,Shift+1);
         
         double close_current = iClose (NULL,0,Shift);
         double close_previous = iClose (NULL,0,Shift+1);
         
         // Signal color 
         double buy_macurrent = iCustom(NULL, 0, "NonLagMA_v7.1",Price,Length,Displace, PctFilter, Color, ColorBarBack, Deviation, AlertMode, WarningMode, 1,Shift);
         double buy_maprevious = iCustom(NULL, 0, "NonLagMA_v7.1",Price,Length,Displace, PctFilter, Color, ColorBarBack, Deviation, AlertMode, WarningMode, 1,Shift+1);
         double sell_macurrent = iCustom(NULL, 0, "NonLagMA_v7.1",Price,Length,Displace, PctFilter, Color, ColorBarBack, Deviation, AlertMode, WarningMode, 2,Shift);
         double sell_maprevious = iCustom(NULL, 0, "NonLagMA_v7.1",Price,Length,Displace, PctFilter, Color, ColorBarBack, Deviation, AlertMode, WarningMode, 2,Shift+1);
         
            if (close_previous <= maprevious && close_current >= macurrent){
               if (sell_maprevious!=EMPTY_VALUE && sell_macurrent==EMPTY_VALUE && buy_macurrent!=EMPTY_VALUE){
                     int buyticket = OrderSend(
                        Symbol(),
                        OP_BUY,
                        0.01,
                        Ask,
                        10,
                        0,
                        0,
                        NULL,
                        0,
                        0,
                        Green
                     );
                }
            }
         
         }
Source code for new candle:  https://mql4tradingautomation.com/mql4-on-new-bar/#:~:text=Compare%20the%20start%20time%20of,true%20and%20update%20the%20time
Reason: