//+------------------------------------------------------------------+
//|                                                   Triple_EMA.mq4 |
//|                                           Copyright © 2010, Kris |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2010, Kris"
#property link      ""

#include <stdlib.mqh>

//external variables
extern double Lots = 0.1;
extern double EquityPercent = 5;
extern double MaxLots = 400;
extern double StopLoss = 50;

//global variables
double   UsePoint;
datetime CurrentTimeStamp;                                              //Store the time stamp of the current bar (CheckOncePerBar)
int MagicNumber;                                                        //Magic EA identifier.  Allows for several co-existing EAs with different input values
string ExpertName;
int Slippage = 4;
double lotMM;
int TakeProfit = 8;
int CurrHour, CurrMin;
int EAOpenTrades;
double EMA1001, EMA1002, EMA201, EMA202, EMA51, EMA52;
double MACD1, MACD2, MACD3;

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//----
      UsePoint = PipPoint(Symbol());                                   //PipPoint function from Initialization_Process.mqh

      CurrentTimeStamp = Time[0];                                      //CheckOncePerBar - set the variable in the init() function in order to
                                                                       //delay the trade condition check until the opening of the next bar.       

      MagicNumber=21345589144;
      ExpertName="Triple_EMA EA for " + Symbol();
         
//----
   return(0);
  }

//+------------------------------------------------------------------+
//|   Point function returns the point value that is equal to one    |
//|   pip.  From Andrew R. Young's book                              |
//+------------------------------------------------------------------+
double PipPoint(string Currency)
   /* This function is for use with brokers that supply fractional pip price quotes, with 3 decimal places for Yen pairs and 5 decimal places
      for all other pairs.  This function returns the point value that is equal to one pip.  From Andrew R. Young's book*/
   {
      int CalcDigits = MarketInfo(Currency,MODE_DIGITS);
      if(CalcDigits == 2 || CalcDigits == 3) double CalcPoint = 0.01;
      else if (CalcDigits == 4 || CalcDigits == 5) CalcPoint = 0.0001;
      return(CalcPoint);
   }  
   
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
//----

      HandleOpenPositions();

      //Check for new bar
      bool NewBar = false;
      if(CurrentTimeStamp != Time[0])
         {
            CurrentTimeStamp = Time[0];
            NewBar = true;
         }
      
      else NewBar = false;
      
      if(NewBar == true)
         {   
            CurrHour = Hour();
            CurrMin = Minute();
            EAOpenTrades = EAOpenPositions();
            
            if(EAOpenTrades == 1)
               {
                  TrailEMAProfit();
               }
               
            if(EAOpenTrades == 0)
               {
                  if((CurrHour > 8 && CurrHour < 21) || (CurrHour == 8 && CurrMin > 29))
                     {
                        GetEMAValues();
                        GetMACDValues();
                        //OK to trade...validate buy or sell trade
                        if(CheckEntryConditionBUY()) 
                           {
                              OpenBuyOrder();
                              OpenBuyOrder();
                           }
                        if(CheckEntryConditionSELL())
                           {
                              OpenSellOrder();
                              OpenSellOrder();
                           }
                     }
               }            
         }         
   
//----
   return(0);
  }
  
//+------------------------------------------------------------------+
//| Handle Open Positions                                            |
//| Check if any open positions need to be closed or modified        |
//+------------------------------------------------------------------+
int HandleOpenPositions()
  {
   int cnt;
   int OpenPos = EAOpenPositions();
   int OrderNo = 0;
//----
   for(cnt=OrdersTotal()-1;cnt>=0;cnt--)
     {
      OrderSelect (cnt, SELECT_BY_POS, MODE_TRADES);
      if(OrderSymbol()!=Symbol()) continue;
      if(OrderMagicNumber()!=MagicNumber)  continue;
      if(OrderType()==OP_BUY)
        {
            //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
            OrderNo++;
            double OpenPrice = OrderOpenPrice();
            double OrderTP = OrderTakeProfit();
         
            if(OrderCloseTime() == 0 && OrderTP == 0.0)
               {
                  //begin monitor TP
                  double BuyTakeProfit = BuyMarketTakeProfit(Symbol(),
                     TakeProfit, OpenPrice);
               
                  RefreshRates();
                  double CurrentBid = Bid;
            
                  if(CurrentBid > BuyTakeProfit)
                     {
                        if(OrderNo == 1 && OrderStopLoss() == 0.0)
                           {
                              CloseSingleMarketOrder(OrderSymbol(),OrderTicket(),OrderLots(),OrderType());
                              //Print("Close1");
                              double BTStopLoss = 0;  
                           }
                        if(OrderNo == 2 && OrderStopLoss() == 0.0)
                           {
                              double SendSL = OpenPrice + (2 * UsePoint);
                              bool Modify = OrderModify(OrderTicket(),OrderOpenPrice(),SendSL,OrderTakeProfit(),0,Blue);
                              
                              //Error Handling
                              if(Modify == false)
                                 {
                                    int ErrorCode = GetLastError();
                                    string ErrDesc = ErrorDescription(ErrorCode);
            
                                    string ErrAlert = StringConcatenate(ExpertName, ": Modify Single Order - Error ",
                                       ErrorCode,": ",ErrDesc,", ",OrderTicket());
                                    Alert(ErrAlert);
            
                                    string ErrLog = StringConcatenate(ExpertName, ": Ticket: ",OrderTicket(),
                                       "Order Type: ",OrderType()," Bid: ",
                                       MarketInfo(OrderSymbol(),MODE_BID)," Ask: ",
                                       MarketInfo(OrderSymbol(),MODE_ASK)," New SL: ",SendSL);
                                    Print(ErrLog);
                                 }                               
                           }
                     }
                  //end monitor TP
                     
                  //begin monitor SL
                  if(OrderStopLoss() == 0)
                     {
                        BTStopLoss = CalcBuySL(Symbol(), OpenPrice);
                     }
                  
                  RefreshRates();
                  CurrentBid = Bid;   
                     
                  if(CurrentBid < BTStopLoss)
                     {
                        CloseSingleMarketOrder(OrderSymbol(),OrderTicket(),OrderLots(),OrderType());
                        //Print("Close2");
                        BTStopLoss = 0;   
                     }                         
                  //end monitor SL
               
               }
            //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        }

      if(OrderType()==OP_SELL)
        {
            //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
            OrderNo++;
            OpenPrice = OrderOpenPrice();
            OrderTP = OrderTakeProfit();
         
            if(OrderCloseTime() == 0 && OrderTP == 0.0)
               {
                  //begin monitor TP
                  double SellTakeProfit = SellMarketTakeProfit(Symbol(),
                     TakeProfit, OpenPrice);
                     
                  RefreshRates();
                  double CurrentAsk = Ask;
                  
                  if(CurrentAsk < SellTakeProfit)
                     {
                        if(OrderNo == 1 && OrderStopLoss() == 0.0)
                           {
                              CloseSingleMarketOrder(OrderSymbol(),OrderTicket(),OrderLots(),OrderType());
                              //Print("Close3");
                              double STStopLoss = 0;  
                           }
                        if(OrderNo == 2 && OrderStopLoss() == 0.0)
                           {
                              SendSL = OpenPrice - (2 * UsePoint);
                              Modify = OrderModify(OrderTicket(),OrderOpenPrice(),SendSL,OrderTakeProfit(),0,Blue);
                              
                              //Error Handling
                              if(Modify == false)
                                 {
                                    ErrorCode = GetLastError();
                                    ErrDesc = ErrorDescription(ErrorCode);
            
                                    ErrAlert = StringConcatenate(ExpertName, ": Modify Single Order - Error ",
                                       ErrorCode,": ",ErrDesc,", ",OrderTicket());
                                    Alert(ErrAlert);
            
                                    ErrLog = StringConcatenate(ExpertName, ": Ticket: ",OrderTicket(),
                                       "Order Type: ",OrderType()," Bid: ",
                                       MarketInfo(OrderSymbol(),MODE_BID)," Ask: ",
                                       MarketInfo(OrderSymbol(),MODE_ASK)," New SL: ",SendSL);
                                    Print(ErrLog);
                                 }                               
                           }
                     }
                  //end monitor TP
                  
                  //begin monitor SL
                  if(OrderStopLoss() == 0)
                     {
                        STStopLoss = CalcSellSL(Symbol(), OpenPrice);
                     }
                  
                  RefreshRates();
                  CurrentAsk = Ask;   
                  CurrentBid = Bid;
                  
                  if(CurrentAsk > STStopLoss && OrderStopLoss() == 0)
                     {
                        CloseSingleMarketOrder(OrderSymbol(),OrderTicket(),OrderLots(),OrderType());
                        //Print("Close4");
                        STStopLoss = 0;   
                     }                         
                  //end monitor SL
                  
               }
            //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        }
     }
  }

//+------------------------------------------------------------------+
//| Trail EMA Profit                                                 |
//| In addition to HandleOpenPositions function, this function       |
//| monitors the profit on the second trade and closes when price    |
//| crosses EMA5 against trade.                                      |
//+------------------------------------------------------------------+
void TrailEMAProfit()
   {
      int cnt;

      for(cnt=OrdersTotal()-1;cnt>=0;cnt--)
         {
            OrderSelect (cnt, SELECT_BY_POS, MODE_TRADES);
            if(OrderSymbol()!=Symbol()) continue;
            if(OrderMagicNumber()!=MagicNumber)  continue;
            
            double PrevClose = iClose(NULL, 0, 1);            
            double PrevEMA5 = iMA(NULL,0,5,0,MODE_EMA,PRICE_CLOSE,1);

            if(OrderType()==OP_BUY)
               {    
                  if(PrevClose < PrevEMA5 || (PrevClose - OrderOpenPrice()) / UsePoint > 100)
                     {
                        CloseSingleMarketOrder(OrderSymbol(),OrderTicket(),OrderLots(),OrderType());
                        //Print("Close5");
                     }               
               }
               
            if(OrderType()==OP_SELL)
               {    
                  if(PrevClose > PrevEMA5 || (OrderOpenPrice() - PrevClose) / UsePoint > 100)
                     {
                        CloseSingleMarketOrder(OrderSymbol(),OrderTicket(),OrderLots(),OrderType());
                        //Print("Close6");
                     }               
               }
         }         
   }

//+------------------------------------------------------------------+
//| Get values for various EMAs                                      |
//+------------------------------------------------------------------+
double GetEMAValues()
   {
      EMA1001 = iMA(NULL,0,100,0,MODE_EMA,PRICE_CLOSE,1);
      EMA1002 = iMA(NULL,0,100,0,MODE_EMA,PRICE_CLOSE,2);
      EMA201 = iMA(NULL,0,20,0,MODE_EMA,PRICE_CLOSE,1);
      EMA202 = iMA(NULL,0,20,0,MODE_EMA,PRICE_CLOSE,2);
      EMA51 = iMA(NULL,0,5,0,MODE_EMA,PRICE_CLOSE,1);
      EMA52 = iMA(NULL,0,5,0,MODE_EMA,PRICE_CLOSE,2);
   }

//+------------------------------------------------------------------+
//| Get values for last 3 MACD bars                                  |
//+------------------------------------------------------------------+
double GetMACDValues()
   {
      MACD1 = iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,1);
      MACD2 = iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,2);
      MACD3 = iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,3);
   }


//+------------------------------------------------------------------+
//| CheckEntryCondition                                              |
//| Check if rules are met for Buy trade - Cross trade               |
//+------------------------------------------------------------------+
bool CheckEntryConditionBUY()
  {
      double Close1;
      double Close2;
      double High1;
      double Low1;
      bool EMA5CrossEMA100 = false;
      bool MACD = false;
      bool Price = false;
      bool EMA5CrossEMA20 = false;
      bool BarSize = false;
      bool M30Doji = true;

      RefreshRates();
      Close1 = Close[1];
      Close2 = Close[2];
      High1 = High[1];
      Low1 = Low[1];
      double CurrPrice = Bid;
      
      if(EMA52 < EMA1002 && EMA51 > EMA1001) EMA5CrossEMA100 = true;
      
      if(MACD1 > 0.0 || (MACD1 > MACD2 && MACD2 > MACD3)) MACD = true;
      
      if(CurrPrice > EMA1001) Price = true;
      
      if(EMA52 < EMA202 && EMA51 > EMA201) EMA5CrossEMA20 = true;
      
      bool ExtPrice = GetExtHigh();
      
      double M15BarSize = (High1 - Low1) / UsePoint;
      if(M15BarSize < 60) BarSize = true;
      
      M30Doji = IsDoji(30,1);

      Print("BUY: Price: ",Price, ", 5Cross100: ",EMA5CrossEMA100, ", 5Cross20: ", EMA5CrossEMA20, ", MACD: ",MACD,", ExtPrice: ",ExtPrice,", BarSize: ",BarSize,", M30Doji: ",M30Doji);
      if(Price == true && EMA5CrossEMA100 == true && MACD == true && ExtPrice == false && BarSize == true && M30Doji == false) return(true);
      if(Price == true && EMA5CrossEMA20 == true && MACD == true && EMA51 > EMA1001 && ExtPrice == false && BarSize == true) return(true);
            
      return(false);
  }   

//+------------------------------------------------------------------+
//| CheckEntryCondition                                              |
//| Check if rules are met for Sell trade                            |
//+------------------------------------------------------------------+
bool CheckEntryConditionSELL()
  {
      double Close1;
      double Close2;
      double High1;
      double Low1;
      bool EMA5CrossEMA100 = false;
      bool MACD = false;
      bool Price = false;
      bool EMA5CrossEMA20 = false;
      bool BarSize = false;
      bool M30Doji = true;

      RefreshRates();
      Close1 = Close[1];
      Close2 = Close[2];
      High1 = High[1];
      Low1 = Low[1];      
      double CurrPrice = Bid;
      
      if(EMA52 > EMA1002 && EMA51 < EMA1001) EMA5CrossEMA100 = true;

      if(MACD1 < 0.0 || (MACD1 < MACD2 && MACD2 < MACD3)) MACD = true;
      
      if(CurrPrice < EMA1001) Price = true;

      if(EMA52 > EMA202 && EMA51 < EMA201) EMA5CrossEMA20 = true;

      bool ExtPrice = GetExtLow();

      double M15BarSize = (High1 - Low1) / UsePoint;
      if(M15BarSize < 60) BarSize = true;

      M30Doji = IsDoji(30,1);
          
      Print("SELL: Price: ",Price, ", 5Cross100: ",EMA5CrossEMA100, ", 5Cross20: ", EMA5CrossEMA20, ", MACD: ",MACD,", ExtPrice: ",ExtPrice,", BarSize: ",BarSize,", M30Doji: ",M30Doji);
      if(Price == true && EMA5CrossEMA100 == true && MACD == true && ExtPrice == false && BarSize == true && M30Doji == false) return(true);            
      if(Price == true && EMA5CrossEMA20 == true && MACD == true && EMA51 < EMA1001 && ExtPrice == false && BarSize == true) return(true);
      
      return(false);
  }

//+------------------------------------------------------------------+
//| Retrieve high from last 20 H1 bars and compare to last M15 high  |
//+------------------------------------------------------------------+
bool GetExtHigh()
   {
      double   M15High;
      M15High = iHigh(NULL, 0, 1);      

      double   H1High[20];
      
      for(int x = 0; x < 20; x++)                                            
         {
            double GetHigh = iHigh(NULL, PERIOD_H1, x+ 1);
            H1High[x] = GetHigh;
         }
      
      int      maxValueID = ArrayMaximum(H1High);
      double   maxH1High = H1High[maxValueID];
      
      if(M15High > maxH1High) return(true);
      
      return(false);
   }

//+------------------------------------------------------------------+
//| Retrieve low from last 20 H1 bars and compare to last M15 low    |
//+------------------------------------------------------------------+
bool GetExtLow()
   {
      double   M15Low1;
      double   M15Low2;
      M15Low1 = iLow(NULL, 0, 1);
      M15Low2 = iLow(NULL, 0, 2);
      
      double   H1Low[20];
      
      for(int x = 0; x < 20; x++)                                            
         {
            double GetLow = iLow(NULL, PERIOD_H1, x + 1);
            H1Low[x] = GetLow;
         }
      
      int      minValueID = ArrayMinimum(H1Low);
      double   minH1Low= H1Low[minValueID];
      
      if(M15Low1 < M15Low2 && M15Low1 < minH1Low) return(true);
      
      return(false);
   }



//+------------------------------------------------------------------+
//|   Calculate take profit for a buy market order                   |     
//+------------------------------------------------------------------+
double BuyMarketTakeProfit(string argSymbol, int argTakeProfit,
  double argOpenPrice)
  {
     if(argTakeProfit == 0) return(0);
     double BuyTakeProfit = argOpenPrice + (argTakeProfit * UsePoint);
     
     return(BuyTakeProfit);
  }

//+------------------------------------------------------------------+
//|   Calculate take profit for a sell market order                  |
//+------------------------------------------------------------------+
double SellMarketTakeProfit(string argSymbol, int argTakeProfit,
  double argOpenPrice)
  {
     if(argTakeProfit == 0) return(0);
     double SellTakeProfit = argOpenPrice - (argTakeProfit * UsePoint);
     
     return(SellTakeProfit);
  }

//+------------------------------------------------------------------+
//| OpenBuyOrder                                                     |
//| If Stop Loss or TakeProfit are used the values are calculated    |
//| for each trade                                                   |
//+------------------------------------------------------------------+
void OpenBuyOrder()
  {

      int err, ticket;
      color myColor = Green;
      
      RefreshRates();
      double myPrice = Ask;
      double myTakeProfit = myPrice + TakeProfit * UsePoint;
      lotMM=GetLots();

      while(IsTradeContextBusy()) Sleep(10);
      
      int Retries = 0;
      int MaxRetries = 5;
      
      while(ticket <= 0)
         {
            ticket=OrderSend(Symbol(),OP_BUY,lotMM,myPrice,Slippage,0,0,ExpertName, MagicNumber,0,myColor);   
            
            if(Retries <= MaxRetries) Retries ++;
            else break;
         }      
   
      string MyTxt;
      MyTxt = " for " + DoubleToStr(myPrice,4); 
         
      if(ticket<=0)
        {
         err=GetLastError();
         Print(ExpertName,": Error opening BUY order " + ": (" + err + ") " + ErrorDescription(err) + " /// " + MyTxt);
         return(0);
        }
      Print(ExpertName, ": OpenBuy" + MyTxt); 
  }

//+------------------------------------------------------------------+
//| OpenSellOrder                                                    |
//| If Stop Loss or TakeProfit are used the values are calculated    |
//| for each trade                                                   |
//+------------------------------------------------------------------+
void OpenSellOrder()
  {
      int err, ticket;
      color myColor = Green;
   
      double myPrice = Bid;         
      double myTakeProfit = myPrice - TakeProfit * UsePoint;
      lotMM=GetLots();

      while(IsTradeContextBusy()) Sleep(10);
      
      int Retries = 0;
      int MaxRetries = 5;
      
      while(ticket <= 0)
         {
            ticket=OrderSend(Symbol(),OP_SELL,lotMM,myPrice,Slippage,0,0,ExpertName, MagicNumber,0,myColor);   
            if(Retries <= MaxRetries) Retries ++;
            else break;
         }      

      string MyTxt;
      MyTxt = " for " + DoubleToStr(myPrice,4);
         
      if(ticket<=0)
        {
         err=GetLastError();
         Print(ExpertName, ": Error opening Sell order " + ": (" + err + ") " + ErrorDescription(err) + " /// " + MyTxt);
         return(0);
        }
      Print(ExpertName, ": OpenSell" + MyTxt); 
  }
  
//+------------------------------------------------------------------+
//|   CloseSingleMarketOrder - closes current market order           |
//+------------------------------------------------------------------+
void CloseSingleMarketOrder(string argSymbol,int argTicket, double argCloseLots, int argOrderType)
   {
      while(IsTradeContextBusy()) Sleep(10);
      RefreshRates();
      if(argOrderType == 0) double ClosePrice = Bid;
      if(argOrderType == 1) ClosePrice = Ask;
      
      bool Closed = OrderClose(argTicket,argCloseLots,ClosePrice,0,Red);
      RefreshRates();

      //Error Handling
      if(Closed == false)
         {
            int ErrorCode = GetLastError();
            string ErrDesc = ErrorDescription(ErrorCode);
            
            string ErrAlert = StringConcatenate(ExpertName, ": Close Single Order - Error ",
               ErrorCode,": ",ErrDesc,", ",argTicket);
            Alert(ErrAlert);
            
            string ErrLog = StringConcatenate(ExpertName, ": Ticket: ",argTicket,
               "Order Type: ",argOrderType," Bid: ",
               MarketInfo(argSymbol,MODE_BID)," Ask: ",
               MarketInfo(argSymbol,MODE_ASK)," Price: ",ClosePrice);
            Print(ErrLog);
         }
   }

//+------------------------------------------------------------------+
//|   Function calculates stop loss for buy market order.            |
//+------------------------------------------------------------------+
double CalcBuySL(string argSymbol, double argTicketOpen)
   {

      double BuySL = argTicketOpen - (StopLoss * UsePoint);
      return(BuySL);   
   }   

//+------------------------------------------------------------------+
//|   Function calculates stop loss for sell market order.           |
//+------------------------------------------------------------------+
double CalcSellSL(string argSymbol, double argTicketOpen)
   {
      double SellSL = argTicketOpen + (StopLoss * UsePoint);
      return(SellSL);   
   }
   
//+------------------------------------------------------------------+
//| Get number of lots for this trade                                |
//+------------------------------------------------------------------+
double GetLots()
   {
      double RiskAmount = AccountEquity() * (EquityPercent / 100);
      double TickValue = MarketInfo(Symbol(),MODE_TICKVALUE);
      if(Point == 0.001 || Point == 0.00001) TickValue *= 10;
      double LotSize = (RiskAmount / StopLoss) / TickValue;
      //Print("TickValue: ",TickValue," Risk: ",RiskAmount);
      //Print("R/SL/Tick: ",(RiskAmount / StopLoss) / TickValue);
      //Print("Lot Size: ",LotSize);
      
      //if(LotSize < 1.0) LotSize = 1.0;
      
      if(LotSize < MarketInfo(Symbol(),MODE_MINLOT))
         {
            LotSize = MarketInfo(Symbol(),MODE_MINLOT);
         }
      else if(LotSize > MarketInfo(Symbol(),MODE_MAXLOT))
         {
            LotSize = MarketInfo(Symbol(),MODE_MAXLOT);
         }
      else if(LotSize > MaxLots)
         {
            LotSize = MaxLots;
         }
      if(MarketInfo(Symbol(),MODE_LOTSTEP) == 0.1)
         {
            LotSize = NormalizeDouble(LotSize, 1);
         }
      else LotSize = NormalizeDouble(LotSize, 2);
      
      double lot = LotSize;
      //Print("LotSize: ",LotSize," LOTSTEP: ",MarketInfo(Symbol(),MODE_LOTSTEP));
      
   return(lot);
  }      

//+------------------------------------------------------------------------+
//| counts the number of open positions                                    |
//+------------------------------------------------------------------------+
int EAOpenPositions(  )
  {
      int op =0;
      for(int i=OrdersTotal()-1;i>=0;i--)                                // scan all orders and positions...
        {
         OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
           {
            if(OrderType()==OP_BUY)op++;
            if(OrderType()==OP_SELL)op++;
            if(OrderType()==OP_BUYLIMIT)op++;
            if(OrderType()==OP_SELLLIMIT)op++;
           }
        }
      return(op);
  }   

//+------------------------------------------------------------------+
//|   Determine if previous bar is a doji/hammer                     |     
//+------------------------------------------------------------------+
bool IsDoji(int argTimePeriod, int argShift)
   {
      double BarClose;
      double BarOpen;
      
      RefreshRates();
      BarClose = iClose(NULL,argTimePeriod,argShift);
      BarOpen = iOpen(NULL,argTimePeriod,argShift);
                           
      if(MathAbs(BarOpen-BarClose) * 10000 < 1.0) return(true);
      return(false);
   }  
    
//+------------------------------------------------------------------+