//+---------------------------------------------------------------------+
//|                                        Stochastic Rainbow [SKH].mq5 |
//|                                         from TradingView PineScript |
//| https://www.tradingview.com/script/eVYlQl6l-Stochastic-Rainbow-SHK/ |
//|           https://forex-station.com/post1295560554.html#p1295560554 |
//+---------------------------------------------------------------------+
//-----------------------------------------------------------------------
#property copyright "c. 2025-32, www.forex-station.com"
#property link      "http://www.forex-station.com/"
#property description "not for sale, rent, nor auction"
// display the %D lines only
//-----------------------------------------------------------------------
#property indicator_separate_window
#property indicator_buffers 16
#property indicator_plots   16
#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_color1   clrNONE
#property indicator_color2   C'193,227,157'
#property indicator_color3   clrNONE
#property indicator_color4   C'136,224,202'
#property indicator_color5   clrNONE
#property indicator_color6   C'140,215,241'
#property indicator_color7   clrNONE
#property indicator_color8   C'150,191,243'

#property indicator_color9   clrNONE; 
#property indicator_color10  C'201,184,243'
#property indicator_color11  clrNONE; 
#property indicator_color12  C'244,183,217'
#property indicator_color13  clrNONE; 
#property indicator_color14  C'253,161,142'
#property indicator_color15  clrNONE; 
#property indicator_color16  C'243,144,155'

#property indicator_width2   2
#property indicator_width4   2
#property indicator_width6   2
#property indicator_width8   2
#property indicator_width10  2
#property indicator_width12  2
#property indicator_width14  2
#property indicator_width16  2

//--- Input parameters
input int              KPeriod1     = 14;             // Stochastic %K period
input int              DPeriod1     = 3;              // Stochastic %D period (smoothing of %K)
input int              Slowing1     = 3;              // Slowing
input ENUM_MA_METHOD   MA_Method1   = MODE_EMA;       // Moving Average Method (SMA, EMA, Smoothed, Linear Weighted)
input ENUM_STO_PRICE   Price_Type1  = STO_CLOSECLOSE; // Price Type (Close/Close, Low/High)

input int              KPeriod2     = 14;             // Stochastic %K period
input int              DPeriod2     = 4;              // Stochastic %D period (smoothing of %K)
input int              Slowing2     = 3;              // Slowing
input ENUM_MA_METHOD   MA_Method2   = MODE_EMA;       // Moving Average Method (SMA, EMA, Smoothed, Linear Weighted)
input ENUM_STO_PRICE   Price_Type2  = STO_CLOSECLOSE; // Price Type (Close/Close, Low/High)

input int              KPeriod3     = 14;             // Stochastic %K period
input int              DPeriod3     = 5;              // Stochastic %D period (smoothing of %K)
input int              Slowing3     = 3;              // Slowing
input ENUM_MA_METHOD   MA_Method3   = MODE_EMA;       // Moving Average Method (SMA, EMA, Smoothed, Linear Weighted)
input ENUM_STO_PRICE   Price_Type3  = STO_CLOSECLOSE; // Price Type (Close/Close, Low/High)

input int              KPeriod4     = 14;             // Stochastic %K period
input int              DPeriod4     = 6;              // Stochastic %D period (smoothing of %K)
input int              Slowing4     = 3;              // Slowing
input ENUM_MA_METHOD   MA_Method4   = MODE_EMA;       // Moving Average Method (SMA, EMA, Smoothed, Linear Weighted)
input ENUM_STO_PRICE   Price_Type4  = STO_CLOSECLOSE; // Price Type (Close/Close, Low/High)

input int              KPeriod5     = 14;             // Stochastic %K period
input int              DPeriod5     = 7;              // Stochastic %D period (smoothing of %K)
input int              Slowing5     = 3;              // Slowing
input ENUM_MA_METHOD   MA_Method5   = MODE_EMA;       // Moving Average Method (SMA, EMA, Smoothed, Linear Weighted)
input ENUM_STO_PRICE   Price_Type5  = STO_CLOSECLOSE; // Price Type (Close/Close, Low/High)

input int              KPeriod6     = 14;             // Stochastic %K period
input int              DPeriod6     = 8;              // Stochastic %D period (smoothing of %K)
input int              Slowing6     = 3;              // Slowing
input ENUM_MA_METHOD   MA_Method6   = MODE_EMA;       // Moving Average Method (SMA, EMA, Smoothed, Linear Weighted)
input ENUM_STO_PRICE   Price_Type6  = STO_CLOSECLOSE; // Price Type (Close/Close, Low/High)

input int              KPeriod7     = 14;             // Stochastic %K period
input int              DPeriod7     = 9;              // Stochastic %D period (smoothing of %K)
input int              Slowing7     = 3;              // Slowing
input ENUM_MA_METHOD   MA_Method7   = MODE_EMA;       // Moving Average Method (SMA, EMA, Smoothed, Linear Weighted)
input ENUM_STO_PRICE   Price_Type7  = STO_CLOSECLOSE; // Price Type (Close/Close, Low/High)

input int              KPeriod8     = 14;             // Stochastic %K period
input int              DPeriod8     = 10;             // Stochastic %D period (smoothing of %K)
input int              Slowing8     = 3;              // Slowing
input ENUM_MA_METHOD   MA_Method8   = MODE_EMA;       // Moving Average Method (SMA, EMA, Smoothed, Linear Weighted)
input ENUM_STO_PRICE   Price_Type8  = STO_CLOSECLOSE; // Price Type (Close/Close, Low/High)

int MyStoch1, MyStoch2, MyStoch3, MyStoch4, MyStoch5, MyStoch6, MyStoch7, MyStoch8; // Indicator Stoch

//--- Indicator buffers
double StochasticMain1[], StochasticSignal1[];
double StochasticMain2[], StochasticSignal2[];
double StochasticMain3[], StochasticSignal3[];
double StochasticMain4[], StochasticSignal4[];

double StochasticMain5[], StochasticSignal5[];
double StochasticMain6[], StochasticSignal6[];
double StochasticMain7[], StochasticSignal7[];
double StochasticMain8[], StochasticSignal8[];


//+------------------------------------------------------------------+
//| Indicator initialization function                               |
//+------------------------------------------------------------------+
int OnInit()
{
   IndicatorSetInteger(INDICATOR_DIGITS, 16);
   // Set the indicator buffers
   SetIndexBuffer(0, StochasticMain1, INDICATOR_DATA);
   SetIndexBuffer(1, StochasticSignal1, INDICATOR_DATA);
   SetIndexBuffer(2, StochasticMain2, INDICATOR_DATA);
   SetIndexBuffer(3, StochasticSignal2, INDICATOR_DATA);
   SetIndexBuffer(4, StochasticMain3, INDICATOR_DATA);
   SetIndexBuffer(5, StochasticSignal3, INDICATOR_DATA);
   SetIndexBuffer(6, StochasticMain4, INDICATOR_DATA);
   SetIndexBuffer(7, StochasticSignal4, INDICATOR_DATA);

   SetIndexBuffer(8,  StochasticMain5, INDICATOR_DATA);
   SetIndexBuffer(9,  StochasticSignal5, INDICATOR_DATA);
   SetIndexBuffer(10, StochasticMain6, INDICATOR_DATA);
   SetIndexBuffer(11, StochasticSignal6, INDICATOR_DATA);
   SetIndexBuffer(12, StochasticMain7, INDICATOR_DATA);
   SetIndexBuffer(13, StochasticSignal7, INDICATOR_DATA);
   SetIndexBuffer(14, StochasticMain8, INDICATOR_DATA);
   SetIndexBuffer(15, StochasticSignal8, INDICATOR_DATA);

   // Set indicator name
   IndicatorSetString(INDICATOR_SHORTNAME, "Stoch (" + IntegerToString(KPeriod1) + "," + IntegerToString(DPeriod1) + "," + IntegerToString(Slowing1) + ") to Stoch ("+ IntegerToString(KPeriod8) + "," + IntegerToString(DPeriod8) + "," + IntegerToString(Slowing8) + ")");
   PlotIndexSetString(0, PLOT_LABEL, "Stoch(" + IntegerToString(KPeriod1) + "," + IntegerToString(DPeriod1) + "," + IntegerToString(Slowing1) + ")");
   PlotIndexSetString(2, PLOT_LABEL, "Stoch(" + IntegerToString(KPeriod2) + "," + IntegerToString(DPeriod2) + "," + IntegerToString(Slowing2) + ")");
   PlotIndexSetString(4, PLOT_LABEL, "Stoch(" + IntegerToString(KPeriod3) + "," + IntegerToString(DPeriod3) + "," + IntegerToString(Slowing3) + ")");
   PlotIndexSetString(6, PLOT_LABEL, "Stoch(" + IntegerToString(KPeriod4) + "," + IntegerToString(DPeriod4) + "," + IntegerToString(Slowing4) + ")");

   PlotIndexSetString(8, PLOT_LABEL, "Stoch(" + IntegerToString(KPeriod5) + "," + IntegerToString(DPeriod5) + "," + IntegerToString(Slowing5) + ")");
   PlotIndexSetString(10, PLOT_LABEL, "Stoch(" + IntegerToString(KPeriod6) + "," + IntegerToString(DPeriod6) + "," + IntegerToString(Slowing6) + ")");
   PlotIndexSetString(12, PLOT_LABEL, "Stoch(" + IntegerToString(KPeriod7) + "," + IntegerToString(DPeriod7) + "," + IntegerToString(Slowing7) + ")");
   PlotIndexSetString(14, PLOT_LABEL, "Stoch(" + IntegerToString(KPeriod8) + "," + IntegerToString(DPeriod8) + "," + IntegerToString(Slowing8) + ")");

   // Set first bar for drawing
   PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, KPeriod1 + Slowing1);
   PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, KPeriod1 + DPeriod1);
   PlotIndexSetInteger(2, PLOT_DRAW_BEGIN, KPeriod2 + Slowing2);
   PlotIndexSetInteger(3, PLOT_DRAW_BEGIN, KPeriod2 + DPeriod2);
   PlotIndexSetInteger(4, PLOT_DRAW_BEGIN, KPeriod3 + Slowing3);
   PlotIndexSetInteger(5, PLOT_DRAW_BEGIN, KPeriod3 + DPeriod3);
   PlotIndexSetInteger(6, PLOT_DRAW_BEGIN, KPeriod4 + Slowing4);
   PlotIndexSetInteger(7, PLOT_DRAW_BEGIN, KPeriod4 + DPeriod4);

   PlotIndexSetInteger(8, PLOT_DRAW_BEGIN, KPeriod5 + Slowing5);
   PlotIndexSetInteger(9, PLOT_DRAW_BEGIN, KPeriod5 + DPeriod5);
   PlotIndexSetInteger(10, PLOT_DRAW_BEGIN, KPeriod6 + Slowing6);
   PlotIndexSetInteger(11, PLOT_DRAW_BEGIN, KPeriod6 + DPeriod6);
   PlotIndexSetInteger(12, PLOT_DRAW_BEGIN, KPeriod7 + Slowing7);
   PlotIndexSetInteger(13, PLOT_DRAW_BEGIN, KPeriod7 + DPeriod7);
   PlotIndexSetInteger(14, PLOT_DRAW_BEGIN, KPeriod8 + Slowing8);
   PlotIndexSetInteger(15, PLOT_DRAW_BEGIN, KPeriod8 + DPeriod8);


   // Create iStochastic indicator MyStoch
   MyStoch1 = iStochastic(Symbol(), 0, KPeriod1, Slowing1, DPeriod1, MA_Method1, Price_Type1);
   MyStoch2 = iStochastic(Symbol(), 0, KPeriod2, Slowing2, DPeriod2, MA_Method2, Price_Type2);
   MyStoch3 = iStochastic(Symbol(), 0, KPeriod3, Slowing3, DPeriod3, MA_Method3, Price_Type3);
   MyStoch4 = iStochastic(Symbol(), 0, KPeriod4, Slowing4, DPeriod4, MA_Method4, Price_Type4);

   MyStoch5 = iStochastic(Symbol(), 0, KPeriod5, Slowing5, DPeriod5, MA_Method5, Price_Type5);
   MyStoch6 = iStochastic(Symbol(), 0, KPeriod6, Slowing6, DPeriod6, MA_Method6, Price_Type6);
   MyStoch7 = iStochastic(Symbol(), 0, KPeriod7, Slowing7, DPeriod7, MA_Method7, Price_Type7);
   MyStoch8 = iStochastic(Symbol(), 0, KPeriod8, Slowing8, DPeriod8, MA_Method8, Price_Type8);
   
   return INIT_SUCCEEDED;
}

//+------------------------------------------------------------------+
//| Indicator calculation function                                  |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,      // Number of bars in history
                const int prev_calculated,  // Number of previously calculated bars
                const datetime &time[],     // Array of bar opening times
                const double &open[],       // Array of open prices
                const double &high[],       // Array of high prices
                const double &low[],        // Array of low prices
                const double &close[],      // Array of close prices
                const long &tick_volume[],  // Array of tick volumes
                const long &volume[],       // Array of real volumes
                const int &spread[])        // Array of spreads
{
   if (rates_total < KPeriod1 + Slowing1) 
      return 0;
   if (rates_total < KPeriod2 + Slowing2) 
      return 0;
   if (rates_total < KPeriod3 + Slowing3) 
      return 0;
   if (rates_total < KPeriod4 + Slowing4) 
      return 0;

   // Copy Stochastic data from indicator buffers
//---------------------------------------------------------------------------
   if (!CopyBuffer(MyStoch1, 0, 0, rates_total, StochasticMain1))
   {
      Print("Error copying Stochastic Main buffer: ", GetLastError());
      return 0;
   }
   if (!CopyBuffer(MyStoch1, 1, 0, rates_total, StochasticSignal1))
   {
      Print("Error copying Stochastic Signal buffer: ", GetLastError());
      return 0;
   }
//---------------------------------------------------------------------------
   if (!CopyBuffer(MyStoch2, 0, 0, rates_total, StochasticMain2))
   {
      Print("Error copying Stochastic Main buffer: ", GetLastError());
      return 0;
   }
   if (!CopyBuffer(MyStoch2, 1, 0, rates_total, StochasticSignal2))
   {
      Print("Error copying Stochastic Signal buffer: ", GetLastError());
      return 0;
   }
//---------------------------------------------------------------------------
   if (!CopyBuffer(MyStoch3, 0, 0, rates_total, StochasticMain3))
   {
      Print("Error copying Stochastic Main buffer: ", GetLastError());
      return 0;
   }
   if (!CopyBuffer(MyStoch3, 1, 0, rates_total, StochasticSignal3))
   {
      Print("Error copying Stochastic Signal buffer: ", GetLastError());
      return 0;
   }
//---------------------------------------------------------------------------
   if (!CopyBuffer(MyStoch4, 0, 0, rates_total, StochasticMain4))
   {
      Print("Error copying Stochastic Main buffer: ", GetLastError());
      return 0;
   }
   if (!CopyBuffer(MyStoch4, 1, 0, rates_total, StochasticSignal4))
   {
      Print("Error copying Stochastic Signal buffer: ", GetLastError());
      return 0;
   }
//---------------------------------------------------------------------------
   if (!CopyBuffer(MyStoch5, 0, 0, rates_total, StochasticMain5))
   {
      Print("Error copying Stochastic Main buffer: ", GetLastError());
      return 0;
   }
   if (!CopyBuffer(MyStoch5, 1, 0, rates_total, StochasticSignal5))
   {
      Print("Error copying Stochastic Signal buffer: ", GetLastError());
      return 0;
   }
//---------------------------------------------------------------------------
   if (!CopyBuffer(MyStoch6, 0, 0, rates_total, StochasticMain6))
   {
      Print("Error copying Stochastic Main buffer: ", GetLastError());
      return 0;
   }
   if (!CopyBuffer(MyStoch6, 1, 0, rates_total, StochasticSignal6))
   {
      Print("Error copying Stochastic Signal buffer: ", GetLastError());
      return 0;
   }
//---------------------------------------------------------------------------
   if (!CopyBuffer(MyStoch7, 0, 0, rates_total, StochasticMain7))
   {
      Print("Error copying Stochastic Main buffer: ", GetLastError());
      return 0;
   }
   if (!CopyBuffer(MyStoch7, 1, 0, rates_total, StochasticSignal7))
   {
      Print("Error copying Stochastic Signal buffer: ", GetLastError());
      return 0;
   }
//---------------------------------------------------------------------------
   if (!CopyBuffer(MyStoch8, 0, 0, rates_total, StochasticMain8))
   {
      Print("Error copying Stochastic Main buffer: ", GetLastError());
      return 0;
   }
   if (!CopyBuffer(MyStoch8, 1, 0, rates_total, StochasticSignal8))
   {
      Print("Error copying Stochastic Signal buffer: ", GetLastError());
      return 0;
   }
//---------------------------------------------------------------------------
   return rates_total;
}

//+------------------------------------------------------------------+
//| Deinitialization function                                       |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   IndicatorRelease(MyStoch1); // Free memory
}
