Need to add Open Price to the formula

 

#property strict
#property indicator_chart_window
#property indicator_buffers 17
//--- input parameters
enum ENUM_WORK_MODE
  {
  DAILY,
  WEEKLY,
  MONTHLY
  };
input ENUM_WORK_MODE workMode=DAILY;
input int      StartHour=3;
input int      lineWidth=1;
input ENUM_LINE_STYLE lineStyle=STYLE_SOLID;
input bool   displayComment=false;
//---- buffers
double Res8[];
double Res7[];
double Res6[];
double Res5[];
double Res4[];
double Res3[];
double Res2[];
double Res1[];
double Pivot[];
double Supp1[];
double Supp2[];
double Supp3[];
double Supp4[];
double Supp5[];
double Supp6[];
double Supp7[];
double Supp8[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
  string short_name="LEVELS "+EnumToString(workMode);
  IndicatorShortName(short_name);
  IndicatorDigits(_Digits);

  SetIndexBuffer(0,Res8);
  SetIndexStyle(0,DRAW_LINE,lineStyle,lineWidth,clrLime);
  SetIndexBuffer(1,Res7);
  SetIndexStyle(1,DRAW_LINE,lineStyle,lineWidth,clrLime);
  SetIndexBuffer(2,Res6);
  SetIndexStyle(2,DRAW_LINE,lineStyle,lineWidth,clrLime);
  SetIndexBuffer(3,Res5);
  SetIndexStyle(3,DRAW_LINE,lineStyle,lineWidth,clrLime);
  SetIndexBuffer(4,Res4);
  SetIndexStyle(4,DRAW_LINE,lineStyle,lineWidth,clrGray);
  SetIndexBuffer(5,Res3);
  SetIndexStyle(5,DRAW_LINE,lineStyle,lineWidth,clrLime);
  SetIndexBuffer(6,Res2);
  SetIndexStyle(6,DRAW_LINE,lineStyle,lineWidth,clrLime);
  SetIndexBuffer(7,Res1);
  SetIndexStyle(7,DRAW_LINE,lineStyle,lineWidth,clrLime);

  SetIndexBuffer(8,Pivot);
  SetIndexStyle(8,DRAW_LINE,lineStyle,lineWidth,clrGray);

  SetIndexBuffer(9,Supp1);
  SetIndexStyle(9,DRAW_LINE,lineStyle,lineWidth,clrLime);
  SetIndexBuffer(10,Supp2);
  SetIndexStyle(10,DRAW_LINE,lineStyle,lineWidth,clrLime);
  SetIndexBuffer(11,Supp3);
  SetIndexStyle(11,DRAW_LINE,lineStyle,lineWidth,clrLime);
  SetIndexBuffer(12,Supp4);
  SetIndexStyle(12,DRAW_LINE,lineStyle,lineWidth,clrGray);
  SetIndexBuffer(13,Supp5);
  SetIndexStyle(13,DRAW_LINE,lineStyle,lineWidth,clrLime);
  SetIndexBuffer(14,Supp6);
  SetIndexStyle(14,DRAW_LINE,lineStyle,lineWidth,clrLime);
  SetIndexBuffer(15,Supp7);
  SetIndexStyle(15,DRAW_LINE,lineStyle,lineWidth,clrLime);
  SetIndexBuffer(16,Supp8);
  SetIndexStyle(16,DRAW_LINE,lineStyle,lineWidth,clrLime);

//---
  return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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[])
  {
//---
  oMain.Calc(rates_total,prev_calculated);
  if(displayComment)Comment(oMain.ToString());
//--- return value of prev_calculated for next call
  return(rates_total);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
enum ENUM_MONTH
  {
  NONE,
  JANUARY,
  FEBRUARY,
  MARCH,
  APRIL,
  MAY,
  JUNE,
  JULY,
  AUGUST,
  SEPTEMBER,
  OCTOBER,
  NOVEMBER,
  DECEMBER
  };
//+------------------------------------------------------------------+
class CMain
  {
    MqlDateTime time;
    datetime timeGetLevels;
    struct SPivotBar
      {
      datetime timeCurPeriodStart;
      datetime timeCurPeriodEnd;

      datetime timePivotOpen;
      datetime timePivotRealOpen;
      datetime timePivotClose;

      double high;
      datetime timeHigh;
      double low;
      datetime timeLow;
      double close;
      datetime timePivotRealClose;

      double r8,r7,r6,r5,r4,r3,r2,r1;
      double p;
      double s1,s2,s3,s4,s5,s6,s7,s8;
      };
    SPivotBar pivotBar;

    bool CalcPivotBarTimes(datetime TIME);
    bool CalcPivotBarHLC(int I,SPivotBar &PIVOT_BAR);
    bool CalcPivotsLevels(SPivotBar &PIVOT_BAR);

    int               arrDayInMonth[13];
    void              SetArrDayInMonth()
      {
      arrDayInMonth[1]=31;
      arrDayInMonth[2]=28;
      arrDayInMonth[3]=31;
      arrDayInMonth[4]=30;
      arrDayInMonth[5]=31;
      arrDayInMonth[6]=30;
      arrDayInMonth[7]=31;
      arrDayInMonth[8]=31;
      arrDayInMonth[9]=30;
      arrDayInMonth[10]=31;
      arrDayInMonth[11]=30;
      arrDayInMonth[12]=31;
      };
    int               GetDaysInMonth(datetime TIME)
      {
      MqlDateTime daysTime;
      TimeToStruct(TIME,daysTime);
      int dayInMonth=arrDayInMonth[daysTime.mon];
      if(daysTime.mon==2 && !((daysTime.year-1804)%4))
        dayInMonth=29;
      return dayInMonth;
      }
  public:
    CMain(void)
      {
      SetArrDayInMonth();
      };
    ~CMain(void) {};
    string ToString();
    void Calc(int RATES_TOTAL, int PREV_CALCULATED);
  };
CMain oMain;
//+------------------------------------------------------------------+
string CMain::ToString(void)
  {
  return StringConcatenate("\n===LEVELS ",EnumToString(workMode),"=== | StartHour",StartHour," | timeGetLevels_",timeGetLevels,
                           "\nCUR ",pivotBar.timeCurPeriodStart," - ",pivotBar.timeCurPeriodEnd," | P_",DoubleToString(pivotBar.p,_Digits),
                           "\ntimePivotOpen",pivotBar.timePivotOpen,
                           " | high_",DoubleToString(pivotBar.high,_Digits)," at_",pivotBar.timeHigh,
                           " | low_",DoubleToString(pivotBar.low,_Digits)," at_",pivotBar.timeLow,
                           " | close_",DoubleToString(pivotBar.close,_Digits)," at_",pivotBar.timePivotRealClose);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CMain::Calc(int RATES_TOTAL,int PREV_CALCULATED)
  {
  int total=RATES_TOTAL-PREV_CALCULATED;
  if(total==RATES_TOTAL ||
      total>1)
    {
    total =RATES_TOTAL-1;
    pivotBar.timeCurPeriodEnd=Time[RATES_TOTAL-2];
    }

  //Print("RATES_TOTAL_",RATES_TOTAL," ",Time[RATES_TOTAL-2]," | pivotBar.timeCurDayEnd_",pivotBar.timeCurDayEnd);
  for(int i=total; i>=0; i--)
    {
    //Print("Time[i]_",Time[i]," | pivotBar.timeCurDayEnd_",pivotBar.timeCurDayEnd);
    if(Time[i]>pivotBar.timeCurPeriodEnd)
      {

      CalcPivotBarTimes(Time[i]);
      CalcPivotBarHLC(i,pivotBar);
      CalcPivotsLevels(pivotBar);

      timeGetLevels=TimeCurrent();
      }
    //--- fill indicator buffers
    Res8[i]=pivotBar.r8;
    Res7[i]=pivotBar.r7;
    Res6[i]=pivotBar.r6;
    Res5[i]=pivotBar.r5;
    Res4[i]=pivotBar.r4;
    Res3[i]=pivotBar.r3;
    Res2[i]=pivotBar.r2;
    Res1[i]=pivotBar.r1;

    Pivot[i]=pivotBar.p;

    Supp1[i]=pivotBar.s1;
    Supp2[i]=pivotBar.s2;
    Supp3[i]=pivotBar.s3;
    Supp4[i]=pivotBar.s4;
    Supp5[i]=pivotBar.s5;
    Supp6[i]=pivotBar.s6;
    Supp7[i]=pivotBar.s7;
    Supp8[i]=pivotBar.s8;
    }
  //---
  }
//+------------------------------------------------------------------+
bool CMain::CalcPivotBarTimes(datetime TIME)
  {
  TimeToStruct(TIME,time);
  time.hour=StartHour;
  time.min=0;
  time.sec=0;

  if(workMode==DAILY)
    {
    pivotBar.timeCurPeriodStart=StructToTime(time);
    pivotBar.timeCurPeriodEnd=pivotBar.timeCurPeriodStart+86400;
    if(TimeCurrent()<pivotBar.timeCurPeriodStart)
      {
      pivotBar.timeCurPeriodStart-=86400;
      pivotBar.timeCurPeriodEnd=pivotBar.timeCurPeriodStart+86400;
      if(time.day_of_week==1)pivotBar.timeCurPeriodEnd+=86400;
      }
    pivotBar.timeCurPeriodEnd--;

    if(time.day_of_week!=1) pivotBar.timePivotOpen=pivotBar.timeCurPeriodStart-86400;
    else //MONDAY // CALC FRIDAY WITHOUT HOUR SHIFT
      {
      time.hour=0;
      datetime timeDayBegin=StructToTime(time);
      pivotBar.timePivotOpen=timeDayBegin-(86400*3);
      }
    pivotBar.timePivotClose=pivotBar.timePivotOpen+86399;
    }
  else if(workMode==WEEKLY)
    {
    pivotBar.timeCurPeriodStart=StructToTime(time)-(time.day_of_week*86400);
    pivotBar.timeCurPeriodEnd=pivotBar.timeCurPeriodStart+(7*86400);

    pivotBar.timePivotOpen=pivotBar.timeCurPeriodStart-(7*86400);
    pivotBar.timePivotClose=pivotBar.timePivotOpen+(7*86400)-1;
    }
  else if(workMode==MONTHLY)
    {
    pivotBar.timeCurPeriodStart=StructToTime(time)-(time.day*86400);
    int nDaysInMonth=GetDaysInMonth(TIME);
    pivotBar.timeCurPeriodEnd=pivotBar.timeCurPeriodStart+(nDaysInMonth*86400);
    
    int nDaysInPreMonth=GetDaysInMonth(pivotBar.timeCurPeriodStart-86400);
    pivotBar.timePivotOpen=pivotBar.timeCurPeriodStart-(nDaysInPreMonth*86400);
    pivotBar.timePivotClose=pivotBar.timePivotOpen+(nDaysInPreMonth*86400)-1;
    }
  return true;
  }
//+------------------------------------------------------------------+
bool CMain::CalcPivotBarHLC(int I,SPivotBar &PIVOT_BAR)
  {
  PIVOT_BAR.timePivotRealOpen=0;
  PIVOT_BAR.timePivotRealClose=0;

  for(int i=I,total=Bars; i<total; i++)
    {
    if(Time[i]<PIVOT_BAR.timePivotOpen) break;
    if(Time[i]>PIVOT_BAR.timePivotClose) continue;

    if(PIVOT_BAR.timePivotRealClose==0)
      {
      PIVOT_BAR.high=High[i];
      PIVOT_BAR.timeHigh=Time[i];
      PIVOT_BAR.low=Low[i];
      PIVOT_BAR.timeLow=Time[i];

      PIVOT_BAR.close=Close[i];
      PIVOT_BAR.timePivotRealClose=Time[i];
      }

    PIVOT_BAR.timePivotRealOpen=Time[i];
    if(NormalizeDouble(High[i]-PIVOT_BAR.high,_Digits)>0)
      {
      PIVOT_BAR.high=High[i];
      PIVOT_BAR.timeHigh=Time[i];
      }
    if(NormalizeDouble(PIVOT_BAR.low-Low[i],_Digits)>0)
      {
      PIVOT_BAR.low=Low[i];
      PIVOT_BAR.timeLow=Time[i];
      }
    }
  return true;
  }
//+------------------------------------------------------------------+
bool CMain::CalcPivotsLevels(SPivotBar &PIVOT_BAR)
  {
  double range = (PIVOT_BAR.high-pivotBar.low);
  double P  =  (PIVOT_BAR.high+PIVOT_BAR.low+PIVOT_BAR.close)/3;

  PIVOT_BAR.r8 = P + (range * 1.618);
  PIVOT_BAR.r7 = P + (range * 1.382);
  PIVOT_BAR.r6 = P + (range * 1.236);
  PIVOT_BAR.r5 = P + (range * 0.764);
  PIVOT_BAR.r4 = P + (range * 0.5);
  PIVOT_BAR.r3 = P + (range * 0.618);
  PIVOT_BAR.r2 = P + (range * 0.382);
  PIVOT_BAR.r1 = P + (range * 0.236);

  PIVOT_BAR.p = P;

  PIVOT_BAR.s1 = P - (range * 0.236);
  PIVOT_BAR.s2 = P - (range * 0.382);
  PIVOT_BAR.s3 = P - (range * 0.618);
  PIVOT_BAR.s4 = P - (range * 0.5);
  PIVOT_BAR.s5 = P - (range * 0.764);
  PIVOT_BAR.s6 = P - (range * 1.236);
  PIVOT_BAR.s7 = P - (range * 1.382);
  PIVOT_BAR.s8 = P - (range * 1.618);

  return true;
  }
//+------------------------------------------------------------------+

 
Please explain your question in detail!
 

First you need to update the pivot bar structure like this , you are declaring an open and a timeOpen :

    struct SPivotBar
      {
      datetime timeCurPeriodStart;
      datetime timeCurPeriodEnd;

      datetime timePivotOpen;
      datetime timePivotRealOpen;
      datetime timePivotClose;
      
      double open;
      datetime timeOpen;
      double high;
      datetime timeHigh;
      double low;
      datetime timeLow;
      double close;
      datetime timePivotRealClose;

      double r8,r7,r6,r5,r4,r3,r2,r1;
      double p;
      double s1,s2,s3,s4,s5,s6,s7,s8;
      };

Then you just go to the bar calculation (the "real" calculation , and since you are looping from the present toward the past you can safely update the open price at every "valid" bar.
(you have grabbed the close once at first so you are set there)

bool CMain::CalcPivotBarHLC(int I,SPivotBar &PIVOT_BAR)
  {
  PIVOT_BAR.timePivotRealOpen=0;
  PIVOT_BAR.timePivotRealClose=0;

  for(int i=I,total=Bars; i<total; i++)
    {
    if(Time[i]<PIVOT_BAR.timePivotOpen) break;
    if(Time[i]>PIVOT_BAR.timePivotClose) continue;

    if(PIVOT_BAR.timePivotRealClose==0)
      {
      PIVOT_BAR.high=High[i];
      PIVOT_BAR.timeHigh=Time[i];
      PIVOT_BAR.low=Low[i];
      PIVOT_BAR.timeLow=Time[i];

      PIVOT_BAR.close=Close[i];
      PIVOT_BAR.timePivotRealClose=Time[i];
      }

    PIVOT_BAR.timePivotRealOpen=Time[i];
    //keep updating the open + open time since you are going into the past
      PIVOT_BAR.open=Open[i];
      PIVOT_BAR.timeOpen=Time[i];
    if(NormalizeDouble(High[i]-PIVOT_BAR.high,_Digits)>0)
      {
      PIVOT_BAR.high=High[i];
      PIVOT_BAR.timeHigh=Time[i];
      }
    if(NormalizeDouble(PIVOT_BAR.low-Low[i],_Digits)>0)
      {
      PIVOT_BAR.low=Low[i];
      PIVOT_BAR.timeLow=Time[i];
      }
    }
  return true;
  }

then the to_string function needs to output the open and open time as well :

string CMain::ToString(void)
  {
  return StringConcatenate("\n===LEVELS ",EnumToString(workMode),"=== | StartHour",StartHour," | timeGetLevels_",timeGetLevels,
                           "\nCUR ",pivotBar.timeCurPeriodStart," - ",pivotBar.timeCurPeriodEnd," | P_",DoubleToString(pivotBar.p,_Digits),
                           "\ntimePivotOpen",pivotBar.timePivotOpen,
                           " | open_",DoubleToString(pivotBar.open,_Digits)," at_",pivotBar.timeOpen,
                           " | high_",DoubleToString(pivotBar.high,_Digits)," at_",pivotBar.timeHigh,
                           " | low_",DoubleToString(pivotBar.low,_Digits)," at_",pivotBar.timeLow,
                           " | close_",DoubleToString(pivotBar.close,_Digits)," at_",pivotBar.timePivotRealClose);
  }

and lastly the P calculation , i did not find any reference to pivot points with the open price but the open is now available in the pivot bar if you need it in the formula.

  double P  =  (PIVOT_BAR.high+PIVOT_BAR.low+PIVOT_BAR.close)/3;
  //you can now call the open price here in the formula , delete the following if its not what you want
    P=(PIVOT_BAR.open+PIVOT_BAR.high+PIVOT_BAR.low+PIVOT_BAR.close)/4;

That's all i think

Reason: