/*
███████╗ ██████╗ ██████╗ ███████╗██╗  ██╗     ███████╗████████╗ █████╗ ████████╗██╗ ██████╗ ███╗   ██╗
██╔════╝██╔═══██╗██╔══██╗██╔════╝╚██╗██╔╝     ██╔════╝╚══██╔══╝██╔══██╗╚══██╔══╝██║██╔═══██╗████╗  ██║
█████╗  ██║   ██║██████╔╝█████╗   ╚███╔╝█████╗███████╗   ██║   ███████║   ██║   ██║██║   ██║██╔██╗ ██║
██╔══╝  ██║   ██║██╔══██╗██╔══╝   ██╔██╗╚════╝╚════██║   ██║   ██╔══██║   ██║   ██║██║   ██║██║╚██╗██║
██║     ╚██████╔╝██║  ██║███████╗██╔╝ ██╗     ███████║   ██║   ██║  ██║   ██║   ██║╚██████╔╝██║ ╚████║
╚═╝      ╚═════╝ ╚═╝  ╚═╝╚══════╝╚═╝  ╚═╝     ╚══════╝   ╚═╝   ╚═╝  ╚═╝   ╚═╝   ╚═╝ ╚═════╝ ╚═╝  ╚═══╝
*/
//------------------------------------------------------------------
#property copyright "© 2011, Forex-Station"
#property link      "https://forex-station.com/post1295578380.html#p1295578380"
//------------------------------------------------------------------

#property indicator_chart_window
#property indicator_buffers 7
#property indicator_color1  clrLime
#property indicator_color2  clrMagenta
#property indicator_color3  clrGreen
#property indicator_color4  clrBrown
#property indicator_color5  clrDarkOrange
#property indicator_color6  clrGreen
#property indicator_color7  clrBrown
#property indicator_width6  3
#property indicator_width7  3
#property indicator_style3  STYLE_DOT
#property indicator_style4  STYLE_DOT
#property strict

//
//
//
//
//

extern ENUM_TIMEFRAMES TimeFrame         = PERIOD_CURRENT; // Timeframe to use
extern int    Tenkan                     = 9;              // Tenkan Period
extern int    Kijun                      = 26;              // Kijun Period
extern int    Senkou                     = 52;             // Senkou Period
extern bool   alertsOn                   = false;          // Alerts On?
extern bool   alertsOnKumoCloudCross     = false;          // Alerts on leaving Kumo cloud?
extern bool   alertsOnTenkanKijunCross   = false;          // Alerts on tenkan and kijun cross?
extern bool   alertsOnPriceKijunCross    = false;          // Alerts on price crossing kijun?
extern bool   alertsOnChinkouTenkanCross = false;          // Alerts on Chinkou and Tenkan cross?
extern bool   alertsOnSpanASpanBCross    = false;          // Alerts on SpanA and SpanB cross?
extern bool   alertsOnCurrent            = false;          // Alerts on current open bar?
extern bool   alertsMessage              = false;          // Alerts message?
extern bool   alertsSound                = false;          // Alerts sound?
extern bool   alertsEmail                = false;          // Alerts send email?
extern bool   alertsNotify               = false;          // Alerts Send Notification?
extern bool   Interpolate                = true;           // Interpolate values if multi timeframe is used

extern bool   Draw_Tenkan                = false;          // Draw Tenkan option
extern bool   Draw_Kijun                 = false;          // Draw Kijun option
extern bool   Draw_Kumo                  = true;           // Draw Kumo cloud option
extern bool   Draw_Chikou                = false;          // Draw Chinkou option
extern bool   Draw_Box                   = true;           // Draw Box (Master Switch)

// Colors for the boxes
extern color  Box_Color_Bear             = clrLavenderBlush;  // Color when SpanA crosses UNDER SpanB
extern color  Box_Color_Bull             = clrHoneydew;       // Color when SpanA crosses OVER SpanB

//Forex-Station button template start41; copy and paste
extern string             button_note1          = "(===||:::::::::::::::::::::::::::::::::>"; // (===||:::::::::::::::::::::::::>
extern int                btn_Subwindow         = 0;                               // What window to put the button on.  If <0, the button will use the same sub-window as the indicator.
extern ENUM_BASE_CORNER   btn_corner            = CORNER_LEFT_UPPER;               // button corner on chart for anchoring
extern string             btn_text1             = "Bull";                          // Button 1 Text
extern string             btn_text2             = "Bear";                          // Button 2 Text
extern string             btn_Font              = "Arial";                         // button font name
extern int                btn_FontSize          = 8;                               // button font size               
extern color              btn_text_ON_color     = clrLime;                         // ON color when the button is turned on
extern color              btn_text_OFF_color    = clrRed;                          // OFF color when the button is turned off
extern color              btn_background_color  = clrDimGray;                      // background color of the button
extern color              btn_border_color      = clrBlack;                        // border color the button
extern int                button_x              = 20;                              // x coordinate of the button 1    
extern int                button_y              = 195;                             // y coordinate of the button     
extern int                btn_Width             = 40;                              // button width
extern int                btn_Height            = 20;                              // button height
extern string             UniqueButtonID        = "IchiBT";                        // Unique ID for each button        
extern string             button_note2          = "(===||:::::::::::::::::::::::::::::::::>"; // (===||:::::::::::::::::::::::::>

bool show_bear, show_bull, recalc=false;
string IndicatorObjPrefix;
string buttonId1, buttonId2;
//Forex-Station button template end41; copy and paste

//
//
//
//
//

double ts[];
double ks[];
double SpanA[];
double SpanB[];
double Chinkou[];
double SpanA2[];
double SpanB2[];
double trend1[];
double trend2[];
double trend3[];
double trend4[];
double trend5[];
string indicatorFileName;
bool   returnBars;

//+------------------------------------------------------------------------------------------------------------------+
//Forex-Station button template start42; copy and paste
int OnInit()
{
   IndicatorDigits(Digits);
   IndicatorObjPrefix = "__" + UniqueButtonID + "__";
      
   buttonId1 = "_" + UniqueButtonID + "_Bear_";
   buttonId2 = "_" + UniqueButtonID + "_Bull_";
   
   // Button 1 (Bearish) - X
   if (ObjectFind(buttonId1)<0) 
      createButton(buttonId1, btn_text1, btn_Width, btn_Height, btn_Font, btn_FontSize, btn_background_color, btn_border_color, btn_text_ON_color, button_x);
   
   // Button 2 (Bullish) - X + Width
   if (ObjectFind(buttonId2)<0) 
      createButton(buttonId2, btn_text2, btn_Width, btn_Height, btn_Font, btn_FontSize, btn_background_color, btn_border_color, btn_text_ON_color, button_x + btn_Width);

   init2();
   
   show_bear = ObjectGetInteger(0, buttonId1, OBJPROP_STATE);
   show_bull = ObjectGetInteger(0, buttonId2, OBJPROP_STATE);
  
   UpdateButtons();
   return(INIT_SUCCEEDED);
}

void UpdateButtons()
{
   if (show_bear) ObjectSetInteger(0,buttonId1,OBJPROP_COLOR,btn_text_ON_color); 
   else ObjectSetInteger(0,buttonId1,OBJPROP_COLOR,btn_text_OFF_color);
   
   if (show_bull) ObjectSetInteger(0,buttonId2,OBJPROP_COLOR,btn_text_ON_color); 
   else ObjectSetInteger(0,buttonId2,OBJPROP_COLOR,btn_text_OFF_color);
}

//+------------------------------------------------------------------------------------------------------------------+
void createButton(string buttonID,string buttonText,int width2,int height,string font,int fontSize,color bgColor,color borderColor,color txtColor, int x_dist)
{
      ObjectDelete    (0,buttonID);
      ObjectCreate    (0,buttonID,OBJ_BUTTON,btn_Subwindow,0,0);
      ObjectSetInteger(0,buttonID,OBJPROP_COLOR,txtColor);
      ObjectSetInteger(0,buttonID,OBJPROP_BGCOLOR,bgColor);
      ObjectSetInteger(0,buttonID,OBJPROP_BORDER_COLOR,borderColor);
      ObjectSetInteger(0,buttonID,OBJPROP_BORDER_TYPE,BORDER_RAISED);
      ObjectSetInteger(0,buttonID,OBJPROP_XSIZE,width2);
      ObjectSetInteger(0,buttonID,OBJPROP_YSIZE,height);
      ObjectSetString (0,buttonID,OBJPROP_FONT,font);
      ObjectSetString (0,buttonID,OBJPROP_TEXT,buttonText);
      ObjectSetInteger(0,buttonID,OBJPROP_FONTSIZE,fontSize);
      ObjectSetInteger(0,buttonID,OBJPROP_SELECTABLE,0);
      ObjectSetInteger(0,buttonID,OBJPROP_CORNER,btn_corner);
      ObjectSetInteger(0,buttonID,OBJPROP_HIDDEN,1);
      ObjectSetInteger(0,buttonID,OBJPROP_XDISTANCE,x_dist);
      ObjectSetInteger(0,buttonID,OBJPROP_YDISTANCE,button_y);
      // Default ON
      ObjectSetInteger(0, buttonID, OBJPROP_STATE, true);
}
//+------------------------------------------------------------------------------------------------------------------+
void OnDeinit(const int reason) 
{
   if(reason != REASON_CHARTCHANGE) 
   {
      ObjectDelete(buttonId1);
      ObjectDelete(buttonId2);
   }
   
   ObjectsDeleteAll(0, "IchiBox_");
}
//+------------------------------------------------------------------------------------------------------------------+
void OnChartEvent(const int id, //don't change anything here
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
{
   if(id==CHARTEVENT_OBJECT_CREATE || id==CHARTEVENT_OBJECT_DELETE) return; 
   if(id==CHARTEVENT_MOUSE_MOVE    || id==CHARTEVENT_MOUSE_WHEEL)   return; 

   if (id==CHARTEVENT_OBJECT_CLICK)
   {
      if(sparam == buttonId1) { show_bear = ObjectGetInteger(0, buttonId1, OBJPROP_STATE); recalc=true; }
      if(sparam == buttonId2) { show_bull = ObjectGetInteger(0, buttonId2, OBJPROP_STATE); recalc=true; }
      
      if(sparam == buttonId1 || sparam == buttonId2)
      {
         UpdateButtons();
         
         if (show_bear || show_bull)
         {
            init2();
            SetIndexStyle(0, DRAW_LINE); 
            SetIndexStyle(2, DRAW_HISTOGRAM); 
            SetIndexStyle(3, DRAW_HISTOGRAM); 
            SetIndexStyle(5, DRAW_LINE, STYLE_SOLID, 3); // Span A
            SetIndexStyle(6, DRAW_LINE, STYLE_SOLID, 3); // Span B
            mystart();
         }
         else
         {
            for (int Money=0; Money<indicator_buffers; Money++)
                 SetIndexStyle(Money,DRAW_NONE);
            ObjectsDeleteAll(0, "IchiBox_");
         }
      }
   }
}
//Forex-Station button template end42; copy and paste
//+------------------------------------------------------------------------------------------------------------------+
int init2()
{
   IndicatorBuffers(12);
   SetIndexBuffer(0, ts);       SetIndexLabel(0,"Tenkan Sen");
   SetIndexBuffer(1, ks);       SetIndexLabel(1,"Kijun Sen");
   SetIndexBuffer(2, SpanA);    SetIndexStyle(2,DRAW_HISTOGRAM);  
   SetIndexBuffer(3, SpanB);    SetIndexStyle(3,DRAW_HISTOGRAM);  
   SetIndexBuffer(4, Chinkou);  SetIndexLabel(4,"Chinkou Span");
   SetIndexBuffer(5, SpanA2);   SetIndexLabel(5,"Senkou Span A");
   SetIndexBuffer(6, SpanB2);   SetIndexLabel(6,"Senkou Span B");
   SetIndexBuffer(7, trend1); 
   SetIndexBuffer(8, trend2); 
   SetIndexBuffer(9, trend3); 
   SetIndexBuffer(10,trend4); 
   SetIndexBuffer(11,trend5); 
   if (!Draw_Tenkan) SetIndexStyle(0, DRAW_NONE);
   if (!Draw_Kijun)  SetIndexStyle(1, DRAW_NONE);
   if (!Draw_Chikou) SetIndexStyle(4, DRAW_NONE);
   if (!Draw_Kumo) 
   {
      SetIndexStyle(2, DRAW_NONE);
      SetIndexStyle(3, DRAW_NONE);
      SetIndexStyle(5, DRAW_NONE);
      SetIndexStyle(6, DRAW_NONE);
   }
   
     //
     //
     //
     //
     //
     
     indicatorFileName = WindowExpertName();
     returnBars        = TimeFrame == -99;
     TimeFrame         = fmax(TimeFrame,_Period);
     SetIndexShift(2,Kijun  * TimeFrame/Period()); 
     SetIndexShift(3,Kijun  * TimeFrame/Period());
     SetIndexShift(4,-Kijun * TimeFrame/Period());
     SetIndexShift(5,Kijun  * TimeFrame/Period());
     SetIndexShift(6,Kijun  * TimeFrame/Period());    
     
     //
     //
     //
     //
     //
     
     IndicatorShortName(timeFrameToString(TimeFrame)+" Ichimoku"); 
return(0);
}
//+------------------------------------------------------------------------------------------------------------------+
int start() {return(mystart()); }
//+------------------------------------------------------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int mystart()
  {
   int limit,i,k,counted_bars=IndicatorCounted();
   if (show_bear || show_bull)
      {
        if(recalc) 
        {
           counted_bars = 0;
           recalc=false;
           ObjectsDeleteAll(0, "IchiBox_"); // Clean boxes on recalc
        }
   if(counted_bars < 0) return(-1);
   if(counted_bars > 0) counted_bars--;
           limit = fmin(Bars-counted_bars,Bars-1); 
           if (returnBars) { ts[0] = limit+1; return(0); }

   //
   //
   //
   //
   //

   if (TimeFrame == Period())
   {
     for(i=limit; i>=0; i--)
     {
        if (i>=Bars-Tenkan) continue;
        double thi = High[i];
        double tlo = Low[i];
        for(k = 1; k<Tenkan; k++)
        {
           if(thi<High[i+k]) thi = High[i+k];
           if(tlo>Low[i+k])  tlo = Low[i+k];
        }
        if ((thi+tlo) > 0.0) 
             ts[i] = (thi + tlo)*0.5; 
        else ts[i] = 0;
       
        //
        //
        //
        //
        //
        
        if (i>=Bars-Kijun) continue;
        double khi = High[i];
        double klo = Low[i];
          for (k=1; k<Kijun; k++)
          {
             if(khi<High[i+k]) khi = High[i+k];
             if(klo>Low[i+k])  klo =  Low[i+k];
          }
          if ((khi+klo) > 0.0) 
               ks[i] = (khi+klo)*0.5; 
          else ks[i] = 0;
          
          //
          //
          //
          //
          //
        
          if  (i>=Bars-Senkou) continue;
          double shi = High[i];
          double slo = Low[i];
          for (k=1; k<Senkou; k++)
          {
             if(shi<High[i+k]) shi  = High[i+k];
             if(slo>Low[i+k])  slo  = Low[i+k];
          }
       
          SpanA[i]   = (ks[i]+ts[i])*0.5;
          SpanA2[i]  = (ks[i]+ts[i])*0.5;
          SpanB[i]   = (shi+slo)*0.5; 
          SpanB2[i]  = (shi+slo)*0.5; 
          Chinkou[i] = Close[i]; 
          trend1[i] = (i<Bars-1) ? (Close[i]>fmax(SpanA[i+Kijun],SpanB[i+Kijun])) ? 1 : (Close[i]<fmin(SpanA[i+Kijun],SpanB[i+Kijun])) ? -1 : trend1[i+1] : 0; 
          trend2[i] = (i<Bars-1) ? (ts[i]>ks[i])                                  ? 1 : (ts[i]<ks[i])                                  ? -1 : trend2[i+1] : 0;  
          trend3[i] = (i<Bars-1) ? (Close[i]>ks[i])                               ? 1 : (Close[i]<ks[i])                               ? -1 : trend3[i+1] : 0;  
          trend4[i] = (i<Bars-1) ? (Chinkou[i]>ts[i])                             ? 1 : (Chinkou[i]<ts[i])                             ? -1 : trend4[i+1] : 0;  
          trend5[i] = (i<Bars-1) ? (SpanA2[i]>SpanB2[i])                          ? 1 : (SpanA2[i]<SpanB2[i])                          ? -1 : trend5[i+1] : 0;  
   }
   
   // Draw boxes AFTER all calculations are done
   if(Draw_Box)
   {
      DrawAllBoxes();
   }
   
  manageAlerts();
  return(0);
  }
  
  //
  //
  //
  //
  //
   
  limit = (int)fmax(limit,fmin(Bars-1,iCustom(NULL,TimeFrame,indicatorFileName,-99,0,0)*TimeFrame/Period()));
  for (i=limit;i>=0;i--)
  {
      int y = iBarShift(NULL,TimeFrame,Time[i]);
         ts[i]     = iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,Tenkan,Kijun,Senkou,alertsOn,alertsOnKumoCloudCross,alertsOnTenkanKijunCross,alertsOnPriceKijunCross,alertsOnChinkouTenkanCross,alertsOnSpanASpanBCross,alertsOn,alertsOnCurrent,alertsMessage,alertsSound,alertsNotify,alertsEmail,0, y);
         ks[i]     = iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,Tenkan,Kijun,Senkou,alertsOn,alertsOnKumoCloudCross,alertsOnTenkanKijunCross,alertsOnPriceKijunCross,alertsOnChinkouTenkanCross,alertsOnSpanASpanBCross,alertsOn,alertsOnCurrent,alertsMessage,alertsSound,alertsNotify,alertsEmail,1, y);
         SpanA[i]  = iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,Tenkan,Kijun,Senkou,alertsOn,alertsOnKumoCloudCross,alertsOnTenkanKijunCross,alertsOnPriceKijunCross,alertsOnChinkouTenkanCross,alertsOnSpanASpanBCross,alertsOn,alertsOnCurrent,alertsMessage,alertsSound,alertsNotify,alertsEmail,2, y);
         SpanB[i]  = iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,Tenkan,Kijun,Senkou,alertsOn,alertsOnKumoCloudCross,alertsOnTenkanKijunCross,alertsOnPriceKijunCross,alertsOnChinkouTenkanCross,alertsOnSpanASpanBCross,alertsOn,alertsOnCurrent,alertsMessage,alertsSound,alertsNotify,alertsEmail,3, y);
         Chinkou[i]= iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,Tenkan,Kijun,Senkou,alertsOn,alertsOnKumoCloudCross,alertsOnTenkanKijunCross,alertsOnPriceKijunCross,alertsOnChinkouTenkanCross,alertsOnSpanASpanBCross,alertsOn,alertsOnCurrent,alertsMessage,alertsSound,alertsNotify,alertsEmail,4, y);
         SpanA2[i] = iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,Tenkan,Kijun,Senkou,alertsOn,alertsOnKumoCloudCross,alertsOnTenkanKijunCross,alertsOnPriceKijunCross,alertsOnChinkouTenkanCross,alertsOnSpanASpanBCross,alertsOn,alertsOnCurrent,alertsMessage,alertsSound,alertsNotify,alertsEmail,5, y);
         SpanB2[i] = iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,Tenkan,Kijun,Senkou,alertsOn,alertsOnKumoCloudCross,alertsOnTenkanKijunCross,alertsOnPriceKijunCross,alertsOnChinkouTenkanCross,alertsOnSpanASpanBCross,alertsOn,alertsOnCurrent,alertsMessage,alertsSound,alertsNotify,alertsEmail,6, y);       
         
         //
         //
         //
         //
         //
       
         if (!Interpolate || (i>0 && y==iBarShift(NULL,TimeFrame,Time[i-1]))) continue;

         //
         //
         //
         //
         //

         int n,x; datetime time = iTime(NULL,TimeFrame,y);
            for(n = 1; i+n < Bars && Time[i+n] >= time; n++) continue;
            for(x = 1; i+n < Bars && i+x < Bars && x < n; x++) 
            {
               ts[i+x]      = ts[i]      + (ts[i+n]      - ts[i])     * x/n;
               ks[i+x]      = ks[i]      + (ks[i+n]      - ks[i])     * x/n;
               SpanA[i+x]   = SpanA[i]   + (SpanA[i+n]   - SpanA[i])  * x/n;
               SpanB[i+x]   = SpanB[i]   + (SpanB[i+n]   - SpanB[i])  * x/n;
               Chinkou[i+x] = Chinkou[i] + (Chinkou[i+n] - Chinkou[i])* x/n;
               SpanA2[i+x]  = SpanA2[i]  + (SpanA2[i+n]  - SpanA2[i]) * x/n;
               SpanB2[i+x]  = SpanB2[i]  + (SpanB2[i+n]  - SpanB2[i]) * x/n;  
           }               
   }
      } //if (show_data)  
return(0);
}

//+------------------------------------------------------------------+
//| Draw all boxes based on SpanA2/SpanB2 cloud regions              |
//| Draws a box for each contiguous bullish/bearish cloud phase      |
//+------------------------------------------------------------------+
void DrawAllBoxes()
{
   int shift = Kijun; // The cloud is shifted forward by Kijun periods
   int boxCount = 0;
   
   // Start from oldest valid bar
   int startIdx = Bars - Senkou - 1;
   if(startIdx < 0) return;
   
   int i = startIdx;
   while(i >= 0)
   {
      double currSpanA = SpanA2[i];
      double currSpanB = SpanB2[i];
      
      // Skip if values are not valid
      if(currSpanA == 0 || currSpanB == 0)
      {
         i--;
         continue;
      }
      
      // Determine current phase
      int phase = 0; // 0 = neutral, 1 = bullish (SpanA > SpanB), -1 = bearish (SpanA < SpanB)
      if(currSpanA > currSpanB) phase = 1;       // Bullish
      else if(currSpanA < currSpanB) phase = -1; // Bearish
      
      if(phase == 0)
      {
         i--;
         continue;
      }
      
      // Found start of a phase, find its extent
      int phaseStartBuf = i; // Buffer index where phase starts (oldest)
      
      // Go forward (decreasing index) to find where phase ends
      while(i >= 0)
      {
         double spanA = SpanA2[i];
         double spanB = SpanB2[i];
         
         if(spanA == 0 || spanB == 0) break;
         
         int currentPhase = 0;
         if(spanA > spanB) currentPhase = 1;
         else if(spanA < spanB) currentPhase = -1;
         
         if(currentPhase != phase) break;
         
         i--;
      }
      
      int phaseEndBuf = i + 1; // Buffer index where phase ends (newest)
      
      // Convert buffer indices to visual positions (account for Kijun shift)
      int visualStart = phaseStartBuf - shift; // Oldest bar (left side of box)
      int visualEnd = phaseEndBuf - shift;     // Newest bar (right side of box)
      
      // Validate positions
      if(visualStart < 0) visualStart = 0;
      if(visualEnd < 0) visualEnd = 0;
      if(visualStart >= Bars) visualStart = Bars - 1;
      if(visualEnd >= Bars) visualEnd = Bars - 1;
      
      // Draw the box based on phase type
      if(phase == 1 && show_bull) // Bullish cloud
      {
         DrawBox("IchiBox_Bull_" + IntegerToString(boxCount), visualStart, visualEnd, Box_Color_Bull);
         boxCount++;
      }
      else if(phase == -1 && show_bear) // Bearish cloud
      {
         DrawBox("IchiBox_Bear_" + IntegerToString(boxCount), visualStart, visualEnd, Box_Color_Bear);
         boxCount++;
      }
   }
}

//+------------------------------------------------------------------+
//| Draw Box for the preceding phase                                 |
//| beginBar = oldest bar (larger index), endBar = newest (smaller)  |
//+------------------------------------------------------------------+
void DrawBox(string name, int beginBar, int endBar, color clr)
{
   // Swap if needed to ensure beginBar >= endBar
   if(beginBar < endBar)
   {
      int temp = beginBar;
      beginBar = endBar;
      endBar = temp;
   }
   
   // Validate: both bars should be within valid range
   if(beginBar >= Bars || endBar < 0) return;
   
   // Clamp to valid range
   if(beginBar >= Bars) beginBar = Bars - 1;
   if(endBar < 0) endBar = 0;
   
   double hHigh = -1.0;
   double lLow = 999999.0;
   
   // Find highest high and lowest low within the box range
   for(int b = endBar; b <= beginBar; b++)
   {
       if(b >= 0 && b < Bars)
       {
           if(High[b] > hHigh) hHigh = High[b];
           if(Low[b] < lLow) lLow = Low[b];
       }
   }
   
   if(hHigh > 0 && lLow < 999999.0 && ObjectFind(name) < 0)
   {
       // Create rectangle from beginBar (older/left) to endBar (newer/right)
       ObjectCreate(0, name, OBJ_RECTANGLE, 0, Time[beginBar], hHigh, Time[endBar], lLow);
       ObjectSetInteger(0, name, OBJPROP_COLOR, clr);
       ObjectSetInteger(0, name, OBJPROP_BACK, true);
       ObjectSetInteger(0, name, OBJPROP_WIDTH, 1);
       ObjectSetInteger(0, name, OBJPROP_FILL, true); 
   }
}

//-------------------------------------------------------------------
//
//-------------------------------------------------------------------
//
//
//
//
//

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("");
}

//
//
//
//
//

void manageAlerts()
{
    int whichBar = 1; if (alertsOnCurrent) whichBar = 0;          
      static datetime time1 = 0;
      static string   mess1 = "";
      if (alertsOnKumoCloudCross && trend1[whichBar] != trend1[whichBar+1])
      {
         if (trend1[whichBar] ==  1) doAlert(time1,mess1,whichBar,"Price crossing Kumo up");
         if (trend1[whichBar] == -1) doAlert(time1,mess1,whichBar,"Price crossing Kumo down");
      }
      static datetime time2 = 0;
      static string   mess2 = "";
      if (alertsOnTenkanKijunCross && trend2[whichBar] != trend2[whichBar+1])
      {
         if (trend2[whichBar] ==  1) doAlert(time2,mess2,whichBar,"Tenkan crossing Kijun up");
         if (trend2[whichBar] == -1) doAlert(time2,mess2,whichBar,"Tenkan crossing Kijun down");
      }
      static datetime time3 = 0;
      static string   mess3 = "";
      if (alertsOnPriceKijunCross && trend3[whichBar] != trend3[whichBar+1])
      {
         if (trend3[whichBar] ==  1) doAlert(time3,mess3,whichBar,"Price crossing Kijun up");
         if (trend3[whichBar] == -1) doAlert(time3,mess3,whichBar,"Price crossing Kijun down");
      }
      static datetime time4 = 0;
      static string   mess4 = "";
      if (alertsOnChinkouTenkanCross && trend4[whichBar] != trend4[whichBar+1])
      {
         if (trend4[whichBar] ==  1) doAlert(time4,mess4,whichBar,"Tenkan crossing Chinkou up");
         if (trend4[whichBar] == -1) doAlert(time4,mess4,whichBar,"Tenkan crossing Chinkou down");
      }
      static datetime time5 = 0;
      static string   mess5 = "";
      if (alertsOnSpanASpanBCross && trend5[whichBar] != trend5[whichBar+1])
      {
         if (trend5[whichBar] ==  1) doAlert(time5,mess5,whichBar,"SpanA crossing SpanB up");
         if (trend5[whichBar] == -1) doAlert(time5,mess5,whichBar,"SpanA crossing SpanB down");
      }
   }

//
//
//
//
//

void doAlert(datetime& previousTime, string& previousAlert, int forBar, string doWhat)
{
   string message;
   
   if (previousAlert != doWhat || previousTime != Time[forBar]) {
       previousAlert  = doWhat;
       previousTime   = Time[forBar];

       //
       //
       //
       //
       //

       message =  StringConcatenate(Symbol()," ",timeFrameToString(_Period)," at ",TimeToStr(TimeLocal(),TIME_SECONDS)," Ichimoku ",doWhat);
          if (alertsMessage) Alert(message);
          if (alertsNotify)  SendNotification(message);
          if (alertsEmail)   SendMail(StringConcatenate(Symbol()," Ichimoku "),message);
          if (alertsSound)   PlaySound("alert2.wav");
   }
}
//+------------------------------------------------------------------------------------------------------------------+
