
#property indicator_chart_window
#property  indicator_buffers 2
#property  indicator_color1  Red
#property  indicator_color2  Blue

#define NEUTRAL 0
#define BUY 1
#define SELL -1

extern int RangeStartTime=8;
extern int RangeEndTime=10;
extern bool InvertBias=false;
extern bool InvertSignal=false;
extern bool IgnoreBias=false;
extern bool ShowTimeLines=true;
extern bool ShowHighLowLines=true;
extern color RangeStartColor = Lime;
extern color RangeEndColor = Yellow;
extern color HighColor=Blue;
extern color LowColor=Red;

double   IndBuff0[];
double   IndBuff1[];
double   IndBuff2[];
double   IndBuff3[];
double   IndBuff4[];
double   IndBuff5[];
double   IndBuff6[];
double   IndBuff7[];

int      Signal,handle;
double   LocalPoint;
double open,close,high,low,mid;
bool lookForEntryShort,lookForEntryLong;
datetime reftime,timeHighBroken,timeLowBroken;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
string shortName;

   IndicatorBuffers(2);
   SetIndexBuffer(0,IndBuff0);
   SetIndexBuffer(1,IndBuff1);
   SetIndexStyle(0,DRAW_ARROW,EMPTY,3);
   SetIndexStyle(1,DRAW_ARROW,EMPTY,3);
   SetIndexArrow(0,234);
   SetIndexArrow(1,233);
   LocalPoint=Point*GetDigitAdjustFactor();
   handle=WindowFind(WindowExpertName());
   lookForEntryShort=false;
   lookForEntryLong=false;
   timeHighBroken=0;
   timeLowBroken=0;
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   int i;
   string name;
   
   for(i=ObjectsTotal()-1;i>=0;i--)
   {
      name=ObjectName(i);
      if(StringSubstr(name,0,2)=="1_")
         ObjectDelete(name);
   }
   Comment(" ");
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   int limit,counted_bars=IndicatorCounted();
   int shift,dayshift,lowestbar,highestbar;
   string name;
   datetime end;
   double stoch,macd[8];
   
   if(counted_bars>0) counted_bars--;
   limit=Bars-1-counted_bars;

   for(int bar=limit; bar>=0; bar--)
   {
      shift=iBarShift(NULL,PERIOD_H1,Time[bar]);
      dayshift=iBarShift(NULL,PERIOD_D1,Time[bar]);
      if(IsNewBar(PERIOD_H1,shift))
      {
         if(TimeHour(Time[bar])==RangeStartTime)
         {
            open=Open[bar];
            if(ShowTimeLines)
            {
               name="1_S_" +TimeToStr(Time[bar]);
               drawLine(name,OBJ_VLINE,0,RangeStartColor,Time[bar],open);
            }            
         }
         else if(TimeHour(Time[bar])==RangeEndTime)
         {
            if(ShowTimeLines)
            {
               name="1_E_" +TimeToStr(Time[bar]);
               drawLine(name,OBJ_VLINE,0,RangeEndColor,Time[bar],open);
            }
            close=Close[bar+1];
            highestbar=iHighest(NULL,PERIOD_H1,MODE_HIGH,RangeEndTime-RangeStartTime,shift+1);
            high=iHigh(NULL,PERIOD_H1,highestbar);
            lowestbar=iLowest(NULL,PERIOD_H1,MODE_LOW,RangeEndTime-RangeStartTime,shift+1);
            low=iLow(NULL,PERIOD_H1,lowestbar);
            end=iTime(NULL,PERIOD_D1,dayshift)+86400;
            reftime=Time[bar];
            if(ShowHighLowLines)
            {
               name="1_H_" +TimeToStr(Time[bar]);
               drawLine(name,OBJ_TREND,0,HighColor,iTime(NULL,PERIOD_H1,highestbar),high,end,high);
               name="1_L_" +TimeToStr(Time[bar]);
               drawLine(name,OBJ_TREND,0,LowColor,iTime(NULL,PERIOD_H1,lowestbar),low,end,low);
            }
            if(IgnoreBias)
            {
               lookForEntryShort=true;            
               lookForEntryLong=true;
            }
            else
            {
               if(close<open)
                  lookForEntryShort=true;
               else if(close>open)
                  lookForEntryLong=true;
               if(InvertBias)
               {
                  lookForEntryShort=!lookForEntryShort;
                  lookForEntryLong=!lookForEntryLong;
               }
            }
            continue;
         }
      }
      if((lookForEntryShort || lookForEntryLong) && IsNewBar(PERIOD_M1,bar))
      {
         stoch = iStochastic(NULL,0,5,3,3,MODE_SMA,0,MODE_MAIN,bar+1);
         
         macd[0]=iCustom(NULL,0,"MACD_4CZ",5,34,0,bar+1);   //green
         macd[1]=iCustom(NULL,0,"MACD_4CZ",5,34,1,bar+1);   //darkgreen
         macd[2]=iCustom(NULL,0,"MACD_4CZ",5,34,2,bar+1);   //red
         macd[3]=iCustom(NULL,0,"MACD_4CZ",5,34,3,bar+1);   //maroon
         macd[4]=iCustom(NULL,0,"MACD_4CZ",5,34,0,bar+2);
         macd[5]=iCustom(NULL,0,"MACD_4CZ",5,34,1,bar+2);
         macd[6]=iCustom(NULL,0,"MACD_4CZ",5,34,2,bar+2);
         macd[7]=iCustom(NULL,0,"MACD_4CZ",5,34,3,bar+2);
         double atr=iATR(NULL,0,5,bar);

         if(HighBoundaryBroken(bar) || LowBoundaryBroken(bar))
         {
            if(timeHighBroken>timeLowBroken)
            {
               lookForEntryShort=false;
               lookForEntryLong=true;
            }
            else if(timeHighBroken<timeLowBroken)
            {
               lookForEntryShort=true;
               lookForEntryLong=false;
            }
         
         }
         //changed from green -> darkgreen?         
         if(macd[1]>0 && macd[5]==0 && macd[0]==0 && macd[4]>0)
         {
            if(stoch>50 && lookForEntryShort && (High[bar+1]<high || IgnoreBias))
            {
               if(InvertSignal)
                  IndBuff1[bar]=Low[bar]-atr;
               else
                  IndBuff0[bar]=High[bar]+atr;
               lookForEntryShort=false;
            }
         }
         //changed from marron -> red?
         else if(macd[2]<0 && macd[6]==0 && macd[3]==0 && macd[7]<0)
         {
            if(stoch<50 && lookForEntryLong && (Low[bar+1]>low || IgnoreBias))
            {
               if(InvertSignal)
                  IndBuff0[bar]=High[bar]+atr;
               else
                  IndBuff1[bar]=Low[bar]-atr;
               lookForEntryLong=false;
            }
         }
      }
   }
//----
   return(0);
  }
//+------------------------------------------------------------------+
int GetDigitAdjustFactor()
{
   if(Digits==5 || Digits==3)
      return(10);
   else
      return(1);
}

void drawLine(string name, int type, int window, color col, datetime time1, double price1, datetime time2=0, double price2=0, datetime time3=0, double price3=0)
{
   if(ObjectFind(name) != -1)
   {
      ObjectDelete(name);
   }
   ObjectCreate(name, type, window, time1, price1, time2, price2);
   ObjectSet(name, OBJPROP_RAY, false);
   ObjectSet(name, OBJPROP_COLOR, col);
   if(type==OBJ_VLINE)
      ObjectSet(name, OBJPROP_STYLE, STYLE_DOT);

}
bool IsNewBar(int thePeriod, int shift=0)
{
static datetime barTime1440=0, barTime240=0, barTime60=0, barTime30=0, barTime15=0, barTime5=0, barTime1=0;

   switch(thePeriod)
   {
      case PERIOD_D1:
         if(barTime1440<iTime(Symbol(),PERIOD_D1,shift))
         {
            barTime1440=iTime(Symbol(),PERIOD_D1,shift);
            return(true);
         }
         break;
      case PERIOD_H4:
         if(barTime240<iTime(Symbol(),PERIOD_H4,shift))
         {
            barTime240=iTime(Symbol(),PERIOD_H4,shift);
            return(true);
         }
         break;
      case PERIOD_H1:
         if(barTime60<iTime(Symbol(),PERIOD_H1,shift))
         {
            barTime60=iTime(Symbol(),PERIOD_H1,shift);
            return(true);
         }
         break;
      case PERIOD_M30:
         if(barTime30<iTime(Symbol(),PERIOD_M30,shift))
         {
            barTime30=iTime(Symbol(),PERIOD_M30,shift);
            return(true);
         }
         break;
      case PERIOD_M15:
         if(barTime15<iTime(Symbol(),PERIOD_M15,shift))
         {
            barTime15=iTime(Symbol(),PERIOD_M15,shift);
            return(true);
         }
         break;
      case PERIOD_M5:
         if(barTime5<iTime(Symbol(),PERIOD_M5,shift))
         {
            barTime5=iTime(Symbol(),PERIOD_M5,shift);
            return(true);
         }
         break;
      case PERIOD_M1:
         if(barTime1<iTime(Symbol(),PERIOD_M1,shift))
         {
            barTime1=iTime(Symbol(),PERIOD_M1,shift);
            return(true);
         }
         break;
   }
   return(false);
}
bool HighBoundaryBroken(int bar)
{
   int start,end,index;
   double price;
   
   start=iBarShift(NULL,0,reftime);
   index=iHighest(NULL,0,MODE_HIGH,start-bar,bar);
   price=High[index];
   if(price>high)
   {
      timeHighBroken=Time[bar];
      return(true);
   }
   
   return(false);
}
bool LowBoundaryBroken(int bar)
{
   int start,end,index;
   double price;
   
   start=iBarShift(NULL,0,reftime);
   index=iLowest(NULL,0,MODE_LOW,start-bar,bar);
   price=Low[index];
   if(price<low)
   {
      timeLowBroken=Time[bar];
      return(true);
   }
   return(false);
}