
#property copyright "FILTER-EXTRA"


#property indicator_separate_window
#property indicator_buffers 2
#property indicator_color1 Red
#property indicator_color2 Blue
#property indicator_width1 2
#property indicator_width2 2

extern int Length   = 55.0;
extern int barsback = 5000;
extern bool   arrowsVisible      = true;
extern string arrowsIdentifier   = "filterArrows";
extern double arrowsDisplacement = 1.0;
extern color  arrowsUpColor      = DeepSkyBlue;
extern color  arrowsDnColor      = Red;
extern int    arrowsUpCode       = 233;
extern int    arrowsDnCode       = 234;
extern int    arrowsUpSize       = 1;
extern int    arrowsDnSize       = 1;
extern bool            alertsOn        = false;
extern bool            alertsOnCurrent = true;
extern bool            alertsMessage   = true;
extern bool            alertsSound     = false;
extern bool            alertsNotify    = false;
extern bool            alertsEmail     = false;
extern string          soundFile       = "alert2.wav";

double buffer1[];
double buffer2[];
bool cer;
bool cer2;
bool cer3 = TRUE;

int init() {
   cer3 = TRUE;
   SetIndexStyle(0, DRAW_HISTOGRAM);
   SetIndexBuffer(0, buffer1);
   SetIndexStyle(1, DRAW_HISTOGRAM);
   SetIndexBuffer(1, buffer2);
   return (0);
}

int deinit() {
   string lookFor       = arrowsIdentifier+":";
   int    lookForLength = StringLen(lookFor);
   for (int i=ObjectsTotal()-1; i>=0; i--)
   {
      string objectName = ObjectName(i);
         if (StringSubstr(objectName,0,lookForLength) == lookFor) ObjectDelete(objectName);
   }
   return (0);
}

int start() {
   double low1;
   double high1;
   double cero[10000][3];
   if (!cer3) return (0);
   
  
   int pep = 0;
   int bep = 0;
   int tep = 0;
  
   double high60 = High[barsback];
   double low68 = Low[barsback];
   
   int li3 = barsback;
   int li6 = barsback;
   for (int li2 = barsback; li2 >= 0; li2--) {
      low1 = 10000000;
      high1 = -100000000;
      for (int li8 = li2 + Length; li8 >= li2 + 1; li8--) {
         if (Low[li8] < low1) low1 = Low[li8];
         if (High[li8] > high1) high1 = High[li8];
      }
      if (Low[li2] < low1 && High[li2] > high1) {
         bep = 2;
         if (pep == 1) li3 = li2 + 1;
         if (pep == -1) li6 = li2 + 1;
      } else {
         if (Low[li2] < low1) bep = -1;
         if (High[li2] > high1)bep  = 1;
      }
      if (bep != pep && pep != 0) {
         if (bep == 2) {
            bep = -pep;
            high60 = High[li2];
            low68 = Low[li2];
            cer = FALSE;
            cer2 = FALSE;
         }
         tep++;
         if (bep == 1) {
            cero[tep][1] = li6;
            cero[tep][2] = low68;
            cer = FALSE;
            cer2 = TRUE;
         }
         if (bep == -1) {
            cero[tep][1] = li3;
            cero[tep][2] = high60;
            cer = TRUE;
            cer2 = FALSE;
         }
         high60 = High[li2];
         low68 = Low[li2];
      }
      if (bep == 1) {
         if (High[li2] >= high60) {
            high60 = High[li2];
            li3 = li2;
         }
      }
      if (bep == -1) {
         if (Low[li2] <= low68) {
            low68 = Low[li2];
            li6 = li2;
         }
      }
      pep = bep;
      if (cer2 == TRUE) {
         buffer2[li2] = 1;
         buffer1[li2] = 0;
      }
      if (cer == TRUE) {
         buffer2[li2] = 0;
         buffer1[li2] = 1;
      }
      manageArrow(li2);
   }
   manageAlerts(); 
   return (0);
}

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//
//
//
//

void manageArrow(int i)
{
   if (arrowsVisible)
   {
      ObjectDelete(arrowsIdentifier+":"+Time[i]);
      
      if (buffer2[i] == 1 && buffer2[i+1] == 0) drawArrow(i,arrowsUpColor,arrowsUpCode,arrowsUpSize,false);
      if (buffer1[i] == 1 && buffer1[i+1] == 0) drawArrow(i,arrowsDnColor,arrowsDnCode,arrowsDnSize,true);
   }      
}               

//
//
//
//
//

void drawArrow(int i,color theColor,int theCode,int theSize, bool up)
{
   string name = arrowsIdentifier+":"+Time[i];
   double gap  = iATR(NULL,0,20,i);   
   
      //
      //
      //
      //
      //
      
      ObjectCreate(name,OBJ_ARROW,0,Time[i],0);
         ObjectSet(name,OBJPROP_ARROWCODE,theCode);
         ObjectSet(name,OBJPROP_COLOR,   theColor);
         ObjectSet(name,OBJPROP_WIDTH,    theSize);      
         
         if (up)
               ObjectSet(name,OBJPROP_PRICE1,High[i] + arrowsDisplacement * gap);
         else  ObjectSet(name,OBJPROP_PRICE1, Low[i] - arrowsDisplacement * gap);
}

//------------------------------------------------------------------
//
//------------------------------------------------------------------

void manageAlerts()
{
   if (alertsOn)
   {
      int whichBar = 1; if (alertsOnCurrent) whichBar = 0;
      if (buffer2[whichBar+1] == 0 && buffer2[whichBar] != 0) doAlert(whichBar,"up");
      if (buffer1[whichBar+1] == 0 && buffer1[whichBar] != 0) doAlert(whichBar,"down");        
   }
}   

//
//
//

void doAlert(int forBar, string doWhat)
{
   static string   previousAlert="nothing";
   static datetime previousTime;
   string message;
   
      if (previousAlert != doWhat || previousTime != Time[forBar]) {
          previousAlert  = doWhat;
          previousTime   = Time[forBar];

          //
          //
          //
          //
          //

          message =  StringConcatenate(Symbol()," ",timeFrameToString(_Period)," at ",TimeToStr(TimeLocal(),TIME_SECONDS)," FILTER-EXTRA ",doWhat);
             if (alertsMessage) Alert(message);
             if (alertsNotify)  SendNotification(message);
             if (alertsEmail)   SendMail(StringConcatenate(Symbol(), Period(), " FILTER-EXTRA "),message);
             if (alertsSound)   PlaySound(soundFile);
      }
}

//+-------------------------------------------------------------------
//|                                                                  
//+-------------------------------------------------------------------

string sTfTable[] = {"M1","M5","M15","M30","H1","H4","D1","W1","MN"};
int    iTfTable[] = {1,5,15,30,60,240,1440,10080,43200};

string timeFrameToString(int tf)
{
   for (int i=ArraySize(iTfTable)-1; i>=0; i--) 
         if (tf==iTfTable[i]) return(sTfTable[i]);
                              return("");
}


