MT4 Backtesting 'Issue' ? - page 2

 
Leon Lodewyks:

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 

You should not just copy someone's code without first understanding how it works. Because maybe it is not the appropriate code for you or it could even be wrong.

If you are trying to prevent multiple orders, then keep track of the Tickets to decide if you have open orders or not, instead of relying on a "time".

You should also detect the beginning of the D1 bars and the beginning of the Chart Bars and act accordingly, instead of calculating things on every tick. Search the MQL4 Forum for "whroeder's" code example for bar detection (see EDIT4 below).

EDIT: For example, every time a new bar is started you could "clear" the Ticket variables and check when its value has been assigned a valid ticket, so as to prevent any further orders during that bar.

EDIT2: You need to make your code more structured and readable and not repeat code so much!

EDIT3: Try to use the updated modern style for MQL4 instead of the old "init()" and "start()" and use "strict" compilation!

EDIT4: Here is WHRoeder's link: Post#3 on New candle - MQL4 forum

Updated MQL4 - MQL4 Reference
Updated MQL4 - MQL4 Reference
  • docs.mql4.com
Updated MQL4 - MQL4 Reference
 
Leon Lodewyks: ...

Here is your code redone with the suggestions already mentioned. Please note the code is not fully tested and there are still problematic points that should be focused on, but it serves as a starting point for you to improve your code and correct your main problem:

Please note that all History Data is based on Bid prices so your conditions should also use Bid prices and not mix Ask and Bid as your original code.

PS! The "while( true )" loop is not actually a loop but just serves to be able to "break" out of the block and not have to check any further conditions!

#property strict

extern double
   Lots      = 0.01,
   SL        = 50.0,
   TP        = 50.0,
   PipAdjust = 10.0;

extern int
   Magic    = 1,
   Slippage = 5;

int Ticket;

double
   TickSize, LotStep, LotMin, LotMax, StopLoss, TakeProfit, PreviousBarClose,
   TodayHigh, TodayLow, YesterdayClose, YesterdayHigh, YesterdayLow,
   Pivot, Resistance1, Resistance2, Resistance3, Support1, Support2, Support3;
  
int OnInit(void)
{
   TickSize   = MarketInfo( _Symbol, MODE_TICKSIZE );
   StopLoss   = round( SL * PipAdjust * _Point / TickSize ) * TickSize;
   TakeProfit = round( TP * PipAdjust * _Point / TickSize ) * TickSize;
  
   LotStep    = MarketInfo( _Symbol, MODE_LOTSTEP );
   LotMin     = MarketInfo( _Symbol, MODE_MINLOT  );
   LotMax     = MarketInfo( _Symbol, MODE_MAXLOT  );
   Lots       = round( Lots / LotStep ) * LotStep;
   if( Lots < LotMin ) Lots = LotMin;
   if( Lots > LotMax ) Lots = LotMax;

   return( INIT_SUCCEEDED );
}

void OnTick()
{
   static datetime barCur; datetime barPre = barCur; barCur = Time[ 0 ];
   bool isNewBar = barCur != barPre;

   static datetime dayCur; datetime dayPre = dayCur; dayCur = iTime( _Symbol, PERIOD_D1, 0 );
   bool isNewDay = dayCur != dayPre;

   if( isNewBar ) //Reset for New Bar
   {
      Ticket = EMPTY; // Prevent Multiple Orders per Bar
      PreviousBarClose = Close[ 1 ];  
   }

   if( isNewDay ) // Reset for New Day
   {
      TodayHigh      = iHigh(  _Symbol, PERIOD_D1, 0 );
      TodayLow       = iLow(   _Symbol, PERIOD_D1, 0 );
      YesterdayClose = iClose( _Symbol, PERIOD_D1, 1 );
      YesterdayHigh  = iHigh(  _Symbol, PERIOD_D1, 1 );
      YesterdayLow   = iLow(   _Symbol, PERIOD_D1, 1 );
      Pivot          = ( YesterdayHigh + YesterdayLow + YesterdayClose ) / 3;
      Resistance1    = ( 2.0 * Pivot ) - YesterdayLow;
      Resistance2    = Pivot + ( YesterdayHigh - YesterdayLow );
      Resistance3    = ( 2.0 * Pivot ) + ( YesterdayHigh - ( 2.0 * YesterdayLow ) );
      Support1       = ( 2.0 * Pivot ) - YesterdayHigh;
      Support2       = Pivot - ( YesterdayHigh - YesterdayLow );
      Support3       = ( 2.0 * Pivot ) - ( ( 2.0 * YesterdayHigh ) - YesterdayLow );
   }

   // Check for previously placed trades for the current Bar
   if( Ticket == EMPTY )
   {
      int OpenOrderType = EMPTY;
      string CommentOrder = "";
      
      while( true )
      {
         if( ( PreviousBarClose < Pivot       ) && ( Bid >= Pivot       ) ) { OpenOrderType = OP_SELL; CommentOrder  = "Pivot Point Sell";  break; }
         if( ( PreviousBarClose < Resistance1 ) && ( Bid >= Resistance1 ) ) { OpenOrderType = OP_SELL; CommentOrder  = "Resistance 1 Sell"; break; }
         if( ( PreviousBarClose < Resistance2 ) && ( Bid >= Resistance2 ) ) { OpenOrderType = OP_SELL; CommentOrder  = "Resistance 2 Sell"; break; }
         if( ( PreviousBarClose < Resistance3 ) && ( Bid >= Resistance3 ) ) { OpenOrderType = OP_SELL; CommentOrder  = "Resistance 3 Sell"; break; }
         if( ( PreviousBarClose > Pivot       ) && ( Bid <= Pivot       ) ) { OpenOrderType = OP_BUY;  CommentOrder  = "Pivot Point Buy";   break; }
         if( ( PreviousBarClose > Support1    ) && ( Bid <= Support1    ) ) { OpenOrderType = OP_BUY;  CommentOrder  = "Support 1 Buy";     break; }
         if( ( PreviousBarClose > Support2    ) && ( Bid <= Support2    ) ) { OpenOrderType = OP_BUY;  CommentOrder  = "Support 2 Buy";     break; }
         if( ( PreviousBarClose > Support3    ) && ( Bid <= Support3    ) ) { OpenOrderType = OP_BUY;  CommentOrder  = "Support 3 Buy";     break; }
         break;
      }
      
      if( OpenOrderType != EMPTY )
      {
         ResetLastError();
        
         switch( OpenOrderType )
         {
            case OP_BUY:
               Ticket = OrderSend( _Symbol, OpenOrderType, Lots, Ask, Slippage, Ask - StopLoss, Ask + TakeProfit, CommentOrder, Magic, 0, clrBlue );
               break;
        
            case OP_SELL:
               Ticket = OrderSend( _Symbol, OpenOrderType, Lots, Bid, Slippage, Bid + StopLoss, Bid - TakeProfit, CommentOrder, Magic, 0, clrRed );
               break;
              
            default:
               Print("Unknown Order Type: ",  OpenOrderType );
         }
        
         if( Ticket == EMPTY )
            Print("Order Placement failed for ", CommentOrder, " with Error: ", _LastError );
      }
   }  
}
 
Fernando Carreiro:

You should not just copy someone's code without first understanding how it works. Because maybe it is not the appropriate code for you or it could even be wrong.

If you are trying to prevent multiple orders, then keep track of the Tickets to decide if you have open orders or not, instead of relying on a "time".

You should also detect the beginning of the D1 bars and the beginning of the Chart Bars and act accordingly, instead of calculating things on every tick. Search the MQL4 Forum for "whroeder's" code example for bar detection (see EDIT4 below).

EDIT: For example, every time a new bar is started you could "clear" the Ticket variables and check when its value has been assigned a valid ticket, so as to prevent any further orders during that bar.

EDIT2: You need to make your code more structured and readable and not repeat code so much!

EDIT3: Try to use the updated modern style for MQL4 instead of the old "init()" and "start()" and use "strict" compilation!

EDIT4: Here is WHRoeder's link: Post#3 on New candle - MQL4 forum

Thanks so much Fernando! I really appreciate all the help.
Reason: