//+------------------------------------------------------------------+
//|                                                  DataMonthly.mq4 |
//+------------------------------------------------------------------+

#property indicator_chart_window
#property indicator_buffers 4
#property indicator_color1  Gold
#property indicator_color2  Maroon
#property indicator_color3  Gold
#property indicator_color4  Red
#property indicator_width1  1
#property indicator_width2  1
#property indicator_width3  4
#property indicator_width4  4

//
//

extern bool  ShowBar             = True;
extern int   CandleShift         = 20;

extern bool  ShowInfo            = False;
extern color zoneColor           = C'30,33,36';
extern int   InfoAreaYShift      = 70;
extern bool  ShowBackground      = False;
extern int   BarsToCalculateAvg  = 10;

extern bool  ShowPivotsLines     = True;
extern bool  ShowPivotsValues    = False;       // problem with placement
extern int   PivotsValuesYShift  = 10;          // manual addjustment of PP values placement

extern int   PivotsLineStyle  = STYLE_SOLID; //0-4: STYLE_SOLID,STYLE_DASH,STYLE_DOT,STYLE_DASHDOT,STYLE_DASHDOTDOT

//
//

double MonthHigh[];
double MonthLow[];
double MonthOpen[];
double MonthClose[];

double prevCurr =-1;
//
int    DataBar_MN;

string indNames = "DataMonthly";

//---------------------------------
double M_day_high=0;
double M_day_low=0;
double M_yesterday_high=0;
double M_yesterday_open=0;
double M_yesterday_low=0;
double M_yesterday_close=0;
double M_today_open=0;
double M_today_high=0;
double M_today_low=0;
double M_P=0;
double M_Q=0;
double M_R1,M_R2,M_R3;
double M_S1,M_S2,M_S3;
double M_nQ=0;
double M_nD=0;
double M_D=0;
double M_rates_d1[2][6];
double M_ExtMapBuffer[];

double AvgBarsRange;
double CloseToHigh;
double CloseToLow;

double   decPoint;

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+

int init()
{
   SetIndexBuffer(0, MonthHigh);
   SetIndexBuffer(1, MonthLow);
   SetIndexBuffer(2, MonthClose);
   SetIndexBuffer(3, MonthOpen);
      if (ShowBar)
         for (int i=0;i<4;i++)
            {
               SetIndexStyle(i,DRAW_HISTOGRAM);
               SetIndexShift(i,CandleShift);
               SetIndexLabel(i,"Monthly data");
            }            
      else  for (i=0;i<4;i++) SetIndexStyle(i,DRAW_NONE);
   
   if (Point == 0.00001) decPoint = 0.0001; //6 digits
   else if (Point == 0.001) decPoint = 0.01; //3 digits (for Yen based pairs)
   else decPoint = Point; //Normal 
               
   prevCurr = -1;
   
   //---- S&R pivot values
   M_R1=0; M_R2=0; M_R3=0;
   M_S1=0; M_S2=0; M_S3=0;
   //----
   AvgBarsRange = 0;
   CloseToHigh  = 0;
   CloseToLow   = 0;
   
   return(0);
}

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+

int deinit()
{
   for (int counter=-1;counter<21;counter++) ObjectDelete(indNames+counter);
   
   ObjectDelete("M_R1 Label");
   ObjectDelete("M_R1 Value");
   ObjectDelete("M_R1 Line");
   ObjectDelete("M_R2 Label");
   ObjectDelete("M_R2 Value");
   ObjectDelete("M_R2 Line");
   ObjectDelete("M_R3 Label");
   ObjectDelete("M_R3 Value");
   ObjectDelete("M_R3 Line");
   ObjectDelete("M_S1 Label");
   ObjectDelete("M_S1 Value");
   ObjectDelete("M_S1 Line");
   ObjectDelete("M_S2 Label");
   ObjectDelete("M_S2 Value");
   ObjectDelete("M_S2 Line");
   ObjectDelete("M_S3 Label");
   ObjectDelete("M_S3 Value");
   ObjectDelete("M_S3 Line");
   ObjectDelete("M_P Label");
   ObjectDelete("M_P Value");
   ObjectDelete("M_P Line");
   
   return(0);
}


//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+

int start()
{
   int    digits   = MarketInfo(Symbol(),MODE_DIGITS);
   double modifier = 1;
   
      if (digits==3 || digits==5) modifier = 10.0;
      else 
            if (ObjectFind(indNames+"21") != -1)
                ObjectDelete(indNames+"21");
      
      //
      //
            
      DataBar_MN  = iBarShift(NULL,PERIOD_MN1,Time[0]);
         double HiMONTHLY = iHigh (NULL,PERIOD_MN1,DataBar_MN);
         double LoMONTHLY = iLow  (NULL,PERIOD_MN1,DataBar_MN); 
         double current   = iClose(NULL,PERIOD_MN1,DataBar_MN);
         double range     = getRange(PERIOD_MN1,0)/modifier;
         double change    = (current-iOpen(NULL,PERIOD_MN1,DataBar_MN))/(Point*modifier);
         int    limit,i;

      if (ShowInfo)
      {
          if (ObjectFind(indNames+"1") ==-1) 
          {
            objectCreate("1",70,InfoAreaYShift,"Monthly",10);  
            objectCreate("2",10,InfoAreaYShift+10,"--------------------------------------",10,NULL);  
            objectCreate("3",35,InfoAreaYShift+32,"distance from high : ");
            objectCreate("4",35,InfoAreaYShift+44,"distance from low : " );
            objectCreate("5",10,InfoAreaYShift+56,"--------------------------------------",10,NULL);
            objectCreate("6",35,InfoAreaYShift+20,"range : "       );
            objectCreate("7",35,InfoAreaYShift+64,"distance from open : ");
            objectCreate("8",10,InfoAreaYShift+76,"--------------------------------------",10,NULL);
            objectCreate("9",35,InfoAreaYShift+88,"avg. " + BarsToCalculateAvg + " bar(s) range : ");
            objectCreate("10",35,InfoAreaYShift+100,"avg. " + BarsToCalculateAvg + " bar(s) C/H : ");
            objectCreate("11",35,InfoAreaYShift+112,"avg. " + BarsToCalculateAvg + " bar(s) C/L : ");
            objectCreate("12",10,InfoAreaYShift+124,"--------------------------------------",10,NULL);
         }

         if (prevCurr != current)
            {
               prevCurr = current;

                  double currFromHi = (HiMONTHLY-current)/(Point*modifier);
                  double currFromLo = (current-LoMONTHLY)/(Point*modifier);

                  objectCreate("13",10,InfoAreaYShift+20,DoubleToStr(range,0)     ,10,"Arial bold",Gold);
                  
                  objectCreate("14",10,InfoAreaYShift+32,DoubleToStr(currFromHi,0),10,"Arial bold",YellowGreen);
                  objectCreate("15",10,InfoAreaYShift+44,DoubleToStr(currFromLo,0),10,"Arial bold",YellowGreen);
                  
                  if (change<0)
                        objectCreate("16",10,InfoAreaYShift+64,DoubleToStr(change,0),10,"Arial bold",Red);
                  else  objectCreate("16",10,InfoAreaYShift+64,DoubleToStr(change,0),10,"Arial bold",Gold);
                  
                  string currentValue = DoubleToStr(current,digits);                  
                  
                  if (modifier !=1)
                     objectCreate("17",10, InfoAreaYShift+0,StringSubstr(currentValue,StringLen(currentValue)-1),12,"Arial bold",Gold);
                  
                  AvgBarsRange = CalculateAVG(BarsToCalculateAvg);
                  CloseToHigh  = CalculateAVGCloseToHigh(BarsToCalculateAvg);
                  CloseToLow   = CalculateAVGCloseToLow(BarsToCalculateAvg);
                  
                  objectCreate("18",10,InfoAreaYShift+88,DoubleToStr(AvgBarsRange,0) ,10,"Arial bold",Gold);
                  objectCreate("19",10,InfoAreaYShift+100,DoubleToStr(CloseToHigh,0) ,10,"Arial bold",Gold);
                  objectCreate("20",10,InfoAreaYShift+112,DoubleToStr(CloseToLow,0) ,10,"Arial bold",Gold);
            }   
      }           
      
      setBarIndicator(change,HiMONTHLY,LoMONTHLY,iOpen(NULL,PERIOD_MN1,DataBar_MN),current);
      
      for(i=0,limit=Bars-1;i<4;i++) SetIndexDrawBegin(i,limit);
      
// PIVOT Point calculation
      ArrayCopyRates(M_rates_d1, Symbol(), 43200);

      M_yesterday_close = M_rates_d1[1][4];
      M_yesterday_open = M_rates_d1[1][1];
      M_today_open = M_rates_d1[0][1];
      M_yesterday_high = M_rates_d1[1][3];
      M_yesterday_low = M_rates_d1[1][2];
      M_day_high = M_rates_d1[0][3];
      M_day_low = M_rates_d1[0][2];


//---- Calculate Pivots

      M_D = (M_day_high - M_day_low);
      M_Q = (M_yesterday_high - M_yesterday_low);
      M_P = (M_yesterday_high + M_yesterday_low + M_yesterday_close) / 3;
      M_R1 = (2*M_P)-M_yesterday_low;
      M_S1 = (2*M_P)-M_yesterday_high;
      M_R2 = M_P+(M_yesterday_high - M_yesterday_low);
      M_S2 = M_P-(M_yesterday_high - M_yesterday_low);
      M_R3 = (2*M_P)+(M_yesterday_high-(2*M_yesterday_low));
      M_S3 = (2*M_P)-((2* M_yesterday_high)-M_yesterday_low);

      if (M_Q > 5)
      {
         M_nQ = M_Q;
      }
      else
      {
         M_nQ = M_Q*10000;
      }
      
      if (M_D > 5)
      {
         M_nD = M_D;
      }
      else
      {
         M_nD = M_D*10000;
      }

      // DAILY Pivot Lines
      if (ShowPivotsLines==true)
      {
         drawPivotValues("M_S3 value","M_S3 label","M_S3",M_S3,"Arial",8,C'200,200,200',PivotsValuesYShift);
         drawPivotValues("M_S2 value","M_S2 label","M_S2",M_S2,"Arial",8,C'200,200,200',PivotsValuesYShift);
         drawPivotValues("M_S1 value","M_S1 label","M_S1",M_S1,"Arial",8,C'200,200,200',PivotsValuesYShift);
         drawPivotValues("M_P value","M_P label","M_P",M_P,"Arial",8,Khaki,PivotsValuesYShift);
         drawPivotValues("M_R1 value","M_R1 label","M_R1",M_R1,"Arial",8,C'200,200,200',PivotsValuesYShift);
         drawPivotValues("M_R2 value","M_R2 label","M_R2",M_R2,"Arial",8,C'200,200,200',PivotsValuesYShift);
         drawPivotValues("M_R3 value","M_R3 label","M_R3",M_R3,"Arial",8,C'200,200,200',PivotsValuesYShift);
      //--- Draw Pivot lines on chart
         drawPivotLine("M_S3 line",M_S3,LightGreen,1);
         drawPivotLine("M_S2 line",M_S2,LightGreen,1);
         drawPivotLine("M_S1 line",M_S1,LightGreen,1);
         drawPivotLine("M_P line",M_P,Khaki,2);
         drawPivotLine("M_R1 line",M_R1,Red,1);
         drawPivotLine("M_R2 line",M_R2,Red,1);
         drawPivotLine("M_R3 line",M_R3,Red,1);
      }
      //---- End of Pivot Line Draw
      
   return(0);
  }

//+------------------------------------------------------------------+
//+------------------------------------------------------------------+  

void drawPivotValues(string objectName, string objectLabel, string objectDescripton, double objectValue, string fontName, int fontSize, color textColor, int object_Y_shift)
{
   int digitsPoints = Digits; // display 4 digits for nonJPY and 2 digidts for JPY crosses
   int index = StringFind(Symbol(),"JPY",0);

// prevent from plasing labels to close to PivotLines if using 5-digits broker
   if (index > 0)
   {
      if (digitsPoints>2)
         object_Y_shift = object_Y_shift*10;
   }
   else
   {
      if (digitsPoints>4)
         object_Y_shift = object_Y_shift*10;
   }
//+--------------------------------------------------------
   if(ObjectFind(objectName) != 0)
   {
      ObjectCreate(objectLabel, OBJ_TEXT, 0, Time[0]+(CandleShift-4)*Period()*60, objectValue);
      ObjectSetText(objectLabel, objectDescripton, fontSize, fontName, textColor);
   }
   else
   {
      ObjectMove(objectLabel, 0, Time[0]+(CandleShift-4)*Period()*60, objectValue);
   }
   
   if(ShowPivotsValues)
      if(ObjectFind(objectName) != 0)
      {
         ObjectCreate(objectName, OBJ_TEXT, 0, Time[0]+(CandleShift-4)*Period()*60, objectValue+object_Y_shift*Point);
         if (index > 0)
         {
            ObjectSetText(objectName, DoubleToStr(objectValue,2), fontSize, fontName, textColor);
         }
         else
         {
            ObjectSetText(objectName, DoubleToStr(objectValue,4), fontSize, fontName, textColor);
         }
      }
      else
      {
         ObjectMove(objectName, 0, Time[0]+(CandleShift-4)*Period()*60, objectValue+object_Y_shift*Point);
      }
}
//
//
void drawPivotLine(string lineName, double lineValue, color lineColor, int lineWidth)
{
if(ObjectFind(lineName) != 0)
   {
      ObjectCreate(lineName, OBJ_TREND, 0, Time[0]+(CandleShift-7)*Period()*60, lineValue,Time[0]+(CandleShift-1)*Period()*60, lineValue);
      ObjectSet(lineName, OBJPROP_STYLE, PivotsLineStyle);
      ObjectSet(lineName, OBJPROP_WIDTH, lineWidth);
      ObjectSet(lineName, OBJPROP_COLOR, lineColor);
      ObjectSet(lineName, OBJPROP_RAY,   False);
   }
   else
   {
      ObjectMove(lineName, 0,Time[0]+(CandleShift-7)*Period()*60,lineValue);
      ObjectMove(lineName, 1,Time[0]+(CandleShift-1)*Period()*60,lineValue);
   }
}
//
//
void setBarIndicator(double change, double hi,double low, double open, double close)
{
   string name_1  = indNames+"-1";
   int    shift = 0;
   
   if (change>0) { MonthHigh[shift]  = hi;  MonthLow[shift] = low; }            
   else          { MonthHigh[shift]  = low; MonthLow[shift] = hi;  }            
                   MonthOpen[shift]  = open;
                   MonthClose[shift] = close;

   if (ShowBackground)
      {                         
         if (ObjectFind(name_1) == -1)
             ObjectCreate(name_1,OBJ_RECTANGLE,0,0,0);
             ObjectSet(name_1,OBJPROP_TIME1,iTime(NULL,PERIOD_MN1,DataBar_MN));
             ObjectSet(name_1,OBJPROP_TIME2,iTime(NULL,         0,0));
             ObjectSet(name_1,OBJPROP_PRICE1,hi);
             ObjectSet(name_1,OBJPROP_PRICE2,low);
             ObjectSet(name_1,OBJPROP_COLOR,zoneColor);
      }             
}
//
//
double CalculateAVG(int BarsToCount)
{
   int   tempSum = 0;
   int   v;
   
   if (BarsToCount<=0) BarsToCount=1;
   
   for (v=1; v<=BarsToCount; v++)
      tempSum = tempSum + getRange(PERIOD_W1,v);
   
   tempSum = tempSum/BarsToCount;

   return (NormalizeDouble(tempSum,0));
}
//
//
double CalculateAVGCloseToHigh(int BarsToCount)
{
   int    tempSum = 0;
   double tmpCloseToHigh = 0;
   int    v;
   
   if (BarsToCount<=0) BarsToCount=1;
   
   for (v=1; v<=BarsToCount; v++)
   {
      tmpCloseToHigh = ( iHigh(NULL, PERIOD_MN1, v) - iClose(NULL, PERIOD_MN1, v) )/decPoint;
      tempSum = tempSum + tmpCloseToHigh;
   }
   tempSum = tempSum/BarsToCount;

   return (NormalizeDouble(tempSum,0));
}
//
//
double CalculateAVGCloseToLow(int BarsToCount)
{
   int    tempSum = 0;
   double tmpCloseToLow = 0;
   int    v;
   
   if (BarsToCount<=0) BarsToCount=1;
   
   for (v=1; v<=BarsToCount; v++)
   {
      tmpCloseToLow = ( iClose(NULL, PERIOD_MN1, v) - iLow(NULL, PERIOD_MN1, v) )/decPoint;
      tempSum = tempSum + tmpCloseToLow;
   }
   
   tempSum = tempSum/BarsToCount;

   return (NormalizeDouble(tempSum,0));
}
//
//
double getRange(int period, int barIdx)
{
   double   range;

      range = iHigh(NULL, period, barIdx) - iLow(NULL, period, barIdx);
      return (NormalizeDouble(range/decPoint,0));
}
//
//
void objectCreate(string name,int x,int y,string text="-",int size=10,
                  string font="Arial",color colour=C'200,200,200',int window = 0)
{
   if (ObjectFind(indNames+name) == -1)
   {
      ObjectCreate(indNames+name,OBJ_LABEL,window,0,0);
         ObjectSet(indNames+name,OBJPROP_CORNER,1);
         ObjectSet(indNames+name,OBJPROP_XDISTANCE,x);
         ObjectSet(indNames+name,OBJPROP_YDISTANCE,y);
   }               
   ObjectSetText(indNames+name,text,size,font,colour);
}