//+------------------------------------------------------------------+
//|                             EO_EA.mq4                            |
//|                             Copyright GodfreyH 2009              |
//|                             Godfreyh@gmail.com                   |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2009, GodfreyH."
#property link      "godfreyh@gmail.com"

//+-------------------------------------------------------------------+
extern string  Expert_Name    = "-------EO_EA -------------";
int MagicNumber          = 12345;
extern double Order_Pips_Slippage = 4;          

extern string  MA_Setting= "Moving Average Settings";
extern double  MA_PERIOD_A =   35;
extern string  MA_TYPE1    = "0=SMA, 1=EMA";
extern double  MA_TYPE_A   = MODE_SMA; 
extern string  MA_PRCE_A   = "0=CLOSE PRICE, 1=OPEN PRICE";
extern int     MA_APPLIED_PRICE_A = 0 ;                  //0=CLOSE, 1=OPEN

extern double  MA_PERIOD_B =   50;
extern string  MA_TYPE2    = "0=SMA, 1=EMA";
extern double  MA_TYPE_B   = MODE_EMA;                   //0=SMA, 1=EMA, 2=SMMA, 3 =LWMA
extern string  MA_PRCE_B   = "0=CLOSE PRICE, 1=OPEN PRICE";
extern int     MA_APPLIED_PRICE_B = 0 ;                  //0=CLOSE, 1=OPEN



extern string   filters     = "---------------LOAD FILTERS------------------";


extern string  Time_Parameters      = "----------- EA Active Time--------------";
extern bool    UseHourTrade = false;
extern int     FromHourTrade = 4; // SERVER TIME
extern int     ToHourTrade = 16;  //SERVER TIME
          

extern bool   Use_Bar_Filter = true;
extern double min_total_bar_length =25; // to avoid ranges
extern string wick_height = "Bar should have a short wick";
extern double BULLBAR_MaxUpperWickPercent =15;
extern double BEARBAR_MaxLowerWickPercent =15;


 
extern string Settings      ="--------------GENERAL SETTINGS--------------------";     
extern bool   Show_Settings  = true;
extern bool   MicroOrdersAllowed = true;
extern bool   MiniOrdersAllowed = true;

extern string MMSettings   ="-----------MONEY MANAGEMENT SETTINGS---------------";    
extern string MM ="--If MM enter risk to get lotsize--";
extern bool   UseMoneyMgmt = true;
extern double RiskPercent = 0.02;
extern bool   Manual_Lot_Size = false;
extern double Lotsize = 0.10;

extern int    ManualTakeProfit = 80;
extern int    manual_stop =35;


extern string Trailing ="----Trailing Stops----";
extern bool   useTrailing = false;        
extern double TrailingStop = 75;  

extern string TrailingII = "Settings for Breakeven";
extern bool   useBreakEven = true;
extern double  BreakEven =  30;
extern int     LockInPips = 10;  
extern double lots_to_close =0.5;

extern string TrailingIII = "Move stop to moving average";
extern bool   use_movestop_to_MA = false;
extern double  MA_PERIOD_ =   35;
extern string  MA_TYPE    = "0=SMA, 1=EMA";
extern double  MA_TYPE_   = MODE_SMA; 
extern string  MA_PRCE_   = "0=CLOSE PRICE, 1=OPEN PRICE";
extern int     MA_APPLIED_PRICE_ = 0 ;                  //0=CLOSE, 1=OPEN
extern int     xtraPIPS = 5 ; 
extern double  closelots =0.5;
double Poin; 


//+--------------------------------------------------------------------------------------------------------+
//END OF USER DEFINED VARIABLES NO CHANGES TO BE MADE BEYOND THIS POINT                                    |
//+--------------------------------------------------------------------------------------------------------+


//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+

int init(){
    
  
  
  //----------------------- GENERATE MAGIC NUMBER AND TICKET COMMENT
    //----------------------- SOURCE : PENGIE
    MagicNumber    = subGenerateMagicNumber( MagicNumber, Symbol(), Period() );


  
   watermark(); 
   
//Checking for unconventional Point digits number
if (Point == 0.00001) Poin = 0.0001; //6 digits
else if (Point == 0.001) Poin = 0.01; //3 digits (for Yen based pairs)
else Poin = Point; //Normal 
   
return(0);

}


//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
{
   return(0);
}


//+------------------------------------------------------------------+
//| CheckForLevel                                                    |
//| Checks ATR Level Stop and places a trade accordingly             |
//|                                                                  |
//+------------------------------------------------------------------+



bool CheckTrade(int cmd)
{
 
   // MOVING AVERAGE VARIABLE  
   double ma_period_a_now, ma_period_a_prev,ma_period_b_now,ma_period_b_prev; 
   ma_period_a_now =  iMA(NULL,0,MA_PERIOD_A,0,MA_TYPE_A,MA_APPLIED_PRICE_A,1);
   ma_period_a_prev = iMA(NULL,0,MA_PERIOD_A,0,MA_TYPE_A,MA_APPLIED_PRICE_A,2);
   ma_period_b_now =  iMA(NULL,0,MA_PERIOD_B,0,MA_TYPE_B,MA_APPLIED_PRICE_B,1);
   ma_period_b_prev = iMA(NULL,0,MA_PERIOD_B,0,MA_TYPE_B,MA_APPLIED_PRICE_B,2);
 
  switch (cmd)
  {
   case OP_BUY  : if ((iClose(NULL,0,1) < ma_period_a_now ) && (iClose(NULL,0,1) < ma_period_b_now )&& (iClose(NULL,0,2) > ma_period_a_prev )&& (iClose(NULL,0,2) > ma_period_b_prev )) return(true); 
                 
                    break; 
  
   case OP_SELL : if ((iClose(NULL,0,1) > ma_period_a_now ) && (iClose(NULL,0,1) > ma_period_b_now )&& (iClose(NULL,0,2) < ma_period_a_prev )&& (iClose(NULL,0,2) < ma_period_b_prev )) return(true); 
  
  
  }

   
   return(false);  
   
}
//+------------------------------------------------------------------+
//| CheckSessionFilter                                               |
//| Checks whether trading session valid                             |
//|                                                                  |
//+------------------------------------------------------------------+
bool Check_Time(int cmd)
{

  switch (cmd)
  {
    
   case OP_BUY : if  ((Hour()>=FromHourTrade)&&(Hour()<=ToHourTrade)) return(true);
             break;     
   case OP_SELL : if ((Hour()>=FromHourTrade)&&(Hour()<=ToHourTrade)) return(true);
  }
  
   
   return(false);
     
}   

//+------------------------------------------------------------------+
//| CheckBarFilter                                               |
//| Checks whether trading session valid                             |
//|                                                                  |
//+------------------------------------------------------------------+
bool Check_Bar(int cmd)
{

  switch (cmd)
  {
    
   case OP_BUY :  if 
      
       (
        (Open[1] > Close[1]) // bar is bear
         &&
        ((High[1] -Low[1]) >= min_total_bar_length*Poin) //  bar at least 30 pips long, no doji's
         &&
        ((Close[1] - Low[1]) <= NormalizeDouble((BEARBAR_MaxLowerWickPercent/100)*(High[1]-Low[1]),Digits)) // lowerwick must be short
        ) return(true);
   
      //-------
   case OP_SELL : if 
       (
        (Close[1] >Open[1]) // bar is bull
         &&
        ((High[1] -Low[1]) >= min_total_bar_length*Poin) // bar at least 30 pips long, no doji's
         &&
        ((High[1] - Close[1]) <= NormalizeDouble((BULLBAR_MaxUpperWickPercent/100)*(High[1]-Low[1]),Digits)) // upperwick must be short
        ) return(true);
       
             break;     
   
   
   
   
   
  }
  
   
   return(false);
     
}   


//+---------------------------------------------------------------------
bool CheckEntryCondition(int cmd)
{
     
      if(!CheckTrade(cmd)) return (false);
      
   
   if (UseHourTrade)
      {
      if(!Check_Time(cmd)) return(false);
      } 
    if(Use_Bar_Filter)  
      {
      if(!Check_Bar(cmd)) return(false);
      } 
  
  
//if we've come this far, everything above has resulted in TRUE, so CheckEntryCondition is TRUE   
   return(true);
  

}
//+-------------------------------------------------------------------
int start() 
{ 

	double Lots,StopLoss; 
 	int   total, ticket; 
 	double DailyAverageRange=0;
  

 	if (Bars < 100) 
	{ 
		Print("bars less than 100"); 
		return(0); 
	} 
	
  int OrdersizeAllowed = 0;
  
  if (MiniOrdersAllowed) OrdersizeAllowed=1;
  if (MicroOrdersAllowed) OrdersizeAllowed=2; 
  
   

     StopLoss = manual_stop;
 
 
  
      
  if (UseMoneyMgmt==true)
  //------------- 
    
  Lots = NormalizeDouble( AccountBalance()*RiskPercent/StopLoss/(MarketInfo(Symbol(), MODE_TICKVALUE)),OrdersizeAllowed);
 
      
  if (Manual_Lot_Size == true) 
   {
  Lots = NormalizeDouble(Lotsize,OrdersizeAllowed); 
  
      }   
  if ((Lots < 0.01&&MicroOrdersAllowed) || (Lots < 0.1&&MiniOrdersAllowed&&MicroOrdersAllowed==false))
  
      {
         Comment("YOUR LOTS SIZE IS TOO SMALL TO PLACE!");
      } 

  
	total = OrdersTotal(); 
	if (total < 1) 
 

	{ 
		// no opened orders identified 
		if (AccountFreeMargin() < (50*Lots)) 
		{ 
			Print("We have no money. Free Margin = ", AccountFreeMargin()); 
			return(0); 
		} 

 
if(CheckEntryCondition(OP_BUY))
  { 
  
      double BuyTakeProfit = ManualTakeProfit;
      
      { 
			ticket = OrderSend(Symbol(), OP_BUY, Lots, Ask, Order_Pips_Slippage, 
							Bid - StopLoss * Poin, Ask + BuyTakeProfit * Poin, 
								"Gann", MagicNumber, 0, Green);        
		} 
	
  }	
		
if(CheckEntryCondition(OP_SELL))
 { 
  
      double SellTakeProfit = ManualTakeProfit;
      
		{ 
			ticket = OrderSend(Symbol(), OP_SELL, Lots, Bid, Order_Pips_Slippage,
							Ask + StopLoss * Poin, Bid - SellTakeProfit * Poin,
							"Gann", MagicNumber, 0, Red); 
		} 
		
 }		
		
		return(0); 
	}

	 //-----
	 //TOTAL Count..
         int btotal=0; int stotal=0; double closelots=0; 
          for( int cnt=OrdersTotal()-1;cnt>=0;cnt--)
         {        
            OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);   
            if(OrderType()==OP_BUY && OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol()){btotal++;  ticket=OrderTicket(); closelots=OrderLots();}   
            if(OrderType()==OP_SELL && OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol()){stotal++; ticket=OrderTicket(); closelots=OrderLots();} 
    
         }// END TOTAL count..
	 

  
	  //If BUY ORDER EXIST && TRAIL == TRUE
	   if (btotal > 0) 
      {
       	if ((useTrailing == true)&& (TrailingStop > 0) )
				{ 
					if (Bid - OrderOpenPrice() > Poin * TrailingStop) 
					{ 
						if (OrderStopLoss() < Bid-Poin * TrailingStop) 
						{ 
							OrderModify(OrderTicket(), OrderOpenPrice(), 
										Bid - Poin * TrailingStop, OrderTakeProfit(), 0, Green); 
							return(0); 
						} 
					} 
				} 
			}	

	  //If BUY ORDER EXIST && useBreakEven ==TRUE
	   if (btotal > 0) 
	   
	     {
        if (useBreakEven == true)
       	{ 
				   if  ( Bid - OrderOpenPrice() > (Poin * BreakEven) )
							
					{ 
					
				double BuyStop;
            BuyStop = OrderOpenPrice() + LockInPips * Poin;
         	BuyStop = NormalizeDouble( BuyStop, Digits);
			
					
						if (OrderStopLoss() < BuyStop) 
						{ 
							OrderModify(OrderTicket(), OrderOpenPrice(),BuyStop, OrderTakeProfit(), 0, Green); 
					 	OrderClose(ticket,NormalizeDouble(lots_to_close*Lots,OrdersizeAllowed),Ask,3,DarkOrange); 	
        	       	return(0); 
						} 
					} 
				} 
   	   }


      //If BUY ORDER EXIST && useMA_Stop ==TRUE
	   if (btotal > 0) 
	   
	     {
        if (use_movestop_to_MA == true)
        double MA =  iMA(NULL,0,MA_PERIOD_,0,MA_TYPE_,MA_APPLIED_PRICE_,1);
        
        	{ 
				   if  ( Bid - OrderOpenPrice() >= (xtraPIPS *Poin)+(MA - OrderOpenPrice()) )
							
					{ 
					
			   BuyStop = MA;
         	BuyStop = NormalizeDouble( BuyStop, Digits);
			
							   		
						if (OrderStopLoss() < BuyStop) 
						{ 
						OrderModify(OrderTicket(), OrderOpenPrice(),BuyStop, OrderTakeProfit(), 0, Green); 
					 	OrderClose(ticket,NormalizeDouble(closelots*Lots,OrdersizeAllowed),Ask,3,DarkOrange); 	
        	       	return(0); 
						} 
					} 
				} 
   	   }
     
     //If SELL ORDER EXIST AND TRAILING ==TRUE
     if (stotal > 0) 
     {
           
         	if ((useTrailing == true)&&(TrailingStop > 0))
				{ 
					if (OrderOpenPrice() - Ask > Poin * TrailingStop) 
					{ 
						if ((OrderStopLoss() > (Ask+Poin * TrailingStop)) || (OrderStopLoss() == 0)) 
						{ 
							OrderModify(OrderTicket(), OrderOpenPrice(),
										Ask+Poin * TrailingStop, OrderTakeProfit(), 0, Red); 
							return(0); 
						} 
					} 
				} 
			}
    //---------------------
    
     //IfSELL ORDER EXIST && useBreakEven ==TRUE
	   if (stotal > 0)
      {
      
      
      if (useBreakEven == true)
			{ 
       	 
					if (  (OrderOpenPrice()-Ask) > (Poin * BreakEven) )

					{ 
					
					 double SellStop;
            	SellStop = OrderOpenPrice() - LockInPips * Poin;
            	SellStop = NormalizeDouble( SellStop, Digits);
		
						if ((OrderStopLoss() > SellStop) || (OrderStopLoss() == 0))
						{ 
							OrderModify(OrderTicket(), OrderOpenPrice(),SellStop, OrderTakeProfit(), 0, Green); 
							OrderClose(ticket,NormalizeDouble(lots_to_close*Lots,OrdersizeAllowed),Ask,3,DarkOrange);
							return(0); 
						} 
					} 
				} 
   	  }
   	  
   	  //--------------
  
  //IfSELL ORDER EXIST && useMA_Stop ==TRUE
	   if (stotal > 0)
      {
      
      
      if (use_movestop_to_MA == true)
			{ 
       	      MA =  iMA(NULL,0,MA_PERIOD_,0,MA_TYPE_,MA_APPLIED_PRICE_,1);
					if (  (OrderOpenPrice()-Ask) >= (xtraPIPS *Poin)+(OrderOpenPrice()- MA) )

					{ 
					
				  	SellStop = MA;
            	SellStop = NormalizeDouble( SellStop, Digits);
		
						if ((OrderStopLoss() > SellStop) || (OrderStopLoss() == 0))
						{ 
							OrderModify(OrderTicket(), OrderOpenPrice(),SellStop, OrderTakeProfit(), 0, Green); 
							OrderClose(ticket,NormalizeDouble(lots_to_close*Lots,OrdersizeAllowed),Ask,3,DarkOrange);
							return(0); 
						} 
					} 
				} 
   	  }
   	  
   	  //--------------	 
	return(0); 
}

void watermark()
  {
   ObjectCreate("AI", OBJ_LABEL, 0, 0, 0);
   ObjectSetText("AI"," EO EA V1",10, "Arial", Aqua);
   ObjectSet("AI", OBJPROP_CORNER, 2);
   ObjectSet("AI", OBJPROP_XDISTANCE, 5);
   ObjectSet("AI", OBJPROP_YDISTANCE, 10);
   return(0);
  }




//----------------------- GENERATE MAGIC NUMBER BASE ON SYMBOL AND TIME FRAME FUNCTION
//----------------------- SOURCE   : PENGIE
//----------------------- MODIFIED : FIREDAVE
int subGenerateMagicNumber(int MagicNumber, string symbol, int timeFrame)
{
   int isymbol = 0;
   if (symbol == "EURUSD")       isymbol = 1;
   else if (symbol == "GBPUSD")  isymbol = 2;
   else if (symbol == "USDJPY")  isymbol = 3;
   else if (symbol == "USDCHF")  isymbol = 4;
   else if (symbol == "AUDUSD")  isymbol = 5;
   else if (symbol == "USDCAD")  isymbol = 6;
   else if (symbol == "EURGBP")  isymbol = 7;
   else if (symbol == "EURJPY")  isymbol = 8;
   else if (symbol == "EURCHF")  isymbol = 9;
   else if (symbol == "EURAUD")  isymbol = 10;
   else if (symbol == "EURCAD")  isymbol = 11;
   else if (symbol == "GBPUSD")  isymbol = 12;
   else if (symbol == "GBPJPY")  isymbol = 13;
   else if (symbol == "GBPCHF")  isymbol = 14;
   else if (symbol == "GBPAUD")  isymbol = 15;
   else if (symbol == "GBPCAD")  isymbol = 16;
   else                          isymbol = 17;
   if(isymbol<10) MagicNumber = MagicNumber * 10;
   return (StrToInteger(StringConcatenate(MagicNumber, isymbol, timeFrame)));
}