//+------------------------------------------------------------------+
//|                            SimpleDailyRangeBreakExpert_v1.22.mq4 |
//|                                Copyright © 2006, TrendLaboratory |
//|            http://finance.groups.yahoo.com/group/TrendLaboratory |
//|                                   E-mail: igorad2003@yahoo.co.uk |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, TrendLaboratory"
#property link      "http://finance.groups.yahoo.com/group/TrendLaboratory"

#include <stdlib.mqh>
#include <Tracert.mqh>

//---- input parameters
extern string     Expert_Name = "---- SimpleDailyRangeBreakExpert_v1.22 ----";

extern int        Magic          = 12345;
extern int        Slippage       =     6;

extern bool       Trace = false;           // Trace Switch

extern string     Main_Parameters = " Trade Volume & Trade Method";
extern double     Lots           =   0.1;
extern double     TrailingStop   =     0;  // Trailing Stop Switch   
extern bool       InitialStop    =  true;  // Initial Stop Switch
extern int        TimeZone       =     0;   

extern string     Data = " Input Data ";
extern double     BuyPercent     =    70;  // Percent from Daily Range for BUY 	
extern double     SellPercent    =    70;  // Percent from Daily Range for SELL
extern double     StopPercent    =    50;  // Percent from Daily Range for StopLoss
extern int        TradePeriod    =     5;  // Max days in trade 
extern double     BreakEven      =     0;  // BreakEven Level in pips
extern double     BreakEvenGap   =     0;  // Pips when BreakEven will be reached

extern string     Trade   =  " Trade Days of Week";
extern int        Monday         =     1;  // Day of the Week for Trade
extern int        Tuesday        =     1;
extern int        Wednesday      =     1;
extern int        Thursday       =     1;
extern int        Friday         =     1;

extern string     MM_Parameters = " MoneyManagement by L.Williams ";
extern bool       MM             = false;  // ΜΜ Switch
extern double     MMRisk         =  0.15;  // Risk Factor
extern double     LossMax        =  1000;  // Maximum Loss by 1 Lot


int      i,cnt=0, ticket, mode=0, digit=0, wenum=0,OrderOpenDay, DaysInTrade, Kz;
double   high=0,low=0, close=0, open=0, range=0, spread=0, Profit=0;
double   smin=0, smax=0, BuyStop=0, SellStop=0, Lotsi=0, rates_h1[][6];
bool     BuyInTrade=false, SellInTrade=false;
datetime StartTime, prevwe=0, Today, PrevDay;
//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//---- 

//----
   return(0);
  }
// ---- Money Management
double MoneyManagement ( bool flag, double Lots, double risk, double maxloss)
{
   double Lotsi=Lots;
	    
   if ( flag ) Lotsi=NormalizeDouble(Lots*AccountFreeMargin()*risk/maxloss,1);   
     
   if (Lotsi<0.1) Lotsi=0.1;  
   return(Lotsi);
}   

// Closing of Pending Orders      
void PendOrdDel()
{
   int total=OrdersTotal();
   for (int cnt=total-1;cnt>=0;cnt--)
   { 
   OrderSelect(cnt, SELECT_BY_POS,MODE_TRADES);   
      
      if ( OrderSymbol()==Symbol() && OrderMagicNumber()==Magic  )     
      {
      int mode=OrderType();
        
      bool result = false;
         switch(mode)
         {
         case OP_BUYSTOP   :  {
                              result = OrderDelete( OrderTicket() );
                                 if(!result)
                                 {
                                 Print("BUYSTOP: OrderDelete failed with error #",GetLastError());
                                 return(0);
                                 }
                              break;
                              }
          
         case OP_SELLSTOP  :  {
                              result = OrderDelete( OrderTicket() );  
                                 if(!result)
                                 {
                                 Print("SELLSTOP: OrderDelete failed with error #",GetLastError());
                                 return(0);
                                 }
                              break;
                              }
                                
         }
      }
   } 
}    

// 

void CloseOrdbyTime()
{
   int total=OrdersTotal();
    
   for (cnt=0;cnt<total;cnt++)
   { 
   OrderSelect(cnt, SELECT_BY_POS);   
   mode=OrderType();
      if ( mode <= OP_SELL && OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
      { 
         if (DaysInTrade >= TradePeriod || OrderProfit()>0)
         {
            if (mode==OP_BUY )
			   OrderClose(OrderTicket(),OrderLots(),Bid,Slippage,Yellow);
			   if (mode==OP_SELL)
			   OrderClose(OrderTicket(),OrderLots(),Ask,Slippage,White);
         }
      }
   }
}       
 
// ---- 
void TrailStop()
{
   for (cnt=0;cnt<OrdersTotal();cnt++)
   { 
   OrderSelect(cnt, SELECT_BY_POS);   
   int mode=OrderType();    
      if ( OrderSymbol()==Symbol() && OrderMagicNumber()==Magic) 
      {
         if (mode==OP_BUY) 
         {
			BuyStop = Bid - TrailingStop*Point;
			   if( OrderOpenPrice() < BuyStop || OrderStopLoss() == 0 ) 
            {   
			      if ( BuyStop > OrderStopLoss() ) 
			      {
			      bool result = OrderModify(OrderTicket(),OrderOpenPrice(),
			                                NormalizeDouble(BuyStop, Digits),
			                                OrderTakeProfit(),0,LightGreen);
			         if( !result )
                  {
                  Print("BUY: OrderModify failed with error #",GetLastError());
                  }
			      return(0);
               }            
            }
         }   
// - SELL Orders          
         if (mode==OP_SELL)
         {
         SellStop = Ask + Point * TrailingStop;   
            if( OrderOpenPrice() > SellStop) 
            {
               if( OrderStopLoss() > SellStop || OrderStopLoss() == 0 ) 
               {
               OrderModify(OrderTicket(), OrderOpenPrice(),
                           NormalizeDouble(SellStop, Digits),
			                  OrderTakeProfit(),0,DarkOrange);
                  if( !result )
                  {
                  Print("SELL: OrderModify failed with error #",GetLastError());
                  }
               return(0);
               }   
   			}	    
         }
      }
   }     
}

void SellOrdOpen()
{		     
   double SellPrice=open - range*SellPercent/100.0 - spread;
	
	if (InitialStop) SellStop=SellPrice + StopPercent*range/100.0; else SellStop=0;
   Profit=0;
	       
	ticket = OrderSend(Symbol(),OP_SELLSTOP,Lotsi,
	                   NormalizeDouble(SellPrice,digit),
	                   Slippage,
	                   NormalizeDouble(SellStop,digit),
	                   Profit,"SELL",Magic,0,Red);
    

   OrderOpenDay  = DayOfWeek();   
   SellInTrade=false;            
       
   if(ticket<0)
   {
   Print("Sell: OrderSend failed with error #",GetLastError());
   return(0);
   }
}

void BuyOrdOpen()
{		     
   double BuyPrice =open + range*BuyPercent/100.0  + spread;
	if (InitialStop) BuyStop = BuyPrice - StopPercent*range/100.0; else BuyStop=0;
   Profit=0;
		 
	ticket = OrderSend(Symbol(),OP_BUYSTOP ,Lotsi,
	                   NormalizeDouble(BuyPrice ,digit),
	                   Slippage,
	                   NormalizeDouble(BuyStop ,digit),
	                   Profit,"BUY",Magic,0,Blue);
           
   OrderOpenDay  = DayOfWeek();
   BuyInTrade=false;            
       
   if(ticket<0)
   {
   Print("Buy: OrderSend failed with error #",GetLastError());
   return(0);
   }
}      

void ExtraOrdDel()
{
   int total = OrdersTotal();
   for (cnt=0;cnt<total;cnt++)
   { 
   OrderSelect(cnt, SELECT_BY_POS);   
   mode=OrderType();
      if ( OrderSymbol()==Symbol() && OrderMagicNumber()==Magic )     
      {
      if (mode==OP_BUY  && !BuyInTrade ) BuyInTrade =true;
      if (mode==OP_SELL && !SellInTrade) SellInTrade=true;
            
         if (mode == OP_SELLSTOP && BuyInTrade )
         { 
         bool result = OrderDelete(OrderTicket()); 
         SellInTrade=false; 
            if(!result)
            {
            Print("ExtraSELL: OrderDelete failed with error #",GetLastError());
            return(0);
            } 
         }
         if (mode == OP_BUYSTOP && SellInTrade )
         { 
         result = OrderDelete(OrderTicket()); 
         BuyInTrade=false; 
            if(!result)
            {
            Print("ExtraBUY: OrderDelete failed with error #",GetLastError());
            return(0);
            }  
         }
      }
   }        
}

// ---- Scan Trades
int ScanTrades()
{   
   int total = OrdersTotal();
   int numords = 0;
      
   for(cnt=0; cnt<total; cnt++) 
   {        
   OrderSelect(cnt, SELECT_BY_POS);            
   if(OrderSymbol() == Symbol() && OrderType()>=OP_BUY && OrderMagicNumber() == Magic) 
   numords++;
   }
   return(numords);
}

datetime OrderOpenDate()
{
   int total = OrdersTotal();
   datetime date;
   for(cnt=0; cnt<total; cnt++) 
   {        
   OrderSelect(cnt, SELECT_BY_POS);            
   if(OrderSymbol() == Symbol() && OrderType()>=OP_BUY && OrderMagicNumber() == Magic) 
   date = StrToTime(TimeToStr(OrderOpenTime(),TIME_DATE));
   }
   return(date);
}  

void BreakEvenStop()
{        
   for (cnt=0;cnt<OrdersTotal();cnt++)
   { 
   OrderSelect(cnt, SELECT_BY_POS);   
   int mode=OrderType();    
      if ( OrderSymbol()==Symbol() && OrderMagicNumber()==Magic) 
      {
         if (mode==OP_BUY)
         {
			   if (Bid-OrderOpenPrice() > BreakEven*Point) 
			   {  
			   Kz = MathFloor((Bid-OrderOpenPrice())/(BreakEven*Point));   
			      if (Bid-OrderOpenPrice() > Kz*BreakEven*Point) 
			      {
			      BuyStop=OrderOpenPrice()+((Kz-1)*BreakEven+BreakEvenGap)*Point;
			      if ( OrderStopLoss() == 0 ) double StopLoss = OrderOpenPrice(); else StopLoss = OrderStopLoss();   
			         if (BuyStop > StopLoss )
			         {
			         OrderModify(OrderTicket(),OrderOpenPrice(),
			                     NormalizeDouble(BuyStop, digit),
			                     OrderTakeProfit(),0,LightBlue);
			            
			          return(0);
			         }
			      }
            }
         }               			         
               
         if (mode==OP_SELL)
         {
            if (OrderOpenPrice()-Ask > BreakEven*Point)
            {
            Kz = MathFloor((OrderOpenPrice()-Ask)/(BreakEven*Point)); 
               if (OrderOpenPrice()-Ask > Kz*BreakEven*Point) 
			      {
			      SellStop=OrderOpenPrice()-((Kz-1)*BreakEven+BreakEvenGap)*Point;
			      if ( OrderStopLoss() == 0 ) StopLoss = OrderOpenPrice(); else StopLoss = OrderStopLoss();   
			         if ( SellStop < StopLoss )
			         {
			         OrderModify(OrderTicket(),OrderOpenPrice(),
			                     NormalizeDouble(SellStop, digit),
			                     OrderTakeProfit(),0,Orange);
			            
			         return(0);
			         }
               }
		      }
         }
      }   
   } 
}	                    
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//---- 
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
{
   if(Bars < 1) {Print("Not enough bars for this strategy"); return(0);}
  
   if ( Trace ) SetTrace();
  
   string   TimeTrade = "00:00";
   StartTime  = StrToTime(TimeTrade) + TimeZone*3600;
  
   if(CurTime() >= StartTime && CurTime() <= StartTime+3600)
   {
      if ( OrderOpenDate() < StrToTime(TimeToStr( StartTime,TIME_DATE))) 
      { 
      if( ScanTrades()>0 && !BuyInTrade && !SellInTrade) PendOrdDel(); 
      Today = StrToTime(TimeToStr( StartTime,TIME_DATE));
      if (Today != PrevDay ) 
      { DaysInTrade = DaysInTrade+1; 
      //Print(" Days=",DaysInTrade,"Today=",TimeToStr(Today,TIME_DATE),"PrevDay=", TimeToStr(PrevDay,TIME_DATE)) ;
      PrevDay=Today;}
      
      if( TradePeriod > 0 )CloseOrdbyTime(); 
      }
      
      if(ScanTrades()<1)
      {
      
      spread= MarketInfo(Symbol(),MODE_SPREAD)*Point;
      digit  = MarketInfo(Symbol(),MODE_DIGITS);
      Lotsi = MoneyManagement ( MM, Lots, MMRisk, LossMax);
      if (TrailingStop > 0) InitialStop=true; 
   
      ArrayCopyRates(rates_h1, Symbol(), PERIOD_H1);
      open = rates_h1[0][1];
      high=0; low=10000000;
      for (i=24;i>=1;i--)
      {
      high = MathMax( high, rates_h1[i][3]);
      low  = MathMin( low , rates_h1[i][2]);      
      }   
       
      range =(high-low); 
      
          
   
      if ( Monday   == 1 ) if(DayOfWeek()==1){BuyOrdOpen(); SellOrdOpen();}
      if ( Tuesday  == 1 ) if(DayOfWeek()==2){BuyOrdOpen(); SellOrdOpen();}
      if ( Wednesday== 1 ) if(DayOfWeek()==3){BuyOrdOpen(); SellOrdOpen();} 
      if ( Thursday == 1 ) if(DayOfWeek()==4){BuyOrdOpen(); SellOrdOpen();} 
      if ( Friday   == 1 ) if(DayOfWeek()==5){BuyOrdOpen(); SellOrdOpen();}
      DaysInTrade = 0;
      }
      
    
   }
   ExtraOrdDel();
   if (BreakEven > 0) BreakEvenStop();
   if (TrailingStop > 0 ) TrailStop(); 
 return(0);
}//int start
//+------------------------------------------------------------------+





