//+------------------------------------------------------------------+
//|                                                     SqueezePro.mq5|
//|                        Custom Indicator Script                   |
//|                       Converted from PineScript                   |
//+------------------------------------------------------------------+
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots   2

#property indicator_label1  "MOM"
#property indicator_type1   DRAW_HISTOGRAM
#property indicator_color1  clrBlue

#property indicator_label2  "SQZ"
#property indicator_type2   DRAW_CIRCLES
#property indicator_color2  clrGreen

input int    length = 20;       // TTM Squeeze Length
input double BB_mult = 2.0;     // Bollinger Band STD Multiplier
input double KC_mult_high = 1.0; // Keltner Channel #1
input double KC_mult_mid = 1.5;  // Keltner Channel #2
input double KC_mult_low = 2.0;  // Keltner Channel #3

double MOMBuffer[];
double SQZBuffer[];

double BB_basis, dev, BB_upper, BB_lower;
double KC_basis, devKC, KC_upper_high, KC_lower_high, KC_upper_mid, KC_lower_mid, KC_upper_low, KC_lower_low;
double mom, prev_mom;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
   SetIndexBuffer(0, MOMBuffer);
   SetIndexBuffer(1, SQZBuffer);
   
   IndicatorSetInteger(INDICATOR_DIGITS, 2);
   IndicatorSetString(INDICATOR_SHORTNAME, "Squeeze Pro");

   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[])
  {
   if (rates_total < length) return(0);

   int start = prev_calculated > 0 ? prev_calculated - 1 : length;

   for (int i = start; i < rates_total; i++)
     {
      // Bollinger Bands
      BB_basis = iMA(NULL, 0, length, 0, MODE_SMA, PRICE_CLOSE, i);
      dev = BB_mult * iStdDev(NULL, 0, length, 0, PRICE_CLOSE, i);
      BB_upper = BB_basis + dev;
      BB_lower = BB_basis - dev;

      // Keltner Channels
      KC_basis = iMA(NULL, 0, length, 0, MODE_SMA, PRICE_CLOSE, i);
      devKC = iMA(NULL, 0, length, 0, MODE_SMA, MODE_TR, i);
      KC_upper_high = KC_basis + devKC * KC_mult_high;
      KC_lower_high = KC_basis - devKC * KC_mult_high;
      KC_upper_mid = KC_basis + devKC * KC_mult_mid;
      KC_lower_mid = KC_basis - devKC * KC_mult_mid;
      KC_upper_low = KC_basis + devKC * KC_mult_low;
      KC_lower_low = KC_basis - devKC * KC_mult_low;

      // Squeeze Conditions
      bool NoSqz = BB_lower < KC_lower_low || BB_upper > KC_upper_low;
      bool LowSqz = BB_lower >= KC_lower_low && BB_upper <= KC_upper_low;
      bool MidSqz = BB_lower >= KC_lower_mid && BB_upper <= KC_upper_mid;
      bool HighSqz = BB_lower >= KC_lower_high && BB_upper <= KC_upper_high;

      // Momentum Oscillator
      double highAvg = iHighest(NULL, 0, MODE_HIGH, length, i);
      double lowAvg = iLowest(NULL, 0, MODE_LOW, length, i);
      mom = iMA(NULL, 0, length, 0, MODE_LINEAR, PRICE_CLOSE - (highAvg + lowAvg) / 2, i);

      MOMBuffer[i] = mom;

      // Momentum Histogram Color
      color mom_color = clrBlue;
      prev_mom = i > 0 ? MOMBuffer[i-1] : mom;
      if (mom > 0) {
         mom_color = mom > prev_mom ? clrAqua : clrBlue;
      } else {
         mom_color = mom < prev_mom ? clrRed : clrYellow;
      }
      PlotIndexSetInteger(0, PLOT_LINE_COLOR, i, mom_color);

      // Squeeze Dots Color
      color sq_color = clrGreen;
      if (HighSqz) sq_color = clrOrange;
      else if (MidSqz) sq_color = clrRed;
      else if (LowSqz) sq_color = clrBlack;
      PlotIndexSetInteger(1, PLOT_LINE_COLOR, i, sq_color);

      SQZBuffer[i] = 0; // This sets the squeeze dots
     }

   return(rates_total);
  }
//+------------------------------------------------------------------+
