Need help with EA

Hi Babypips,

I’m looking for your help with a bit of MQL4 code.

My current (and first!) EA isn’t very selective and places too many awesome trades at once. Preferably I’d like it to not trade if either of the following items are true:

  1. Frequency) If the last trade was more than X minutes ago (long or short)

  2. Amount) If there are more than Y amount of trades in the same direction. If the decision engine wants to go long, but I’m already long by Y amount of trades, then I would like it to not trade.

The EA is a rip-off of the MACD Sample that came with my MetaTrader client. Here’s my current EA with the decision engine ripped out:
extern double TakeProfit = 40;
extern double TrailingStop = 20;
extern double StopLoss = 20;
extern double Lots = 0.1;
extern double Slippage = 3;

//±-----------------------------------------------------------------+
//| |
//±-----------------------------------------------------------------+
int start()
{//A1
int t = 0;
int cnt, ticket, total;
// INITIAL DATA CHECKS
// on a chart of less than 100 bars
if(Bars<100)
{//B1
Print(“bars less than 100”);
return(0);
}//B1
if(TakeProfit<20)
{//B2
Print(“TakeProfit less than 20”);
return(0); // check TakeProfit
}//B2
//I’m thinking I need something here to prevent it from trading too often
//to simplify the coding and speed up access
//data are put into internal variables

total=OrdersTotal();
if(total<1)
{//C1
// no opened orders identified
if(AccountFreeMargin()<(10000*Lots))
{//C2
Print("Not enough Free Margin to Trade. Free Margin = ", AccountFreeMargin());
return(0);
}//C2
}//C1
// CHECK FOR LONG POSTITION (BUY) possibility

if
(//D1
//Long Decision Engine Goes Here
//Needs something to prevent it from making too many long trades

)//D1
{//E1
ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,Slippage,0,Ask+Point*TrailingStop,"LONG-Price/Volume Robot",30138,0,Green);
if(ticket&gt;0)
  {//E2
  if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
    {//E3
    Print("BUY order opened : ",OrderOpenPrice());
    }//E3
    }//E2
  else
    {//E4
    Print("Error opening BUY order : ",GetLastError()); 
    return(0);        
    }//E4
}//E1

// CHECK FOR SHORT POSITION (SELL) possibility
if
(//F1
//Short Decision Engine Goes Here
//Needs something to prevent it from making too many short trades
)//F1
{//F6
ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,Slippage,0,Bid-Point*TrailingStop,“SHORT-Price/Volume Robot”,30138,0,Red);
if(ticket>0)
{//F7
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
{//F8
Print("SELL order opened : ",OrderOpenPrice());
}//F8
}//F7
else
{//F9
Print("Error opening SELL order : ",GetLastError());
return(0);
}//F9
return(0);
}//F6

//EXITING INSTRUCTIONS BELOW
for(cnt=0;cnt<total;cnt++)
{//G1
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
if
(//G2
OrderType()<=OP_SELL && // check for opened position
OrderSymbol()==Symbol() // check for symbol
)//G2

//CAN LONG POSITION BE CLOSED?

{//G3
  if(OrderType()==OP_BUY)   // CHECKS TO FIND LONG POSITIONS
    {//G4
    if((Bid-OrderOpenPrice())&gt;=(Point*TakeProfit))
      {//G5
      OrderClose(OrderTicket(),OrderLots(),Bid,Slippage,Green); // close position
      return(0); // exit
      }//G5
    if((OrderOpenPrice()-Bid)&gt;=(Point*StopLoss))
      {//G6
      OrderClose(OrderTicket(),OrderLots(),Bid,Slippage,Red); // close position
      return(0);
      }//G6
    if(((Bid-OrderOpenPrice())&gt;=(Point*TrailingStop)) && (Bid-OrderOpenPrice()&lt;(Point*TakeProfit)))
      {//G7
      OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Blue);
      return(0);
      }//G7

//CAN SHORT POSITION BE CLOSED?

  else 
    {//H1
    if((OrderOpenPrice()-Ask)&gt;=(Point*TakeProfit))
      {//H2
      OrderClose(OrderTicket(),OrderLots(),Ask,Slippage,Green); // close position
      return(0); // exit
      }//H2
    if((Ask-OrderOpenPrice())&gt;=(Point*StopLoss))
      {//H3
      OrderClose(OrderTicket(),OrderLots(),Ask,Slippage,Red); // close position
      }//H3		
    if(((OrderOpenPrice()-Ask)&gt;=(Point*TrailingStop)) && (OrderOpenPrice()-Ask&lt;(Point*TakeProfit)))
      {//H4
      OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*TrailingStop,OrderTakeProfit(),0,Green);
      }//H4
    }//H1
    }//G4

return(0);
}//G3
}//G1
}//A1
// ÇA SUFFIT!!!

I didn’t look closely at your code, I’m not into that.

Here is my suggestion, which has worked time after time. The best way to limit your orders is by time or bars. Say trade once every 10 bars. In the program you check OrderOpenTime for the newest order and when its time to open another trade, go ahead. nbars = MathCeil((Time[0] - orderOpenTime)/(Period()*60)). orderOpenTime is for the newest order. The user could control the number of bars with an input setting.

The solution for the other situation is to count the number of open orders before opening another order. Again the user should be able to set this maximum. In your case I guess you need 2 settings for long and short. OrdersTotal will give you the raw number, but it doesn’t tell you the pending total or the sell/buy totals. So you have to examine each order’s type with OrderType.

Hope that helps.

There is a way to attach your EA in zip file rather then Ctrl+C & Ctrl+V it.

Or use The CODE tag like this:

extern double TakeProfit = 40;
extern double TrailingStop = 20;
extern double StopLoss = 20;
extern double Lots = 0.1;
extern double Slippage = 3;


//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int start()
  {//A1
  int t = 0;
  int cnt, ticket, total;
// INITIAL DATA CHECKS
// on a chart of less than 100 bars
  if(Bars<100)
    {//B1
    Print("bars less than 100");
    return(0);  
    }//B1
  if(TakeProfit<20)
    {//B2
    Print("TakeProfit less than 20");
    return(0);  // check TakeProfit
    }//B2
//I'm thinking I need something here to prevent it from trading too often
//to simplify the coding and speed up access
//data are put into internal variables

  total=OrdersTotal();
  if(total<1) 
    {//C1
// no opened orders identified
  if(AccountFreeMargin()<(10000*Lots))
    {//C2
    Print("Not enough Free Margin to Trade. Free Margin = ", AccountFreeMargin());
    return(0);  
    }//C2
    }//C1
// CHECK FOR LONG POSTITION (BUY) possibility

  if
    (//D1
//Long Decision Engine Goes Here
//Needs something to prevent it from making too many long trades

    )//D1
    {//E1
    ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,Slippage,0,Ask+Point*TrailingStop,"LONG-Price/Volume Robot",30138,0,Green);
    if(ticket>0)
      {//E2
      if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
        {//E3
        Print("BUY order opened : ",OrderOpenPrice());
        }//E3
        }//E2
      else
        {//E4
        Print("Error opening BUY order : ",GetLastError()); 
        return(0);        
        }//E4
    }//E1


// CHECK FOR SHORT POSITION (SELL) possibility
  if
    (//F1
//Short Decision Engine Goes Here
//Needs something to prevent it from making too many short trades
    )//F1
    {//F6
    ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,Slippage,0,Bid-Point*TrailingStop,"SHORT-Price/Volume Robot",30138,0,Red);
    if(ticket>0)
      {//F7
      if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
        {//F8
        Print("SELL order opened : ",OrderOpenPrice());
        }//F8
      }//F7
      else
        {//F9
        Print("Error opening SELL order : ",GetLastError()); 
        return(0); 
        }//F9
      return(0);
    }//F6


//EXITING INSTRUCTIONS BELOW
  for(cnt=0;cnt<total;cnt++)
    {//G1
    OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
    if
      (//G2
      OrderType()<=OP_SELL &&  // check for opened position 
      OrderSymbol()==Symbol()  // check for symbol
      )//G2  

//CAN LONG POSITION BE CLOSED?

    {//G3
      if(OrderType()==OP_BUY)   // CHECKS TO FIND LONG POSITIONS
        {//G4
        if((Bid-OrderOpenPrice())>=(Point*TakeProfit))
          {//G5
          OrderClose(OrderTicket(),OrderLots(),Bid,Slippage,Green); // close position
          return(0); // exit
          }//G5
        if((OrderOpenPrice()-Bid)>=(Point*StopLoss))
          {//G6
          OrderClose(OrderTicket(),OrderLots(),Bid,Slippage,Red); // close position
          return(0);
          }//G6
        if(((Bid-OrderOpenPrice())>=(Point*TrailingStop)) && (Bid-OrderOpenPrice()<(Point*TakeProfit)))
          {//G7
          OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Blue);
          return(0);
          }//G7


//CAN SHORT POSITION BE CLOSED?		

      else 
        {//H1
        if((OrderOpenPrice()-Ask)>=(Point*TakeProfit))
          {//H2
          OrderClose(OrderTicket(),OrderLots(),Ask,Slippage,Green); // close position
          return(0); // exit
          }//H2
        if((Ask-OrderOpenPrice())>=(Point*StopLoss))
          {//H3
          OrderClose(OrderTicket(),OrderLots(),Ask,Slippage,Red); // close position
          }//H3		
        if(((OrderOpenPrice()-Ask)>=(Point*TrailingStop)) && (OrderOpenPrice()-Ask<(Point*TakeProfit)))
          {//H4
          OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*TrailingStop,OrderTakeProfit(),0,Green);
          }//H4
        }//H1
        }//G4

return(0);
  }//G3
  }//G1
  }//A1
// ÇA SUFFIT!!!!

:wink:

One trick I haven’t seen used here is having 'static int prevtime; ’ declaring a var with this method will store it’s value for the next time the chart ticks, so you could count for each event maybe.

a common one is to do
if (Time[0]!=prevtime)
{
’ do dometing’
prevtime=Time[0]
}

[B]fxmatics[/B], I’ll be sure to post future code in the format you mentioned.

To all, I was able to fix with the following code:

if((TimeCurrent() - OrderOpenTime())<TimeLimit)
{
Print("Not enough time since last trade. TimePassed = ",TimeCurrent()-OrderOpenTime())
return(0);
}