//+------------------------------------------------------------------+
//|             TelepathicSync_WithBands.mq4                         |
//|     Sync Line with Dynamic Volume Regression Bands               |
//+------------------------------------------------------------------+
#property strict
#property indicator_separate_window
#property indicator_buffers 3
#property indicator_plots   3

#property indicator_color1 clrAqua      // Telepathic Sync Line
#property indicator_color2 clrRed       // Upper Band
#property indicator_color3 clrLime      // Lower Band

#property indicator_level1 0.0
#property indicator_levelstyle 2
#property indicator_levelcolor clrLightGray

//--- buffer indices
#define IDX_SYNC      0
#define IDX_LR_UPPER  1
#define IDX_LR_LOWER  2

//--- buffers
double SyncLineBuffer[];
double VolLRUpper[];
double VolLRLower[];

//--- internal
double MACDCore[];
double Sine2Buf[];

//--- constants
#define PI 3.14159265358979323846

//--- inputs
extern int     WarpFieldFast     = 7;
extern int     WarpFieldSlow     = 21;
extern int     SignalAntenna     = 7;
extern double  SyncStretch       = 500.0;    // Vertical stretch for Telepathic Sync Line

extern double  Amp2              = 0.5;
extern double  Freq2             = 1.0;
extern double  Phase2            = 0.0;
extern double  PriceScale2       = 10.0;
extern int     PricePer2         = 1;
extern double  VolMultiplier     = 1.0;
extern double  VolScale          = 0.1;
extern int     LRPeriod          = 21;
extern double  StdDevMult        = 1.236;
extern int     DaysToShow        = 21;

//+------------------------------------------------------------------+
int init()
{
   SetIndexBuffer(IDX_SYNC,     SyncLineBuffer); SetIndexStyle(IDX_SYNC, DRAW_LINE); SetIndexLabel(IDX_SYNC, "Telepathic Sync Line");
   SetIndexBuffer(IDX_LR_UPPER, VolLRUpper);     SetIndexStyle(IDX_LR_UPPER, DRAW_LINE); SetIndexLabel(IDX_LR_UPPER, "LR Band Upper");
   SetIndexBuffer(IDX_LR_LOWER, VolLRLower);     SetIndexStyle(IDX_LR_LOWER, DRAW_LINE); SetIndexLabel(IDX_LR_LOWER, "LR Band Lower");

   IndicatorShortName("Telepathic Sync Line + Bands");
   return(0);
}

//+------------------------------------------------------------------+
int start()
{
   int counted = IndicatorCounted();
   if (counted < 0) return(-1);
   int limit = Bars - counted;

   datetime newestBarTime = Time[0];
   int secondsToShow = DaysToShow * 24 * 3600;

   ArrayResize(MACDCore, Bars);
   ArrayResize(Sine2Buf, Bars);
   ArraySetAsSeries(MACDCore, true);
   ArraySetAsSeries(Sine2Buf, true);

   for (int i = limit - 1; i >= 0; i--)
   {
      if (Time[i] < newestBarTime - secondsToShow)
      {
         SyncLineBuffer[i] = EMPTY_VALUE;
         VolLRUpper[i]     = EMPTY_VALUE;
         VolLRLower[i]     = EMPTY_VALUE;
         continue;
      }

      //--- 1) MACD core = EMA(fast) - EMA(slow)
      double fastEMA = iMA(NULL, 0, WarpFieldFast, 0, MODE_EMA, PRICE_CLOSE, i);
      double slowEMA = iMA(NULL, 0, WarpFieldSlow, 0, MODE_EMA, PRICE_CLOSE, i);
      MACDCore[i] = fastEMA - slowEMA;

      //--- 2) Telepathic Sync Line = SMA of MACD core
      double sum = 0;
      int count = 0;
      for (int k = 0; k < SignalAntenna; k++)
      {
         if (i + k < Bars)
         {
            sum += MACDCore[i + k];
            count++;
         }
      }
      if (count > 0)
         SyncLineBuffer[i] = (sum / count) * SyncStretch;
      else
         SyncLineBuffer[i] = EMPTY_VALUE;

      //--- 3) Volume-scaled sine
      double price2  = iMA(NULL, 0, PricePer2, 0, MODE_SMA, PRICE_CLOSE, i);
      double vol     = iVolume(NULL, 0, i);
      double scaled2 = price2 / PriceScale2;
      double scaledV = (vol * VolMultiplier) / VolScale;
      Sine2Buf[i]    = Amp2 * MathSin(Freq2 * (scaled2 + scaledV) + Phase2);

      //--- 4) Linear regression bands
      if (i + LRPeriod <= Bars)
      {
         double sumX=0, sumY=0, sumXY=0, sumX2=0;
         for (int j = 0; j < LRPeriod; j++)
         {
            double y = Sine2Buf[i + j];
            sumX  += j;
            sumY  += y;
            sumXY += j * y;
            sumX2 += j * j;
         }
         double n     = LRPeriod;
         double denom = n * sumX2 - sumX * sumX;
         double slope = (denom != 0) ? ((n * sumXY - sumX * sumY) / denom) : 0;
         double intercept = (sumY - slope * sumX) / n;
         double currentY  = intercept + slope * (LRPeriod - 1);

         double sumRes = 0;
         for (int j = 0; j < LRPeriod; j++)
         {
            double resid = Sine2Buf[i + j] - (intercept + slope * j);
            sumRes += resid * resid;
         }
         double variance = (n > 2) ? (sumRes / (n - 2)) : 0;
         double stdev = MathSqrt(variance);

         VolLRUpper[i] = currentY + StdDevMult * stdev;
         VolLRLower[i] = currentY - StdDevMult * stdev;
      }
      else
      {
         VolLRUpper[i] = EMPTY_VALUE;
         VolLRLower[i] = EMPTY_VALUE;
      }
   }

   return(0);
}
//+------------------------------------------------------------------+
