MT4 Backtesting 'Issue' ?

 

Hi

I wonder whether someone could help me. 

I have written, what I consider to be a very simple EA but when trying to back-test this EA using MT4, the backtester seems to work for a few trades and then 'stops' (by running to the end without placing any further trades).

It is almost like it runs out of memory, but I do not know how to check whether this is the case.

As an example, if I want to back-test the code from the 1st of Jan 2016 to today, it might place a few trades in January up to say the 10th of January and then it suggests that it won't place any other trades for the rest of the year, but if you were to set your start date to later in the month, it would place trades. 

Could anyone suggest what the issue could be please, as this is driving me crazy.

Thanks

Leon 

 
See line 128 and 278 of your code.
 

Leon Lodewyks: I wonder whether someone could help me.

I have written, what I consider to be a very simple EA but when trying to back-test this EA using MT4, the backtester seems to work for a few trades and then 'stops' (by running to the end without placing any further trades).

It is almost like it runs out of memory, but I do not know how to check whether this is the case.

As an example, if I want to back-test the code from the 1st of Jan 2016 to today, it might place a few trades in January up to say the 10th of January and then it suggests that it won't place any other trades for the rest of the year, but if you were to set your start date to later in the month, it would place trades. 

Could anyone suggest what the issue could be please, as this is driving me crazy.

You will have to post your code if you want us to be able to help you. We can only guess at what the problem can be.

Alain, mentioned lines 128 and 278, but I think he was just joking in order to make the point that we can only guess to what the problem can be because you have not provided any code to look at.

However, also make sure that you actually have history data available for the period in question that is being tested.

 
Fernando Carreiro:

You will have to post your code if you want us to be able to help you. We can only guess at what the problem can be.

Alain, mentioned lines 128 and 278, but I think he was just joking in order to make the point that we can only guess to what the problem can be because you have not provided any code to look at.

However, also make sure that you actually have history data available for the period in question that is being tested.

Exactly.
 
Fernando Carreiro:

You will have to post your code if you want us to be able to help you. We can only guess at what the problem can be.

Alain, mentioned lines 128 and 278, but I think he was just joking in order to make the point that we can only guess to what the problem can be because you have not provided any code to look at.

However, also make sure that you actually have history data available for the period in question that is being tested.

haha...thank you! I completely missed the joke :)

I'll paste the code, I thought it may be a generic MT4 error, so I didn't post the code.

 

Sorry - here is the code.

I have downloaded tickdata and tried that, but also just by downloading the data through the history centre. Both, the same behaviour.

extern double Lots = 0.01;
extern double SL = 50;
extern double TP = 50;
extern int Magic = 1;
datetime Time_open=3600;
datetime Time_bar = 0;


int init()
  {
      return(0);
  }

int start()
  {

// Calculate Levels

   double p,r1,r2,r3,s1,s2,s3;
   double today_high = iHigh(Symbol(),PERIOD_D1,0);
   double today_low = iLow(Symbol(),PERIOD_D1,0);
   double yesterday_close = iClose(Symbol(),PERIOD_D1,1);
   double yesterday_high = iHigh(Symbol(),PERIOD_D1,1);
   double yesterday_low = iLow(Symbol(),PERIOD_D1,1);
   p = (yesterday_high + yesterday_low + yesterday_close) / 3;

   r1 = (2*p)-yesterday_low;
   r2 = p+(yesterday_high - yesterday_low);
   r3 = (2*p)+(yesterday_high-(2*yesterday_low));
   s1 = (2*p)-yesterday_high;
   s2 = p-(yesterday_high - yesterday_low);
   s3 = (2*p)-((2* yesterday_high)-yesterday_low);

   double previousCandleClosePrice = iClose(Symbol(),PERIOD_CURRENT,1);

   double Pivot = NormalizeDouble(p,Digits);
   double Resistance1 = NormalizeDouble(r1,Digits);
   double Resistance2 = NormalizeDouble(r2,Digits);
   double Resistance3 = NormalizeDouble(r3,Digits);
   double Support1 = NormalizeDouble(s1,Digits);
   double Support2 = NormalizeDouble(s2,Digits);
   double Support3 = NormalizeDouble(s3,Digits);
            
          
//Pivot Point
        if(previousCandleClosePrice < Pivot && Pivot == Ask && (TimeCurrent()- Time[0])<Time_open)
         {
        int ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,5, Ask+(SL*10*Point),Ask-(TP*10*Point),"Pivot Point Sell",Magic,0,Green);
        Print("Pivot Level: " + Pivot);
        if (ticket > 0)
        {
        Time_open = TimeCurrent()-Time[0]; //enter new string (store interval from the bar opening time with the entry until the exit moment)
              Time_bar = Time[0]; //enter new string (remember opening time of the bar that had 1st entry)
        Print("Pivot Point Sell Placed");
        }
        
        else
        {
        Print("Error placing Trade: ",GetLastError());
        Print("Tried opening order at: " + Bid + " with SL at " + (Ask+SL) + " and TP at " + (Ask-TP));
        return(0);
        }
                
        }
        
        if(previousCandleClosePrice > Pivot && Pivot == Bid && (TimeCurrent()- Time[0])<Time_open)
        {
        ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,5,Bid-(SL*10*Point), Bid+(TP*10*Point),"Pivot Point Buy",Magic,0,Green);
        //Print("Pivot Level: " + Pivot);
        
        if (ticket > 0)
        {
        Time_open = TimeCurrent()-Time[0]; //enter new string (store interval from the bar opening time with the entry until the exit moment)
              Time_bar = Time[0]; //enter new string (remember opening time of the bar that had 1st entry)
                Print("Pivot Point Buy Placed");
        }
         else{
        Print("Error placing Trade: ",GetLastError());
        //Print("Tried opening order at: " + Ask + " with SL at " + (Bid-SL) + " and TP at " + (Bid+TP));
        return(0);
        }
                
        }
        
//Resistance 1
        if(previousCandleClosePrice < Resistance1 && Resistance1 == Ask && (TimeCurrent()- Time[0])<Time_open)
         {
        int ticketResistance1 =OrderSend(Symbol(),OP_SELL,Lots,Bid,5, Ask+(SL*10*Point),Ask-(TP*10*Point),"Resistance 1 Sell",Magic,0,Green);
        
        if (ticketResistance1 > 0)
        {
        Time_open = TimeCurrent()-Time[0]; //enter new string (store interval from the bar opening time with the entry until the exit moment)
        Time_bar = Time[0]; //enter new string (remember opening time of the bar that had 1st entry)
        
        }
        
        else
        {
        Print("Error placing Trade: ",GetLastError());
        Print("Tried opening order at: " + Bid + " with SL at " + (Ask+SL) + " and TP at " + (Ask-TP));
        return(0);
        }
                
        }
        

//Resistance 2
        if(previousCandleClosePrice < Resistance2 && Resistance2 == Ask && (TimeCurrent()- Time[0])<Time_open)
         {
        int ticketResistance2 =OrderSend(Symbol(),OP_SELL,Lots,Bid,5, Ask+(SL*10*Point),Ask-(TP*10*Point),"Resistance 2 Sell",Magic,0,Green);
        
        if (ticketResistance2 > 0)
        {
        Time_open = TimeCurrent()-Time[0]; //enter new string (store interval from the bar opening time with the entry until the exit moment)
        Time_bar = Time[0]; //enter new string (remember opening time of the bar that had 1st entry)
        
        }
        
        else
        {
        Print("Error placing Trade: ",GetLastError());
        Print("Tried opening order at: " + Bid + " with SL at " + (Ask+SL) + " and TP at " + (Ask-TP));
        return(0);
        }
                
        }



//Resistance 3
        if(previousCandleClosePrice < Resistance3 && Resistance3 == Ask && (TimeCurrent()- Time[0])<Time_open)
         {
        int ticketResistance3 =OrderSend(Symbol(),OP_SELL,Lots,Bid,5, Ask+(SL*10*Point),Ask-(TP*10*Point),"Resistance 3 Sell",Magic,0,Green);
        
        if (ticketResistance3 > 0)
        {
        Time_open = TimeCurrent()-Time[0]; //enter new string (store interval from the bar opening time with the entry until the exit moment)
        Time_bar = Time[0]; //enter new string (remember opening time of the bar that had 1st entry)
        
        }
        
        else
        {
        Print("Error placing Trade: ",GetLastError());
        Print("Tried opening order at: " + Bid + " with SL at " + (Ask+SL) + " and TP at " + (Ask-TP));
        return(0);
        }
                
        }


//Support1    

if(previousCandleClosePrice > Support1 && Support1 == Bid && (TimeCurrent()- Time[0])<Time_open)
        {
        int ticketSupport1 = OrderSend(Symbol(),OP_BUY,Lots,Ask,5,Bid-(SL*10*Point), Bid+(TP*10*Point),"Support 1 Buy",Magic,0,Green);
        
        
        if (ticketSupport1 > 0)
        {
        Time_open = TimeCurrent()-Time[0]; //enter new string (store interval from the bar opening time with the entry until the exit moment)
        Time_bar = Time[0]; //enter new string (remember opening time of the bar that had 1st entry)
              
        }
         else{
        Print("Error placing Trade: ",GetLastError());
        //Print("Tried opening order at: " + Ask + " with SL at " + (Bid-SL) + " and TP at " + (Bid+TP));
        return(0);
        }
                
        }


//Support2    

if(previousCandleClosePrice > Support2 && Support2 == Bid && (TimeCurrent()- Time[0])<Time_open)
        {
        int ticketSupport2 = OrderSend(Symbol(),OP_BUY,Lots,Ask,5,Bid-(SL*10*Point), Bid+(TP*10*Point),"Support 2 Buy",Magic,0,Green);
        
        
        if (ticketSupport2 > 0)
        {
        Time_open = TimeCurrent()-Time[0]; //enter new string (store interval from the bar opening time with the entry until the exit moment)
        Time_bar = Time[0]; //enter new string (remember opening time of the bar that had 1st entry)
              
        }
         else{
        Print("Error placing Trade: ",GetLastError());
        return(0);
        }
                
        }



//Support3  

if(previousCandleClosePrice > Support3 && Support3 == Bid && (TimeCurrent()- Time[0])<Time_open)
        {
        int ticketSupport3 = OrderSend(Symbol(),OP_BUY,Lots,Ask,5,Bid-(SL*10*Point), Bid+(TP*10*Point),"Support 3 Buy",Magic,0,Green);
        
        
        if (ticketSupport3 > 0)
        {
        Time_open = TimeCurrent()-Time[0]; //enter new string (store interval from the bar opening time with the entry until the exit moment)
        Time_bar = Time[0]; //enter new string (remember opening time of the bar that had 1st entry)
              
        }
         else{
        Print("Error placing Trade: ",GetLastError());
        //Print("Tried opening order at: " + Ask + " with SL at " + (Bid-SL) + " and TP at " + (Bid+TP));
        return(0);
        }
                
        }

   return(0);
  }
 
Leon Lodewyks: Sorry - here is the code. I have downloaded tickdata and tried that, but also just by downloading the data through the history centre. Both, the same behaviour.

Where do I start???? There are so many problematic areas I am not sure even which is the culprit or the culprits, but the first thing I noticed was the several lines where you use "variable == Bid" or "variable == Ask".

This will cause many a problem, because there is no guarantee that a price will exactly match. You should use a ">=" or "<=" depending on the situation.

As for the rest, I have not analysed properly yet. Try to fix this first and test it before we look at it again. Then post the new code once you have done that.

 
Fernando Carreiro:

Where do I start???? There are so many problematic areas I am not sure even which is the culprit or the culprits, but the first thing I noticed was the several lines where you use "variable == Bid" or "variable == Ask".

This will cause many a problem, because there is no guarantee that a price will exactly match. You should use a ">=" or "<=" depending on the situation.

As for the rest, I have not analysed properly yet. Try to fix this first and test it before we look at it again. Then post the new code once you have done that.

Many thanks Fernando. Let me make that change and I'll let you know how it goes.
 
Leon Lodewyks:
Many thanks Fernando. Let me make that change and I'll let you know how it goes.

Also, what is up with the "Time_open = TimeCurrent()-Time[0];" and the "(TimeCurrent()- Time[0])<Time_open)"? It will get to a point when you could get a difference of Zero (or one, or a very small value) and then you will no longer be able to place orders.

EDIT: Reconsidering this situation, this is probably the main culprit for your problem.

 
Fernando Carreiro: "variable == Bid" or "variable == Ask". there is no guarantee that a price will exactly match.
Exactly. Floating point has infinite number of decimals, it's your not understanding floating point and that some numbers can't be represented exactly. (like 1/10.) Double-precision floating-point format - Wikipedia, the free encyclopedia See also The == operand. - MQL4 forum
 
Fernando Carreiro:

Also, what is up with the "Time_open = TimeCurrent()-Time[0];" and the "(TimeCurrent()- Time[0])<Time_open)"? It will get to a point when you could get a difference of Zero (or one, or a very small value) and then you will no longer be able to place orders.

EDIT: Reconsidering this situation, this is probably the main culprit for your problem.

This was actually some code I took from the below to prevent the EA from trading more than once in the same bar.

https://www.mql5.com/en/articles/2110 

False trigger protection for Trading Robot
False trigger protection for Trading Robot
  • 2016.08.26
  • Alexander Masterskikh
  • www.mql5.com
Profitability of trading systems is defined not only by logic and precision of analyzing the financial instrument dynamics, but also by the quality of the performance algorithm of this logic. False trigger is typical for low quality performance of the main logic of a trading robot. Ways of solving the specified problem are considered in this article.