//+------------------------------------------------------------------+
//|                                                  MACD Sample.mq4 |
//|                      Copyright © 2005, MetaQuotes Software Corp. |
//|                                       http://www.metaquotes.net/ |
//+------------------------------------------------------------------+
extern string separator2 = "*** Indicator Settings ***";
extern double Lots = 0.1;
extern double TakeProfit = 500;
extern double StopLoss = 100;
extern double TrailingStop = 20;
extern string separator1 = "*** OSMA Settings ***";
extern int    fastEMA = 12;
extern int    slowEMA = 26;
extern int    signal = 9;
extern bool   drawDivergenceLines = true;
extern bool   displayAlert = false;

//---- buffers
double upOsMA[];
double downOsMA[];
double bullishDivergence[];
double bearishDivergence[];
double OsMA[];

//---- Signals
bool ClassicalBullishDivergence;
bool ReverseBullishDivergence;
bool ClassicalBearishDivergence;
bool ReverseBearishDivergence;


//---------------------------------
// Verify that a new bar appeared.|
//---------------------------------
bool NewBar()
{
   static int lastBars;
   if (lastBars != Bars)
   {
      lastBars = Bars;
      return(true);
   }
   else
   {
      return(false);
   }
}
//+------------------------------------------------------------------+
//|  Main Method                                                     |
//+------------------------------------------------------------------+
int start()
{
   double MacdCurrent, MacdPrevious, SignalCurrent;
   double SignalPrevious, MaCurrent, MaPrevious;
   int cnt, ticket, total;

   //return if not a new bar
   if (!NewBar()) return(0);
   
   if(Bars<10)
   {
      Print("bars less than 10");
   
      return(0);  
   }
   
   if(TakeProfit<10)
   {
      Print("TakeProfit less than 10");
      
      return(0);  // check TakeProfit
   }

   total=OrdersTotal();
 
   Print(iCustom(NULL,0,"OsMaDivergence",separator1,fastEMA,slowEMA,signal,separator2,drawDivergenceLines,displayAlert,2,0));

   if(total<1) 
   {
      // no opened orders identified
      if(AccountFreeMargin()<(1000*Lots))
      {
         Print("We have no money. Free Margin = ", AccountFreeMargin());
         
         return(0);  
      }
     
      ClassicalBullishDivergence = false;
      ReverseBullishDivergence = false;   
      ClassicalBearishDivergence = false;
      ReverseBearishDivergence = false;
      
      if (iCustom(NULL,0,"OsMaDivergence",separator1,fastEMA,slowEMA,signal,separator2,drawDivergenceLines,displayAlert,2,1) == 1)
         ClassicalBullishDivergence = true;     
       
      if (iCustom(NULL,0,"OsMaDivergence",separator1,fastEMA,slowEMA,signal,separator2,drawDivergenceLines,displayAlert,2,1) == 2)
         ReverseBullishDivergence = true;     
     
     if (iCustom(NULL,0,"OsMaDivergence",separator1,fastEMA,slowEMA,signal,separator2,drawDivergenceLines,displayAlert,3,1) == -1)
         ClassicalBearishDivergence = true;     
     
     if (iCustom(NULL,0,"OsMaDivergence",separator1,fastEMA,slowEMA,signal,separator2,drawDivergenceLines,displayAlert,3,1) == -2)
         ReverseBearishDivergence = true;     
      
         
      //Print(ClassicalBullishDivergence);
      //Print(ReverseBullishDivergence);
      //Print(ClassicalBearishDivergence);
      //Print(ReverseBearishDivergence);
     
      // check for long position (BUY) possibility
      if(ClassicalBullishDivergence)// || ReverseBullishDivergence)
      {
         ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,3,Bid-StopLoss*Point,Ask+TakeProfit*Point,"Bullish Divergance",16384,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()); 
         
         return(0); 
      }
     
      // check for short position (SELL) possibility
      if(ClassicalBearishDivergence || ReverseBearishDivergence)
      {
         ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,3,Ask+StopLoss*Point,Bid-TakeProfit*Point,"macd sample",16384,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()); 
         
         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 && OrderSymbol()==Symbol()) // check for opened position and symbol
      {
         if(OrderType()==OP_BUY)   // long position is opened
         {
            // should it be closed?
            //if(MacdCurrent>0 && MacdCurrent<SignalCurrent && MacdPrevious>SignalPrevious &&
            //   MacdCurrent>(MACDCloseLevel*Point))
            //    {
            //     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)
                  {
                     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))
            //  {
            //   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))
                  {
                     OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*TrailingStop,OrderTakeProfit(),0,Red);
                  
                     return(0);
                  }
               }
            }
         }
      }
   }
     
   return(0);
}

