How do I store the value at US open?

 

Hi, I copied a Donchian channel indicator from online resources. I want to plot the Upper and Lower at US market open. The values should only change at US market open. Then remain the same value after 16:30(IC market server time at US open). But I failed to do so.

#property indicator_chart_window
#property indicator_buffers 5
#property indicator_plots 5
input int indPeriod=20; //Period
input int usOpenHour = 16;
input int usOpenMin = 30;
double upperBuff[];
double lowerBuff[];
double middleBuff[];
double usOpenUpper[];
double usOpenLower[];
double upExtend = 0;
double downExtend = 0;
double upperLine,lowerLine,middleLine;
int start, bar;
void indInit(int index, double &buffer[],string label, color clr)
  {
   SetIndexBuffer(index, buffer, INDICATOR_DATA);
   PlotIndexSetInteger(index, PLOT_DRAW_TYPE, DRAW_LINE);
   PlotIndexSetInteger(index, PLOT_LINE_WIDTH, 2);
   PlotIndexSetInteger(index, PLOT_DRAW_BEGIN, indPeriod-1);
   PlotIndexSetInteger(index, PLOT_SHIFT, 1);
   PlotIndexSetInteger(index, PLOT_LINE_COLOR, clr);
   PlotIndexSetString(index, PLOT_LABEL, label);
   PlotIndexSetDouble(index, PLOT_EMPTY_VALUE, EMPTY_VALUE);
  }
  
int OnInit(){
   indInit(0,upperBuff,"Donchian Channel", clrBlue);
   indInit(1,lowerBuff,"Donchian Channel", clrBlue);
   indInit(2,middleBuff,"Middle Donchian", clrOrange);
   indInit(3, usOpenUpper, "usOpenUpper", clrAqua);
   indInit(4, usOpenLower, "usOpenLower", clrAqua);
   IndicatorSetString(INDICATOR_SHORTNAME,"Donchian ("+IntegerToString(indPeriod)+")");
   return(INIT_SUCCEEDED);
}
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
   MqlDateTime mdt;
   if(rates_total<indPeriod+1){
      return 0;
   }
   start = prev_calculated == 0 ? indPeriod : prev_calculated - 1;
   for(bar=start; bar < rates_total; bar++){
      upperLine=high[ArrayMaximum(high, bar - indPeriod + 1, indPeriod)];
      lowerLine=low[ArrayMinimum(low, bar - indPeriod + 1, indPeriod)];
      middleLine=(upperLine + lowerLine) / 2; 
      TimeToStruct(time[0], mdt);
      if (mdt.hour == usOpenHour && mdt.min == usOpenMin){
         upExtend = upperLine;
         downExtend = lowerLine;
      } 
      usOpenUpper[bar] = upExtend;
      usOpenLower[bar] = downExtend;
      upperBuff[bar] = upperLine - (upperLine - lowerLine);
      lowerBuff[bar] = lowerLine + (upperLine - lowerLine);
      middleBuff[bar] = middleLine;
   }
   return(rates_total);
 }

The Code I added to donchian channel indicator but failed to plot :

      if (mdt.hour == usOpenHour && mdt.min == usOpenMin){
         upExtend = upperLine;
         downExtend = lowerLine;
      } 
      usOpenUpper[bar] = upExtend;
      usOpenLower[bar] = downExtend;

Thanks in advanced. 

 

time[0] won't reference the open time of the current bar each time there's a new bar, but it will when you set the time buffer to series (ArraySetAsSeries)


You'll fix the plotting issue if you do this at the start of OnCalculate:

   ArraySetAsSeries(time, true);

If you wanted to focus exclusively on the bar when the time came around, you could use a state control mechanism

static int currentState = 0;
static int saved_index = 0;

for(int bar=start; bar < rates_total; bar++){

      if (mdt.hour == usOpenHour && mdt.min == usOpenMin && currentState != 1){
         upExtend = upperLine;
         downExtend = lowerLine;
         saved_index = bar;  // save the index for when the condition is true
         currentState = 1; // stop this condition from being accessed again
      } 
}


and...a working edit:

#property indicator_chart_window
#property indicator_buffers 5
#property indicator_plots 5
input int indPeriod=20; //Period
input int usOpenHour = 16;
input int usOpenMin = 30;
double upperBuff[];
double lowerBuff[];
double middleBuff[];
double usOpenUpper[];
double usOpenLower[];
double upExtend = 0;
double downExtend = 0;
double upperLine,lowerLine,middleLine;

void indInit(int index, double &buffer[],string label, color clr)
  {
   SetIndexBuffer(index, buffer, INDICATOR_DATA);
   PlotIndexSetInteger(index, PLOT_DRAW_TYPE, DRAW_LINE);
   PlotIndexSetInteger(index, PLOT_LINE_WIDTH, 2);
   PlotIndexSetInteger(index, PLOT_DRAW_BEGIN, indPeriod-1);
   PlotIndexSetInteger(index, PLOT_SHIFT, 1);
   PlotIndexSetInteger(index, PLOT_LINE_COLOR, clr);
   PlotIndexSetString(index, PLOT_LABEL, label);
   PlotIndexSetDouble(index, PLOT_EMPTY_VALUE, EMPTY_VALUE);
  }
  
int OnInit(){
   indInit(0,upperBuff,"Donchian Channel", clrDodgerBlue);
   indInit(1,lowerBuff,"Donchian Channel", clrDodgerBlue);
   indInit(2,middleBuff,"Middle Donchian", clrOrange);
   indInit(3, usOpenUpper, "usOpenUpper", clrAqua);
   indInit(4, usOpenLower, "usOpenLower", clrAqua);
   IndicatorSetString(INDICATOR_SHORTNAME,"Donchian ("+IntegerToString(indPeriod)+")");
   return(INIT_SUCCEEDED);
}
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
  
   ArraySetAsSeries(time, true);
   
   MqlDateTime mdt;
   if(rates_total<indPeriod+1){
      return 0;
   }
   int start = prev_calculated == 0 ? indPeriod : prev_calculated - 1;
   
   static int currentState = 0;
   static int saved_index = 0;
   
   for(int bar=start; bar < rates_total; bar++){
      upperLine=high[ArrayMaximum(high, bar - indPeriod + 1, indPeriod)];
      lowerLine=low[ArrayMinimum(low, bar - indPeriod + 1, indPeriod)];
      middleLine=(upperLine + lowerLine) / 2; 
      TimeToStruct(time[0], mdt);
      if (mdt.hour == usOpenHour && mdt.min == usOpenMin && currentState != 1){
         upExtend = upperLine;
         downExtend = lowerLine;
         saved_index = bar;  // save the index for when the condition is true
         currentState = 1; // stop this condition from being accessed again
      } 

      upperBuff[bar] = upperLine;
      lowerBuff[bar] = lowerLine;
      middleBuff[bar] = middleLine;
      
      usOpenUpper[bar] = upperBuff[saved_index];
      usOpenLower[bar] = lowerBuff[saved_index];
   }
   

   return(rates_total);
 }