//+------------------------------------------------------------------+
//|                                               Pouria EA Beta.mq4 |
//|                      Copyright © 2007, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net"

//----------------------- INCLUDES
#include <stdlib.mqh>


//----------------------- EA PARAMETER
extern string  
         Expert_Name          = "---------- Pouria EA Beta";
extern int
         MagicNumber          = 1234;
extern int 
         StopLoss             = 20,
         TakeProfit           = 30;
extern int
         BreakEvenAfterPips   = 0;
extern bool
         ConfirmedOnEntry     = false;
extern string  
         Order_Setting        = "---------- Order Setting";
extern int
         NumberOfTries        = 10,
         Slippage             = 5;
extern string  
         MM_Parameters        = "---------- Money Management";
extern double 
         Lots                 = 1;
extern bool 
         MM                   = true, //Use Money Management or not
         AccountIsMicro       = false; //Use Micro-Account or not
extern int 
         Risk                 = 10; //10%
         
extern string  
         Alert_Setting        = "---------- Alert Setting";
extern bool
         EnableAlert          = true;

//----------------------- GLOBAL VARIABLE
static int 
         TimeFrame            = 0;
string
         TicketComment        = "Pouraia EA Beta",
         CurrentMA,
         PreviousMA,
         CurrentMACD,
         MASignal,
         MACDSignal,
         EntrySignal,
         PreviousMACD;
int      
         SlowShift,
         FastShift,
         total,
         cnt,
         ticket;
datetime 
         CrossTime;                 
//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//----
//----------------------- GENERATE MAGIC NUMBER AND TICKET COMMENT
//----------------------- SOURCE : PENGIE
   MagicNumber    = subGenerateMagicNumber(MagicNumber, Symbol(), Period());
	TicketComment  = StringConcatenate(TicketComment, "-", Symbol(), "-", Period());
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----------------------- PREVENT RE-COUNTING WHILE USER CHANGING TIME FRAME
//----------------------- SOURCE : CODERSGURU
   TimeFrame=Period(); 
   return(0);
  }
  
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
//--------Define nidicator Values
      if(ConfirmedOnEntry)
      {
         SlowShift = 2;
         FastShift = 1; 
      }
      else
      {
         SlowShift = 1;
         FastShift = 0; 
      }
      double MA5Previous     = iMA(NULL,TimeFrame,5,0,MODE_EMA,PRICE_CLOSE,SlowShift);
      double MA85Previous    = iMA(NULL,TimeFrame,85,0,MODE_LWMA,PRICE_LOW,SlowShift);
      double MA75Previous    = iMA(NULL,TimeFrame,75,0,MODE_LWMA,PRICE_LOW,SlowShift);
      
      double MA5Current      = iMA(NULL,TimeFrame,5,0,MODE_EMA,PRICE_CLOSE,FastShift);
      double MA85Current     = iMA(NULL,TimeFrame,85,0,MODE_LWMA,PRICE_LOW,FastShift);
      double MA75Current     = iMA(NULL,TimeFrame,75,0,MODE_LWMA,PRICE_LOW,FastShift);
      
      double MacdCurrent     = iMACD(NULL,TimeFrame,15,26,1,PRICE_CLOSE,MODE_MAIN,FastShift);
      double MacdPrevious    = iMACD(NULL,TimeFrame,15,26,1,PRICE_CLOSE,MODE_MAIN,SlowShift);

//----------------------- BREAK EVEN AFTER PIPS SECTION
   if(BreakEvenAfterPips >0 && subTotalTrade()>0)
   {  
      total = OrdersTotal();
      for(cnt=0;cnt<total;cnt++)
      {
         OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);

         if(OrderType()<=OP_SELL &&
            OrderSymbol()==Symbol() &&
            OrderMagicNumber()==MagicNumber)
         {
            subBreakEvenAfterPips (OrderType());
         }
      }
   }
//----------------------- ADJUST LOTS IF USING MONEY MANAGEMENT
   if(MM) Lots = subLotSize();  
//---------Set MA Conditions
   if((MA5Current>MA85Current)&&(MA5Current>MA75Current)){CurrentMA = "Buy";}
   
   else if((MA5Current<MA85Current)&&(MA5Current<MA75Current)){CurrentMA = "Sell";}
   
   
   if((MA5Previous >MA85Previous )&&(MA5Previous >MA75Previous )){PreviousMA = "Buy";}
   
   else if((MA5Previous <MA85Previous )&&(MA5Previous <MA75Previous )){PreviousMA = "Sell";}
   
   
   
//---------Generate MA Signal   
   if((CurrentMA == "Buy")&&(PreviousMA!="Buy")){MASignal = "Buy";}
   else if ((CurrentMA == "Sell")&&(PreviousMA!="Sell")){MASignal = "Sell";}
   else{MASignal = "None";}
   
//---------Set MACD Conditions
   if(MacdCurrent>0){CurrentMACD = "Buy";}
   
   else if(MacdCurrent<0){CurrentMACD = "Sell";}
   
   
   if(MacdPrevious>0){PreviousMACD = "Buy";}
   
   else if(MacdPrevious<0){PreviousMACD = "Sell";}
   
   
//---------Generate MACD Signal
   if((CurrentMACD == "Buy")&&(PreviousMACD!="Buy")){MASignal = "Buy";}
   else if ((CurrentMACD == "Sell")&&(PreviousMACD!="Sell")){MACDSignal = "Sell";}
   else{MACDSignal = "None";}

//---------Generate Entry Signal
   //-----------------MACROSS ENTRY
   total = subTotalTrade();
   if(total<1)
   {  
      if(CrossTime == iTime(NULL,TimeFrame,0))
      {return(0);}
      if((MASignal=="Buy")&&(CurrentMACD=="Buy"))
      {
         ticket = subOpenOrder(OP_BUY,StopLoss,TakeProfit);
         if(ticket<=0) ticket = subOpenOrder(OP_BUY,StopLoss,TakeProfit);
         if(ticket<=0) ticket = subOpenOrder(OP_BUY,StopLoss,TakeProfit);
         CrossTime      = iTime(NULL,TimeFrame,0);
         if(EnableAlert)
         {
            Alert("RUN WITH THE BULLS!");
         }
         return(0);
      }
      
      if((MASignal=="Sell")&&(CurrentMACD=="Sell"))
      {
         ticket = subOpenOrder(OP_SELL,StopLoss,TakeProfit);
         if(ticket<=0) ticket = subOpenOrder(OP_SELL,StopLoss,TakeProfit);
         if(ticket<=0) ticket = subOpenOrder(OP_SELL,StopLoss,TakeProfit);
         CrossTime      = iTime(NULL,TimeFrame,0);
         if(EnableAlert)
         {
            Alert("HUNT WITH THE BEARS!");
         }
         return(0);
      }
   //-----------------MACDCROSS ENTRY
      
      if((MACDSignal == "Buy")&&(CurrentMA == "Buy"))
      {
         ticket = subOpenOrder(OP_SELL,StopLoss,TakeProfit);
         if(ticket<=0) ticket = subOpenOrder(OP_SELL,StopLoss,TakeProfit);
         if(ticket<=0) ticket = subOpenOrder(OP_SELL,StopLoss,TakeProfit);
         CrossTime      = iTime(NULL,TimeFrame,0);
         if(EnableAlert)
         {
            Alert("RUN WITH THE BULLS!");
         }
         return(0);
      }
      
      if((MACDSignal == "Sell")&&(CurrentMA == "Sell"))
      {
         ticket = subOpenOrder(OP_BUY,StopLoss,TakeProfit);
         if(ticket<=0) ticket = subOpenOrder(OP_BUY,StopLoss,TakeProfit);
         if(ticket<=0) ticket = subOpenOrder(OP_BUY,StopLoss,TakeProfit);
         CrossTime      = iTime(NULL,TimeFrame,0);
         if(EnableAlert)
         {
            Alert("HUNT WITH THE BEARS!");
         }
         return(0);
      }
      return(0);
   }   
   return(0);
  }
//+------------------------------------------------------------------+

//---------------------- BREAK EVEN FUNCTION
void subBreakEvenAfterPips(int Type)
{
   if(Type==OP_BUY)
   {
      if((Bid-OrderOpenPrice()) > (Point*BreakEvenAfterPips))
            OrderModify(
                        OrderTicket(),
                        OrderOpenPrice(),
                        OrderOpenPrice(),
                        OrderTakeProfit(),
                        0,
                        GreenYellow);
   }
   if(Type==OP_SELL)
   {
    if((OrderOpenPrice()-Ask) > (Point*BreakEvenAfterPips))
            OrderModify(
                        OrderTicket(),
                        OrderOpenPrice(),
                        OrderOpenPrice(),
                        OrderTakeProfit(),
                        0,
                        Red);
   }
}
int subTotalTrade()
{
   int
      cnt, 
      total = 0;

   for(cnt=0;cnt<OrdersTotal();cnt++)
   {
      OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES);
      if(OrderType()<=OP_SELL &&
         OrderSymbol()==Symbol() &&
         OrderMagicNumber()==MagicNumber) total++;
   }
   return(total);
}
double subLotSize()
{
   if(MM==false) return(Lots);
   double lot=Lots;
   int    orders=HistoryTotal();
   int    losses=0;
   int    decimalPlaces=1;
   
   if(AccountIsMicro==true) decimalPlaces=2;

   lot=NormalizeDouble((AccountFreeMargin()*Risk/1000.0)/100,decimalPlaces);

   if(lot<0.1 && AccountIsMicro==false) lot=0.1;
   if(lot<0.01 && AccountIsMicro==true) lot=0.01;
   if(lot>99) lot=99;
   return(lot);

}
//----------------------- OPEN ORDER FUNCTION
//----------------------- SOURCE   : CODERSGURU
//----------------------- SOURCE   : PENGIE
//----------------------- MODIFIED : FIREDAVE
int subOpenOrder(int type, int stoploss, int takeprofit)
{
   int
         ticket      = 0,
         err         = 0,
         c           = 0;
         
   double         
         aStopLoss   = 0,
         aTakeProfit = 0,
         bStopLoss   = 0,
         bTakeProfit = 0;

   if(stoploss!=0)
   {
      aStopLoss   = NormalizeDouble(Ask-stoploss*Point,4);
      bStopLoss   = NormalizeDouble(Bid+stoploss*Point,4);
   }
   
   if(takeprofit!=0)
   {
      aTakeProfit = NormalizeDouble(Ask+takeprofit*Point,4);
      bTakeProfit = NormalizeDouble(Bid-takeprofit*Point,4);
   }
   
   if(type==OP_BUY)
   {
      for(c=0;c<NumberOfTries;c++)
      {
         ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,Slippage,aStopLoss,aTakeProfit,TicketComment,MagicNumber,0,Green);
         err=GetLastError();
         if(err==0)
         { 
            if(ticket>0) break;
         }
         else
         {
            if(err==0 || err==4 || err==136 || err==137 || err==138 || err==146) //Busy errors
            {
               Sleep(5000);
               continue;
            }
            else //normal error
            {
               if(ticket>0) break;
            }  
         }
      }   
   }
   if(type==OP_SELL)
   {   
      for(c=0;c<NumberOfTries;c++)
      {
         ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,Slippage,bStopLoss,bTakeProfit,TicketComment,MagicNumber,0,Red);
         err=GetLastError();
         if(err==0)
         { 
            if(ticket>0) break;
         }
         else
         {
            if(err==0 || err==4 || err==136 || err==137 || err==138 || err==146) //Busy errors
            {
               Sleep(5000);
               continue;
            }
            else //normal error
            {
               if(ticket>0) break;
            }  
         }
      }   
   }  
   return(ticket);
}
//----------------------- 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)));
}