
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Silver
#property indicator_color2 Silver

extern bool LineAsBackground = false;
extern string Info1 = "<< Asian Session >>";
extern int OpenHour = 0;
extern int CloseHour = 9;
extern bool CloseOnHour = TRUE;
extern bool RangeAlarm = TRUE;
extern bool RangeShow = TRUE;
extern int RangeThreshold = 40;
extern color RangeTextColor = Gray;
extern int NrOfDays = 10;
extern bool SessionHLLineShow = TRUE;
extern int SessionHLLineEnd = 22;
extern color SessionHLLineColor = Blue;
extern int SessionHLLineStyle = 2;
extern int SessionHLLineWidth = 1;

extern bool OpenVLineShow = false;
extern color OpenVLineColor = Gainsboro;
extern int OpenVLineStyle = 2;
extern int OpenVLineWidth = 1;
extern bool CloseVLineShow = false;
extern color CloseVLineColor = Gainsboro;
extern int CloseVLineStyle = 2;
extern int CloseVLineWidth = 1;

double Gda_208[];
double Gda_212[];
string Gs_216;
string Gs_224 = " ";
bool Gi_232;
int Gi_236 = 0;
bool Gi_240 = FALSE;
bool Gi_244 = FALSE;

int init() {
   SetIndexStyle(0, DRAW_LINE);
   SetIndexBuffer(0, Gda_208);
   SetIndexLabel(0, "Asian Session High");
   SetIndexEmptyValue(0, EMPTY_VALUE);
   SetIndexStyle(1, DRAW_LINE);
   SetIndexBuffer(1, Gda_212);
   SetIndexLabel(1, "Asian Session Low");
   SetIndexEmptyValue(1, EMPTY_VALUE);
   Gs_216 = "Xi-AsianSession " + Gs_224;
   IndicatorShortName(Gs_216);
   Gi_232 = FALSE;
   return (0);
}

int deinit() {
   for (int Li_0 = ObjectsTotal() - 1; Li_0 > -1; Li_0--)
      if (StringFind(ObjectName(Li_0), "Xi-AsianSession") >= 0) ObjectDelete(ObjectName(Li_0));
   return (0);
}

int start() {
   int Li_4 = IndicatorCounted();
   if (Li_4 < 0) return (-1);
   int Li_0 = Bars - Li_4;
   if (Gi_232 == FALSE) {
      DrawPreviousSessions();
      Gi_232 = TRUE;
   }
   DrawCurrentSession(Li_0);
   return (0);
}

int GetSessionBars(int Ai_0, int Ai_4, int Ai_8) {
   int Li_16 = 0;
   for (int Li_12 = Ai_8; Li_12 < Bars - Ai_8; Li_12++) {
      if (TimeHour(Time[Li_12]) == Ai_0 && TimeMinute(Time[Li_12]) == 0) return (Li_16);
      if (IsSessionActive(Ai_0, Ai_4, Time[Li_12]) == 0) {
         Li_16--;
         return (Li_16);
      }
      Li_16++;
   }
   return (0);
}

void DrawCurrentSession(int Ai_0) {
   int Li_12;
   double Ld_16;
   double Ld_24;
   if (IsSessionActive(OpenHour, CloseHour - 1, Time[0]) == 1) {
      if (Gi_244 == FALSE) Gi_244 = TRUE;
      Li_12 = GetSessionBars(OpenHour, CloseHour - 1, 0);
      Ld_16 = High[iHighest(NULL, 0, MODE_HIGH, Li_12 + 1, 0)];
      Ld_24 = Low[iLowest(NULL, 0, MODE_LOW, Li_12 + 1, 0)];
      for (int Li_4 = 0; Li_4 <= Li_12; Li_4++) {
         Gda_208[Li_4] = Ld_16;
         Gda_212[Li_4] = Ld_24;
      }
      if (OpenVLineShow == TRUE) {
         DrawLine(Time[Li_12], OpenVLineStyle, OpenVLineWidth, OpenVLineColor, "Open");
      }
      if (RangeShow == TRUE) DrawRangeValue(PriceToPips(Ld_16 - Ld_24), Time[Li_12 / 2], Ld_16, RangeTextColor);
      Gi_236 = PriceToPips(Ld_16 - Ld_24);
      if (Gi_236 > RangeThreshold && RangeAlarm == TRUE) {
         if (Gi_240 == FALSE) {
            Alert(Gs_216, ", ", Symbol(), ", Range: ", Gi_236);
            Gi_240 = TRUE;
         }
      } else Gi_240 = FALSE;
   } else {
      if (Gi_244 == TRUE) {
         Gi_244 = FALSE;
         DrawPreviousSessions();
      }
   }
}

void DrawPreviousSessions() {
   int Li_4;
   int Li_8;
   int Li_12;
   double Ld_16;
   double Ld_24;
   string Ls_36;
   string Ls_44;
   int Li_52;
   int Li_32 = 0;
   for (int Li_0 = 0; Li_0 < Bars; Li_0++) {
      Gda_208[Li_4] = EMPTY_VALUE;
      Gda_212[Li_4] = EMPTY_VALUE;
   }
   if (CloseOnHour == TRUE) Li_12 = 0;
   else Li_12 = 1;
   for (Li_0 = 0; Li_0 < Bars && Li_32 < NrOfDays; Li_0++) {
      if (TimeHour(Time[Li_0]) == CloseHour && TimeMinute(Time[Li_0]) == 0) {
         Li_8 = GetSessionBars(OpenHour, CloseHour, Li_0);
         Ld_16 = High[iHighest(NULL, 0, MODE_HIGH, Li_8, Li_0 + Li_12)];
         Ld_24 = Low[iLowest(NULL, 0, MODE_LOW, Li_8, Li_0 + Li_12)];
         for (Li_4 = Li_0 + Li_12; Li_4 <= Li_0 + Li_8; Li_4++) {
            Gda_208[Li_4] = Ld_16;
            Gda_212[Li_4] = Ld_24;
         }
         if (OpenVLineShow == TRUE) {
            DrawLine(Time[Li_0 + Li_8], OpenVLineStyle, OpenVLineWidth, OpenVLineColor, "Open");
         }
         if (CloseVLineShow == TRUE) {
            DrawLine(Time[Li_0] - 60 * Period() * Li_12, CloseVLineStyle, CloseVLineWidth, CloseVLineColor, "Close");
         }
         if (RangeShow == TRUE) DrawRangeValue(PriceToPips(Ld_16 - Ld_24), Time[Li_0 + Li_8 / 2], Ld_16, RangeTextColor);
         if (SessionHLLineShow == TRUE) {
            Li_52 = StrToTime(TimeToStr(Time[Li_0], TIME_DATE) + " " + SessionHLLineEnd + ":00");
            DrawHLine(Ld_16, Time[Li_0] - 60 * Period(), Li_52, "High" + Li_32 + 1, SessionHLLineStyle, SessionHLLineWidth, SessionHLLineColor);
            DrawHLine(Ld_24, Time[Li_0] - 60 * Period(), Li_52, "Low" + Li_32 + 1, SessionHLLineStyle, SessionHLLineWidth, SessionHLLineColor);
         }
         Li_32++;
      }
   }
}

int DrawRangeValue(double Ad_0, double Ad_8, double Ad_16, color Ai_24) {
   double Ld_28 = 0;
   string Ls_44 = DoubleToStr(Ad_0, PipDigits());
   string Ls_36 = "Xi-AsianSession" + "_Range_" + TimeToStr(Ad_8, TIME_DATE);
   if (ObjectFind(Ls_36) >= 0) ObjectDelete(Ls_36);
   ObjectCreate(Ls_36, OBJ_TEXT, 0, Ad_8, Ad_16);
   ObjectSet(Ls_36, OBJPROP_BACK, FALSE);
   ObjectSetText(Ls_36, Ls_44, 8, "Arial", Ai_24);
   return (0);
}

int IsSessionActive(int Ai_0, int Ai_4, int Ai_8) {
   bool Li_20;
   int Li_12 = TimeHour(Ai_8);
   int Li_16 = TimeMinute(Ai_8);
   if (Ai_0 < Ai_4) {
      if (Li_12 >= Ai_0 && Li_12 <= Ai_4) Li_20 = TRUE;
      else Li_20 = FALSE;
   } else {
      if (Li_12 >= Ai_0 || Li_12 <= Ai_4) Li_20 = TRUE;
      else Li_20 = FALSE;
   }
   return (Li_20);
}

int DrawLine(double Ad_0, int Ai_8, int Ai_12, color Ai_16, string As_20) {
   string Ls_28 = "Xi-AsianSession" + As_20 + "_" + TimeToStr(Ad_0, TIME_DATE);
   if (ObjectFind(Ls_28) >= 0) ObjectDelete(Ls_28);
   ObjectCreate(Ls_28, OBJ_TREND, 0, Ad_0, 0, Ad_0, 10);
   ObjectSet(Ls_28, OBJPROP_STYLE, Ai_8);
   ObjectSet(Ls_28, OBJPROP_WIDTH, Ai_12);
   ObjectSet(Ls_28, OBJPROP_BACK, TRUE);
   ObjectSet(Ls_28, OBJPROP_COLOR, Ai_16);
   ObjectSet(Ls_28,OBJPROP_BACK,LineAsBackground);


   return (0);
}

int DrawTextLabel(double Ad_0, string As_8, color Ai_16) {
   double Ld_20 = 0;
   string Ls_28 = "";
   string Ls_36 = "Xi-AsianSession" + As_8 + "_" + TimeToStr(Ad_0, TIME_DATE);
   Ld_20 = WindowPriceMin() + (WindowPriceMax() - WindowPriceMin()) / 2.0;
   if (ObjectFind(Ls_36) >= 0) ObjectDelete(Ls_36);
   ObjectCreate(Ls_36, OBJ_TEXT, 0, Ad_0, Ld_20);
   ObjectSet(Ls_36, OBJPROP_ANGLE, 90);
   ObjectSet(Ls_36, OBJPROP_BACK, TRUE);
   ObjectSetText(Ls_36, As_8, 8, "Arial", Ai_16);
   
   return (0);
}

int DrawHLine(double Ad_0, int Ai_8, int Ai_12, string As_16, int Ai_24, int Ai_28, color Ai_32) {
   As_16 = "Xi-AsianSession" + "_" + As_16;
   if (ObjectFind(As_16) >= 0) ObjectDelete(As_16);
   ObjectCreate(As_16, OBJ_TREND, 0, Ai_8, Ad_0, Ai_12, Ad_0);
   ObjectSet(As_16, OBJPROP_STYLE, Ai_24);
   ObjectSet(As_16, OBJPROP_WIDTH, Ai_28);
   ObjectSet(As_16, OBJPROP_BACK, TRUE);
   ObjectSet(As_16, OBJPROP_RAY, FALSE);
   ObjectSet(As_16, OBJPROP_COLOR, Ai_32);
   ObjectSet(As_16,OBJPROP_BACK,LineAsBackground);
   return (0);
}

double PriceToPips(double Ad_0) {
   if (Digits == 2 || Digits == 3) return (Ad_0 / 0.01);
   if (Digits == 4 || Digits == 5) return (Ad_0 / 0.0001);
   return (Ad_0);
}

double PipDigits() {
   if (Digits == 3 || Digits == 5) return (1);
   if (Digits == 2 || Digits == 4) return (0);
   return (0);
}
