Prior day levels with day shift option

 

I need to add the ability to set the day shift for this indicator I've adapted from an indicator showing prior day levels. I know there's lots of indies out there providing prior day levels but most have issues handling partial days (holidays, Sundays, etc.) and/or have performance issues. I'd like to use this one but need assistance with figuring out how to have it recognize a day shift. I'd like to add an integer input called DayShift and for example if set to 2 it will draw levels from two days prior. Note: All existing levels expressed in this indicator must continue to be supported including highest/lowest close, day open, day close, etc.

For extra points, having GMTOffset as a working option would also be nice. That way one could use a GMT+0 broker but still use levels from GMT+2 time frames. Of course, partial days and Sundays must be properly mapped.

Lastly, I'd like to expand my definition of PartialDays to include not only specific holiday date but basically any day which has less than x number of bars. For example, on an M30 chart one might determine that if the day doesn't continue at least 14 bars then it should be considered a partial day. The levels of partial days do not get observed. Rather, the levels from the preceding day are carried forward.

Thanks in advance for assistance with adding DayShift, GMTOffset and more robust handling of Partial Days.

Bill

//*************************************************************** 0 **
// PriorDayLevels                                                     
//********************************************************************

#property copyright "Copyright © 2011, Bill Doerrfeld"
#property link      "http://www.BillDoerrfeld.com"

/*
Derived from dayHL_Average by KCBT http://www.kcbt.ru/forum/index.php?
*/

#property indicator_chart_window
#property indicator_buffers 7
#property indicator_color1 Blue
#property indicator_color2 Blue
#property indicator_color3 Yellow
#property indicator_color4 Orange
#property indicator_color5 Red
#property indicator_color6 Red
#property indicator_color7 Gray

//*************************************************************** 1 **
// User Input Parameters                                                     
//********************************************************************

extern bool ShowHighAndLowClose = 1;
extern bool ShowDayClose = 1;
extern bool ShowPivot = 1;
//extern int  GMTOffset = 0;


//*************************************************************** 2 **
// Indicator Buffers                                                    
//********************************************************************

double PriorHigh[];
double PriorHighClose[];
double PriorMid[];
double PriorPivot[];
double PriorLowClose[];
double PriorLow[];
double PriorClose[];

//*************************************************************** 3 **
// Initialization                                                    
//********************************************************************

int init()
   {
   SetIndexBuffer(0, PriorHigh);
   SetIndexStyle(0, DRAW_LINE,STYLE_SOLID,1);
   SetIndexLabel(0,"High");
   
   SetIndexBuffer(1, PriorHighClose);
   SetIndexStyle(1, DRAW_LINE,STYLE_DOT,1);
   SetIndexLabel(1,"HighClose");
   
   SetIndexBuffer(2, PriorMid);
   SetIndexStyle(2, DRAW_LINE,STYLE_DOT,1);
   SetIndexLabel(2,"Mid");
   
   SetIndexBuffer(3, PriorPivot);
   SetIndexStyle(3, DRAW_LINE,STYLE_DOT,1);
   SetIndexLabel(3,"Pivot");
   
   SetIndexBuffer(4, PriorLowClose);
   SetIndexStyle(4, DRAW_LINE,STYLE_DOT,1);
   SetIndexLabel(4,"LowClose");
   
   SetIndexBuffer(5, PriorLow);
   SetIndexStyle(5, DRAW_LINE,STYLE_SOLID,1);
   SetIndexLabel(5,"Low");
         
   SetIndexBuffer(6, PriorClose);
   SetIndexStyle(6, DRAW_LINE,STYLE_DOT,1);
   SetIndexLabel(6,"PriorClose");
   
   return(0);
   }


//*************************************************************** 4 **
// DeInitialization                                                    
//********************************************************************

int deinit()
   {
   Comment("");
   return(0);
   }


//*************************************************************** 5 **
// Start Program                                                    
//********************************************************************

int start()
   {
   
   // Set variables
   int cnt=0;
   int begin_bar=0;
   int prev_day, cur_day;
   
   double day_high=0;
   double day_low=0;
   double day_highclose=0;
   double day_lowclose=0;
   
   double yesterday_high=0;
   double yesterday_low=0;
   double yesterday_highclose=0;
   double yesterday_lowclose=0;
   
   double yesterday_close=0;
   double H, HC, M, P, LC, L, C;

   // Period warning
   if (Period() >= PERIOD_D1) 
      {
      Comment("WARNING: Invalid timeframe! Valid value < D1.");
      return(0);
      }

   // Loop thru bars
   int day_bar_count = 0;
   int bars_in_day = 0;
   
   for (cnt = Bars; cnt >= 0; cnt--)
      {
      cur_day = TimeDay(Time[cnt]);
      bool Sunday = TimeDayOfWeek(Time[cnt]) == 0;
      bool Xmas = TimeDayOfYear(Time[cnt]) == 360;
      bool NewYear = TimeDayOfYear(Time[cnt]) == 1;
      bool PartialDay = Sunday || Xmas || NewYear;

      // Get Levels
      if (prev_day != cur_day && !PartialDay) 
         {
         yesterday_close = Close[cnt+1];
         yesterday_high = day_high;
         yesterday_low = day_low;
         yesterday_highclose = day_highclose;
         yesterday_lowclose = day_lowclose;
         
         H = yesterday_high;
         HC = yesterday_highclose;
         M = (yesterday_high + yesterday_low ) / 2;
         L = yesterday_low;
         LC = yesterday_lowclose;
         C = yesterday_close;
         P = (H + L + C ) / 3;

         day_high = High[cnt];
         day_low = Low[cnt];
         day_highclose = Close[cnt];
         day_lowclose = Close[cnt];

         prev_day = cur_day;

         }

      if(!PartialDay)
         {
         day_high = MathMax(day_high, High[cnt]);
         day_low = MathMin(day_low, Low[cnt]);
         day_highclose = MathMax(day_highclose, Close[cnt]);
         day_lowclose = MathMin(day_lowclose, Close[cnt]);
         }      

      // Set Indicator Buffers

      PriorHigh[cnt] = H; 
      if(ShowHighAndLowClose)PriorHighClose[cnt] = HC; 
      PriorMid[cnt] = M;
      if(ShowPivot)PriorPivot[cnt] = P;
      if(ShowHighAndLowClose)PriorLowClose[cnt] = LC; 
      PriorLow[cnt] = L; 
      if(ShowDayClose)PriorClose[cnt] = C; 
      
      }

   return(0);
   }
 
billworld:

I need to add the ability to set the day shift for this indicator . . .

I've adapted from an indicator showing prior day levels. . . .

Lastly, I'd like to expand my definition of PartialDays to include not only . . .

OK, you want to do all these things . . . what is stopping you, get on with it.
 
RaptorUK:
OK, you want to do all these things . . . what is stopping you, get on with it.


Umm. I'm not the genius coder that some others are (or think they are) and that's why I humbly seek assistance on this forum.
 
RaptorUK:
OK, you want to do all these things . . . what is stopping you, get on with it.


Maybe you missed the point where I said I "need assistance with figuring out how to have it recognize a day shift." I've worked with other code structures to achieve a day shift, but, I'm just not seeing how to accomplish that with this code structure while retaining the other features offered in this indy. Thanks in advance for any help with this.
 

Where have you posted your attempt at a "day shift"? Where have you posted your definition of a "day shift"?

Since there are no slaves here, you have only three choices: Search for it, learn to code it, or pay someone. We're not going to code it FOR you. We are willing to HELP you when you post your attempt (using SRC) and the nature of your problem.
 

I didn't post any of my failed attempts as it seemed that would be confusing to the reader. The code I posted works, but, lacks the DayShift option. What do I mean by DayShift? The ability to set the number of days back from which to grab the day's levels. This issue gets somewhat complicated if one makes the decision to skip incomplete/partial days (such as Sundays and holidays or days when there are less than x hours of data) and rather grab the level from the last prior full trading day. IMO and based on my study of charts, it makes the most sense to grab a day's level from a complete day and ignore and/or skip incomplete days.

I've examined and edited dozens of DayHiLo, DayRange, DayLevels, etc. indicators and have yet to find one which IMO works well. Some have DayShift options but fail miserably when applied to charts based on GMT+0. The one I've created and posted the full source code above works quite well and has excellent performance. However, it lacks the ability to handle DayShift. As the number of hours of bar data needs to be determined in order to determine whether or not the day is a full or partial trading day, it appears setting a loop on daily bars within this code construct won't work. Further, the need to retain the highest close and lowest close bar values necessitates deriving day levels from intraday bars.

 

Hi,

as I wanted something similar, I thought that I would try to adapt your code, but it ended up almost completely different.

It effectively combines the small Sunday candle with Monday .

As it works with H1 data, it is best to make sure that the H1 data is up to date as there are no checks for error 4066 etc

as yet, I have been unable to do anything about chart offset and day shift .

Perhaps you can look at the code and see if you have any ideas

#property indicator_chart_window
#property indicator_buffers 7
#property indicator_color1 Blue
#property indicator_color2 Blue
#property indicator_color3 Yellow
#property indicator_color4 Orange
#property indicator_color5 Red
#property indicator_color6 Red
#property indicator_color7 Gray

//*************************************************************** 1 **
// User Input Parameters                                                     
//********************************************************************

extern bool ShowHighAndLowClose = true;
extern bool ShowDayClose = true;
extern bool ShowPivot = true;
//extern int  DayShift=1;
//extern int  GMTOffset = 0;


//*************************************************************** 2 **
// Indicator Buffers                                                    
//********************************************************************

double PriorHigh[];
double PriorHighClose[];
double PriorMid[];
double PriorPivot[];
double PriorLowClose[];
double PriorLow[];
double PriorClose[];

//*************************************************************** 3 **
// Initialization                                                    
//********************************************************************

int init()
   {
   SetIndexBuffer(0, PriorHigh);
   SetIndexStyle(0, DRAW_LINE,STYLE_SOLID,1);
   SetIndexLabel(0,"High");
   
   SetIndexBuffer(1, PriorHighClose);
   SetIndexStyle(1, DRAW_LINE,STYLE_DOT,1);
   SetIndexLabel(1,"HighClose");
   
   SetIndexBuffer(2, PriorMid);
   SetIndexStyle(2, DRAW_LINE,STYLE_DOT,1);
   SetIndexLabel(2,"Mid");
   
   SetIndexBuffer(3, PriorPivot);
   SetIndexStyle(3, DRAW_LINE,STYLE_DOT,1);
   SetIndexLabel(3,"Pivot");
   
   SetIndexBuffer(4, PriorLowClose);
   SetIndexStyle(4, DRAW_LINE,STYLE_DOT,1);
   SetIndexLabel(4,"LowClose");
   
   SetIndexBuffer(5, PriorLow);
   SetIndexStyle(5, DRAW_LINE,STYLE_SOLID,1);
   SetIndexLabel(5,"Low");
         
   SetIndexBuffer(6, PriorClose);
   SetIndexStyle(6, DRAW_LINE,STYLE_DOT,1);
   SetIndexLabel(6,"PriorClose");
   
   return(0);
   }


//*************************************************************** 4 **
// DeInitialization                                                    
//********************************************************************

int deinit()
   {
   Comment("");
   return(0);
   }


//*************************************************************** 5 **
// Start Program                                                    
//********************************************************************

int start()
   {
   int cnt;
  
   // Period warning
   if (Period() >= PERIOD_D1) 
      {
      Comment("WARNING: Invalid timeframe! Valid value < D1.");
      return(0);
      }

      // Set Indicator Buffers
      
  int limit;
     int counted_bars=IndicatorCounted();
  //---- check for possible errors
     if(counted_bars<0) return(-1);
  //---- the last counted bar will be recounted
     if(counted_bars>0) counted_bars--;
     limit=Bars-counted_bars;    
      
      

 for(cnt=limit;cnt>=0;cnt--)
   {
   
   datetime midnight = Time[cnt]-(Time[cnt] % (PERIOD_D1*60));
   datetime prevmidnight = midnight - (PERIOD_D1*60);
   if(TimeDayOfWeek( midnight)==0)
      {
      prevmidnight=prevmidnight - (PERIOD_D1*60);
      midnight = prevmidnight + (PERIOD_D1*60); 
      }
   if(TimeDayOfWeek( midnight)==1)
      {
      prevmidnight=midnight - (PERIOD_D1*60*3);
      midnight =midnight - (PERIOD_D1*60); 
      }
   if(TimeDayOfWeek( midnight)==2)
      {
      prevmidnight=midnight - (PERIOD_D1*60*2);
      //midnight =midnight - (PERIOD_D1*60); 
      }
   
   int shiftend = iBarShift(NULL,PERIOD_H1,midnight,true);
   if(shiftend == -1)
      shiftend = iBarShift(NULL,PERIOD_H1,midnight,false)-1;
   int shiftstart = iBarShift(NULL,PERIOD_H1,prevmidnight,true);
   if(shiftstart == -1)
      shiftstart = iBarShift(NULL,PERIOD_H1,prevmidnight,false)-1;
   int shiftbars =shiftstart-shiftend;
      
   PriorHigh[cnt] = iHigh(NULL,PERIOD_H1,iHighest(NULL,PERIOD_H1,MODE_HIGH,shiftbars,shiftend+1) ); 
   PriorLow[cnt] = iLow(NULL,PERIOD_H1,iLowest(NULL,PERIOD_H1,MODE_LOW,shiftbars,shiftend+1) );
   PriorMid[cnt] = (PriorHigh[cnt]+PriorLow[cnt])/2;
   if(ShowHighAndLowClose)
      {
      PriorHighClose[cnt] =iClose(NULL,PERIOD_H1,iHighest(NULL,PERIOD_H1,MODE_CLOSE,shiftbars,shiftend+1) );
      PriorLowClose[cnt] = iClose(NULL,PERIOD_H1,iLowest(NULL,PERIOD_H1,MODE_CLOSE,shiftbars,shiftend+1) );
      }
   if(ShowDayClose)
      PriorClose[cnt] =iClose(NULL,PERIOD_H1,shiftend+1); 
   if(ShowPivot)
      PriorPivot[cnt] =(PriorHigh[cnt]+PriorLow[cnt]+PriorClose[cnt])/3;
   }
     
      

//----
   return(0);
  }
 
GumRai:

Hi,

as I wanted something similar, I thought that I would try to adapt your code, but it ended up almost completely different.

It effectively combines the small Sunday candle with Monday .

As it works with H1 data, it is best to make sure that the H1 data is up to date as there are no checks for error 4066 etc

as yet, I have been unable to do anything about chart offset and day shift .

Perhaps you can look at the code and see if you have any ideas


Thanks GumRai for taking a stab at this. I'm not advanced yet in my coding and troubleshooting to look at your code and determine if that approach will get us more easily to DayShift, GMTShift, partial day handling (holidays, etc) and support for all timeframes (<D1 of course). Since there are partial trading days that fall on known days (Sunday and set holiday dates) and then partial trading days which don't follow such rules (holidays whose date changes, or even days with missing broker data), it seems the most robust way of handling skipping partial days is to count the number of bars for a given day. That way one is ensured that the levels will only be drawn if there's sufficient data available. I worked with someone a few years back that cracked that nut along with DayShift, but, I found the performance of the indy too slow and the code quite cumbersome to work with. That's why I've been attempting to get at a more streamlined approach. Anyway, thanks for putting your brain power on this one. Much appreciated.
 
billworld:

Thanks GumRai for taking a stab at this. I'm not advanced yet in my coding and troubleshooting to look at your code and determine if that approach will get us more easily to DayShift, GMTShift, partial day handling (holidays, etc) and support for all timeframes (<D1 of course). Since there are partial trading days that fall on known days (Sunday and set holiday dates) and then partial trading days which don't follow such rules (holidays whose date changes, or even days with missing broker data), it seems the most robust way of handling skipping partial days is to count the number of bars for a given day. That way one is ensured that the levels will only be drawn if there's sufficient data available. I worked with someone a few years back that cracked that nut along with DayShift, but, I found the performance of the indy too slow and the code quite cumbersome to work with. That's why I've been attempting to get at a more streamlined approach. Anyway, thanks for putting your brain power on this one. Much appreciated.


I'm not an advanced coder, so it was a good exercise for me. I intend to continue with this and see what I can do.

What exactly do you mean about the GMT offset?

I'm guessing that if, for example, you have a Sunday candle on the chart that starts at 10PM, then you will want each day's data to start at 10PM and finish at 9:59PM the next day.

 
GumRai:


I'm not an advanced coder, so it was a good exercise for me. I intend to continue with this and see what I can do.

What exactly do you mean about the GMT offset?

I'm guessing that if, for example, you have a Sunday candle on the chart that starts at 10PM, then you will want each day's data to start at 10PM and finish at 9:59PM the next day.


GMTOffset would yield the start of the day based on the offset amount, while observing all partial day rules. For example, if your charts are in GMT+0 but you'd like prior day levels to be based on GMT+3 prior day levels, all levels would be based on the GMT+3 start of day if the GMTOffset value was set to +3. I've seen that done, but, I haven't seen it properly recognize partial days along with other goals for this project. Thanks for your interest.
Reason: