//+------------------------------------------------------------------+
//|                         Daily Range Strategy by Micardo v0.1.mq4 |
//|                                    Copyright ?2006, Hua Ai (aha) |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Copyright ?2006, Hua Ai (aha)"
#property link      ""

//---- input parameters
extern int       Timetotrade=0;
extern int       NumofLots=2;
extern double    Lotsize=0.1;
extern int       StraddleDistance=50;
extern int       TP1=27;
extern int       TP2=77;
extern int       TP3=77;
extern bool      ReEntryIfNoProfit=true;

int              magicnum, spread, TP[10];
double           dailyopen;
bool             LTP, STP, nolongorder, noshortorder, orderplaced;
//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//----
   magicnum = 1000 + GetTimeframeConstant(Period()) + GetSymbolConstant(Symbol());
   spread = MarketInfo(Symbol(),MODE_SPREAD);
   
   TP[0]=TP1;
   TP[1]=TP2;
   if(NumofLots>2) TP[2]=TP3;
   
   LTP=false;STP=false;nolongorder=true;noshortorder=true;orderplaced=false;

//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
//----
   int i, cnt, orders, ticket, total, TimetoClose;
   
   if(Hour()==Timetotrade) dailyopen=iOpen(NULL, PERIOD_D1, 0);

   if(Timetotrade==0) 
      TimetoClose=23; 
   else 
      TimetoClose=Timetotrade-1;
   
   // Close all existing orders (Market&limit) at the end of the day.
   if(Hour()==TimetoClose&&Minute()>=50)
   {
      total=OrdersTotal();

      for(cnt=0;cnt<total;cnt++)
      {
         OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
         ticket=OrderTicket();
         if(OrderMagicNumber()==magicnum)
         {
            if(OrderType()==OP_BUY) OrderClose(ticket,OrderLots(),Bid,3,Violet);
            if(OrderType()==OP_SELL) OrderClose(ticket,OrderLots(),Ask,3,Violet);
            if(OrderType()==OP_BUYLIMIT||OrderType()==OP_SELLLIMIT) OrderDelete(ticket);
         }
      }
      nolongorder=true;noshortorder=true;LTP=false;STP=false;
   }
   
   // Take Profit and Break Even
   total=OrdersTotal();
   if(Bid-dailyopen-StraddleDistance*Point>=TP1*Point&&Bid-dailyopen-StraddleDistance*Point<TP2*Point)
   {
      for(cnt=0;cnt<total;cnt++)
      {
         OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
         ticket=OrderTicket();
         if(OrderMagicNumber()==magicnum&&OrderType()==OP_BUY&&OrderLots()==NumofLots*Lotsize)
         {
            if(NumofLots==2) 
            {
               OrderModify(ticket,OrderOpenPrice(),OrderOpenPrice(),dailyopen+(StraddleDistance+TP2)*Point,0);
               LTP=true;
            }
            OrderClose(ticket,Lotsize,Bid,3,Violet);
         }
      }
   }
   else if (Bid-dailyopen-StraddleDistance*Point>=TP2*Point&&Bid-dailyopen-StraddleDistance*Point<TP3*Point)
   {
      for(cnt=0;cnt<total;cnt++)
      {
         OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
         ticket=OrderTicket();
         if(OrderMagicNumber()==magicnum&&OrderType()==OP_BUY&&OrderLots()==(NumofLots-1)*Lotsize)
         {
            if(NumofLots==3) 
            {
               OrderModify(ticket,OrderOpenPrice(),OrderOpenPrice(),dailyopen+(StraddleDistance+TP3)*Point,0);
               LTP=true;
            }
            OrderClose(ticket,Lotsize,Bid,3,Violet);
            if(NumofLots==2) nolongorder=true;
         }
      }
   }
   else if (Bid-dailyopen-StraddleDistance*Point>=TP3*Point&&NumofLots==3)
   {
      for(cnt=0;cnt<total;cnt++)
      {
         OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
         ticket=OrderTicket();
         if(OrderMagicNumber()==magicnum&&OrderType()==OP_BUY)
         {
            OrderClose(ticket,Lotsize,Bid,3,Violet);
         }
         nolongorder=true;
      }
   }
   else if (dailyopen-StraddleDistance*Point-Ask>=TP1*Point&&dailyopen-StraddleDistance*Point-Ask<TP2*Point)
   {
      for(cnt=0;cnt<total;cnt++)
      {
         OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
         ticket=OrderTicket();
         if(OrderMagicNumber()==magicnum&&OrderType()==OP_SELL&&OrderLots()==NumofLots*Lotsize)
         {
            if(NumofLots==2) 
            {
               OrderModify(ticket,OrderOpenPrice(),OrderOpenPrice(),dailyopen-(StraddleDistance+TP2)*Point,0);
               STP=true;
            }
            OrderClose(ticket,Lotsize,Ask,3,Violet);
         }
      }
   }
   else if (dailyopen-StraddleDistance*Point-Ask>=TP2*Point&&dailyopen-StraddleDistance*Point-Ask<TP3*Point)
   {
      for(cnt=0;cnt<total;cnt++)
      {
         OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
         ticket=OrderTicket();
         if(OrderMagicNumber()==magicnum&&OrderType()==OP_SELL&&OrderLots()==(NumofLots-1)*Lotsize)
         {
            if(NumofLots==3) 
            {
               OrderModify(ticket,OrderOpenPrice(),OrderOpenPrice(),dailyopen-(StraddleDistance+TP3)*Point,0);
               STP=true;
            }
            OrderClose(ticket,Lotsize,Ask,3,Violet);
            if(NumofLots==2) noshortorder=true;
         }
      }
   }
   else if (dailyopen-StraddleDistance*Point-Ask>=TP3*Point&&NumofLots==3)
   {
      for(cnt=0;cnt<total;cnt++)
      {
         OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
         ticket=OrderTicket();
         if(OrderMagicNumber()==magicnum&&OrderType()==OP_SELL)
         {
            OrderClose(ticket,Lotsize,Ask,3,Violet);
            noshortorder=true;
         }
      }
   }

      total=OrdersTotal();
      nolongorder=true;noshortorder=true;
      for(cnt=0;cnt<total;cnt++)
      {
         OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
         if(OrderSymbol()==Symbol()&&OrderMagicNumber()==magicnum)
         {
            if(OrderType()==OP_BUY) nolongorder=false;
            if(OrderType()==OP_SELL) noshortorder=false;
         }
      }

   // Entry and Reentry logic
   //if((Ask>=dailyopen+StraddleDistance*Point||Bid<=dailyopen-StraddleDistance*Point)&&Hour()!=TimetoClose)
   //if((Ask>=dailyopen+6*Point||Bid<=dailyopen-6*Point)&&Hour()!=TimetoClose)
   if(Hour()!=TimetoClose)
   {
      /*total=OrdersTotal();
      nolongorder=true;noshortorder=true;
      for(cnt=0;cnt<total;cnt++)
      {
         OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
         if(OrderSymbol()==Symbol()&&OrderMagicNumber()==magicnum)
         {
            if(OrderType()==OP_BUY) nolongorder=false;
            if(OrderType()==OP_SELL) noshortorder=false;
         }
      }*/
      
      //if(nolongorder&&((ReEntryIfNoProfit&&!LTP)||!ReEntryIfNoProfit)&&(Ask>=dailyopen+StraddleDistance*Point))
      if(nolongorder&&((ReEntryIfNoProfit&&!LTP)||!ReEntryIfNoProfit))
      //if(nolongorder)
      {
         //ticket=OrderSend(Symbol(),OP_BUY,NumofLots*Lotsize,dailyopen+StraddleDistance*Point,3,dailyopen,0,"Daily Range Strategy",magicnum,0,Green);
         ticket=OrderSend(Symbol(),OP_BUY,NumofLots*Lotsize,dailyopen+StraddleDistance*Point,3,dailyopen,0,"Daily Range Strategy",magicnum,0,Green);
         if(ticket>0&&OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
         {
            nolongorder=false;LTP=false;
            Print("Long order opened : ",OrderOpenPrice());
         }
         else Print("Error opening Long limit order : ",GetLastError()); 
      }

      if(noshortorder&&((ReEntryIfNoProfit&&!STP)||!ReEntryIfNoProfit)&&(Bid<=dailyopen-StraddleDistance*Point))
      {
         ticket=OrderSend(Symbol(),OP_SELL,NumofLots*Lotsize,dailyopen-StraddleDistance*Point,3,dailyopen,0,"Daily Range Strategy",magicnum,0,Red);
         if(ticket>0&&OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
         {
            noshortorder=false;STP=false;
            Print("Short order opened : ",OrderOpenPrice());
         }
         else Print("Error opening Short limit order : ",GetLastError()); 
      }
   }
//----
   return(0);
  }
//+------------------------------------------------------------------+


//+------------------------------------------------------------------+
//| Time frame interval appropriation function                       |
//+------------------------------------------------------------------+
int GetTimeframeConstant(int chart_period) {
   switch(chart_period) {
      case 1:  // M1
         return(50);
      case 5:  // M5
         return(100);
      case 15:
         return(150);
      case 30:
         return(200);
      case 60:
         return(250);
      case 240:
         return(300);
      case 1440:
         return(350);
      case 10080:
         return(400);
      case 43200:
         return(450);
   }
}


//+------------------------------------------------------------------+
//| Symbol to index                                                  |
//+------------------------------------------------------------------+
int GetSymbolConstant(string symbol) {

	if(symbol=="EURUSD") {	return(1);
	} else if(symbol=="GBPUSD") { return(2);
	} else if(symbol=="USDCHF") {	return(3);
	} else if(symbol=="USDJPY") {	return(4);
	} else if(symbol=="USDCAD") {	return(5);
	} else if(symbol=="AUDUSD") {	return(6);
	} else if(symbol=="CHFJPY") {	return(7);
	} else if(symbol=="EURAUD") {	return(8);
	} else if(symbol=="EURCAD") {	return(9);
	} else if(symbol=="EURCHF") {	return(10);
	} else if(symbol=="EURGBP") {	return(11);
	} else if(symbol=="EURJPY") {	return(12);
   } else if(symbol=="GBPCHF") {	return(13);
	} else if(symbol=="GBPJPY") {	return(14);
	} else if(symbol=="GOLD") {	return(15);
	} else {Print("Error: Unexpected symbol."); return(0);
	}
}