//+------------------------------------------------------------------+
//|                                                     Emini-HL.mq4 |
//+------------------------------------------------------------------+

#property indicator_chart_window

extern int      NumCandles        = 999;
extern int      VertSpacing       = 5;
extern int      AboveSymbol       = 242;
extern int      BelowSymbol       = 241;
extern color    SymbolColor       = White;
extern int      SymbolSize        = 3;
extern bool     ChartAlerts       = false;
extern bool     BreakoutAlerts    = false;

double    spr, pnt, tickval, HighPrice, LowPrice;
int       dig, tf;
string    IndiName, ccy;
datetime  prev_time, HighTime, LowTime, LastAlertHigh, LastAlertLow;

//+------------------------------------------------------------------+
int init()   {
//+------------------------------------------------------------------+
  int checksum = 0;
  string str = "0";
  for (int i=0; i<StringLen(str); i++)  
    checksum += i * StringGetChar(str,i);
  IndiName = "Emini-HL-" + checksum;
  IndicatorShortName(IndiName);

  ccy     = Symbol();
  tf      = Period();
  pnt     = MarketInfo(ccy,MODE_POINT);
  dig     = MarketInfo(ccy,MODE_DIGITS);
  spr     = MarketInfo(ccy,MODE_SPREAD);
  tickval = MarketInfo(ccy,MODE_TICKVALUE);
  if (dig == 3 || dig == 5) {
    pnt     *= 10;
    spr     /= 10;
    tickval *= 10;
  }
  LastAlertHigh = 0;
  LastAlertLow  = 0;

  del_obj();
  plot_obj(false);    
  prev_time = -9999;
  return(0);
}

//+------------------------------------------------------------------+
int deinit()  {
//+------------------------------------------------------------------+
  del_obj();
  return(0);
}

//+------------------------------------------------------------------+
int start()  {
//+------------------------------------------------------------------+
  if(prev_time != Time[0])  {
    del_obj();
    plot_obj(true);    
  }  
  prev_time = Time[0];
  return(0);
  return(0);
}

//+------------------------------------------------------------------+
void plot_obj(bool AlertFlag)   {
//+------------------------------------------------------------------+
  string AlertText  = ccy + "," + TFToStr(tf) + " : ";
  string AlertText2 = " ";
  HighTime  = 0;
  HighPrice = 0;
  LowTime   = 0;
  LowPrice  = 0;
  for (int i=1; i<NumCandles; i++)  {
    if(High[i+4]<High[i+3] && High[i+3]<High[i+2] && High[i+2]>High[i+1] && High[i+1]>High[i])   {
      string ObjName = IndiName + "H" + i;
      ObjectCreate(ObjName,OBJ_ARROW,0,Time[i+2],High[i+2]+VertSpacing*pnt*3);
      ObjectSet(ObjName,OBJPROP_ARROWCODE,AboveSymbol);
      ObjectSet(ObjName,OBJPROP_COLOR,SymbolColor);
      ObjectSet(ObjName,OBJPROP_WIDTH,SymbolSize);
      AlertText2 = "High pattern";
      if (HighPrice == 0)  {
        HighPrice = High[i+2];
        HighTime  = Time[i+2];
    } }
    if(Low[i+4]>Low[i+3] && Low[i+3]>Low[i+2] && Low[i+2]<Low[i+1] && Low[i+1]<Low[i])   {
      ObjName = IndiName + "L" + i;
      ObjectCreate(ObjName,OBJ_ARROW,0,Time[i+2],Low[i+2]-VertSpacing*pnt);
      ObjectSet(ObjName,OBJPROP_ARROWCODE,BelowSymbol);
      ObjectSet(ObjName,OBJPROP_COLOR,SymbolColor);
      ObjectSet(ObjName,OBJPROP_WIDTH,SymbolSize);
      AlertText2 = "Low pattern";
      if (LowPrice == 0)  {
        LowPrice = Low[i+2];
        LowTime  = Time[i+2];
    } }
    if (AlertText2 != " " && i==1 && AlertFlag)   {
      AlertText = AlertText + AlertText2;  
      if (ChartAlerts)   Alert(AlertText);
  } }

  Comment("HT = " + TimeToStr(HighTime,TIME_DATE|TIME_MINUTES)
      + "\nHP = " + HighPrice
      + "\nLT = " + TimeToStr(LowTime,TIME_DATE|TIME_MINUTES)
      + "\nLP = " + LowPrice);

  AlertText  = ccy + "," + TFToStr(tf) + " : ";
  if (Close[0] >= HighPrice && HighTime > LastAlertHigh && AlertFlag)  {
    LastAlertHigh = HighTime;
    AlertText2 = "Price hit/exceeds high candle";
    AlertText = AlertText + AlertText2;  
    if (BreakoutAlerts)   Alert(AlertText);
  }  
  if (Close[0] <= LowPrice && LowTime > LastAlertLow && AlertFlag)  {
    LastAlertLow = LowTime;
    AlertText2 = "Price hit/exceeds low candle";
    AlertText = AlertText + AlertText2;  
    if (BreakoutAlerts)   Alert(AlertText);
  }  
  return(0);
}

//+------------------------------------------------------------------+
double DivZero(double n, double d)
//+------------------------------------------------------------------+
// Divides N by D, and returns 0 if the denominator (D) = 0
// Usage:   double x = DivZero(y,z)  sets x = y/z
{
  if (d == 0) return(0);  else return(n/d);
}  

//+------------------------------------------------------------------+
//| del_obj                                                          |
//+------------------------------------------------------------------+
void del_obj()
{
  int k=0;
  while (k<ObjectsTotal())   {
    string objname = ObjectName(k);
    if (StringSubstr(objname,0,StringLen(IndiName)) == IndiName)  
      ObjectDelete(objname);
    else
      k++;
  }    
  return(0);
}

//+------------------------------------------------------------------+
string TFToStr(int tf)
//+------------------------------------------------------------------+
// Converts a MT4-numeric timeframe to its descriptor string
// Usage:   string s=TFToStr(15) returns s="M15"
{
  switch (tf)  {
    case     1 :  return("M1");
    case     5 :  return("M5");
    case    15 :  return("M15");
    case    30 :  return("M30");
    case    60 :  return("H1");
    case   240 :  return("H4");
    case  1440 :  return("D1");
    case 10080 :  return("W1");
    case 43200 :  return("MN");
  }  
  return(0);
}  


