Strategy Tester in MQL5 gives very Different Results than in MQL4.

 

Hi everyone,

I'm a newbie when it comes to the MQL5 version. I took the exact script I used in MqL4 and adjuste it to Mql5 for learning purposes. To my surprise, the tester result was horrible in Mql5, while the tester result in Mql5 was outstanding. Am I doing something wrong?? Please help and thank you.

 

//+------------------------------------------------------------------+
//|                                                 Real Trender.mq5 |
//|                                                            Test  |
//|                                              http://www.Test.com |
//+------------------------------------------------------------------+
#property copyright "Test"
#property link      "Test"
#property version   "1.00"


double SignalP;
double SignalN;
double Ratio;
double PVIT;
double PVIY;
double NVIT;
double NVIY;
string EAName="Real Trender";
int TakeProfit=220;     // 22 pips
int Stoploss=2500;      // 250 pips
int MagicNumber=12345;
int ticket;
int NumOfTrades=0;
int Lots=1;
int MaxTrades=3;
double RiskAdjuster=0;
double MaximumRisk = 0.10;

MqlTradeRequest trReq;
MqlTradeResult trRez;



//+------------------------------------------------------------------+
//| Calculate optimal lot size                                       |
//+------------------------------------------------------------------+
double LotsOptimized(void)
  {
//--- select lot size
   double lot=NormalizeDouble(AccountInfoDouble(ACCOUNT_FREEMARGIN)*MaximumRisk/1000.0,1);
//--- calculate number of losses orders without a break
   if(RiskAdjuster>0)
     {
      //--- select history for access
      HistorySelect(0,TimeCurrent());
      //---
      int    orders=HistoryDealsTotal();  // total history deals
      int    losses=0;                    // number of losses orders without a break

      for(int i=orders-1;i>=0;i--)
        {
         ulong ticket=HistoryDealGetTicket(i);
         if(ticket==0)
           {
            Print("HistoryDealGetTicket failed, no trade history");
            break;
           }
         //--- check symbol
         if(HistoryDealGetString(ticket,DEAL_SYMBOL)!=_Symbol) continue;
         //--- check profit
         double profit=HistoryDealGetDouble(ticket,DEAL_PROFIT);
         if(profit>0.0) break;
         if(profit<0.0) losses++;
        }
      //---
      if(losses>1) lot=NormalizeDouble(lot-lot*losses/RiskAdjuster,1);
     }
//--- normalize and check limits
   double stepvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP);
   lot=stepvol*NormalizeDouble(lot/stepvol,0);

   double minvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN);
   if(lot<minvol) lot=minvol;

   double maxvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MAX);
   if(lot>maxvol) lot=maxvol;
//--- return trading volume
   return(lot);
   }

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {

   //Set default values for all new order requests
      trReq.action=TRADE_ACTION_DEAL;
      trReq.magic=MagicNumber;
      trReq.symbol=Symbol();                 // Trade symbol
      trReq.volume=LotsOptimized();          // Requested optimized volume for a deal in lots
      trReq.deviation=3;                     // Maximal possible deviation from the requested price
      trReq.tp=TakeProfit;                   // Take Profit  
      trReq.sl=Stoploss;                     // StopLoss
      trReq.type_filling=ORDER_FILLING_AON;  // Order execution type
      trReq.type_time=ORDER_TIME_GTC;        // Order execution time
      trReq.comment="Real Trender";
      trReq.order=NumOfTrades; 
   //end
       
   //Support for acount with 5 decimals
      //if(_Digits==5)
      //{
         //Stoploss*=2500;
         //TakeProfit=220;
     // }
   //end
   
   
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//----
   
//----

  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
void OnTick()
  {

   MqlTick tick; //variable for tick info
   if(!SymbolInfoTick(Symbol(),tick))
   {
      Print("Failed to get Symbol info!");
      return;
   }

   //Create Variables for indicators
   double CurrentVolume, PreviousVolume1, PreviousVolume2;
   long myVolume[];
   
    
   CopyTickVolume(_Symbol,PERIOD_M15,0,3,myVolume);
   ArraySetAsSeries(myVolume,true);
   
   CurrentVolume = myVolume[0]; // current bar Volume.
   PreviousVolume1 = myVolume[1]; // equals bar Volume 1 bar back from current bar.
   PreviousVolume2 = myVolume[2]; // equals bar Volume 2 bars back from current bar.

   
   PVIY=(((PreviousVolume1+PreviousVolume2)/PreviousVolume2));
   PVIT=(((PVIY+(CurrentVolume)+(PreviousVolume1))/(PreviousVolume1)));
   
   NVIY=(((PreviousVolume1+PreviousVolume2)/PreviousVolume2));
   NVIT=(((NVIY+(CurrentVolume)+(PreviousVolume1))/(PreviousVolume1)));
   
   double CurrentClose, PreviousClose1, PreviousClose2;
   double myClose[];
   CopyClose(_Symbol,PERIOD_M15, 0, 3, myClose); 
   
   ArraySetAsSeries(myClose,true);
   CurrentClose = myClose[0]; // current bar close.
   PreviousClose1 = myClose[1]; // equals bar close 1 bar back from current bar.
   PreviousClose2 = myClose[2]; // equals bar close 2 bars back from current bar.
   
   if (CurrentClose>PreviousClose1)
   SignalP= PVIY+PVIT;
   else         
   SignalP=PVIY;
   
   if (CurrentClose<PreviousClose1)
   SignalN=NVIY+NVIT;
   else
   SignalN=NVIY;
   
   Ratio = NormalizeDouble(((100*SignalP)/(SignalP+SignalN)),2);
   Comment("Ratio Percentage  : ",NormalizeDouble(Ratio,2)," % ",
   "\nSignalP ",NormalizeDouble(SignalP,2),
   "\nSignalN ",NormalizeDouble(SignalN,2));
   //end
   
   if ((Ratio < 25.00)&& (OrdersTotal()<MaxTrades))
   {
         trReq.price=tick.ask;                   // SymbolInfoDouble(NULL,SYMBOL_ASK);
         trReq.sl=tick.ask-_Point*Stoploss;      // Stop Loss level of the order
         trReq.tp=tick.ask+_Point*TakeProfit;    // Take Profit level of the order
         trReq.type=ORDER_TYPE_BUY;              // Order type
         OrderSend(trReq,trRez);

   }
   if ((Ratio > 75.00)&& (OrdersTotal()<MaxTrades))
   {
         trReq.price=tick.bid;
         trReq.sl=tick.bid+_Point*Stoploss;      // Stop Loss level of the order
         trReq.tp=tick.bid-_Point*TakeProfit;    // Take Profit level of the order
         trReq.type=ORDER_TYPE_SELL;             // Order type
         OrderSend(trReq,trRez);
   }

      

}

  
 

I made a typo! Should read Mql5 test result = horrible & Mql4 test result = great.

 
Cornelis van der Westhuizen: Should read Mql5 test result = horrible & Mql4 test result = great.

MT5 has the spread in history. MT4 uses what you set. Set it correctly and you'll get horrible results in MT4 also.

Always specify. Don't use current. Most brokers with variable spread widen considerably at end of day (5 PM ET) ± 30 minutes. My GBPJPY (OANDA) shows average spread = 26 points, but average maximum spread = 134.

Always specify Tester-SpreadDon't use current

The spread is constant during the run. It is the current spread for the pair (your broker,) at the moment you start the test.

If you start the test on the weekend, the current spread is likely to be very large.

Most brokers with variable spread widen considerably at end of day (5 PM ET) ± 30 minutes. My GBPJPY (OANDA) shows average spread = 26 points, but average maximum spread = 134. The charts show Bid prices only. Turn on the Ask line to see how big the spread is, Tools → Options (control+O) → charts → Show ask line.
 
Cornelis van der Westhuizen :

Hi everyone,

I'm a newbie when it comes to the MQL5 version. I took the exact script I used in MqL4 and adjuste it to Mql5 for learning purposes. To my surprise, the tester result was horrible in Mql5, while the tester result in Mql5 was outstanding. Am I doing something wrong?? Please help and thank you.

 

Code

 OrdersTotal() 

- this is mistake. There are no pending orders! You have a POSITION. And positions are defined as follows:

 PositionsTotal() 
Reason: