#property copyright ""
#property link      ""

#property indicator_separate_window
#property indicator_minimum -35.0
#property indicator_maximum 35.0
#property indicator_buffers 4
#property indicator_level2 12.0
#property indicator_level3 -12.0

input color              HistoUpClr      = clrDodgerBlue;
input color              HistoDnClr      = clrMagenta;
input color              DotUpClr        = clrBlue;
input color              DotDnClr        = clrRed;
input color              LevelClr        = clrWhite;
input bool               alertsOn        = false;
input bool               alertsOnCurrent = false;
input bool               alertsMessage   = true;
input bool               alertsSound     = false;
input bool               alertsEmail     = false;
input bool               alertsNotify    = false;

// New inputs for histogram widths
input int                AboveWidth      = 2;   // Width of the above histogram
input int                BelowWidth      = 2;   // Width of the below histogram

double AboveBuff[];
double ShortBuff[];
double LongBuffe[];
double BelowBuff[];

// ---
int init() {
   SetIndexBuffer(0, AboveBuff);
   SetIndexStyle(0, DRAW_HISTOGRAM, EMPTY, AboveWidth, HistoDnClr); // Above histogram
   SetIndexBuffer(1, BelowBuff);
   SetIndexStyle(1, DRAW_HISTOGRAM, EMPTY, BelowWidth, HistoUpClr); // Below histogram
   SetIndexBuffer(2, ShortBuff);
   SetIndexStyle(2, DRAW_ARROW, EMPTY, 2, DotDnClr); 
   SetIndexArrow(2, 108); // Red
   SetIndexBuffer(3, LongBuffe);
   SetIndexStyle(3, DRAW_ARROW, EMPTY, 2, DotUpClr); 
   SetIndexArrow(3, 108); // Blue
   
   SetLevelStyle(STYLE_DOT, 0, LevelClr);
   
   SetIndexLabel(0, "Above");
   SetIndexLabel(1, "Below");   
   SetIndexLabel(2, NULL);  
   SetIndexLabel(3, NULL);  

   IndicatorShortName("ProfessionalSwing");
   return (0);
}

// ---
void deinit() {
   Comment("");
}

// ---
void start() {
   double Temp;
   double Main;
   double Minr;
   int Limit;
   int CntBr = IndicatorCounted();
   if (CntBr >= 0) {
      if (CntBr > 0) CntBr--;
      Limit = Bars - CntBr;
      for (int i = 0; i < Bars; i++) {
         Temp = 0.0;
         for (int j = i; j < i + 5; j++) Temp += (High[j] + Low[j]) / 2.0;
         Main = Temp / 5.0;
         Temp = 0.0;
         for (j = i; j < i + 5; j++) Temp += High[j] - Low[j];
         Minr = 0.2 * (Temp / 5.0);
         AboveBuff[i] = 3.0 * (High[i]  - Main) / Minr;
         BelowBuff[i] = 3.0 * (Low[i]   - Main) / Minr;
      }
      for (i = 0; i < Limit; i++) {
         if (AboveBuff[i] >  24.0) ShortBuff[i] =  25;
         if (BelowBuff[i] < -24.0) LongBuffe[i] = -25;
      }
   }
   manageAlerts();
}

//------------ 
void manageAlerts() {
   if (alertsOn) {
      int whichBar = 1; 
      if (alertsOnCurrent) whichBar = 0;
      if (ShortBuff[whichBar] != EMPTY_VALUE || LongBuffe[whichBar] != EMPTY_VALUE) {
         if (LongBuffe[whichBar] != EMPTY_VALUE) doAlert(whichBar,"up");
         if (ShortBuff[whichBar] != EMPTY_VALUE) doAlert(whichBar,"down");
      }
   }
}

void doAlert(int forBar, string doWhat) {
   static string   previousAlert="nothing";
   static datetime previousTime;
   
   if (previousAlert != doWhat || previousTime != Time[forBar]) {
       previousAlert  = doWhat;
       previousTime   = Time[forBar];

       string message = timeFrameToString(_Period)+" "+_Symbol+" at "+TimeToString(TimeLocal(),TIME_SECONDS)+" Prof. Swing "+doWhat;
       if (alertsMessage) Alert(message);
       if (alertsNotify)  SendNotification(message);
       if (alertsEmail)   SendMail(_Symbol+" Prof. Swing",message);
       if (alertsSound)   PlaySound("alert2.wav");
   }
}
//-------------------------------------------------------------------
//
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("");
}

int timeFrameValue(int _tf) {
   int add  = (_tf>=0) ? 0 : fabs(_tf);
   if (add != 0) _tf = _Period;
   int size = ArraySize(iTfTable); 
   int i = 0; 
   for (;i<size; i++) 
      if (iTfTable[i]==_tf) break;
   if (i==size) return(_Period);
   return(iTfTable[(int)fmin(i+add,size-1)]);
}
