//+------------------------------------------------------------------+
//|                                                         Grid.mq4 |
//|                                                          4xcoder |
//|                                              4xcoder@4xcoder.com |
//+------------------------------------------------------------------+
#property copyright "4xcoder"
#property link      "4xcoder@4xcoder.com"

#property indicator_chart_window
//---- input parameters
extern int       HGrid.Weeks=10;       // Period over which to calc High/Low of gird
extern int       HGrid.Pips=1000;        // Size of grid in Pipettes (I have a 5 digit broker.
extern color     HLine=Purple;        // Color of grid
extern color     HLine2=DeepPink;     // Every 5000 pipettes, change grid color to this.

extern int       GridTime=150;          // Number of periods (days or weeks) to draw time grid
extern int       TimeGridShort=PERIOD_H1;   // Grid period in minutes
extern color     TimeGridShortColor=Silver;
extern int       TimeGridLong=PERIOD_H4;
extern color     TimeGridLongColor=Black;
extern int       TimeZoneOffsetMins=60; // This affects how far forward each of the vertical lines are placed on the chart.
// But does not affect the London or New York Open lines. 

extern int       Lon_Open_Hour_On_MT4=10;         // For hour grids, draw color line at this hour (broker time)
extern color     London_Open=Blue;
extern int       NY_Open_Hour_On_MT4=15; // Should land on the selected hour no matter what timezone offset is selected.
extern color     New_York_Open=Red;


// Recommends settings:
// 1 minute - HGrid.Pips=10, TimeGridShort = 10
// 5, 15 minutes - HGrid.Pips=20, TimeGridShort= PERIOD_H1 (60)
// 30, 60 minutes - HGrid.Pips=20, TimeGridShort = PERIOD_H4 (240) or 2 hours (120)
// 4 hour - HGrid.Pips=50, TimeGridShort = PERIOD_D1 (1440) or 12 hours (720)
// 1 day - HGrid.Pips=50, TimeGridShort = PERIOD_W1 (10800).


bool firstTime = true;
datetime lastTime = 0;
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   int    counted_bars=IndicatorCounted();
//----
   if ( true /*lastTime == 0 || CurTime() - lastTime > 5*/ ) {
      firstTime = false;
      lastTime = CurTime();
      
      if ( HGrid.Weeks > 0 && HGrid.Pips > 0 ) {
         double weekH = iHigh( NULL, PERIOD_W1, 0 );
         double weekL = iLow( NULL, PERIOD_W1, 0 );
         
         for ( int i = 1; i < HGrid.Weeks; i++ ) {
            weekH = MathMax( weekH, iHigh( NULL, PERIOD_W1, i ) );
            weekL = MathMin( weekL, iLow( NULL, PERIOD_W1, i ) );
         }
      
         double pipRange = HGrid.Pips * Point;
         if ( Symbol() == "GOLD" )
            pipRange = pipRange * 10.0;

         double topPips = (weekH + pipRange) - MathMod( weekH, pipRange );
         double botPips = weekL - MathMod( weekL, pipRange );
      
         for ( double p = botPips; p <= topPips; p += pipRange ) {
            string gridname = "grid_" + DoubleToStr( p, Digits );
            string grid_4name = "gridLong_" + DoubleToStr(p,Digits);
            ObjectCreate( gridname, OBJ_HLINE, 0, 0, p );
            
            double pp = p / Point;
            int pInt = MathRound( pp );
            int mod = 5000;
            if ( Symbol() == "GOLD" )
               mod = 50000;
            if ( (pInt % mod) == 0 )
               ObjectSet( gridname, OBJPROP_COLOR, HLine2 );
            else
               ObjectSet( gridname, OBJPROP_COLOR, HLine );
            ObjectSet( gridname, OBJPROP_STYLE, STYLE_DASHDOT );
            ObjectSet( gridname, OBJPROP_PRICE1, p );
            ObjectSet( gridname, OBJPROP_BACK, true );
         }
      }
            
   }
   
   datetime start;
   datetime start2;
   if ( TimeGridShort == PERIOD_W1 ) {
      int weekCount = GridTime - 1;
      int bar=0;
      while ( weekCount >= 0 && bar < Bars ) {
         if ( TimeDayOfWeek( Time[bar] ) == 1 && TimeHour( Time[bar] ) == 0  ) {
            start = Time[bar];
            gridname = "grid_" + DoubleToStr( start, 0 );
            ObjectCreate( gridname, OBJ_VLINE, 0, start, 0 );
            if ( TimeHour( start ) == Lon_Open_Hour_On_MT4 && TimeMinute( start ) == 0 ) 
               {
               ObjectSet( gridname, OBJPROP_COLOR, London_Open );
               ObjectSet( gridname, OBJPROP_STYLE, STYLE_DASHDOT);
               }
            else if ( TimeHour(start)==NY_Open_Hour_On_MT4 && TimeMinute(start)==0)
               {
               ObjectSet( gridname, OBJPROP_COLOR, New_York_Open );
               ObjectSet( gridname, OBJPROP_STYLE, STYLE_DASHDOT);
               }
            else   
               {
               ObjectSet( gridname, OBJPROP_COLOR, TimeGridShortColor );
               ObjectSet( gridname, OBJPROP_STYLE, STYLE_DOT );
               }
            ObjectSet( gridname, OBJPROP_TIME1, start );
            ObjectSet( gridname, OBJPROP_BACK, true );
            weekCount--;
         }
         bar++;
      }
   }
   
   if ( TimeGridShort > 0) {
      start = Time[0];
      int skip = TimeGridShort * 60;
      int skip2 = TimeZoneOffsetMins * 60;
      start = start - (start % skip) + skip + skip2;

      
      int thisDay = TimeDay( start );
      int dayCount = GridTime - 1;
      
      while ( dayCount >= 0 ) {
         gridname = "grid_" + DoubleToStr( start, 0 );
         ObjectCreate( gridname, OBJ_VLINE, 0, start, 0 );
         if ( TimeHour( start ) == Lon_Open_Hour_On_MT4 && TimeMinute( start ) == 0 ) 
            {
            ObjectSet( gridname, OBJPROP_COLOR, London_Open );
            ObjectSet( gridname, OBJPROP_STYLE, STYLE_DASHDOT);
            }
         else if ( TimeHour(start)==NY_Open_Hour_On_MT4 && TimeMinute(start)==0)
            {
            ObjectSet( gridname, OBJPROP_COLOR, New_York_Open );
            ObjectSet( gridname, OBJPROP_STYLE, STYLE_DASHDOT);
            }
         else
            {
            ObjectSet( gridname, OBJPROP_COLOR, TimeGridShortColor);
            ObjectSet( gridname, OBJPROP_STYLE, STYLE_DOT);
            }
         ObjectSet( gridname, OBJPROP_TIME1, start);
         ObjectSet( gridname, OBJPROP_BACK, true);
         
         start = start - skip;
         if ( TimeDay( start ) != thisDay ) {
            dayCount--;
            thisDay = TimeDay( start );
         }
      }
   if ( TimeGridLong > 0 )
	  {
      start2 = Time[0];
      int skipa = TimeGridLong * 60;
      int skip2a = TimeZoneOffsetMins * 60;
      start2 = start2 - (start2 % skipa) + skipa + skip2a;
      
      int thisDay2 = TimeDay( start2 );
      int dayCount2 = GridTime - 1;
      
      while ( dayCount2 >= 0 )
         {
         grid_4name = "grid_4_" + DoubleToStr( start2, 0 );
         ObjectCreate( grid_4name, OBJ_VLINE, 0, start2, 0 );
         ObjectSet( grid_4name, OBJPROP_COLOR, TimeGridLongColor);
         ObjectSet( grid_4name, OBJPROP_STYLE, STYLE_DOT);
         ObjectSet( grid_4name, OBJPROP_TIME1, start2);
         ObjectSet( grid_4name, OBJPROP_BACK, true);
         
         start2 = start2 - skipa;
         if ( TimeDay( start2 ) != thisDay )
         {
            dayCount2--;
            thisDay2 = TimeDay( start2 );
         }
         }
      }

      
   }

//----
   return(0);
  }

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
   firstTime = true;
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
  }
//+------------------------------------------------------------------+