//+------------------------------------------------------------------+
//|                                        Bogie-MACD_MaTrend-v1.mq4 |
//|                     This Expert Advisor is for FREE Distrubution |
//|                                                 Bogie Enterprises|
//|                                                                  |
//|           Modified MACD-Sample EA from MetaQuotes Software Corp. |
//|                                       http://www.metaquotes.net/ |
//+------------------------------------------------------------------+


extern bool   MiniAcct= false; 		// false=min lot size 0.1  -  true=min lot size 0.01.
extern bool   UseMM= true;
extern double Risk = 1.0;             // Allows fractional Risk percent
extern double Lots = 0.1;
extern double TakeProfit = 17;
extern double StopLoss = 0;
extern double TrailingStop = 0;
extern double MACDOpenLevel=6;
extern double MACDCloseLevel=46;
extern double MATrendPeriod=8;
extern int    MagicNumber=12345;

string ExpertName = "Bogie-MACD_MaTrend-v1";

int nBars;
double tp,sl;
double ask, bid;

int init()
{
nBars = Bars;

int dig=MarketInfo(Symbol(),MODE_DIGITS);
    int x;
    if(dig==2) x=1;
    if(dig==3) x=10;
    if(dig==4) x=1;
    if(dig==5) x=10;
            
                                    
   if(StopLoss>0) StopLoss = NormalizeDouble((StopLoss*x) * Point,Digits); else StopLoss=0; 
   if(TakeProfit>0) TakeProfit = NormalizeDouble((TakeProfit*x) * Point,Digits); else TakeProfit=0; 
// Robert added because of how Point is used with x.
   if(TrailingStop>0) TrailingStop = NormalizeDouble((TrailingStop*x) * Point,Digits); else TrailingStop=0; 
   

}

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int start()
  {
  string Broker = AccountCompany();
  Comment(Broker," - Server Time = ",TimeToStr(TimeCurrent(),TIME_SECONDS));
  
  if(!IsBarEnd())
        return(0);
  
   double MacdCurrent, MacdPrevious, SignalCurrent;
   double SignalPrevious, MaCurrent, MaPrevious;
   int cnt, ticket, total;
// initial data checks
// it is important to make sure that the expert works with a normal
// chart and the user did not make any mistakes setting external 
// variables (Lots, StopLoss, TakeProfit, 
// TrailingStop) in our case, we check TakeProfit
// on a chart of less than 100 bars
   if(Bars<100)
     {
      Print("bars less than 100");
      return(0);  
     }
   
// to simplify the coding and speed up access
// data are put into internal variables
   MacdCurrent=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,0);
   MacdPrevious=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,1);
   SignalCurrent=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,0);
   SignalPrevious=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,1);
   MaCurrent=iMA(NULL,0,MATrendPeriod,0,MODE_EMA,PRICE_CLOSE,0);
   MaPrevious=iMA(NULL,0,MATrendPeriod,0,MODE_EMA,PRICE_CLOSE,1);

   total=OrdersTotal();
   if(total<1) 
     {
      // no opened orders identified
      if(AccountFreeMargin()<(1000*Lots))
        {
         Print("We have no money. Free Margin = ", AccountFreeMargin());
         return(0);  
        }
      // check for long position (BUY) possibility
      if(MacdCurrent<0 && MacdCurrent>SignalCurrent && MacdPrevious<SignalPrevious &&
         MathAbs(MacdCurrent)>(MACDOpenLevel*Point) && MaCurrent>MaPrevious)
        {
         if(TakeProfit>0) tp= Ask + TakeProfit; else tp=0;
         if(StopLoss>0) sl= Ask - StopLoss; else sl=0;
         while(!IsTradeAllowed() || IsTradeContextBusy()) {Sleep(5000);}
         RefreshRates();
         ask = NormalizeDouble(MarketInfo(Symbol(),MODE_ASK),Digits);
         ticket=OrderSend(Symbol(),OP_BUY,_Lots(),ask,3,0,0,ExpertName,MagicNumber,0,Green);
         if(ticket>0)
           {
            if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print("BUY order opened : ",OrderOpenPrice());
           }
         else Print("Error opening BUY order : ",GetLastError()); 
         total = OrdersTotal();
            for(cnt=0;cnt<total;cnt++)
	           {
		          OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
		          if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
		             {
                     if(IsTradeContextBusy() || !IsTradeAllowed())
                        {
                           Print("Trade context is busy! The expert cannot modify Buy position!");
                           return(-1);
                        }
                     OrderModify(OrderTicket(),OrderOpenPrice(),sl,tp,0,GreenYellow);
                   }      
	           }
         return(0); 
        }
      // check for short position (SELL) possibility
      if(MacdCurrent>0 && MacdCurrent<SignalCurrent && MacdPrevious>SignalPrevious && 
         MacdCurrent>(MACDOpenLevel*Point) && MaCurrent<MaPrevious)
        {
         if(TakeProfit>0) tp= Bid - TakeProfit; else tp=0;
         if(StopLoss>0) sl= Bid + StopLoss; else sl=0;
         while(!IsTradeAllowed() || IsTradeContextBusy()) {Sleep(5000);}
         RefreshRates();
         bid = NormalizeDouble(MarketInfo(Symbol(),MODE_BID),Digits);
         ticket=OrderSend(Symbol(),OP_SELL,_Lots(),bid,3,0,0,ExpertName,MagicNumber,0,Red);
         if(ticket>0)
           {
            if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print("SELL order opened : ",OrderOpenPrice());
           }
         else Print("Error opening SELL order : ",GetLastError()); 
         total = OrdersTotal();
            for(cnt=0;cnt<total;cnt++)
	           {
		          OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
		          if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
		             {
                     if(IsTradeContextBusy() || !IsTradeAllowed()) 
                        {
                           Print("Trade context is busy! The expert cannot modify Sell position!");
                           return(-1);
                        }
                     OrderModify(OrderTicket(),OrderOpenPrice(),sl,tp,0,GreenYellow);
                   }      
	           }
         return(0); 
        }
      return(0);
     }
   // it is important to enter the market correctly, 
   // but it is more important to exit it correctly...   
   for(cnt=0;cnt<total;cnt++)
     {
      OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
      if(OrderType()<=OP_SELL &&   // check for opened position 
         OrderSymbol()==Symbol() && OrderMagicNumber() == MagicNumber)  // check for symbol
        {
         if(OrderType()==OP_BUY)   // long position is opened
           {
            // should it be closed?
            if(MacdCurrent>0 && MacdCurrent<SignalCurrent && MacdPrevious>SignalPrevious &&
               MacdCurrent>(MACDCloseLevel*Point))
                {
                 while(!IsTradeAllowed() || IsTradeContextBusy()) {Sleep(5000);}
                 RefreshRates();
                 bid = NormalizeDouble(MarketInfo(Symbol(),MODE_BID),Digits);
                 OrderClose(OrderTicket(),OrderLots(),bid,3,Violet); // close position
                 return(0); // exit
                }
            // check for trailing stop
            if(TrailingStop>0)  
              {                 
               if(Bid-OrderOpenPrice()>Point*TrailingStop)
                 {
                  if(OrderStopLoss()<Bid-Point*TrailingStop)
                    {
                     while(!IsTradeAllowed() || IsTradeContextBusy()) {Sleep(5000);}
                     RefreshRates();
                     OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Green);
                     return(0);
                    }
                 }
              }
           }
         else // go to short position
           {
            // should it be closed?
            if(MacdCurrent<0 && MacdCurrent>SignalCurrent &&
               MacdPrevious<SignalPrevious && MathAbs(MacdCurrent)>(MACDCloseLevel*Point))
              {
               while(!IsTradeAllowed() || IsTradeContextBusy()) {Sleep(5000);}
               RefreshRates();
               ask = NormalizeDouble(MarketInfo(Symbol(),MODE_ASK),Digits);
               OrderClose(OrderTicket(),OrderLots(),ask,3,Violet); // close position
               return(0); // exit
              }
            // check for trailing stop
            if(TrailingStop>0)  
              {                 
               if((OrderOpenPrice()-Ask)>(Point*TrailingStop))
                 {
                  if((OrderStopLoss()>(Ask+Point*TrailingStop)) || (OrderStopLoss()==0))
                    {
                     while(!IsTradeAllowed() || IsTradeContextBusy()) {Sleep(5000);}
                     RefreshRates();
                     OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*TrailingStop,OrderTakeProfit(),0,Red);
                     return(0);
                    }
                 }
              }
           }
        }
     }
   return(0);
  }
// the end.

bool IsBarEnd()
{
    bool bIsBarEnd = false;
    if(nBars != Bars)
    {
        bIsBarEnd = true;
        nBars = Bars;
    }
    
    return(bIsBarEnd);
}

double _Lots()
{
   if(UseMM==false) return(Lots);
   double lot=Lots;
   int    orders=HistoryTotal();     // history orders total
   double Risk2=0;
	//---- select lot size
   int    dp=1; 
	if(MiniAcct==true) dp=2;
   lot=NormalizeDouble(AccountFreeMargin()*Risk/100/1000.0,dp);
   
	//---- return lot size
   if(lot<0.1 && MiniAcct==false) lot=0.1;
   if(lot<0.01 && MiniAcct==true) lot=0.01;
   if(lot>50)lot=50;
   return(lot);
}