//+------------------------------------------------------------------+
//|                                                 pivot points.mq4 |
//|                                                           mladen |
//+------------------------------------------------------------------+
#property copyright "mladen"
#property link      "mladenfx@gmail.com"

#property indicator_chart_window
#property indicator_buffers 7
#property indicator_color1 DimGray
#property indicator_color2 SteelBlue
#property indicator_color3 RosyBrown
#property indicator_color4 SteelBlue
#property indicator_color5 RosyBrown
#property indicator_color6 SteelBlue
#property indicator_color7 RosyBrown
#property indicator_style1 STYLE_DOT
#property indicator_style2 STYLE_DOT
#property indicator_style3 STYLE_DOT
#property indicator_style4 STYLE_DOT
#property indicator_style5 STYLE_DOT
#property indicator_style6 STYLE_DOT
#property indicator_style7 STYLE_DOT

//
//
//
//
//

extern string PivotIdentifier       = "pivot1";
extern string TimeFrame             = "D1";
extern int    HourShift             = 0;
extern bool   FixSundays            = true;
extern bool   HideConnections       = true;
extern bool   ShowLabels            = false;
extern bool   ShowPrices            = false;
extern color  LabelsColor           = DimGray;
extern int    LabelsFontSize        =  10;
extern int    LabelsShiftHorizontal = -10;
extern int    LabelsShiftVertical   =   1;


//
//
//
//
//

double PBuffer[];
double S1Buffer[];
double R1Buffer[];
double S2Buffer[];
double R2Buffer[];
double S3Buffer[];
double R3Buffer[];

//
//
//
//
//

string labels[7] = {"pivot" ,"S1","R1","S2","R2","S3","R3"};
int    timeFrame;
int    lookupTimeFrame;
string Description;


//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+

int init()
{
   lookupTimeFrame = PERIOD_H1;
   timeFrame       = stringToTimeFrame(TimeFrame);
            if (timeFrame<PERIOD_D1)
            {
               HourShift=0;
               lookupTimeFrame = timeFrame;
            }         
            if (timeFrame==PERIOD_W1)
            {
               if (HourShift<0) HourShift -= 24;
               if (HourShift>0) HourShift += 24;
            }
   
   //
   //
   //
   //
   //
   
      SetIndexBuffer(0,PBuffer);  SetIndexLabel(0,Description+labels[0]);
      SetIndexBuffer(1,S1Buffer); SetIndexLabel(1,Description+labels[1]);
      SetIndexBuffer(2,R1Buffer); SetIndexLabel(2,Description+labels[2]);
      SetIndexBuffer(3,S2Buffer); SetIndexLabel(3,Description+labels[3]);
      SetIndexBuffer(4,R2Buffer); SetIndexLabel(4,Description+labels[4]);
      SetIndexBuffer(5,S3Buffer); SetIndexLabel(5,Description+labels[5]);
      SetIndexBuffer(6,R3Buffer); SetIndexLabel(6,Description+labels[6]);
   return(0);
}

int deinit()
{
   for (int i = 7; i>0; i--) ObjectDelete(StringConcatenate(PivotIdentifier,"-",i));
   return(0);
}


//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//
//
//
//

int start()
{
   int counted_bars=IndicatorCounted();
   int i,limit;

   if (Period() >= timeFrame) return(-1);
   if (counted_bars<0) return(-1);
   if (counted_bars>0) counted_bars--;
      limit = MathMin(Bars-counted_bars,Bars-1);

   //
   //
   //
   //
   //

   double P =  PBuffer[limit+1];
   double S1 = S1Buffer[limit+1];
   double R1 = R1Buffer[limit+1];
   double S2 = S2Buffer[limit+1];
   double R2 = R2Buffer[limit+1];
   double S3 = S3Buffer[limit+1];
   double R3 = R3Buffer[limit+1];
   
   for (i=limit; i>=0; i--)
   {
      int x = iBarShift(NULL,timeFrame,Time[i+1]-HourShift*3600,true);
      int y = iBarShift(NULL,timeFrame,Time[i]  -HourShift*3600,true);
      if (x!=y)
      {
         int k = i;
         if (FixSundays && timeFrame==PERIOD_D1)
         {
            while (k<Bars && TimeDayOfWeek(Time[k+1]-HourShift*3600)==0) k++;
         }
         int z = iBarShift(NULL,lookupTimeFrame,Time[k+1]-timeFrame*60-HourShift*3600);
             x = iBarShift(NULL,lookupTimeFrame,Time[k+1]             -HourShift*3600);
               
             //
             //
             //
             //
             //

             double LastHigh  = iHigh (NULL,lookupTimeFrame,iHighest(NULL,lookupTimeFrame,MODE_HIGH,z-x,x));
             double LastLow   = iLow  (NULL,lookupTimeFrame,iLowest( NULL,lookupTimeFrame,MODE_LOW ,z-x,x));
             double LastClose = Close[k+1];
               
             //
             //
             //
             //
             //
               
             P  = (LastHigh+LastLow+LastClose)/3;
             R1 = (2*P)-LastLow;
             S1 = (2*P)-LastHigh;
             R2 = P+(LastHigh - LastLow);
             S2 = P-(LastHigh - LastLow);
             R3 = (2*P)+(LastHigh-(2*LastLow));
             S3 = (2*P)-((2* LastHigh)-LastLow); 
      }
                  
      //
      //
      //
      //
      //
         
      PBuffer[i] =P;
      S1Buffer[i]=S1;
      R1Buffer[i]=R1;
      S2Buffer[i]=S2;
      R2Buffer[i]=R2;
      S3Buffer[i]=S3;
      R3Buffer[i]=R3;
   }
   if (ShowLabels || ShowPrices) DisplayLabels();
   if (HideConnections) DoHideConnections(limit);
   return(0);
}




//+------------------------------------------------------------------+
//|
//+------------------------------------------------------------------+
//
//
//
//
//

int barTime(int a)
{
   if(a<0)
         return(Time[0]+Period()*60*MathAbs(a));
   else  return(Time[a]);   
}

//
//
//
//
//

void DisplayLabels()
{
   ShowLabel(1,PBuffer ,Description+labels[0]);
   ShowLabel(2,S1Buffer,Description+labels[1]);
   ShowLabel(3,R1Buffer,Description+labels[2]);
   ShowLabel(4,S2Buffer,Description+labels[3]);
   ShowLabel(5,R2Buffer,Description+labels[4]);
   ShowLabel(6,S3Buffer,Description+labels[5]);
   ShowLabel(7,R3Buffer,Description+labels[6]);
}
void ShowLabel(string ID, double& forLine[],string label)
{
   string finalLabel = "";
   
   if (ShowLabels) finalLabel = label;
   if (ShowPrices) finalLabel = finalLabel+" "+DoubleToStr(forLine[0],Digits);
         SetLabel(ID,forLine[0],finalLabel);
}

//
//
//
//
//

void SetLabel(string ID,double forLine,string label)
{
   datetime theTime = barTime(LabelsShiftHorizontal);
   string   name    = PivotIdentifier+"-"+ID;
   
   if(ObjectFind(name)==-1) {
      ObjectCreate(name,OBJ_TEXT,0,0,0);
      ObjectSetText(name,label,LabelsFontSize,"Arial",LabelsColor); }
      ObjectMove(name,0,theTime,forLine+LabelsShiftVertical*Point);
   
}

//+------------------------------------------------------------------+
//|
//+------------------------------------------------------------------+
//
//
//
//
//

void DoHideConnections(int limit)
{
   
   for (int i=limit;i>=0;i--)
   {
      if (PBuffer[i]  != PBuffer[i+1])  HideIt(i,PBuffer);
      if (R1Buffer[i] != R1Buffer[i+1]) HideIt(i,R1Buffer);
      if (S1Buffer[i] != S1Buffer[i+1]) HideIt(i,S1Buffer);
      if (R2Buffer[i] != R2Buffer[i+1]) HideIt(i,R2Buffer);
      if (S2Buffer[i] != S2Buffer[i+1]) HideIt(i,S2Buffer);
      if (R3Buffer[i] != R3Buffer[i+1]) HideIt(i,R3Buffer);
      if (S3Buffer[i] != S3Buffer[i+1]) HideIt(i,S3Buffer);
   }
}

void HideIt(int i, double& from[])
{
   if ((from[i] != EMPTY_VALUE) && (from[i+1] != EMPTY_VALUE))
        from[i+1] = EMPTY_VALUE;  
}

//+------------------------------------------------------------------+
//|
//+------------------------------------------------------------------+
//
//
//
//
//

int stringToTimeFrame(string tfs)
{
   int tf=0;
       tfs = StringUpperCase(tfs);
         if (tfs=="M1" || tfs=="1")     { tf=PERIOD_M1;  Description = "";}
         if (tfs=="M5" || tfs=="5")     { tf=PERIOD_M5;  Description = "5 minutes "; }
         if (tfs=="M15"|| tfs=="15")    { tf=PERIOD_M15; Description = "15 minutes ";}
         if (tfs=="M30"|| tfs=="30")    { tf=PERIOD_M30; Description = "half hour "; }
         if (tfs=="H1" || tfs=="60")    { tf=PERIOD_H1;  Description = "hourly ";    }
         if (tfs=="H4" || tfs=="240")   { tf=PERIOD_H4;  Description = "4 hourly ";  }
         if (tfs=="D1" || tfs=="1440")  { tf=PERIOD_D1;  Description = "daily ";     }
         if (tfs=="W1" || tfs=="10080") { tf=PERIOD_W1;  Description = "weekly ";    }
         if (tfs=="MN" || tfs=="43200") { tf=PERIOD_MN1; Description = "monthly ";   }
  return(tf);
}

//
//
//
//
//

string StringUpperCase(string str)
{
   string   s = str;
   int      length = StringLen(str) - 1;
   int      char;
   
   while(length >= 0)
      {
         char = StringGetChar(s, length);
         
         //
         //
         //
         //
         //
         
         if((char > 96 && char < 123) || (char > 223 && char < 256))
                  s = StringSetChar(s, length, char - 32);
         else 
              if(char > -33 && char < 0)
                  s = StringSetChar(s, length, char + 224);
         length--;
   }
   return(s);
}