//+------------------------------------------------------------------+
//|                                               LondonBreakout.mq4 |
//+------------------------------------------------------------------+

#property indicator_chart_window

extern string StartTime    = "03:00";    // time for start of price establishment window
extern string EndTime      = "06:00";    // time for end of price establishment window
extern string SessionEndTime= "00:00";   // end of daily session; tomorrow is another day!
extern color  SessionColor = PapayaWhip; // show Session periods with a different background color
extern int    NumDays      = 60;         // days back
extern int    MaxBoxSizeInPips   = 50;   // pips
extern double EntryFactor  = 0.3;
extern double TPFactor     = 1.3;
extern color  BoxColorOK   = LightBlue;
extern color  BoxColorNOK  = Red;
extern color  LevelColor   = Black;
extern int    FibLength    = 9;

int StartShift;
int EndShift;

int digits;
double point;

int ObjCnt;
//+------------------------------------------------------------------+
int init()  {
//+------------------------------------------------------------------+

  GetPoint();
  del_obj();
  
  return(0);
}/*init*/

//+------------------------------------------------------------------+
int deinit()  {
//+------------------------------------------------------------------+
  del_obj();
  return(0);
}/*deinit*/


//+------------------------------------------------------------------+
void start()  {
//+------------------------------------------------------------------+
  int i, limit, counted_bars=IndicatorCounted();

  int BarsBack = NumDays*(PERIOD_D1/Period());
  limit = MathMin(BarsBack,Bars-counted_bars-1);

  for (i=limit; i>=0; i--)  
   {   
    datetime thistime   = Time[i];  
    datetime RangeStart = StrToTime(TimeToStr(Time[i],TIME_DATE) + " "  + StartTime);    
    datetime RangeEnd   = StrToTime(TimeToStr(Time[i],TIME_DATE) + " "  + EndTime);
    datetime SessionEnd = StrToTime(TimeToStr(Time[i],TIME_DATE) + " "  + SessionEndTime);

    if (RangeStart > RangeEnd) RangeStart = RangeStart - 24*60*60; // midnight wrap fix

    if (TimeDayOfWeek(RangeStart)==0) continue; //don't show saturday; sunday=0~saturday=6;

    //get hi/lo
    int StartShift = iBarShift(NULL,0,RangeStart);
    int EndShift   = iBarShift(NULL,0,RangeEnd);
    double vHigh   = High[iHighest(NULL,0,MODE_HIGH,(StartShift-EndShift+1),EndShift)];
    double vLow    = Low[iLowest(NULL,0,MODE_LOW,(StartShift-EndShift+1),EndShift)];

    double extent = vHigh - vLow;
    double LongEntryPrice  = NormalizeDouble(vHigh + extent*EntryFactor, digits);
    double ShortEntryPrice = NormalizeDouble(vLow  - extent*EntryFactor, digits);
    double LongTakeProfit  = NormalizeDouble(vHigh + extent*TPFactor, digits);
    double ShortTakeProfit = NormalizeDouble(vLow  - extent*TPFactor, digits);
    double LongTPpips      = (LongTakeProfit-LongEntryPrice)/point;
    double ShortTPpips     = (ShortEntryPrice-ShortTakeProfit)/point;
    double BuyStoppips     = (vLow-LongEntryPrice)/point;
    double SellStoppips    = (ShortEntryPrice-vHigh)/point;

    // show session period with a different "background" color
    string objname = "BF-Session-"+RangeEnd;
    if(ObjectFind(objname)==-1) {// draw only once
      datetime begin = RangeEnd;
      if (begin > SessionEnd) begin = begin + 24*60*60; // midnight wrap fix
      ObjectCreate(objname, OBJ_RECTANGLE, 0, begin,0, SessionEnd, LongTakeProfit*2);
      ObjectSet(objname, OBJPROP_COLOR, SessionColor);
      ObjectSet(objname, OBJPROP_BACK, True);
    }
  
    // draw session results at session end time
    if (thistime == SessionEnd) drawSessionResults(RangeEnd, SessionEnd, LongEntryPrice, ShortEntryPrice, LongTakeProfit, ShortTakeProfit);

    // wait for the box to be complete
    if (thistime < RangeEnd) continue;

    // draw pre-breakout box blue/red:
    objname = "BF-Box-"+RangeEnd;
    if(ObjectFind(objname)!=-1) continue; // draw box only once per day!

    ObjectCreate(objname,OBJ_RECTANGLE,0,RangeStart,vLow,RangeEnd,vHigh);
    if (extent <= MaxBoxSizeInPips * point) {
      ObjectSet(objname,OBJPROP_COLOR,BoxColorOK);
    } else {
      ObjectSet(objname,OBJPROP_COLOR,BoxColorNOK);
    }

  // draw "fib" lines for entry+stop+TP levels:
    objname = "BF-Fibo-" + RangeEnd;
    ObjectCreate(objname,OBJ_FIBO,0,RangeStart,vLow,RangeStart+FibLength*Period()*60,vHigh);
    ObjectSet(objname,OBJPROP_RAY,false);
    ObjectSet(objname,OBJPROP_LEVELCOLOR,LevelColor); 
    ObjectSet(objname,OBJPROP_FIBOLEVELS,6);
    ObjectSet(objname,OBJPROP_LEVELSTYLE,STYLE_SOLID);
    ObjectSet(objname,OBJPROP_FIRSTLEVEL+0,0.0);
    ObjectSet(objname,OBJPROP_FIRSTLEVEL+1,1.0);
    ObjectSet(objname,OBJPROP_FIRSTLEVEL+2,-EntryFactor);
    ObjectSet(objname,OBJPROP_FIRSTLEVEL+3,-1-EntryFactor);
    ObjectSet(objname,OBJPROP_FIRSTLEVEL+4,TPFactor);
    ObjectSet(objname,OBJPROP_FIRSTLEVEL+5,1+TPFactor);      
    ObjectSetFiboDescription(objname,1,"Initial Buy Stop = %$  ("+DoubleToStr(BuyStoppips,0)+"p)");
    ObjectSetFiboDescription(objname,0,"Initial Sell Stop = %$  ("+DoubleToStr(SellStoppips,0)+"p)");
    ObjectSetFiboDescription(objname,2,"Entry Buy= %$");
    ObjectSetFiboDescription(objname,3,"Profit Target = %$  (+"+DoubleToStr(LongTPpips,0)+"p)");
    ObjectSetFiboDescription(objname,4,"Entry Sell= %$");
    ObjectSetFiboDescription(objname,5,"Profit Target = %$  (+"+DoubleToStr(ShortTPpips,0)+"p)");
  }
  
  return(0);
}/*start*/

//+------------------------------------------------------------------+
void del_obj()  {
//+------------------------------------------------------------------+
  string ObjName;
  int ObjTotal = ObjectsTotal();
  for(int i = ObjTotal-1; i>=0; i--) {
    ObjName = ObjectName(i);
    if(StringFind(ObjName,"BF-",0)!=-1) ObjectDelete(ObjName);
  }
  return(0);
}/*del_obj*/


//--------------------------------------------------------------------------------------
void drawSessionResults(
  datetime tSessionStart, datetime tSessionEnd,
  double LongEntry,
  double ShortEntry,
  double LongTP,
  double ShortTP
)
//--------------------------------------------------------------------------------------
{

// TODO: compute session's winners/loosers and draw green/red corresponding boxes

  int xEnd;
  double yStart,yEnd;

  // fix midnight issue...
  if (tSessionEnd <= tSessionStart) tSessionEnd = tSessionEnd + 24*60*60;

  int start = iBarShift(NULL,0,tSessionStart);
  int end   = iBarShift(NULL,0,tSessionEnd);

  // get Session hi/lo values
  int xSessionHigh    = iHighest(NULL,0,MODE_HIGH,(start-end+1),end);
  int xSessionLow     = iLowest(NULL,0,MODE_LOW,(start-end+1),end);
  double vSessionHigh = High[xSessionHigh];
  double vSessionLow  = Low[xSessionLow];

}/*drawSessionResults*/

//--------------------------------------------------------------------------------------
void GetPoint()
//--------------------------------------------------------------------------------------
{
	if (Digits == 3 || Digits == 5)   
		point = Point * 10;
	else
		point = Point;
      
	if (Digits == 3 || Digits == 2)
		digits = 2;
	else
		digits = 4;
} /* GetPoint*/

//end

