Download MetaTrader 5

Binary EA buy on new candle

To add comments, please log in or register
funkynation
45
funkynation 2015.08.17 19:10 

hi guys, im new to mql4 coding.

i started by a simple binary ea with 60s trades, bollinger and rsi, everything works, but it doesnt wait to buy/sell for the new candle, i want to open a trade on the next candle if the conditions are true.

i looked already in the forum and found nice help for new bars, but in my ea it doesnt seem to work.

maybe someone can help me?

thanks :)

extern int MagicNumber=190001;
extern double Lots =10;
extern double Deviation =3;
extern double RSIperiod =4;
extern double RSIupper =90;
extern double RSIlower =10;
static datetime lastbar;

bool IsNewBar() 
{ 
datetime curbar = Time[0];

if (lastbar!=curbar) 
   { 
    lastbar=curbar; 
    return (true); 
   } 

  return(false); 

}

int init()
{
lastbar=Time[1];
  double MyPoint=Point;
  if(Digits==3 || Digits==5) MyPoint=Point*10;
return (0);
}


int start()
{
  if( TotalOrdersCount()==0 ) 
  {
     int result=0;
      if((Close[0]<iBands(NULL,0,20,Deviation,0,PRICE_CLOSE,MODE_LOWER,0))&&(iRSI(NULL,0,RSIperiod,PRICE_CLOSE,0)<RSIlower))
     {
        if (IsNewBar())
        {
        result=OrderSend(Symbol(),OP_BUY,Lots,Ask,0,0,0,"BO exp:60",MagicNumber,0,Blue);
        }
        {
        return(0);
        }
     }
     if((Close[0]>iBands(NULL,0,20,Deviation,0,PRICE_CLOSE,MODE_UPPER,0))&&(iRSI(NULL,0,RSIperiod,PRICE_CLOSE,0)>RSIupper))
        {
        if (IsNewBar())
        {
        result=OrderSend(Symbol(),OP_BUY,Lots,Ask,0,0,0,"BO exp:60",MagicNumber,0,Blue);
        {
        }
        return(0);
        }
     }
  }
  
  for(int cnt=0;cnt<OrdersTotal();cnt++)
     {
      result=OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
      if(OrderType()<=OP_SELL &&   
         OrderSymbol()==Symbol() &&
         OrderMagicNumber()==MagicNumber 
         )  
        {
         if(OrderType()==OP_BUY)  
           {
              {                 
                return(0);
                    }
                 }
              }
        
                 }
       
   return(0);
}

int TotalOrdersCount()
{
  int result=0;
  for(int i=0;i<OrdersTotal();i++)
  {
     result=OrderSelect(i,SELECT_BY_POS ,MODE_TRADES);
     if (OrderMagicNumber()==MagicNumber) result++;

   }
  return (result);
}

Keith Watford
Moderator
9640
Keith Watford 2015.08.17 22:54  

int start()
{
  if( TotalOrdersCount()==0 && IsNewBar()) 
  {
     int result=0;
      if((Close[0]<iBands(NULL,0,20,Deviation,0,PRICE_CLOSE,MODE_LOWER,0))&&(iRSI(NULL,0,RSIperiod,PRICE_CLOSE,0)<RSIlower))
     {
        //if (IsNewBar())
        {
        result=OrderSend(Symbol(),OP_BUY,Lots,Ask,0,0,0,"BO exp:60",MagicNumber,0,Blue);
        }
        {
        return(0);
        }
     }
     if((Close[0]>iBands(NULL,0,20,Deviation,0,PRICE_CLOSE,MODE_UPPER,0))&&(iRSI(NULL,0,RSIperiod,PRICE_CLOSE,0)>RSIupper))
        {
        //if (IsNewBar())
        {
        result=OrderSend(Symbol(),OP_BUY,Lots,Ask,0,0,0,"BO exp:60",MagicNumber,0,Blue);
        {
        }
        return(0);
        }
     }
  }

 Check index 1, not index 0 if you don't want to use the values from the first tick of a new bar

Why do the checks every tick if you are only going to use them when there is a new bar? Use the new bar as a condition for the whole block.

funkynation
45
funkynation 2015.08.18 06:20  
Thank you very much for your help,  works exactly as i want :) after thinking what i did wrong its now logical why it didnt worked.
Im going to optimize the system with a martingale method to increase the profits and let you all know when its done. 
Wish a nice day
funkynation
45
funkynation 2015.08.19 10:35  

now i tried to increase the lot size, but it uses always the same lot.. tried to print which value losses has but doesnt work, maybe you can help me?

dont worry about the entry conditions its just for testing.

extern int MagicNumber=1291;

extern double Deviation =1;
extern double RSIperiod =4;
extern double RSIupper =50;
extern double RSIlower =40;

static datetime lastbar;

extern bool UseTradingHours =true;
extern int OpenHour =09;
extern int OpenMin =15;
extern int CloseHour =23;
extern int CloseMin =45;

extern double Lots =2;
extern double Lots2 =4;   

int init()
{
lastbar=Time[1];
  double MyPoint=Point;
  if(Digits==3 || Digits==5) 
  {
  MyPoint=Point*10;
  }
return (0);
}

double checkloss()
{8
  int losses=0;                        
   int i;                                
   for(i=0; i<OrdersHistoryTotal(); i++) 
   {                                     
       OrderSelect(i,SELECT_BY_POS,MODE_HISTORY); 
       if(OrderSymbol()!=Symbol() ||     
       OrderMagicNumber()!=MagicNumber) 
       continue; 
       if(OrderProfit()<0) losses++;
       else                losses=0;  
   }
     return(losses); 
     Print("trade nr" ,losses);                           
}
int start()
{
  if((TotalOrdersCount()==0) && (IsNewBar() == true) && (UseTradingHours == true) && (TradingHours()== true)) 
  {
  int result=0;
 
      if((Close[1]<iBands(NULL,0,20,Deviation,0,PRICE_CLOSE,MODE_LOWER,1))&&(iRSI(NULL,0,RSIperiod,PRICE_CLOSE,1)<RSIlower))
     {
     if (checkloss() == 0) 
     {
     result=OrderSend(Symbol(),OP_BUY,Lots,Ask,0,0,0,"BO exp:60",MagicNumber,0,Blue);
     }
     if (checkloss() == 1)
     {
     result=OrderSend(Symbol(),OP_BUY,Lots2,Ask,0,0,0,"BO exp:60",MagicNumber,0,Blue);
     }
     }
     if((Close[1]>iBands(NULL,0,20,Deviation,0,PRICE_CLOSE,MODE_UPPER,1))&&(iRSI(NULL,0,RSIperiod,PRICE_CLOSE,1)>RSIupper))
        {
        if (checkloss() == 0) 
        {
        result=OrderSend(Symbol(),OP_SELL,Lots,Bid,0,0,0,"BO exp:60",MagicNumber,0,Blue);
             }
     if (checkloss() == 1)
     {
     result=OrderSend(Symbol(),OP_SELL,Lots2,Bid,0,0,0,"BO exp:60",MagicNumber,0,Blue);
        }
        }
          }
  for(int cnt=0;cnt<OrdersTotal();cnt++)
     {
      result=OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
    }
   return(0);
}

bool IsNewBar() 
{ 
datetime curbar = Time[0];
if (lastbar!=curbar) 
   { 
    lastbar=curbar; 
    return (true); 
   } 
  return(false); 
}

int TotalOrdersCount()
{
  int result=0;
  for(int i=0;i<OrdersTotal();i++)
  {
     result=OrderSelect(i,SELECT_BY_POS ,MODE_TRADES);
     if (OrderMagicNumber()==MagicNumber)
     { 
     result++;
     }
   }
  return (result);
}

bool TradingHours()
{
   if(CloseHour>OpenHour)
   {
      if (OpenHour < TimeHour(TimeCurrent()) && TimeHour(TimeCurrent()) < CloseHour)
         {
         Comment("Open For Trading");
         return(true);
         }
      if (OpenHour == TimeHour(TimeCurrent()))
      {
         if(OpenMin<=TimeMinute(TimeCurrent()))
         {
         Comment("Open For Trading");
         return(true);
         }
         return(false);
      }
      
      if (CloseHour == TimeHour(TimeCurrent()))
      {
         if(CloseMin>=TimeMinute(TimeCurrent()))
         {
         Comment("Open For Trading");
         return(true);
         }
         return(false);
      }
      Comment("Closed");
      return(false);
   }
   if(OpenHour>CloseHour) 
   {
      if (CloseHour < TimeHour(TimeCurrent()) && TimeHour(TimeCurrent()) < OpenHour)
         {
         Comment("Closed");
         return(false);
         }
      if (OpenHour == TimeHour(TimeCurrent()))
      {
         if(OpenMin<=TimeMinute(TimeCurrent()))
         {
         Comment("Open For Trading");
         return(true);
         }
         return(false);
      }
      if (CloseHour == TimeHour(TimeCurrent()))
      {
         if(CloseMin>=TimeMinute(TimeCurrent()))
         {
         Comment("Open For Trading");
         return(true);
         }
         return(false);
      }
      Comment("Open For Trading");
      return(true);
   }
return(0);
}
Keith Watford
Moderator
9640
Keith Watford 2015.08.19 12:29  
double checkloss()
{8                          //What is the 8????
  int losses=0;                        
   int i;                                
   for(i=0; i<OrdersHistoryTotal(); i++) 
   {                                     
       OrderSelect(i,SELECT_BY_POS,MODE_HISTORY); 
       if(OrderSymbol()!=Symbol() ||     
       OrderMagicNumber()!=MagicNumber) 
       continue; 
       if(OrderProfit()<0) losses++;
       else                losses=0;  
   }
     return(losses); 
     Print("trade nr" ,losses);                           
}

Your function doesn't make sense.

When it finds one trade with a profit it resets losses to 0

Why is it a double when it returns an int?

The print cannot print after a return 

funkynation
45
funkynation 2015.08.20 19:47  

thanks for your response, the function makes no sense, so i inegrated the loop into the start function. i made new half of the code to keep it more simple to learn and understand.

what i want to do is, buy/sell normal lot if conditions are true, then if this is a loosing trade, immidiatly buy/sell on the next candle the doubled lot size.

i tried the following code. it doesnt double up the lot size.. i think the problem is by finding the last lost trade?

thanks for your help

extern int MagicNumber=1291;

extern double Deviation =1;
extern double RSIperiod =4;
extern double RSIupper =10;
extern double RSIlower =90;

static datetime lastbar;

extern bool UseTradingHours =true;
extern int OpenHour =09;
extern int OpenMin =15;
extern int CloseHour =23;
extern int CloseMin =45;

extern double Lots =1;

bool buycondition()
{
if((Close[1]<iBands(NULL,0,20,Deviation,0,PRICE_CLOSE,MODE_LOWER,1))&& (iRSI(NULL,0,RSIperiod,PRICE_CLOSE,1)<RSIlower))
{
return(true);
}
return(false);
}

bool sellcondition()
 {
if((Close[1]>iBands(NULL,0,20,Deviation,0,PRICE_CLOSE,MODE_UPPER,1))&&(iRSI(NULL,0,RSIperiod,PRICE_CLOSE,1)>RSIupper))
{
return(true);
}
return(false);
}

string buy1(){OrderSend(Symbol(),OP_BUY,Lots,Ask,0,0,0,"BO exp:60",MagicNumber,0,Blue); return(0);}
string buy2(){OrderSend(Symbol(),OP_BUY,Lots*2,Ask,0,0,0,"BO exp:60",MagicNumber,0,Blue);return(0);}

string sell1(){OrderSend(Symbol(),OP_SELL,Lots,Bid,0,0,0,"BO exp:60",MagicNumber,0,Red); return(0);}
string sell2(){OrderSend(Symbol(),OP_SELL,Lots*2,Bid,0,0,0,"BO exp:60",MagicNumber,0,Red);return(0);}

int buyloss=0;
int sellloss=0;
  


int init()
{
lastbar=Time[1];
  double MyPoint=Point;
  if(Digits==3 || Digits==5) 
  {
  MyPoint=Point*10;
  }
return (0);
}

int start()
{
int result=0;
if (TotalOrderCount() > 0)
{
 return(0);
 }
 if((UseTradingHours == true) && (TradingHours()== true) && (IsNewBar() == true)) 
  {
 if(buycondition() == true)
     {
     result=buy1();
     }
     if (sellcondition() == true)
     {
     result=sell1();
     }
if (buyloss == 1)
{
result=buy2();
}
if (sellloss == 1)
{
result=sell2();
}
for(int i=(OrdersHistoryTotal()-1);i>=0;i--)
 {
   result=OrderSelect(i, SELECT_BY_POS,MODE_HISTORY);
   if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
    {
       if(OrderType()==OP_BUY && OrderProfit()>0) buyloss=0;
       if(OrderType()==OP_BUY && OrderProfit()<0) buyloss++;
       if(OrderType()==OP_SELL && OrderProfit()>0) sellloss=0;
       if(OrderType()==OP_SELL && OrderProfit()<0) sellloss++;
    }
 }
}
return(0);
}


int TotalOrderCount()
{
    int count=0;
    int pos=0;
    for(pos = OrdersTotal()-1; pos >= 0 ; pos--) 
    if 
    (
        OrderSelect(pos, SELECT_BY_POS)                
    &&  OrderMagicNumber()  == MagicNumber            
    &&  OrderSymbol()       == Symbol() 
    )
    {              
        count++;
    }
    return(count);
}

bool IsNewBar() 
{ 
datetime curbar = Time[0];
if (lastbar!=curbar) 
   { 
    lastbar=curbar; 
    return (true); 
   } 
  return(false); 
}

bool TradingHours()
{
   if(CloseHour>OpenHour)
   {
      if (OpenHour < TimeHour(TimeCurrent()) && TimeHour(TimeCurrent()) < CloseHour)
         {
         Comment("Open For Trading");
         return(true);
         }
      if (OpenHour == TimeHour(TimeCurrent()))
      {
         if(OpenMin<=TimeMinute(TimeCurrent()))
         {
         Comment("Open For Trading");
         return(true);
         }
         return(false);
      }
      
      if (CloseHour == TimeHour(TimeCurrent()))
      {
         if(CloseMin>=TimeMinute(TimeCurrent()))
         {
         Comment("Open For Trading");
         return(true);
         }
         return(false);
      }
      Comment("Closed");
      return(false);
   }
   if(OpenHour>CloseHour) 
   {
      if (CloseHour < TimeHour(TimeCurrent()) && TimeHour(TimeCurrent()) < OpenHour)
         {
         Comment("Closed");
         return(false);
         }
      if (OpenHour == TimeHour(TimeCurrent()))
      {
         if(OpenMin<=TimeMinute(TimeCurrent()))
         {
         Comment("Open For Trading");
         return(true);
         }
         return(false);
      }
      if (CloseHour == TimeHour(TimeCurrent()))
      {
         if(CloseMin>=TimeMinute(TimeCurrent()))
         {
         Comment("Open For Trading");
         return(true);
         }
         return(false);
      }
      Comment("Open For Trading");
      return(true);
   }
return(0);
}

Keith Watford
Moderator
9640
Keith Watford 2015.08.21 00:30  

If you just need to check if the last closed order was in profit or not

   int last_order_type=-1;
   datetime last_order_time=0;
   bool last_order_profit=true;
   
   for(int i=(OrdersHistoryTotal()-1);i>=0;i--)
     {
      result=OrderSelect(i,SELECT_BY_POS,MODE_HISTORY);
      if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
        {
         if(OrderCloseTime()>last_order_time)
            {
            last_order_time=OrderCloseTime();
            last_order_type=OrderType();
            last_order_profit=OrderProfit()>0;
            }
        }
     }

 last_order_profit will be true if no order found or the last order made a profit.

 false if the last order closed with a loss. 

 if(buycondition() == true)

 if (buyloss == 1)

 if (sellloss == 1)

 Because all 3 conditions are checked regardless of each other, it is possible for 3 trades to be placed in 1 tick.

Daniel Lagoshniak
225
Daniel Lagoshniak 2015.08.21 09:32  

What do you think about introducing a new variable that keeps ticket number in memory i.e. "ticket"? if ticket = 0 then there is no orders open and the last closed with profit. if ticket > 0 then order existed last bar so check its OrderCloseTime() and then OrderProfit()<0. if order ended with loss -> send a new order ticket = OrderSend(...); otherwise set ticket to be 0. this makes  TotalOrdersCount() useless

 if((UseTradingHours == true) && (TradingHours()== true) && (IsNewBar() == true)) - checks all three conditions or at least 1st then 2nd then 3rd of them every tick.does it make sense?

if (IsNewBar()) { if (UseTradingHours && !TradingHours()) return; ... //go with your conditions } - this checks only new bar every tick and then trading hours once a bar.

funkynation
45
funkynation 2015.08.25 17:10  
thanks for your help guys, im going to try it and let you know when its working :)
funkynation
45
funkynation 2015.09.24 17:53  

thanks for all your assitance, im new to mql4 and learning day by day :) my code still doenst work.. it uses always the same lotsize. i tried the following:

my goal is to use lot2 if the first trade is a loss, then use lot 3 if the second trade is a loss, no matter if its opbuy or opsell.

i think the problem is that losses returns always 0, but why?

extern double Lot1 =1;
extern double Lot2 =2;
extern double Lot3 =4;
int losses;

int checkforlosses()                   
{                                                               
int x;                               
   for(x=0; x<OrdersHistoryTotal(); x++) 
   {                                     
       OrderSelect(x,SELECT_BY_POS,MODE_HISTORY);
       if((OrderSymbol()==Symbol()) && (OrderMagicNumber()== MagicNumber) && (OrderProfit() < 0))
       {
       losses++;                         
       }                                 
       else 
       { 
       losses=0;
       }
   }
  return(losses);          
}

int start()
{
if (AccountBalance() >= DDAccountbalance)
{
int result=0;
if (TotalOrderCount() > 0)
{
return(0);
}
if (IsNewBar() == true)
{
if (checkforlosses() == 0 ) double Mylot =Lot1;
if (checkforlosses() == 1 ) Mylot =Lot2;
if (checkforlosses() == 2 ) Mylot =Lot3;
if(((UseTradingHours == true) && (TradingHours()== true) && (buycondition() == true)) || ((UseTradingHours == false) && (buycondition() == true)))
{
result=OrderSend(Symbol(),OP_BUY,Mylot,Ask,0,0,0,BOExpiry,MagicNumber,0,Blue);
}
if (((UseTradingHours == true) && (TradingHours() == true) && (sellcondition() == true)) || ((UseTradingHours == false) && (sellcondition() == true)))
{
result=OrderSend(Symbol(),OP_SELL,Mylot,Bid,0,0,0,BOExpiry,MagicNumber,0,Red);
}
}
}
else if (AccountBalance() <= DDAccountbalance)
{
Comment(EAName, ">>> MAX DD on Accountbalanced reached, STOPPED trading!!");
}
return(0);
}
Keith Watford
Moderator
9640
Keith Watford 2015.09.24 21:59  
                             
   for(x=0; x<OrdersHistoryTotal(); x++) 
   {                                     
       OrderSelect(x,SELECT_BY_POS,MODE_HISTORY);
       if((OrderSymbol()==Symbol()) && (OrderMagicNumber()== MagicNumber) && (OrderProfit() < 0))
       {
       losses++;                         
       }                                 
       else 
       { 
       losses=0;
       }
   }

You are checking all history, so unless you are changing the  magic number every time you start the EA, you may be counting irrelevant trades

The else means that if a trade is checked that isn't the same magic number or is a different symbol or made a profit, losses is set to 0. 

123
To add comments, please log in or register