/*
Versi 2.0
- perbaikan identifikasi range awal market. Sebelumnya di BAR kedua awal market. SUDAH OKE.
- tambahan fitur pemberi tanda Open/Close 3 market, reqeust by azka@KGForexWorld.com.

Versi sebelumnya
- tambahan fitur range pertemuan market(irisan market), reqeust by azka@KGForexWorld.com.
*/
//+------------------------------------------------------------------+
#property copyright "DaSimplify@KGForexWorld.com"
#property link      "http://www.MelatiWetan.com"

#property indicator_chart_window

extern string Ini.Untuk.Broker = "GMT+0 punya nih";
extern int    NumberOfDays = 21;
extern string AsiaBegin    = "01:00";
extern string AsiaEnd      = "12:00";
extern color  AsiaColor    = C'0,32,0';
extern string EurBegin     = "11:00";
extern string EurEnd       = "20:00";
extern color  EurColor     = C'48,0,0';
extern string USABegin     = "16:00";
extern string USAEnd       = "23:59";
extern color  USAColor     = C'0,0,56';
extern bool   ShowPrice    = false;
extern color  clFont       = Blue;
extern int    OffSet                = 10;

extern string __________________3   = "=============================";
extern bool   Show.garis.Close.Market  = true;
extern int    Garis.C.brp.BAR          = 5;
extern color  Warna.Garis.C.Tokyo      = HotPink;
extern color  Warna.Garis.C.London     = HotPink;
extern color  Warna.Garis.C.NewYork    = HotPink;
extern string _________________3   = "=============================";
extern string __________________2   = "=============================";
extern bool   Show.garis.Open.Market= true;
extern int    Garis.O.brp.BAR         = 5;
extern color  Warna.Garis.O.Tokyo     = White;
extern color  Warna.Garis.O.London    = White;
extern color  Warna.Garis.O.NewYork   = White;
extern string _________________2   = "=============================";
extern string __________________1   = "=============================";
extern bool   Show.Irisan           = true;
extern color  Warna.Tulisan.Irisan  = White;
extern int    Jarak.Tulisan.Irisan  = 0;
extern string _________________1   = "=============================";
extern string __________________0   = "=============================";
extern bool   ShowRange             = true;
extern color  Warna.Tulisan.Range   = DarkKhaki;
extern int    SizeFont              = 9;
extern int    Jarak.Tulisan.Range   = 0;
extern string _________________0   = "=============================";
extern string ___________________   = "#############################";
extern bool   Tampilkan.Statistik   = true;
extern int    Corner                = 0;
extern int     sudut.X              = 15;
extern int     sudut.Y              = 40;
extern int     fontsize             = 8;
extern string  fontstyle            = "Comic Sans";
extern color warna.Keterangan       = White;
extern string __________________    = "___________";

extern string TOKYO_SETTINGS        = "Tokyo";
extern int  Jum.Hari.AVG.Tokyo      = 20;
extern color warna.Tokyo            = Pink;
extern string _________________     = "___________";

extern string LONDON_SETTINGS       = "London";
extern int  Jum.Hari.AVG.London     = 20;
extern color warna.London           = MediumBlue;
extern string ________________      = "___________";

extern string NEWYORK_SETTINGS      = "NewYork";
extern int  Jum.Hari.AVG.NewYork    = 20;
extern color warna.NewYork          = Green;
extern string ____________________  = "#############################";

int tok.avg, lon.avg, new.avg;
int tok.cur, lon.cur, new.cur;
int tok.h=0, lon.h=0, new.h=0;
int tok.l=1000, lon.l=1000, new.l=1000;
int temp.tok, temp.lon, temp.new;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void init() {

if(NumberOfDays-Jum.Hari.AVG.Tokyo < 1){
Alert("Maaf om,  \"NumberOfDays\" harus lebih besar dari \"Jum.Hari.AVG.Tokyo\", Trims.");
return(0);
}
if(NumberOfDays-Jum.Hari.AVG.London < 1){
Alert("Maaf om,  \"NumberOfDays\" harus lebih besar dari \"Jum.Hari.AVG.London\", Trims.");
return(0);
}
if(NumberOfDays-Jum.Hari.AVG.NewYork < 1){
Alert("Maaf om,  \"NumberOfDays\" harus lebih besar dari \"Jum.Hari.AVG.NewYork\", Trims.");
return(0);
}
  DeleteObjects();
  for (int i=0; i<NumberOfDays; i++) {
    CreateObjects("ASIA"+i, AsiaColor);
    CreateObjects("EU"+i, EurColor);
    CreateObjects("USA"+i, USAColor);
  }
  Comment("");
}

//+------------------------------------------------------------------+
//| Custor indicator deinitialization function                       |
//+------------------------------------------------------------------+
void deinit() {
  DeleteObjects();
  Comment("");
}

//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
void CreateObjects(string no, color cl) {
  ObjectCreate(no, OBJ_RECTANGLE, 0, 0,0, 0,0);
  ObjectSet(no, OBJPROP_STYLE, STYLE_SOLID);
  ObjectSet(no, OBJPROP_COLOR, cl);
  ObjectSet(no, OBJPROP_BACK, True);
}

//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
void DeleteObjects() {
  for (int i=0; i<NumberOfDays; i++) {
    ObjectDelete("ASIA"+i);
    ObjectDelete("EU"+i);
    ObjectDelete("USA"+i);
    ObjectDelete("ASIA-"+i);
    ObjectDelete("EU-"+i);
    ObjectDelete("USA-"+i);
    ObjectDelete("ASIA+"+i);
    ObjectDelete("EU+"+i);
    ObjectDelete("USA+"+i);
    ObjectDelete("ASIA"+i+"Range");
    ObjectDelete("EU"+i+"Range");
    ObjectDelete("USA"+i+"Range");
    
    ObjectDelete("EUo - ASIAc"+i+" Irisan");
    ObjectDelete("USAo - EUc"+i+" Irisan");
  }

  ObjectDelete("ASup");
  ObjectDelete("ASdn");
  ObjectDelete("EUup");
  ObjectDelete("EUdn");
  ObjectDelete("USup");
  ObjectDelete("USdn");
  
   ObjectDelete("AVG Session");
   ObjectDelete("Current Session");
   ObjectDelete("Min Session");
   ObjectDelete("Max Session");

   ObjectDelete("AVG Tokyo");
   ObjectDelete("Current Tokyo");
   ObjectDelete("Min Tokyo");
   ObjectDelete("Max Tokyo");
   ObjectDelete("Tokyo");

   ObjectDelete("AVG London");
   ObjectDelete("Current London");
   ObjectDelete("Min London");
   ObjectDelete("Max London");
   ObjectDelete("London");

   ObjectDelete("AVG NewYork");
   ObjectDelete("Current NewYork");
   ObjectDelete("Min NewYork");
   ObjectDelete("Max NewYork");
   ObjectDelete("NewYork");

   ObjectDelete("Percent Session");
   ObjectDelete("% Tokyo");
   ObjectDelete("% London");
   ObjectDelete("% NewYork");
   
}

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
void start() {
  datetime dt=CurTime();
  
  for (int i=0; i<NumberOfDays; i++) {
    if (ShowPrice && i==0) {
      DrawPrices(dt, "ASIA", AsiaBegin, AsiaEnd);
      DrawPrices(dt, "EU", EurBegin, EurEnd);
      DrawPrices(dt, "USA", USABegin, USAEnd);
    }
    if (ShowRange) {
      DrawRanges(dt, "ASIA"+i, AsiaBegin, AsiaEnd);
      DrawRanges(dt, "EU"+i, EurBegin, EurEnd);
      DrawRanges(dt, "USA"+i, USABegin, USAEnd);
    }
    DrawObjects(dt, "ASIA"+i, AsiaBegin, AsiaEnd);
    DrawObjects(dt, "EU"+i, EurBegin, EurEnd);
    DrawObjects(dt, "USA"+i, USABegin, USAEnd);

    if(Show.garis.Open.Market)
    {
        DrawObjects2(dt, "ASIA-"+i, AsiaBegin, Warna.Garis.O.Tokyo);
        DrawObjects2(dt, "EU-"+i, EurBegin, Warna.Garis.O.London);
        DrawObjects2(dt, "USA-"+i, USABegin, Warna.Garis.O.NewYork);
    }
    if(Show.garis.Close.Market)
    {
        DrawObjects3(dt, "ASIA+"+i, AsiaEnd, Warna.Garis.C.Tokyo);
        DrawObjects3(dt, "EU+"+i, EurEnd, Warna.Garis.C.London);
        DrawObjects3(dt, "USA+"+i, USAEnd, Warna.Garis.C.NewYork);
    }

    if (Show.Irisan) {
      DrawIrisan(dt, "EUo - ASIAc"+i, EurBegin, AsiaEnd);
      DrawIrisan(dt, "USAo - EUc"+i, USABegin, EurEnd);
    }
    
    dt=decDateTradeDay(dt);
    while (TimeDayOfWeek(dt)==0 ||TimeDayOfWeek(dt)>5) dt=decDateTradeDay(dt);
  }

   if(Tampilkan.Statistik)
   {
      Stats();
   }
}

//+------------------------------------------------------------------+
//+------------------------------------------------------------------+

void Stats()
{
   tok.avg=0;
   lon.avg=0;
   new.avg=0;
   tok.cur=0;
   lon.cur=0;
   new.cur=0;
   tok.h=0;
   lon.h=0;
   new.h=0;
   tok.l=1000;
   lon.l=1000;
   new.l=1000;

   for(int i=1; i<=Jum.Hari.AVG.Tokyo; i++)
   {
   temp.tok = StrToDouble(ObjectDescription("ASIA"+i+"Range"));
   if(tok.h < temp.tok) tok.h = temp.tok;
   if(tok.l > temp.tok) {tok.l = temp.tok;}// Alert(tok.l);}
   tok.avg += temp.tok;
   }

   for(    i=1; i<=Jum.Hari.AVG.London; i++)
   {
   temp.lon = StrToDouble(ObjectDescription("EU"+i+"Range"));
   if(lon.h < temp.lon) lon.h = temp.lon;
   if(lon.l > temp.lon) lon.l = temp.lon;
   lon.avg += temp.lon;
   }
   
   for(    i=1; i<=Jum.Hari.AVG.NewYork; i++)
   {
   temp.new = StrToDouble(ObjectDescription("USA"+i+"Range"));
   if(new.h < temp.new) new.h = temp.new;
   if(new.l > temp.new) new.l = temp.new;
   new.avg += temp.new;
   }
   
   tok.avg = tok.avg/Jum.Hari.AVG.Tokyo;
   lon.avg = lon.avg/Jum.Hari.AVG.London;
   new.avg = new.avg/Jum.Hari.AVG.NewYork;
   
   tok.cur = StrToDouble(ObjectDescription("ASIA"+0+"Range"));
   lon.cur = StrToDouble(ObjectDescription("EU"+0+"Range"));
   new.cur = StrToDouble(ObjectDescription("USA"+0+"Range"));

   if(TimeHour(TimeCurrent()) < StrToInteger(StringSubstr(AsiaBegin,0, 2))) tok.cur=0;
   if(TimeHour(TimeCurrent()) < StrToInteger(StringSubstr(EurBegin, 0, 2))) lon.cur=0;
   if(TimeHour(TimeCurrent()) < StrToInteger(StringSubstr(USABegin, 0, 2))) new.cur=0;
   
   
   string per.tok = DoubleToStr(NormalizeDouble(tok.cur*100,2)/tok.avg,2); 
   string per.lon = DoubleToStr(NormalizeDouble(lon.cur*100,2)/lon.avg,2); 
   string per.new = DoubleToStr(NormalizeDouble(new.cur*100,2)/new.avg,2); 

   plot("AVG Session"    , "AVG", sudut.X   , sudut.Y, warna.Keterangan, Corner);
   plot("Current Session", "Cur", sudut.X+30, sudut.Y, warna.Keterangan, Corner);
   plot("Min Session"    , "Min", sudut.X+60, sudut.Y, warna.Keterangan, Corner);
   plot("Max Session"    , "Max", sudut.X+90, sudut.Y, warna.Keterangan, Corner);
   plot("Percent Session",   "%", sudut.X+120, sudut.Y, warna.Keterangan, Corner);

   sudut.Y+=20;
   plot("AVG Tokyo"    , tok.avg, sudut.X    , sudut.Y, warna.Tokyo, Corner);
   plot("Current Tokyo", tok.cur, sudut.X+30 , sudut.Y, warna.Tokyo, Corner);
   plot("Min Tokyo"    , tok.l  , sudut.X+60 , sudut.Y, warna.Tokyo, Corner);
   plot("Max Tokyo"    , tok.h  , sudut.X+90 , sudut.Y, warna.Tokyo, Corner);
   plot("% Tokyo"      , per.tok, sudut.X+120, sudut.Y, warna.Tokyo, Corner);

   plot("Tokyo"        , "Tokyo", sudut.X+150, sudut.Y, warna.Tokyo, Corner);
   sudut.Y-=20;
   
   sudut.Y+=40;
   plot("AVG London"    , lon.avg , sudut.X    , sudut.Y, warna.London, Corner);
   plot("Current London", lon.cur , sudut.X+30 , sudut.Y, warna.London, Corner);
   plot("Min London"    , lon.l   , sudut.X+60 , sudut.Y, warna.London, Corner);
   plot("Max London"    , lon.h   , sudut.X+90 , sudut.Y, warna.London, Corner);
   plot("% London"      , per.lon , sudut.X+120, sudut.Y, warna.London, Corner);

   plot("London"        , "London", sudut.X+150, sudut.Y, warna.London, Corner);
   sudut.Y-=40;
   
   sudut.Y+=60;
   plot("AVG NewYork"    , new.avg  , sudut.X    , sudut.Y, warna.NewYork, Corner);
   plot("Current NewYork", new.cur  , sudut.X+30 , sudut.Y, warna.NewYork, Corner);
   plot("Min NewYork"    , new.l    , sudut.X+60 , sudut.Y, warna.NewYork, Corner);
   plot("Max NewYork"    , new.h    , sudut.X+90 , sudut.Y, warna.NewYork, Corner);
   plot("% NewYork"      , per.new  , sudut.X+120, sudut.Y, warna.NewYork, Corner);

   plot("NewYork"        , "NewYork", sudut.X+150, sudut.Y, warna.NewYork, Corner);
   sudut.Y-=60;
}

void plot(string nama, string ket, int x, int y, color warna, int corner)
{
   ObjectDelete (nama);
   ObjectCreate(nama, OBJ_LABEL, 0, 0, 0 );
   ObjectSetText(nama,ket,fontsize, fontstyle, warna);
   ObjectSet(nama, OBJPROP_CORNER, corner );
   ObjectSet(nama, OBJPROP_XDISTANCE, x );
   ObjectSet(nama, OBJPROP_YDISTANCE, y );
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
void DrawObjects(datetime dt, string no, string tb, string te) {
  datetime t1, t2;
  double   p1, p2;
  int      b1, b2;
  
  t1=StrToTime(TimeToStr(dt, TIME_DATE)+" "+tb);
  t2=StrToTime(TimeToStr(dt, TIME_DATE)+" "+te);
  if(t2<t1)t2+=86400;
  b1=iBarShift(NULL, 0, t1);
  b2=iBarShift(NULL, 0, t2);
  
  p1=High[iHighest(NULL, 0, MODE_HIGH, b1-b2+1, b2)];
  p2=Low [iLowest (NULL, 0, MODE_LOW , b1-b2+1, b2)];
  
  ObjectSet(no, OBJPROP_TIME1 , t1);
  ObjectSet(no, OBJPROP_PRICE1, p1);
  ObjectSet(no, OBJPROP_TIME2 , t2);
  ObjectSet(no, OBJPROP_PRICE2, p2);
}

//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
void DrawObjects2(datetime dt, string no, string tb, color wrn) {
  datetime t1, t2;
  double   p1;
  int      b1;
  
  t1=StrToTime(TimeToStr(dt, TIME_DATE)+" "+tb);
  t2=t1+(60*Period()*Garis.O.brp.BAR);
  if(t2<t1)t2+=86400;
  b1=iBarShift(NULL, 0, t1);
  p1=Open[b1];
  
  ObjectCreate(no, OBJ_TREND, 0, 0,0, 0,0);
  ObjectSet(no, OBJPROP_STYLE, STYLE_SOLID);
  ObjectSet(no, OBJPROP_COLOR, wrn);
  ObjectSet(no, OBJPROP_RAY, false);
  ObjectSet(no, OBJPROP_TIME1 , t1);
  ObjectSet(no, OBJPROP_PRICE1, p1);
  ObjectSet(no, OBJPROP_TIME2 , t2);
  ObjectSet(no, OBJPROP_PRICE2, p1);
}

//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
void DrawObjects3(datetime dt, string no, string tb, color wrn) {
  datetime t1, t2;
  double   p1;
  int      b1;
  
  t1=StrToTime(TimeToStr(dt, TIME_DATE)+" "+tb);
  t2=t1+(60*Period()*Garis.C.brp.BAR);
  if(t2<t1)t2+=86400;
  b1=iBarShift(NULL, 0, t1);
  p1=Close[b1];
  
  ObjectCreate(no, OBJ_TREND, 0, 0,0, 0,0);
  ObjectSet(no, OBJPROP_STYLE, STYLE_SOLID);
  ObjectSet(no, OBJPROP_COLOR, wrn);
  ObjectSet(no, OBJPROP_RAY, false);
  ObjectSet(no, OBJPROP_TIME1 , t1);
  ObjectSet(no, OBJPROP_PRICE1, p1);
  ObjectSet(no, OBJPROP_TIME2 , t2);
  ObjectSet(no, OBJPROP_PRICE2, p1);
}

//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
void DrawRanges(datetime dt, string no, string tb, string te) {
  datetime t1, t2;
  double   p1, p2;
  int      b1, b2;

  t1=StrToTime(TimeToStr(dt, TIME_DATE)+" "+tb);
  
  
  
  
  
  
  t2=StrToTime(TimeToStr(dt, TIME_DATE)+" "+te);
  
  b1=iBarShift(NULL, 0, t1);
  b2=iBarShift(NULL, 0, t2);

  p1=High[iHighest(NULL, 0, MODE_HIGH, b1-b2+1, b2)];
  p2=Low [iLowest (NULL, 0, MODE_LOW , b1-b2+1, b2)];

  if (ObjectFind(no+"Range")<0) ObjectCreate(no+"Range", OBJ_TEXT, 0, 0,0);
  ObjectSet(no+"Range", OBJPROP_TIME1   , t2-1800);
  ObjectSet(no+"Range", OBJPROP_PRICE1  , p1+Jarak.Tulisan.Range*Point);
  ObjectSet(no+"Range", OBJPROP_COLOR   , Warna.Tulisan.Range);
  ObjectSet(no+"Range", OBJPROP_FONTSIZE, SizeFont);

  if(Digits==5 || Digits==3)
  ObjectSetText(no+"Range", DoubleToStr(((p1-p2)/Point)*0.1, 0)+".");
  else
  ObjectSetText(no+"Range", DoubleToStr((p1-p2)/Point, 0)+".");

/*  if (ObjectFind(no+"dn")<0) ObjectCreate(no+"dn", OBJ_TEXT, 0, 0,0);
  ObjectSet(no+"dn", OBJPROP_TIME1   , t2);
  ObjectSet(no+"dn", OBJPROP_PRICE1  , p2);
  ObjectSet(no+"dn", OBJPROP_COLOR   , Warna.Tulisan.Range);
  ObjectSet(no+"dn", OBJPROP_FONTSIZE, SizeFont);
  ObjectSetText(no+"dn", DoubleToStr(p2, Digits));
*/
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
void DrawIrisan(datetime dt, string no, string tb, string te) {
  datetime t1, t2;
  double   p1, p2;
  int      b1, b2;

  t1=StrToTime(TimeToStr(dt, TIME_DATE)+" "+tb);
  if(te=="00:00")
  {dt+=86400;
  t2=StrToTime(TimeToStr(dt, TIME_DATE)+" "+te);
  
  }
  else
  t2=StrToTime(TimeToStr(dt, TIME_DATE)+" "+te);
  
  b1=iBarShift(NULL, 0, t1);
  b2=iBarShift(NULL, 0, t2);

  p1=High[iHighest(NULL, 0, MODE_HIGH, b1-b2+1, b2)];
  p2=Low [iLowest (NULL, 0, MODE_LOW , b1-b2+1, b2)];
  
  if (ObjectFind(no+" Irisan")<0)
  ObjectCreate(no+" Irisan", OBJ_TEXT, 0, 0,0);
  
  ObjectSet(no+" Irisan", OBJPROP_TIME1   , t2-1800);
  ObjectSet(no+" Irisan", OBJPROP_PRICE1  , p2-Jarak.Tulisan.Irisan*Point);
  ObjectSet(no+" Irisan", OBJPROP_COLOR   , Warna.Tulisan.Irisan);
  ObjectSet(no+" Irisan", OBJPROP_FONTSIZE, SizeFont);

  if(Digits==5 || Digits==3)
  ObjectSetText(no+" Irisan", DoubleToStr(((p1-p2)/Point)*0.1, 0)+".");
  else
  ObjectSetText(no+" Irisan", DoubleToStr((p1-p2)/Point, 0)+".");
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
void DrawPrices(datetime dt, string no, string tb, string te) {
  datetime t1, t2;
  double   p1, p2;
  int      b1, b2;

  t1=StrToTime(TimeToStr(dt, TIME_DATE)+" "+tb);
  t2=StrToTime(TimeToStr(dt, TIME_DATE)+" "+te);
  b1=iBarShift(NULL, 0, t1);
  b2=iBarShift(NULL, 0, t2);
  p1=High[iHighest(NULL, 0, MODE_HIGH, b1-b2+1, b2)];
  p2=Low [iLowest (NULL, 0, MODE_LOW , b1-b2+1, b2)];

  if (ObjectFind(no+"up")<0) ObjectCreate(no+"up", OBJ_TEXT, 0, 0,0);
  ObjectSet(no+"up", OBJPROP_TIME1   , t2);
  ObjectSet(no+"up", OBJPROP_PRICE1  , p1+OffSet*Point);
  ObjectSet(no+"up", OBJPROP_COLOR   , clFont);
  ObjectSet(no+"up", OBJPROP_FONTSIZE, SizeFont);
  ObjectSetText(no+"up", DoubleToStr(p1+Ask-Bid, Digits));

  if (ObjectFind(no+"dn")<0) ObjectCreate(no+"dn", OBJ_TEXT, 0, 0,0);
  ObjectSet(no+"dn", OBJPROP_TIME1   , t2);
  ObjectSet(no+"dn", OBJPROP_PRICE1  , p2);
  ObjectSet(no+"dn", OBJPROP_COLOR   , clFont);
  ObjectSet(no+"dn", OBJPROP_FONTSIZE, SizeFont);
  ObjectSetText(no+"dn", DoubleToStr(p2, Digits));
}

//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
datetime decDateTradeDay (datetime dt) {
  int ty=TimeYear(dt);
  int tm=TimeMonth(dt);
  int td=TimeDay(dt);
  int th=TimeHour(dt);
  int ti=TimeMinute(dt);

  td--;
  if (td==0) {
    tm--;
    if (tm==0) {
      ty--;
      tm=12;
    }
    if (tm==1 || tm==3 || tm==5 || tm==7 || tm==8 || tm==10 || tm==12) td=31;
    if (tm==2) if (MathMod(ty, 4)==0) td=29; else td=28;
    if (tm==4 || tm==6 || tm==9 || tm==11) td=30;
  }
  return(StrToTime(ty+"."+tm+"."+td+" "+th+":"+ti));
}
//+------------------------------------------------------------------+

