//+------------------------------------------------------------------+
//|                                                      QQE_RSI.mq4 |
//| Converted from PineScript v5 by Troopek for TradingView to MT4   |
//| Fixed version: Added array resizing and corrected cross detection|
//+------------------------------------------------------------------+
#property copyright "Converted and fixed by Grok 4"
#property link      "https://x.ai"
#property version   "1.01"
#property strict

#property indicator_separate_window
#property indicator_buffers 5
#property indicator_plots   5

#property indicator_type1   DRAW_LINE
#property indicator_color1  clrWhite
#property indicator_style1  STYLE_SOLID
#property indicator_width1  2
#property indicator_label1  "QQE Line"

#property indicator_type2   DRAW_HISTOGRAM
#property indicator_color2  clrDodgerBlue // Approximate #00bcd4
#property indicator_style2  STYLE_SOLID
#property indicator_width2  2
#property indicator_label2  "QQE Up"

#property indicator_type3   DRAW_HISTOGRAM
#property indicator_color3  clrMagenta // Approximate #e91e63
#property indicator_style3  STYLE_SOLID
#property indicator_width3  2
#property indicator_label3  "QQE Down"

#property indicator_type4   DRAW_HISTOGRAM
#property indicator_color4  clrGray // #5d606b
#property indicator_style4  STYLE_SOLID
#property indicator_width4  2
#property indicator_label4  "None"

#property indicator_type5   DRAW_LINE
#property indicator_color5  clrWhite
#property indicator_style5  STYLE_DOT
#property indicator_width5  1
#property indicator_label5  "Zero"

// Inputs
extern int RSI_Period = 6;
extern int SF = 5;
extern int RSI_Period2 = 6;
extern int SF2 = 5;
extern double QQE = 3.0;
extern int ThreshHold = 3;
extern double QQE2 = 1.61;
extern int ThreshHold2 = 3;
extern int length = 50;
extern double mult = 0.35;
extern color Blue_Color = clrDodgerBlue;
extern color Red_Color = clrMagenta;
extern color Grey_Color = clrGray;
extern color White_Color = clrWhite;
extern color White2_Color = clrWhite;

// Buffers
double LineBuffer[];
double BlueHist[];
double RedHist[];
double GrayHist[];
double ZeroBuffer[];

// Arrays for calculations
double RsiArray[];
double RsiArray2[];
double RsiMaArray[];
double RsiMaArray2[];
double AtrRsi[];
double AtrRsi2[];
double MaAtrRsi[];
double MaAtrRsi2[];
double dar[];
double dar2[];
double newlongband[];
double newshortband[];
double newlongband2[];
double newshortband2[];
double LongbandArray[];
double ShortbandArray[];
double LongbandArray2[];
double ShortbandArray2[];
double TrendArray[];
double TrendArray2[];
double FastAtrRsiTL[];
double FastAtrRsiTL2[];
double FastAtrRsiTL_minus50[];
double BasisArray[];
double DevArray[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
   SetIndexBuffer(0, LineBuffer);
   SetIndexBuffer(1, BlueHist);
   SetIndexBuffer(2, RedHist);
   SetIndexBuffer(3, GrayHist);
   SetIndexBuffer(4, ZeroBuffer);

   SetIndexEmptyValue(1, EMPTY_VALUE);
   SetIndexEmptyValue(2, EMPTY_VALUE);
   SetIndexEmptyValue(3, EMPTY_VALUE);

   ArraySetAsSeries(RsiArray, true);
   ArraySetAsSeries(RsiArray2, true);
   ArraySetAsSeries(RsiMaArray, true);
   ArraySetAsSeries(RsiMaArray2, true);
   ArraySetAsSeries(AtrRsi, true);
   ArraySetAsSeries(AtrRsi2, true);
   ArraySetAsSeries(MaAtrRsi, true);
   ArraySetAsSeries(MaAtrRsi2, true);
   ArraySetAsSeries(dar, true);
   ArraySetAsSeries(dar2, true);
   ArraySetAsSeries(newlongband, true);
   ArraySetAsSeries(newshortband, true);
   ArraySetAsSeries(newlongband2, true);
   ArraySetAsSeries(newshortband2, true);
   ArraySetAsSeries(LongbandArray, true);
   ArraySetAsSeries(ShortbandArray, true);
   ArraySetAsSeries(LongbandArray2, true);
   ArraySetAsSeries(ShortbandArray2, true);
   ArraySetAsSeries(TrendArray, true);
   ArraySetAsSeries(TrendArray2, true);
   ArraySetAsSeries(FastAtrRsiTL, true);
   ArraySetAsSeries(FastAtrRsiTL2, true);
   ArraySetAsSeries(FastAtrRsiTL_minus50, true);
   ArraySetAsSeries(BasisArray, true);
   ArraySetAsSeries(DevArray, true);
   ArraySetAsSeries(LineBuffer, true);
   ArraySetAsSeries(BlueHist, true);
   ArraySetAsSeries(RedHist, true);
   ArraySetAsSeries(GrayHist, true);
   ArraySetAsSeries(ZeroBuffer, true);

   IndicatorShortName("QQE / RSI");

   return(0);
  }

//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
   return(0);
  }

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   int counted = IndicatorCounted();
   int limit = Bars - counted - 1;
   if (counted < 1) limit = Bars - 1;

   int bars = Bars;
   if (ArraySize(RsiArray) < bars) {
      ArrayResize(RsiArray, bars);
      ArrayResize(RsiArray2, bars);
      ArrayResize(RsiMaArray, bars);
      ArrayResize(RsiMaArray2, bars);
      ArrayResize(AtrRsi, bars);
      ArrayResize(AtrRsi2, bars);
      ArrayResize(MaAtrRsi, bars);
      ArrayResize(MaAtrRsi2, bars);
      ArrayResize(dar, bars);
      ArrayResize(dar2, bars);
      ArrayResize(newlongband, bars);
      ArrayResize(newshortband, bars);
      ArrayResize(newlongband2, bars);
      ArrayResize(newshortband2, bars);
      ArrayResize(LongbandArray, bars);
      ArrayResize(ShortbandArray, bars);
      ArrayResize(LongbandArray2, bars);
      ArrayResize(ShortbandArray2, bars);
      ArrayResize(TrendArray, bars);
      ArrayResize(TrendArray2, bars);
      ArrayResize(FastAtrRsiTL, bars);
      ArrayResize(FastAtrRsiTL2, bars);
      ArrayResize(FastAtrRsiTL_minus50, bars);
      ArrayResize(BasisArray, bars);
      ArrayResize(DevArray, bars);
   }

   // Fill RSI arrays
   for (int i = limit; i >= 0; i--) {
      RsiArray[i] = iRSI(NULL, 0, RSI_Period, PRICE_CLOSE, i);
      RsiArray2[i] = iRSI(NULL, 0, RSI_Period2, PRICE_CLOSE, i);
   }

   // Fill RsiMa arrays
   for (int i = limit; i >= 0; i--) {
      RsiMaArray[i] = iMAOnArray(RsiArray, 0, SF, 0, MODE_EMA, i);
      RsiMaArray2[i] = iMAOnArray(RsiArray2, 0, SF2, 0, MODE_EMA, i);
   }

   int Wilders_Period = RSI_Period * 2 - 1;
   int Wilders_Period2 = RSI_Period2 * 2 - 1;

   // Fill AtrRsi arrays
   for (int i = limit; i >= 0; i--) {
      if (i + 1 < bars) {
         AtrRsi[i] = MathAbs(RsiMaArray[i + 1] - RsiMaArray[i]);
         AtrRsi2[i] = MathAbs(RsiMaArray2[i + 1] - RsiMaArray2[i]);
      } else {
         AtrRsi[i] = 0;
         AtrRsi2[i] = 0;
      }
   }

   // Fill MaAtrRsi arrays
   for (int i = limit; i >= 0; i--) {
      MaAtrRsi[i] = iMAOnArray(AtrRsi, 0, Wilders_Period, 0, MODE_EMA, i);
      MaAtrRsi2[i] = iMAOnArray(AtrRsi2, 0, Wilders_Period2, 0, MODE_EMA, i);
   }

   // Fill dar arrays
   for (int i = limit; i >= 0; i--) {
      dar[i] = iMAOnArray(MaAtrRsi, 0, Wilders_Period, 0, MODE_EMA, i) * QQE;
      dar2[i] = iMAOnArray(MaAtrRsi2, 0, Wilders_Period2, 0, MODE_EMA, i) * QQE2;
   }

   // Fill newband arrays
   for (int i = limit; i >= 0; i--) {
      newshortband[i] = RsiMaArray[i] + dar[i];
      newlongband[i] = RsiMaArray[i] - dar[i];
      newshortband2[i] = RsiMaArray2[i] + dar2[i];
      newlongband2[i] = RsiMaArray2[i] - dar2[i];
   }

   // Fill longband and shortband with trailing logic
   for (int i = limit; i >= 0; i--) {
      if (i + 1 < bars) {
         if (RsiMaArray[i + 1] > LongbandArray[i + 1] && RsiMaArray[i] > LongbandArray[i + 1]) {
            LongbandArray[i] = MathMax(LongbandArray[i + 1], newlongband[i]);
         } else {
            LongbandArray[i] = newlongband[i];
         }
         if (RsiMaArray[i + 1] < ShortbandArray[i + 1] && RsiMaArray[i] < ShortbandArray[i + 1]) {
            ShortbandArray[i] = MathMin(ShortbandArray[i + 1], newshortband[i]);
         } else {
            ShortbandArray[i] = newshortband[i];
         }
      } else {
         LongbandArray[i] = newlongband[i];
         ShortbandArray[i] = newshortband[i];
      }
   }

   // Fill longband2 and shortband2
   for (int i = limit; i >= 0; i--) {
      if (i + 1 < bars) {
         if (RsiMaArray2[i + 1] > LongbandArray2[i + 1] && RsiMaArray2[i] > LongbandArray2[i + 1]) {
            LongbandArray2[i] = MathMax(LongbandArray2[i + 1], newlongband2[i]);
         } else {
            LongbandArray2[i] = newlongband2[i];
         }
         if (RsiMaArray2[i + 1] < ShortbandArray2[i + 1] && RsiMaArray2[i] < ShortbandArray2[i + 1]) {
            ShortbandArray2[i] = MathMin(ShortbandArray2[i + 1], newshortband2[i]);
         } else {
            ShortbandArray2[i] = newshortband2[i];
         }
      } else {
         LongbandArray2[i] = newlongband2[i];
         ShortbandArray2[i] = newshortband2[i];
      }
   }

   // Fill trend
   for (int i = limit; i >= 0; i--) {
      bool cross_1 = false;
      bool cross_rs = false;
      if (i + 1 < bars && i + 2 < bars) {
         double a = LongbandArray[i + 1];
         double b = RsiMaArray[i];
         double a1 = LongbandArray[i + 2];
         double b1 = RsiMaArray[i + 1];
         cross_1 = (a > b) != (a1 > b1);
      }

      if (i + 1 < bars && i + 2 < bars) {
         double a_rs = RsiMaArray[i];
         double b_rs = ShortbandArray[i + 1];
         double a1_rs = RsiMaArray[i + 1];
         double b1_rs = ShortbandArray[i + 2];
         cross_rs = (a_rs > b_rs) != (a1_rs > b1_rs);
      }

      if (cross_rs) TrendArray[i] = 1;
      else if (cross_1) TrendArray[i] = -1;
      else if (i + 1 < bars) TrendArray[i] = TrendArray[i + 1];
      else TrendArray[i] = 1;

      FastAtrRsiTL[i] = (TrendArray[i] == 1) ? LongbandArray[i] : ShortbandArray[i];
   }

   // Fill trend2
   for (int i = limit; i >= 0; i--) {
      bool cross_2 = false;
      bool cross_rs2 = false;
      if (i + 1 < bars && i + 2 < bars) {
         double a = LongbandArray2[i + 1];
         double b = RsiMaArray2[i];
         double a1 = LongbandArray2[i + 2];
         double b1 = RsiMaArray2[i + 1];
         cross_2 = (a > b) != (a1 > b1);
      }

      if (i + 1 < bars && i + 2 < bars) {
         double a_rs = RsiMaArray2[i];
         double b_rs = ShortbandArray2[i + 1];
         double a1_rs = RsiMaArray2[i + 1];
         double b1_rs = ShortbandArray2[i + 2];
         cross_rs2 = (a_rs > b_rs) != (a1_rs > b1_rs);
      }

      if (cross_rs2) TrendArray2[i] = 1;
      else if (cross_2) TrendArray2[i] = -1;
      else if (i + 1 < bars) TrendArray2[i] = TrendArray2[i + 1];
      else TrendArray2[i] = 1;

      FastAtrRsiTL2[i] = (TrendArray2[i] == 1) ? LongbandArray2[i] : ShortbandArray2[i];
   }

   // Bollinger Bands
   for (int i = limit; i >= 0; i--) {
      FastAtrRsiTL_minus50[i] = FastAtrRsiTL[i] - 50;
   }

   for (int i = limit; i >= 0; i--) {
      BasisArray[i] = iMAOnArray(FastAtrRsiTL_minus50, 0, length, 0, MODE_SMA, i);
      DevArray[i] = mult * iStdDevOnArray(FastAtrRsiTL_minus50, 0, length, 0, MODE_SMA, i);
   }

   // Plots
   for (int i = limit; i >= 0; i--) {
      ZeroBuffer[i] = 0;
      LineBuffer[i] = FastAtrRsiTL2[i] - 50;
      double val = RsiMaArray2[i] - 50;
      double upper = BasisArray[i] + DevArray[i];
      double lower = BasisArray[i] - DevArray[i];
      bool Greenbar1 = val > ThreshHold2;
      bool Greenbar2 = (RsiMaArray[i] - 50) > upper;
      bool Redbar1 = val < -ThreshHold2;
      bool Redbar2 = (RsiMaArray[i] - 50) < lower;

      BlueHist[i] = EMPTY_VALUE;
      RedHist[i] = EMPTY_VALUE;
      GrayHist[i] = EMPTY_VALUE;

      if (Greenbar1 && Greenbar2) {
         BlueHist[i] = val;
      } else if (Redbar1 && Redbar2) {
         RedHist[i] = val;
      } else if (val > ThreshHold2 || val < -ThreshHold2) {
         GrayHist[i] = val;
      }
   }

   return(0);
  }
//+------------------------------------------------------------------+