//+------------------------------------------------------------------+
//|                                  GI_Qrtly Cam + Pivot_BT.mq5    |
//|                        Copyright 2022, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2022, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.01"
#property strict

#property indicator_chart_window
#property indicator_buffers 20
#property indicator_plots   20

#property indicator_label1  "QP"
#property indicator_label2  "QS1"
#property indicator_label3  "QR1"
#property indicator_label4  "QS2"
#property indicator_label5  "QR2"
#property indicator_label6  "QS3"
#property indicator_label7  "QR3"
#property indicator_label8  "QMid"
#property indicator_label9  "QRovr"
#property indicator_label10 "QL3"
#property indicator_label11 "QH3"
#property indicator_label12 "QL4"
#property indicator_label13 "QH4"
#property indicator_label14 "QL5"
#property indicator_label15 "QH5"
#property indicator_label16 "LQLow"
#property indicator_label17 "LQHigh"
#property indicator_label18 "QOpen"
#property indicator_label19 "buf19"
#property indicator_label20 "buf20"

#property indicator_color1  White
#property indicator_color2  Blue
#property indicator_color3  Orange
#property indicator_color4  Red
#property indicator_color5  Aqua
#property indicator_color6  Yellow
#property indicator_color7  White
#property indicator_color8  White
#property indicator_color9  Yellow
#property indicator_color10 Orange
#property indicator_color11 Aqua
#property indicator_color12 Yellow
#property indicator_color13 Orange
#property indicator_color14 Yellow
#property indicator_color15 Lime
#property indicator_color16 Crimson
#property indicator_color17 Lime
#property indicator_color18 White
#property indicator_color19 clrNONE
#property indicator_color20 clrNONE

#property indicator_type1   DRAW_LINE
#property indicator_type2   DRAW_LINE
#property indicator_type3   DRAW_LINE
#property indicator_type4   DRAW_LINE
#property indicator_type5   DRAW_LINE
#property indicator_type6   DRAW_LINE
#property indicator_type7   DRAW_LINE
#property indicator_type8   DRAW_LINE
#property indicator_type9   DRAW_LINE
#property indicator_type10  DRAW_LINE
#property indicator_type11  DRAW_LINE
#property indicator_type12  DRAW_LINE
#property indicator_type13  DRAW_LINE
#property indicator_type14  DRAW_LINE
#property indicator_type15  DRAW_LINE
#property indicator_type16  DRAW_LINE
#property indicator_type17  DRAW_LINE
#property indicator_type18  DRAW_LINE
#property indicator_type19  DRAW_NONE
#property indicator_type20  DRAW_NONE

#property indicator_style1  STYLE_SOLID
#property indicator_style2  STYLE_SOLID
#property indicator_style3  STYLE_SOLID
#property indicator_style4  STYLE_SOLID
#property indicator_style5  STYLE_SOLID
#property indicator_style6  STYLE_SOLID
#property indicator_style7  STYLE_SOLID
#property indicator_style8  STYLE_SOLID
#property indicator_style9  STYLE_SOLID
#property indicator_style10 STYLE_SOLID
#property indicator_style11 STYLE_SOLID
#property indicator_style12 STYLE_SOLID
#property indicator_style13 STYLE_SOLID
#property indicator_style14 STYLE_SOLID
#property indicator_style15 STYLE_SOLID
#property indicator_style16 STYLE_SOLID
#property indicator_style17 STYLE_SOLID
#property indicator_style18 STYLE_SOLID

#property indicator_width1  2
#property indicator_width2  2
#property indicator_width3  2
#property indicator_width4  2
#property indicator_width5  2
#property indicator_width6  2
#property indicator_width7  2
#property indicator_width8  2
#property indicator_width9  2
#property indicator_width10 2
#property indicator_width11 2
#property indicator_width12 2
#property indicator_width13 2
#property indicator_width14 2
#property indicator_width15 2
#property indicator_width16 2
#property indicator_width17 2
#property indicator_width18 2

//---- input parameters
input bool             Display_Qtr_Times    = false;
input int              Distance_from_chart  = 1350;
input string           button_note1         = "------------------------------";
input int              btn_Subwindow        = 0;
input ENUM_BASE_CORNER btn_corner           = CORNER_LEFT_UPPER;
input string           btn_Font             = "Arial";
input int              btn_FontSize         = 10;
input color            btn_text_ON_color    = clrLime;
input color            btn_text_OFF_color   = clrRed;
input string           btn_pressed          = "QCamPiv OFF";
input string           btn_unpressed        = "QCamPiv ON";
input color            btn_background_color = clrDimGray;
input color            btn_border_color     = clrBlack;
input int              button_x             = 40;
input int              button_y             = 150;
input int              btn_Width            = 130;
input int              btn_Height           = 20;
input string           button_note2         = "------------------------------";

int  fontsize    = 9;

//---- buffers
double QPivot[];
double QSupp1[], QRes1[];
double QSupp2[], QRes2[];
double QSupp3[], QRes3[];
double QSupp4[], QRes4[];
double QSupp5[], QRes5[];
double QSupp6[], QRes6[];
double QSupp7[], QRes7[];
double QSupp8[], QRes8[];
double QSupp9[], QRes9[];

string buttonId    = "CamPivotQuarterly_";
bool   showcomment = false;

//+------------------------------------------------------------------+
int OnInit()
  {
   showcomment = Display_Qtr_Times;

   SetIndexBuffer(0,  QPivot, INDICATOR_DATA);
   SetIndexBuffer(1,  QSupp1, INDICATOR_DATA);
   SetIndexBuffer(2,  QRes1,  INDICATOR_DATA);
   SetIndexBuffer(3,  QSupp2, INDICATOR_DATA);
   SetIndexBuffer(4,  QRes2,  INDICATOR_DATA);
   SetIndexBuffer(5,  QSupp3, INDICATOR_DATA);
   SetIndexBuffer(6,  QRes3,  INDICATOR_DATA);
   SetIndexBuffer(7,  QSupp4, INDICATOR_DATA);
   SetIndexBuffer(8,  QRes4,  INDICATOR_DATA);
   SetIndexBuffer(9,  QSupp5, INDICATOR_DATA);
   SetIndexBuffer(10, QRes5,  INDICATOR_DATA);
   SetIndexBuffer(11, QSupp6, INDICATOR_DATA);
   SetIndexBuffer(12, QRes6,  INDICATOR_DATA);
   SetIndexBuffer(13, QSupp7, INDICATOR_DATA);
   SetIndexBuffer(14, QRes7,  INDICATOR_DATA);
   SetIndexBuffer(15, QSupp8, INDICATOR_DATA);
   SetIndexBuffer(16, QRes8,  INDICATOR_DATA);
   SetIndexBuffer(17, QSupp9, INDICATOR_DATA);
   SetIndexBuffer(18, QRes9,  INDICATOR_DATA);

   static double _d1[], _d2[];
   SetIndexBuffer(19, _d1, INDICATOR_CALCULATIONS);
   SetIndexBuffer(20, _d2, INDICATOR_CALCULATIONS);

   ArraySetAsSeries(QPivot, true);
   ArraySetAsSeries(QSupp1, true); ArraySetAsSeries(QRes1, true);
   ArraySetAsSeries(QSupp2, true); ArraySetAsSeries(QRes2, true);
   ArraySetAsSeries(QSupp3, true); ArraySetAsSeries(QRes3, true);
   ArraySetAsSeries(QSupp4, true); ArraySetAsSeries(QRes4, true);
   ArraySetAsSeries(QSupp5, true); ArraySetAsSeries(QRes5, true);
   ArraySetAsSeries(QSupp6, true); ArraySetAsSeries(QRes6, true);
   ArraySetAsSeries(QSupp7, true); ArraySetAsSeries(QRes7, true);
   ArraySetAsSeries(QSupp8, true); ArraySetAsSeries(QRes8, true);
   ArraySetAsSeries(QSupp9, true); ArraySetAsSeries(QRes9, true);

   CreateButton(buttonId, btn_unpressed, btn_Width, btn_Height, btn_Font, btn_FontSize,
                btn_background_color, btn_border_color, btn_text_ON_color);
   ObjectSetInteger(ChartID(), buttonId, OBJPROP_YDISTANCE, button_y);
   ObjectSetInteger(ChartID(), buttonId, OBJPROP_XDISTANCE, button_x);

   return INIT_SUCCEEDED;
  }

//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   string names[] = {
      "QPivot","QSupp1","QRes1","QSupp2","QRes2","QSupp3","QRes3",
      "QSupp4","QRes4","QSupp5","QRes5","QSupp6","QRes6",
      "QSupp7","QRes7","QSupp8","QRes8","QSupp9","QRes9"
   };
   for(int n = 0; n < ArraySize(names); n++) ObjectDelete(0, names[n]);
   ObjectDelete(0, buttonId);
   Comment(" ");
  }

//+------------------------------------------------------------------+
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);
   ArraySetAsSeries(open,  true);
   ArraySetAsSeries(high,  true);
   ArraySetAsSeries(low,   true);
   ArraySetAsSeries(close, true);

   // --- Negyedév nyitó meghatározása ---
   MqlDateTime dtNow;
   datetime    tMN0 = iTime(_Symbol, PERIOD_MN1, 0);
   TimeToStruct(tMN0, dtNow);
   int mi = dtNow.mon;

   int candlestartmonth = 0;
   if(mi >= 1  && mi <= 3)  candlestartmonth = 1;
   else if(mi >= 4  && mi <= 6)  candlestartmonth = 4;
   else if(mi >= 7  && mi <= 9)  candlestartmonth = 7;
   else if(mi >= 10 && mi <= 12) candlestartmonth = 10;

   double QtrOpen = 0;
   string cmtmsg  = "";
   for(int m = 0; m <= 11; m++)
     {
      MqlDateTime dtM;
      datetime    tM = iTime(_Symbol, PERIOD_MN1, m);
      TimeToStruct(tM, dtM);
      if(dtM.mon == candlestartmonth)
        {
         QtrOpen = iOpen(_Symbol, PERIOD_MN1, m);
         cmtmsg  = "Qtr Start time: " + TimeToString(tM) + "\n";
         cmtmsg += "Qtr Open: " + DoubleToString(QtrOpen, _Digits) + "\n\n";
         break;
        }
     }
   if(showcomment) Comment(cmtmsg);

   bool isOn = (ObjectGetString(ChartID(), buttonId, OBJPROP_TEXT) == btn_unpressed);

   int limit = rates_total - prev_calculated;
   if(prev_calculated > 0) limit++;
   if(limit > rates_total) limit = rates_total;

   for(int i = 0; i < limit; i++)
     {
      // --- Melyik negyedévhez tartozik ez a bar ---
      MqlDateTime dtThis;
      TimeToStruct(time[i], dtThis);
      int nMonth   = dtThis.mon;
      int qtrMonth = 0;
      switch(nMonth)
        {
         case 1: case 4: case 7: case 10: qtrMonth = 1; break;
         case 2: case 5: case 8: case 11: qtrMonth = 2; break;
         case 3: case 6: case 9: case 12: qtrMonth = 3; break;
        }

      int MonthlyBar      = iBarShift(_Symbol, PERIOD_MN1, time[i], false) + qtrMonth;
      double lastQtrHigh  = iHigh(_Symbol,  PERIOD_MN1, iHighest(_Symbol, PERIOD_MN1, MODE_HIGH, 3, MonthlyBar));
      double lastQtrLow   = iLow(_Symbol,   PERIOD_MN1, iLowest (_Symbol, PERIOD_MN1, MODE_LOW,  3, MonthlyBar));
      double lastQtrClose = iClose(_Symbol, PERIOD_MN1, MonthlyBar);

      double QP  = (lastQtrHigh + lastQtrLow + lastQtrClose) / 3.0;
      double QS1 = (2*QP) - lastQtrHigh;
      double QR1 = (2*QP) - lastQtrLow;
      double QS2 = QP - (lastQtrHigh - lastQtrLow);
      double QR2 = QP + (lastQtrHigh - lastQtrLow);
      double QS3 = (2*QP) - ((2*lastQtrHigh) - lastQtrLow);
      double QR3 = (2*QP) + (lastQtrHigh - (2*lastQtrLow));
      double QS4 = (lastQtrHigh + lastQtrLow) / 2.0;
      double QR4 = lastQtrClose;
      double QS5 = lastQtrClose - (lastQtrHigh - lastQtrLow)*1.1/4.0;
      double QR5 = lastQtrClose + (lastQtrHigh - lastQtrLow)*1.1/4.0;
      double QS6 = lastQtrClose - (lastQtrHigh - lastQtrLow)*1.1/2.0;
      double QR6 = lastQtrClose + (lastQtrHigh - lastQtrLow)*1.1/2.0;
      double QS7 = lastQtrClose - (lastQtrHigh - lastQtrLow);
      double QR7 = lastQtrClose + (lastQtrHigh - lastQtrLow);
      double QS8 = lastQtrLow;
      double QR8 = lastQtrHigh;

      QPivot[i] = QP;
      QSupp1[i] = QS1; QRes1[i] = QR1;
      QSupp2[i] = QS2; QRes2[i] = QR2;
      QSupp3[i] = QS3; QRes3[i] = QR3;
      QSupp4[i] = QS4; QRes4[i] = QR4;
      QSupp5[i] = QS5; QRes5[i] = QR5;
      QSupp6[i] = QS6; QRes6[i] = QR6;
      QSupp7[i] = QS7; QRes7[i] = QR7;
      QSupp8[i] = QS8; QRes8[i] = QR8;

      // Feliratokat csak az aktuális (i==0) baron frissítjük
      if(i == 0 && isOn)
        {
         datetime labelTime = GetLabelTime();

         string  names[] = {"QPivot","QSupp1","QRes1","QSupp2","QRes2","QSupp3","QRes3",
                            "QSupp4","QRes4","QSupp5","QRes5","QSupp6","QRes6",
                            "QSupp7","QRes7","QSupp8","QRes8"};
         double  vals[]  = {QP, QS1, QR1, QS2, QR2, QS3, QR3, QS4, QR4, QS5, QR5, QS6, QR6, QS7, QR7, QS8, QR8};
         color   clrs[]  = {White,Blue,Orange,Red,Aqua,Yellow,White,White,Yellow,Orange,Aqua,Yellow,Orange,Yellow,Lime,Crimson,Lime};
         string  txts[]  = {
            " QP:"      +DoubleToString(QP, _Digits),
            " QS1:"     +DoubleToString(QS1,_Digits),
            " QR1:"     +DoubleToString(QR1,_Digits),
            " QS2:"     +DoubleToString(QS2,_Digits),
            " QR2:"     +DoubleToString(QR2,_Digits),
            " QS3:"     +DoubleToString(QS3,_Digits),
            " QR3:"     +DoubleToString(QR3,_Digits),
            " QMid:"    +DoubleToString(QS4,_Digits),
            " QRovr:"   +DoubleToString(QR4,_Digits),
            " QL3:"     +DoubleToString(QS5,_Digits),
            " QH3:"     +DoubleToString(QR5,_Digits),
            "QL4:"      +DoubleToString(QS6,_Digits),
            " QH4:"     +DoubleToString(QR6,_Digits),
            " QL5:"     +DoubleToString(QS7,_Digits),
            " QH5:"     +DoubleToString(QR7,_Digits),
            " LQ Low:"  +DoubleToString(QS8,_Digits),
            " LQ High:" +DoubleToString(QR8,_Digits)
         };

         for(int n = 0; n < ArraySize(names); n++)
           {
            if(ObjectFind(0, names[n]) < 0)
              {
               ObjectCreate(0, names[n], OBJ_TEXT, 0, labelTime, vals[n]);
               ObjectSetInteger(0, names[n], OBJPROP_ANCHOR,     ANCHOR_LEFT);
               ObjectSetString(0,  names[n], OBJPROP_FONT,       "Arial");
               ObjectSetInteger(0, names[n], OBJPROP_FONTSIZE,   fontsize);
               ObjectSetInteger(0, names[n], OBJPROP_SELECTABLE, false);
               ObjectSetInteger(0, names[n], OBJPROP_HIDDEN,     false);
              }
            ObjectSetInteger(0, names[n], OBJPROP_TIME,  labelTime);
            ObjectSetDouble(0,  names[n], OBJPROP_PRICE, vals[n]);
            ObjectSetString(0,  names[n], OBJPROP_TEXT,  txts[n]);
            ObjectSetInteger(0, names[n], OBJPROP_COLOR, clrs[n]);
           }
        }
     }

   ChartRedraw(0);
   return rates_total;
  }

//+------------------------------------------------------------------+
datetime GetLabelTime()
  {
   int firstBar    = (int)ChartGetInteger(0, CHART_FIRST_VISIBLE_BAR);
   int visibleBars = (int)ChartGetInteger(0, CHART_VISIBLE_BARS);
   int labelBar    = MathMax(0, firstBar - visibleBars + 3);
   datetime t[];
   ArraySetAsSeries(t, true);
   if(CopyTime(_Symbol, _Period, labelBar, 1, t) > 0)
      return t[0];
   return TimeCurrent();
  }

//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long   &lparam,
                  const double &dparam,
                  const string &sparam)
  {
   if(id == CHARTEVENT_CHART_CHANGE)
     {
      bool isOn = (ObjectGetString(ChartID(), buttonId, OBJPROP_TEXT) == btn_unpressed);
      if(isOn)
        {
         datetime labelTime = GetLabelTime();
         string names[] = {"QPivot","QSupp1","QRes1","QSupp2","QRes2","QSupp3","QRes3",
                           "QSupp4","QRes4","QSupp5","QRes5","QSupp6","QRes6",
                           "QSupp7","QRes7","QSupp8","QRes8"};
         for(int n = 0; n < ArraySize(names); n++)
            if(ObjectFind(0, names[n]) >= 0)
               ObjectSetInteger(0, names[n], OBJPROP_TIME, labelTime);
         ChartRedraw(0);
        }
     }

   if(id == CHARTEVENT_OBJECT_CLICK && sparam == buttonId)
     {
      string txt = ObjectGetString(ChartID(), sparam, OBJPROP_TEXT);
      if(txt == btn_unpressed)
        {
         ObjectSetString(ChartID(),  sparam, OBJPROP_TEXT,  btn_pressed);
         ObjectSetInteger(ChartID(), sparam, OBJPROP_COLOR, btn_text_OFF_color);
         ObjectSetInteger(ChartID(), sparam, OBJPROP_STATE, false);
         for(int p = 0; p < 20; p++) PlotIndexSetInteger(p, PLOT_DRAW_TYPE, DRAW_NONE);
         string names[] = {"QPivot","QSupp1","QRes1","QSupp2","QRes2","QSupp3","QRes3",
                           "QSupp4","QRes4","QSupp5","QRes5","QSupp6","QRes6",
                           "QSupp7","QRes7","QSupp8","QRes8","QSupp9","QRes9"};
         for(int n = 0; n < ArraySize(names); n++) ObjectDelete(0, names[n]);
         showcomment = false;
         Comment("");
        }
      else
        {
         ObjectSetString(ChartID(),  sparam, OBJPROP_TEXT,  btn_unpressed);
         ObjectSetInteger(ChartID(), sparam, OBJPROP_COLOR, btn_text_ON_color);
         ObjectSetInteger(ChartID(), sparam, OBJPROP_STATE, false);
         for(int p = 0; p < 18; p++) PlotIndexSetInteger(p, PLOT_DRAW_TYPE, DRAW_LINE);
         showcomment = Display_Qtr_Times;
         ChartSetSymbolPeriod(0, _Symbol, _Period);
        }
     }
  }

//+------------------------------------------------------------------+
void CreateButton(string buttonID, string buttonText, int width, int height,
                  string font, int fontSize, color bgColor, color borderColor, color txtColor)
  {
   ObjectDelete(ChartID(), buttonID);
   ObjectCreate(ChartID(), buttonID, OBJ_BUTTON, btn_Subwindow, 0, 0);
   ObjectSetInteger(ChartID(), buttonID, OBJPROP_COLOR,        txtColor);
   ObjectSetInteger(ChartID(), buttonID, OBJPROP_BGCOLOR,      bgColor);
   ObjectSetInteger(ChartID(), buttonID, OBJPROP_BORDER_COLOR, borderColor);
   ObjectSetInteger(ChartID(), buttonID, OBJPROP_XSIZE,        width);
   ObjectSetInteger(ChartID(), buttonID, OBJPROP_YSIZE,        height);
   ObjectSetString (ChartID(), buttonID, OBJPROP_FONT,         font);
   ObjectSetString (ChartID(), buttonID, OBJPROP_TEXT,         buttonText);
   ObjectSetInteger(ChartID(), buttonID, OBJPROP_FONTSIZE,     fontSize);
   ObjectSetInteger(ChartID(), buttonID, OBJPROP_SELECTABLE,   0);
   ObjectSetInteger(ChartID(), buttonID, OBJPROP_CORNER,       btn_corner);
   ObjectSetInteger(ChartID(), buttonID, OBJPROP_HIDDEN,       1);
   ObjectSetInteger(ChartID(), buttonID, OBJPROP_XDISTANCE,    9999);
   ObjectSetInteger(ChartID(), buttonID, OBJPROP_YDISTANCE,    9999);
  }
//+------------------------------------------------------------------+
