One Trade per bar until Max Reached - EA not working properly

 

Dear All, 

I just designed an EA MetaEditor. I am now testing the code, but it will not open any trades even though conditions are met. It makes a sound, meaning that it wants to open a trade, but then it doesn't. I suspect there is something wrong with the portion of the code where I want the EA to open one trade per bar, until the Maximum trades allowed has been reached.

Basically, i want the EA to do the following: 

  1. Open a trade onlyat the beginning of a bar (I am currently using the code on H4 and D1 time frames, but I want to design it so that it is flexible for different time frames)
  2. Be able to set Maximum allowed trades
  3. Open one trade per bar until the maximum trades have been reached
  4. The formula will only allow trades that are in the same direction (i.e. either all buy or all sell), so no hedging.  
  5. Use a formula to open trades and to close trades - therefore, no TP and SL.
Your assistance will be greatly appreciated. 
property copyright   "SIYA SAUKA"
#property version     "1.00"
#property strict

extern double  Lots=0.01;                           //Lots Size
extern string  str1="Magic EA";                     //Special Name/Code of EA
extern int     Slippage=0;                          //Slippage in Pips
extern int     Max_Trades=5;                        //Maximum Number of Open Trades
extern int     MagicNumber=1986;                    //Magic Number

extern string  str2="Indicator 1";
// input criteria for Indicator 1

extern string  str3="Indicator 2";
// input criteria for Indicator 2

extern string  str4="Indicator 3";
// input criteria for Indicator 3


//---- expert initialization function --------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------------------------

int OnInit()
  { int   T,L;                       // Setting integers for different timeframes
    switch(Period())                 // Calculating coefficient for different timeframes
     {
      case     1:    L=PERIOD_M1;   T=PERIOD_M1;   break;   // Timeframe M1
      case     5:    L=PERIOD_M5;   T=PERIOD_M5;   break;   // Timeframe M5
      case    15:    L=PERIOD_M15;  T=PERIOD_M15;  break;   // Timeframe M15
      case    30:    L=PERIOD_M30;  T=PERIOD_M30;  break;   // Timeframe M30
      case    60:    L=PERIOD_H1;   T=PERIOD_H1;   break;   // Timeframe H1
      case   240:    L=PERIOD_H4;   T=PERIOD_H4;   break;   // Timeframe H4
      case  1440:    L=PERIOD_D1;   T=PERIOD_D1;   break;   // Timeframe D1
      case 10080:    L=PERIOD_W1;   T=PERIOD_W1;   break;   // Timeframe W1
      case 43200:    L=PERIOD_MN1;  T=PERIOD_MN1;  break;   // Timeframe MN
     }
    return(INIT_SUCCEEDED);
  }

void OnDeinit(const int reason)
  { }


//---- expert trading function ---------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------------------------

void OnTick(void)
  { static datetime dtBarCurrent=WRONG_VALUE;                                                     // Check for New Bar (Compatible with both MQL4 and MQL5)
    datetime dtBarPrevious=dtBarCurrent;
             dtBarCurrent=(datetime) SeriesInfoInteger(_Symbol,_Period,SERIES_LASTBAR_DATE);
    bool NewBarFlag=(dtBarCurrent!=dtBarPrevious);
    if(NewBarFlag)
    {
              
     int total = OrdersTotal();                                                                    // Opens multiple trades
     if(total < Max_Trades)
     { for(total; total >=0; total++)                                                              // Cycle searching in number of open orders
        { if(OrderSelect(total+1,SELECT_BY_POS,MODE_TRADES))                                       // Check if next order is available
           { if(OrderSymbol()==Symbol()) 
             total++; }
        }
     }
   
// calculate indicators

//-------------------------------------------------------------------------------------------------------------------------------

   if(OrdersTotal() < Max_Trades)                                                                 // Buy and sell criteria
     {
      if(insert criteria)                                                                         // Buy criteria                  
        { int OpenBuy = OrderSend(Symbol(),OP_BUY,Lots,Ask,Slippage,0,0,str1+" :",MagicNumber,0,Blue); }

      if(insert criteria)                                                                         // Sell criteria
        { int OpenSell=OrderSend(Symbol(),OP_SELL,Lots,Bid,Slippage,0,0,str1+" :",MagicNumber,0,Red);  }
     }
 //-------------------------------------------------------------------------------------------------------------------------------
 
   if(OrdersTotal() > 0)                                                                          // Close trades criteria
     {
      if(OrderType() == OP_BUY)                                                                   // Close Buy positions
        {
         if(insert criteria) 
           { int CloseBuy = OrderClose(OrderTicket(), OrderLots(),OrderClosePrice(), 5, LightBlue); }
        }

      if(OrderType() == OP_SELL)                                                                  // Close Sell positions
        {
         if(insert criteria)
           { int CloseSell = OrderClose(OrderTicket(), OrderLots(),OrderClosePrice(), 5, Orange); }       
        }
     }
   }
  }
//-------------------------------------------------------------------------------------------------------------------------------
 
  1.     if(OrdersTotal() > 0)
    Using OrdersTotal/OrdersHistoryTotal (MT4) or PositionsTotal (MT5), directly and/or no Magic number filtering on your OrderSelect/Position select loop means your code is incompatible with every EA (including itself on other charts and manual trading.)
              Symbol Doesn't equal Ordersymbol when another currency is added to another seperate chart . - MQL4 programming forum
              MagicNumber: "Magic" Identifier of the Order - MQL4 Articles

  2.       if(OrderType() == OP_BUY)                                                                   // Close Buy positions
            {
             if(insert criteria) 
               { int CloseBuy = OrderClose(OrderTicket(), OrderLots(),OrderClosePrice(), 5, LightBlue); }
    You can not use any Trade Functions unless you select an order first.

  3.         { int OpenBuy = OrderSend(Symbol(),OP_BUY,Lots,Ask,Slippage,0,0,str1+" :",MagicNumber,0,Blue); }
            { int OpenSell=OrderSend(Symbol(),OP_SELL,Lots,Bid,Slippage,0,0,str1+" :",MagicNumber,0,Red);  }
    Check your return codes for errors, and report them including GLE/LE and your variable values. Don't look at GLE/LE unless you have an error. Don't just silence the compiler, it is trying to help you.
              What are Function return values ? How do I use them ? - MQL4 programming forum
              Common Errors in MQL4 Programs and How to Avoid Them - MQL4 Articles

  4. siyasauka I suspect there is something wrong 
    Use the debugger or print out your variables, including _LastError and prices and . Do you really expect us to debug your code for you?
 
William Roeder:
  1. Using OrdersTotal/OrdersHistoryTotal (MT4) or PositionsTotal (MT5), directly and/or no Magic number filtering on your OrderSelect/Position select loop means your code is incompatible with every EA (including itself on other charts and manual trading.)
              Symbol Doesn't equal Ordersymbol when another currency is added to another seperate chart . - MQL4 programming forum
              MagicNumber: "Magic" Identifier of the Order - MQL4 Articles

  2. You can not use any Trade Functions unless you select an order first.

  3. Check your return codes for errors, and report them including GLE/LE and your variable values. Don't look at GLE/LE unless you have an error. Don't just silence the compiler, it is trying to help you.
              What are Function return values ? How do I use them ? - MQL4 programming forum
              Common Errors in MQL4 Programs and How to Avoid Them - MQL4 Articles

  4. Use the debugger or print out your variables, including _LastError and prices and . Do you really expect us to debug your code for you?

Thanks for your pointers... it's greatly appreciated. :-) 

I rewrote the code, as per your advice and it works almost perfectly (it took me a week since I am a beginner :-) ). The only issue is that the EA also opens trades when i load it - it does not wait for the next bar.  

The only thing I still need to add are the errors (as you suggested), but I'll do it shortly. 

This is the code that I have landed on: 

extern double  Lots=0.01;                           //Lots Size
extern string  str1="Magic EA";                     //Special Name/Code of EA
extern int     Max_Trades=2;                        //Maximum Number of Trades Per Currency
extern int     MagicNumber=1986;                    //Magic Number

//criteria for indicators

//---- expert initialization function -----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------

int OnInit()
  { return(0); }

void OnDeinit(const int reason)
  { }

//---- expert trading function ------------------------------------------------------------------------------------------------------------
//+----------------------------------------------------------------------------------------------------------------------------------------

int OpenOrders()
{
   int Orders=0;
   for(int i=0; i<OrdersTotal(); i++)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false)
        { continue; }
      if(OrderSymbol()!=Symbol())
        { continue; }
      Orders++;
     }
   return(Orders);
}

void OnTick(void)
{ 
  static datetime BarCurr = WRONG_VALUE;                                                     // Check for New Bar (Compatible with both MQL4 and MQL5)
  datetime BarPrev = BarCurr;
           BarCurr = (datetime) SeriesInfoInteger(_Symbol,_Period,SERIES_LASTBAR_DATE);
  bool NewBar = (BarCurr!=BarPrev);
 
  if(NewBar)
  {         
    //add indicators
    
    if(OpenOrders()<Max_Trades)        
    { 
         // Open Buy Trade
         if(//add indicators)                                                                                                        
            {  int OpenBuy =OrderSend(Symbol(),OP_BUY,Lots,Ask,5,0,0,str1+" ",MagicNumber,0,Blue);
               Print("Buy order opened successfully: ", _Symbol); 
               if(OpenBuy<1) Print("Buy order could not be opened for ", _Symbol);  }
            
         // Open Sell Trade
         if(//add indicators)                                                                                                     
            {  int OpenSend = OrderSend(Symbol(),OP_SELL,Lots,Bid,5,0,0,str1+" ",MagicNumber,0,Red);
               Print("Buy order opened successfully: ", _Symbol); 
               if(OpenSend<1) Print("Sell order could not be opened for ", _Symbol);  }
     }

   if (OrdersTotal() > 0)
   {
     for(int k=0; k<=OrdersTotal(); k++)                                                  // Cycle check open orders
     { if(OrderSelect(k,SELECT_BY_POS,MODE_TRADES)==true)
       { if(OrderSymbol() != Symbol()) continue; 
         
         else          
         { 
            // Close Buy Trades             
            if(OrderType() == OP_BUY)                                                      
            {  if(//add indicators)       
               {  int CloseBuy = OrderClose(OrderTicket(), OrderLots(),Bid, 5, LightBlue); k--;
                  Print("Buy order closed successfully for ", _Symbol); }
            }
            
            // Close Sell Trades
            if(OrderType() == OP_SELL)                                                    
            {  if(//add indicators)         
               {  int CloseSend = OrderClose(OrderTicket(), OrderLots(),Ask, 5, Magenta); k--;
                  Print("Buy order closed successfully for ", _Symbol); }
            }
         }
       }
    }}

}}
//-----------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------
 

As per comment above, the EA also opens trades when i load it - it does not wait for the next bar.  How do i update the following text to ensure that it waits for the next bar to open a trade?


void OnTick(void)
{ 
  static datetime BarCurr = WRONG_VALUE;                                                     
  datetime BarPrev = BarCurr;
           BarCurr = (datetime) SeriesInfoInteger(_Symbol,_Period,SERIES_LASTBAR_DATE);
  bool NewBar = (BarCurr!=BarPrev);
 
  if(NewBar)
  {
	// add code
  }
}