//+------------------------------------------------------------------+
//|                                                XU EFFECT v8.34   |
//|   v8.34 PRODUCTION BUILD | DUAL VWAP RIBBON + MULTI-CHART ISO     |
//|   PRODUCTION HARDENED | ATOMIC I/O | VAULT-READY | MULTI-CHART   |
//+------------------------------------------------------------------+
#property copyright "XU AI & The Cognitive Collective"
#property version   "1.03"
#property indicator_chart_window
#property indicator_buffers 24
#property indicator_plots   11

#ifndef DBL_EPSILON
#define DBL_EPSILON 2.2204460492503131e-016
#endif

//--- Plot 0: Inner ribbon ±1σ (drawn first = behind lines)
#property indicator_label1  "Ribbon ±1σ"
#property indicator_type1   DRAW_FILLING
#property indicator_color1  C'46,56,64'

//--- Plot 1: Outer upper ribbon +1σ→+2σ (50% opaque)
#property indicator_label2  "Ribbon +1σ→+2σ"
#property indicator_type2   DRAW_FILLING
#property indicator_color2  C'128,46,56,64'

//--- Plot 2: Outer lower ribbon −2σ→−1σ (50% opaque)
#property indicator_label3  "Ribbon −2σ→−1σ"
#property indicator_type3   DRAW_FILLING
#property indicator_color3  C'128,46,56,64'

//--- Plot 3: VWAP
#property indicator_label4  "VWAP"
#property indicator_type4   DRAW_LINE
#property indicator_color4  clrGold
#property indicator_style4  STYLE_SOLID
#property indicator_width4  2

//--- Plot 4: EMA 36
#property indicator_label5  "EMA 36"
#property indicator_type5   DRAW_COLOR_LINE
#property indicator_color5  clrCrimson,clrGreen
#property indicator_width5  4

//--- Plot 5: Trigger
#property indicator_label6  "Trigger"
#property indicator_type6   DRAW_LINE
#property indicator_color6  clrWhite
#property indicator_style6  STYLE_SOLID
#property indicator_width6  2

//--- Plot 6: VWAP SD+1.0
#property indicator_label7  "VWAP SD+1.0"
#property indicator_type7   DRAW_LINE
#property indicator_color7  clrDodgerBlue
#property indicator_style7  STYLE_DOT
#property indicator_width7  1

//--- Plot 7: VWAP SD-1.0
#property indicator_label8  "VWAP SD-1.0"
#property indicator_type8   DRAW_LINE
#property indicator_color8  clrDodgerBlue
#property indicator_style8  STYLE_DOT
#property indicator_width8  1

//--- Plot 8: VWAP SD+2.0
#property indicator_label9  "VWAP SD+2.0"
#property indicator_type9   DRAW_LINE
#property indicator_color9  clrCrimson
#property indicator_style9  STYLE_DOT

//--- Plot 9: VWAP SD-2.0
#property indicator_label10  "VWAP SD-2.0"
#property indicator_type10   DRAW_LINE
#property indicator_color10  clrCrimson
#property indicator_style10  STYLE_DOT

//--- Plot 10: Candles
#property indicator_label11  "Candles"
#property indicator_type11   DRAW_COLOR_CANDLES
#property indicator_color11  clrDodgerBlue, clrOrchid, clrDarkGray

#define MAX_BARS          1800
#define PANEL_UPDATE_SEC  3
#define JSON_UPDATE_SEC   5
#define MIN_BARS_REQUIRED 50
#define MAX_STATES        10

#define M1_MULT            4

#define TARGET_BIAS          0.5
#define COIL_BIAS_FACTOR     0.62

#define COIL_ATR_MULTIPLIER  2.0
#define COIL_CONFIDENCE_MAX  100.0
#define SCORE_COL_THRESHOLD  2
#define HEBBIAN_SEED_VALUE   0.5
#define HEBBIAN_SEED_DELTA   0.5
#define GENOME_HIGH_THRESH   0.70
#define GENOME_MID_THRESH    0.55
#define GENOME_LOW_THRESH    0.30
#define GENOME_VLOW_THRESH   0.45
#define GENOME_EXTREME_HIGH  0.85
#define GENOME_EXTREME_LOW   0.15
#define COIL_POWER_MAX       100.0
#define ATR_PERIOD           14

#define DOTS_TOTAL           8

#define VOLUME_BINS          200
#define FIXED_WINDOW_SIZE    1000

#define MIN_SENSITIVITY      0.5

enum ENUM_HUD_THEME {
   THEME_CYBER  = 0,
   THEME_MATRIX = 1,
   THEME_EMBER  = 2,
   THEME_ARCTIC = 3,
   THEME_BLOOD  = 4
};

input group "=== CORE SETTINGS ==="
input bool   InpM1x4Mode          = false;
input bool   InpM4x4Mode          = false;
input bool   InpShowVWAP          = true;
input bool   InpShowSD            = true;
input int    InpEMA_Main          = 36;
input int    InpEMA_Signal        = 4;
input int    ZZ_Depth             = 236;

input int    InpTriggerPeriod     = 16;
input int    InpTriggerShift      = 10;

input group "=== GENOME SETTINGS ==="
input bool   InpUseTRITGenome      = true;
input double InpTRITSensitivity   = 50.0;
input double InpTRITDeadZone      = 0.000001;
input int    InpTRITMemoryPeriod  = 2;
input int    InpHebbianPeriod     = 13;
input bool   InpAutoScale          = true;
input double InpMinScale          = 1.0;
input double InpMaxScale          = 40.0;
input bool   InpUseCoilRandomization = false;
input double InpGenomeNeutralWidth = 0.01;
input double InpGenomeMaxStep      = 0.08;
input bool   InpDynamicSensitivity = true;

input group "=== COIL ALERT SETTINGS ==="
input double InpCoilFireHigh      = 70.0;
input double InpCoilFireLow       = 45.0;
input int    InpCoilFireCooldown  = 3;

input double InpCoilSpringPowerMin= 75.0;

input group "=== KINETIC REGIME (v8.28+) ==="
input bool   InpKineticRegime      = true;
input double InpKineticMultiplier = 1.15;

input group "=== SESSION SETTINGS ==="
input bool   InpUseSessionReset   = true;
input int    InpMaxSessionGapHours= 4;

input group "=== OUTPUT SETTINGS ==="
input bool   InpFileOutput        = true;

input group "=== HEADER SETTINGS ==="
input bool   InpShowHeader        = true;
input int    InpHeaderFontSize    = 42;
input int    InpHeaderXOffset     = 120;
input int    InpHeaderYOffset     = 10;
input color  InpHeaderBullColor   = clrDodgerBlue;
input color  InpHeaderBearColor   = clrCrimson;
input color  InpHeaderNeutralColor= clrDarkGray;

input group "=== VCD PANEL SETTINGS ==="
input bool   InpShowVCDPanel      = true;
input int    InpVCDPanelX         = 20;
input int    InpVCDPanelY         = 120;
input int    InpVCDPanelWidth     = 360;

input group "=== VCD LAYOUT & FONT ==="
input int    InpLabelColWidth     = 100;
input int    InpCircleColWidth    = 28;
input int    InpRowHeight         = 22;
input int    InpPanelFontSize     = 9;
input int    InpActionFontSize    = 11;

input group "=== COLOR THEME ==="
input ENUM_HUD_THEME InpColorTheme = THEME_CYBER;

input group "=== ALERTS ==="
input bool   InpUseAlerts         = true;

input group "=== VWAP RIBBON ==="
input bool   InpShowInnerRibbon   = true;
input bool   InpShowOuterRibbon   = true;
input double InpInnerSD           = 1.0;
input double InpOuterSD           = 2.0;

input group "=== BUTTONS ==="
input int    InpBtnSubwindow      = 0;
input int    InpBtnWidth          = 80;
input int    InpBtnHeight         = 20;
input int    InpBtnFontSize       = 8;
input string InpUniqueID          = "XU834";

//--- Buffers (24)
// Plots 0-2: Ribbon fills
double RibbonInnerUBuf[];
double RibbonInnerLBuf[];
double RibbonOuterUHiBuf[];
double RibbonOuterULoBuf[];
double RibbonOuterLHiBuf[];
double RibbonOuterLLoBuf[];
// Plots 3-10: Lines/Candles
double VWAPBuf[];
double EMA_Main_Buf[];
double EMA_Main_Col[];
double TriggerBuf[];
double VWAPSD1UpperBuf[];
double VWAPSD1LowerBuf[];
double VWAPSDUpperBuf[];
double VWAPSDLowerBuf[];
double CandleOpen[];
double CandleHigh[];
double CandleLow[];
double CandleClose[];
double CandleCol[];
double EMA_Signal_Buf[];
double zzUp[];
double zzDown[];
double highMap[];
double lowMap[];

bool g_timerActive = false;

#define TCR_BULL   0
#define TCR_BEAR   1
#define TCR_NEUT   2
#define TCR_LABEL  3
#define TCR_FRAME  4
#define TCR_BG     5
#define TCR_HDRBG  6
#define TCR_META   7
#define TCR_GENHI  8
#define TCR_FOOTER 9
color g_themeColors[5][10];

int g_col1X, g_col2X, g_col3X;
int g_rowY_Candle,  g_rowY_Trend;
int g_rowY_Genome,  g_rowY_Price;
int g_rowY_Align,   g_rowY_Vacuum;
int g_rowY_Power,   g_rowY_Vwap;
int g_rowY_Trigger, g_rowY_TernHdr;
int g_rowY_ST,      g_rowY_MT, g_rowY_LT, g_rowY_Cons;
int g_scoreBarY,    g_actionY,  g_footerY;
int g_panelH;

string g_btnHudId    = "";
bool   g_hudVisible   = true;

int g_emaMainPeriod, g_emaSignalPeriod, g_trigPeriod, g_trigShift;

//+------------------------------------------------------------------+
//| Utility functions                                                 |
//+------------------------------------------------------------------+
int HighestSeries(const double &arr[], int count, int start, int total)
{
   int idx = start; double val = arr[start];
   for(int i = start + 1; i < start + count && i < total; i++)
      if(arr[i] > val){ val = arr[i]; idx = i; }
   return(idx);
}

int LowestSeries(const double &arr[], int count, int start, int total)
{
   int idx = start; double val = arr[start];
   for(int i = start + 1; i < start + count && i < total; i++)
      if(arr[i] < val){ val = arr[i]; idx = i; }
   return(idx);
}

class SwingMemory
{
private:
   double memHigh,memLow;
   string keyH,keyL;
public:
   SwingMemory()
   {
      keyH="XU834_H_"+_Symbol+"_"+IntegerToString(_Period);
      keyL="XU834_L_"+_Symbol+"_"+IntegerToString(_Period);
      if(GlobalVariableCheck(keyH)) memHigh=GlobalVariableGet(keyH); else memHigh=EMPTY_VALUE;
      if(GlobalVariableCheck(keyL)) memLow =GlobalVariableGet(keyL); else memLow =EMPTY_VALUE;
   }
  ~SwingMemory()
   {
      if(memHigh!=EMPTY_VALUE) GlobalVariableSet(keyH,memHigh);
      if(memLow !=EMPTY_VALUE) GlobalVariableSet(keyL,memLow);
   }
   void Update(int bias,double h,double l)
   {
      if(bias==1 && (memLow==EMPTY_VALUE || l<memLow)) memLow=l;
      if(bias==-1 && (memHigh==EMPTY_VALUE || h>memHigh)) memHigh=h;
   }
   double High(){return(memHigh);}
   double Low() {return(memLow);}
};

void GetZigZagSeries(double &up[], double &dn[], double &hmap[], double &lmap[],
                     int limit, int total, int depth,
                     const double &hi[], const double &lo[])
{
   if(total <= depth) return;

   int search = 0, cnt = 0;
   int shift, last_hp = 0, last_lp = 0;
   double last_l = EMPTY_VALUE, last_h = EMPTY_VALUE, curh = EMPTY_VALUE, curl = EMPTY_VALUE;

   int start = limit - 1;
   if(limit >= total - depth)
   {
      ArrayInitialize(up, EMPTY_VALUE); ArrayInitialize(dn, EMPTY_VALUE);
      ArrayInitialize(hmap, EMPTY_VALUE); ArrayInitialize(lmap, EMPTY_VALUE);
      start = total - depth - 1;
   }
   else
   {
      int maxLookback = limit - 1 + depth * 2;

      int i = start + 4;
      if(i >= total) i = total - 1;
      while(cnt < 3 && i < total && i < maxLookback + 4) { if(up[i] != EMPTY_VALUE || dn[i] != EMPTY_VALUE) cnt++; i++; }
      start = i - 1;

      if(start > maxLookback) start = maxLookback;
      if(start >= total) start = total - 1;
      if(start < 0) start = 0;
      if(lmap[start] != EMPTY_VALUE) { curl = lmap[start]; search = 1; }
      else if(start < total && hmap[start] != EMPTY_VALUE) { curh = hmap[start]; search = -1; }
      for(int j = start - 1; j >= 0; j--) { hmap[j] = lmap[j] = up[j] = dn[j] = EMPTY_VALUE; }
   }

   int stop = 0;
   for(shift = start; shift >= stop && !IsStopped(); shift--)
   {
      double v = lo[LowestSeries(lo, depth, shift, total)];
      if(v == last_l) v = EMPTY_VALUE; else { last_l = v; if(lo[shift] > v) v = EMPTY_VALUE; }
      lmap[shift] = (lo[shift] == v) ? v : EMPTY_VALUE;

      v = hi[HighestSeries(hi, depth, shift, total)];
      if(v == last_h) v = EMPTY_VALUE; else { last_h = v; if(hi[shift] < v) v = EMPTY_VALUE; }
      hmap[shift] = (hi[shift] == v) ? v : EMPTY_VALUE;
   }

   if(search == 0) { last_l = last_h = EMPTY_VALUE; }
   else { last_l = curl; last_h = curh; }

   for(shift = start; shift >= stop && !IsStopped(); shift--)
   {
      switch(search)
      {
         case 0:
            if(last_l == EMPTY_VALUE && last_h == EMPTY_VALUE)
            {
               if(hmap[shift] != EMPTY_VALUE) { last_h = hmap[shift]; last_hp = shift; search = -1; dn[shift] = last_h; }
               else if(lmap[shift] != EMPTY_VALUE) { last_l = lmap[shift]; last_lp = shift; search = 1; up[shift] = last_l; }
            }
            break;
         case 1:
            if(lmap[shift] != EMPTY_VALUE && lmap[shift] < last_l && hmap[shift] == EMPTY_VALUE)
            { up[last_lp] = EMPTY_VALUE; last_lp = shift; last_l = lmap[shift]; up[shift] = last_l; }
            if(hmap[shift] != EMPTY_VALUE && lmap[shift] == EMPTY_VALUE)
            { last_h = hmap[shift]; last_hp = shift; dn[shift] = last_h; search = -1; }
            break;
         case -1:
            if(hmap[shift] != EMPTY_VALUE && hmap[shift] > last_h && lmap[shift] == EMPTY_VALUE)
            { dn[last_hp] = EMPTY_VALUE; last_hp = shift; last_h = hmap[shift]; dn[shift] = last_h; }
            if(lmap[shift] != EMPTY_VALUE && hmap[shift] == EMPTY_VALUE)
            { last_l = lmap[shift]; last_lp = shift; up[shift] = last_l; search = 1; }
            break;
      }
   }
}

//--- Volume Engine Structures
struct VolumeProfile {
   double bins[VOLUME_BINS];
   double minPrice;
   double maxPrice;
   double binSize;
   double pocPrice;
   double pocVolume;

   void Clear() {
      ArrayInitialize(bins, 0);
      minPrice = DBL_MAX; maxPrice = 0; binSize = 0; pocPrice = 0; pocVolume = 0;
   }

   void Calculate(int startBar, int count, const double &high[], const double &low[], const double &close[], const long &volume[]) {
      Clear();
      int maxBars = ArraySize(high);
      if(startBar < 0 || startBar >= maxBars) return;
      int endBar = MathMin(startBar + count, maxBars);
      for(int i=startBar; i<endBar; i++) {
         if(high[i] > maxPrice) maxPrice = high[i];
         if(low[i] < minPrice) minPrice = low[i];
      }
      if(maxPrice <= minPrice) return;
      binSize = (maxPrice - minPrice) / (double)VOLUME_BINS;
      if(binSize <= 0) return;

      for(int i=startBar; i<endBar; i++) {
         double typical = (high[i] + low[i] + close[i]) / 3.0;
         int bin = (int)((typical - minPrice) / binSize);
         bin = MathMax(0, MathMin(VOLUME_BINS - 1, bin));
         if(bin >= 0 && bin < VOLUME_BINS) {
            bins[bin] += (double)volume[i];
            if(bins[bin] > pocVolume) {
               pocVolume = bins[bin];
               pocPrice = minPrice + (bin + 0.5) * binSize;
            }
         }
      }
   }

   double GetDensity(double price) {
      if(binSize <= 0) return 0;
      int bin = (int)((price - minPrice) / binSize);
      bin = MathMax(0, MathMin(VOLUME_BINS - 1, bin));
      if(bin >= 0 && bin < VOLUME_BINS) return bins[bin] / (pocVolume > 0 ? pocVolume : 1.0);
      return 0;
   }
};

int GetScaledPeriod(int basePeriod)
{
   if(InpM1x4Mode && _Period == PERIOD_M1) return basePeriod * M1_MULT;
   if(InpM4x4Mode && _Period == PERIOD_M4) return basePeriod * M1_MULT;
   return basePeriod;
}
int GetScaledShift(int baseShift)
{
   if(InpM1x4Mode && _Period == PERIOD_M1) return baseShift * M1_MULT;
   if(InpM4x4Mode && _Period == PERIOD_M4) return baseShift * M1_MULT;
   return baseShift;
}

uint ComputeCRC32(const string &data)
{
    uint crc = 0xFFFFFFFF;
    for(int i = 0; i < StringLen(data); i++)
    {
        crc ^= (uchar)StringGetCharacter(data, i);
        for(int j = 0; j < 8; j++)
            crc = (crc >> 1) ^ (0xEDB88320 * (crc & 1));
    }
    return ~crc;
}

void LoadButtonStates()
{
   string hName = "XU834_HUD_" + IntegerToString(ChartID());
   if(GlobalVariableCheck(hName)) g_hudVisible = (bool)GlobalVariableGet(hName); else g_hudVisible = true;
}

void SaveButtonStates()
{
   GlobalVariableSet("XU834_HUD_" + IntegerToString(ChartID()), g_hudVisible);
}

struct SignalState
{
   int      candleColor;
   int      stTernary;
   int      mtTernary;
   int      ltTernary;
   double   vwap;
   double   vwap_sd1_upper;
   double   vwap_sd1_lower;
   double   vwap_sd2_upper;
   double   vwap_sd2_lower;
   double   emaMain;
   double   emaSignal;
   int      currentZZ;
   double   trigger;
   double   price;
   double   hebbian;
   double   hebbian_delta;
   double   coil_tightness;
   double   coil_power;
   double   prev_coil_tightness;
   double   vwap_distance;
   int      trit_sum;
   datetime barTime;

   double   session_poc;
   double   fixed_poc;
   double   vacuum_density;
   double   poc_align_pips;

   void Clear()
   {
      candleColor = 2;
      stTernary = mtTernary = ltTernary = 0;
      vwap = vwap_sd1_upper = vwap_sd1_lower = vwap_sd2_upper = vwap_sd2_lower = emaMain = emaSignal = trigger = price = hebbian = 0.5;
      currentZZ = 0;
      hebbian_delta = coil_tightness = coil_power = vwap_distance = 0.0;
      prev_coil_tightness = 0.0;
      trit_sum = 0;
      barTime = 0;
      session_poc = fixed_poc = vacuum_density = poc_align_pips = 0.0;
   }

   void Calculate(double closePrice, double vwapVal, double vwapSD1U, double vwapSD1L, double vwapSD2U, double vwapSD2L,
                  double emaM, double emaSig, double trigVal, datetime timeVal, int cZZ)
   {
      price = closePrice;
      vwap = vwapVal;
      vwap_sd1_upper = vwapSD1U;
      vwap_sd1_lower = vwapSD1L;
      vwap_sd2_upper = vwapSD2U;
      vwap_sd2_lower = vwapSD2L;
      emaMain = emaM;
      emaSignal = emaSig;
      trigger = trigVal;
      barTime = timeVal;
      currentZZ = cZZ;

      mtTernary = (emaSignal >= emaMain) ? 1 : (emaSignal <= emaMain) ? -1 : 0;
      ltTernary = (price > vwap && vwap > 0) ? 1 : (price < vwap && vwap > 0) ? -1 : 0;

      double emaMid = emaMain;
      bool aboveVWAP = (price > vwap && vwap > 0);
      bool aboveEMAMid = (price > emaMid && emaMid > 0);

      if(aboveVWAP && aboveEMAMid) stTernary = 1;
      else if(!aboveVWAP && !aboveEMAMid) stTernary = -1;
      else stTernary = 0;

      if(currentZZ == 1 && emaSignal >= emaMain) candleColor = 0;
      else if(currentZZ == -1 && emaSignal <= emaMain) candleColor = 1;
      else candleColor = 2;

      vwap_distance = price - vwap;
      trit_sum = stTernary + mtTernary + ltTernary;
   }

   string GetActionString()
   {
      if(candleColor == 0) return "BULLISH -- BUY";
      if(candleColor == 1) return "BEARISH -- SELL";
      return "NEUTRAL -- WAIT";
   }

   string GetConsensusString()
   {
      if(stTernary == mtTernary && mtTernary == ltTernary && stTernary != 0)
         return (stTernary == 1) ? "FULL BULL" : "FULL BEAR";
      return "MIXED";
   }
};

struct ChartState
{
    double  tritMemory;
    double  hebbianMemory;
    double  hebbianEMA;
    bool    hebbianSeeded;
    double  lastBarHebbian;
    datetime lastBarTime;
    string  chartID;
    double  pvAccum[];
    double  pv2Accum[];
    double  vAccum[];
    datetime lastJsonWrite;
    double  lastJsonHebbian;
    double  lastJsonPrice;
    int      lastJsonColor;
    datetime lastPanelUpdate;
    uint    lastRedrawTick;
    string  symbol;
    int      period;
    bool    arraysAllocated;
    double  atrValue;
    double  atrBuf[];
    bool    atrSeeded;
    bool    alertsInitialized;
    double  releasePower;
    int     currentZZ;
    SwingMemory *swingMem;

    VolumeProfile sessionProfile;
    VolumeProfile fixedProfile;

    SignalState lastSignalForTimer;
    SignalState prevBarSignal;
    SignalState atomicSignal;
    datetime    lastCandleAlertBar;
    datetime    lastConsensusAlertBar;
    datetime    lastGenomeAlertBar;
    datetime    lastCoilFireAlertBar;
    datetime    lastCoilSpringAlertBar;
    int          lastSpringCooldownBars;

    void AllocateArrays()
    {
        if(!arraysAllocated)
        {
            ArrayResize(pvAccum, MAX_BARS);
            ArrayResize(pv2Accum, MAX_BARS);
            ArrayResize(vAccum, MAX_BARS);
            ArrayResize(atrBuf, MAX_BARS);
            ArraySetAsSeries(pvAccum, true);
            ArraySetAsSeries(pv2Accum, true);
            ArraySetAsSeries(vAccum, true);
            ArraySetAsSeries(atrBuf, true);
            ArrayInitialize(pvAccum, 0.0);
            ArrayInitialize(pv2Accum, 0.0);
            ArrayInitialize(vAccum, 0.0);
            ArrayInitialize(atrBuf, 0.0);
            arraysAllocated = true;
            atrSeeded = false;
            atrValue = 0.0;
            alertsInitialized = false;
            currentZZ = 0;
            swingMem = NULL;
            ClearAlertState();
        }
    }

    void ClearAlertState()
    {
        lastSignalForTimer.Clear();
        prevBarSignal.Clear();
        atomicSignal.Clear();
        lastCandleAlertBar    = 0;
        lastConsensusAlertBar = 0;
        lastGenomeAlertBar    = 0;
        lastCoilFireAlertBar  = 0;
        lastCoilSpringAlertBar = 0;
        lastSpringCooldownBars = 0;
        releasePower = 0.0;
    }
};
ChartState g_states[MAX_STATES];

string g_currentChartID;
string g_currentSymbol;
int    g_currentPeriod;
string g_tfName;
double g_symbolPoint;

SignalState g_currentSignal;

int g_hEMAMain, g_hEMASignal, g_hTrigger, g_hATR;

string GetObjectPrefix() { return "XU834_" + IntegerToString(ChartID()) + "_"; }

string GetTFName()
{
   switch(_Period)
   {
      case PERIOD_M1:   return "M1";
      case PERIOD_M2:   return "M2";
      case PERIOD_M3:   return "M3";
      case PERIOD_M4:   return "M4";
      case PERIOD_M5:   return "M5";
      case PERIOD_M6:   return "M6";
      case PERIOD_M10:  return "M10";
      case PERIOD_M12:  return "M12";
      case PERIOD_M15:  return "M15";
      case PERIOD_M20:  return "M20";
      case PERIOD_M30:  return "M30";
      case PERIOD_H1:   return "H1";
      case PERIOD_H2:   return "H2";
      case PERIOD_H3:   return "H3";
      case PERIOD_H4:   return "H4";
      case PERIOD_H6:   return "H6";
      case PERIOD_H8:   return "H8";
      case PERIOD_H12:  return "H12";
      case PERIOD_D1:   return "D1";
      case PERIOD_W1:   return "W1";
      case PERIOD_MN1:  return "MN1";
      default: return "M" + IntegerToString(_Period);
   }
}
color StateToColor(int state) { if(state==0)return InpHeaderBullColor; if(state==1)return InpHeaderBearColor; return InpHeaderNeutralColor; }

bool IsSessionGap(datetime curr, datetime prev)
{
   if(!InpUseSessionReset) return false;
   if(InpMaxSessionGapHours <= 0) return false;
   MqlDateTime ct,pt; TimeToStruct(curr,ct); TimeToStruct(prev,pt);
   if(ct.day!=pt.day||ct.mon!=pt.mon||ct.year!=pt.year) return true;
   if(curr-prev>InpMaxSessionGapHours*3600)return true;
   return false;
}

double GetAdaptiveDeadZone() { double p=g_symbolPoint>0?g_symbolPoint:_Point; return MathMax(InpTRITDeadZone*MathMax(p*1000,0.000001),1e-9); }

void SanitizeBuffers(int limit, const double &closeRef[])
{
    for(int i = 0; i < limit; i++)
    {
        if(i >= MAX_BARS) break;
        double fallback = closeRef[i];
        if(EMA_Main_Buf[i] == EMPTY_VALUE || !MathIsValidNumber(EMA_Main_Buf[i]))
        {
            Print("XU EFFECT v8.34: SanitizeBuffers - EMA_Main_Buf[", i, "] invalid, using close price fallback");
            EMA_Main_Buf[i] = fallback;
        }
        if(EMA_Signal_Buf[i] == EMPTY_VALUE || !MathIsValidNumber(EMA_Signal_Buf[i]))
        {
            Print("XU EFFECT v8.34: SanitizeBuffers - EMA_Signal_Buf[", i, "] invalid, using close price fallback");
            EMA_Signal_Buf[i] = fallback;
        }
        if(TriggerBuf[i] == EMPTY_VALUE || !MathIsValidNumber(TriggerBuf[i]))
        {
            Print("XU EFFECT v8.34: SanitizeBuffers - TriggerBuf[", i, "] invalid, using close price fallback");
            TriggerBuf[i] = fallback;
        }
    }
}

bool ReliableCopyBuffer(int handle, int buffer_idx, int count, double &dest[])
{
   if(handle == INVALID_HANDLE) return false;
   int copied = CopyBuffer(handle, buffer_idx, 0, count, dest);
   if(copied > 0) return true;
   for(int tries=0; tries<3; tries++)
   {
      copied = CopyBuffer(handle, buffer_idx, 0, count, dest);
      if(copied > 0) return true;
   }
   if(handle == g_hEMAMain) { IndicatorRelease(g_hEMAMain); g_hEMAMain = iMA(_Symbol,_Period,g_emaMainPeriod,0,MODE_EMA,PRICE_CLOSE); handle = g_hEMAMain; }
   else if(handle == g_hEMASignal) { IndicatorRelease(g_hEMASignal); g_hEMASignal = iMA(_Symbol,_Period,g_emaSignalPeriod,0,MODE_EMA,PRICE_CLOSE); handle = g_hEMASignal; }
   else if(handle == g_hTrigger) { IndicatorRelease(g_hTrigger); g_hTrigger = iMA(_Symbol,_Period,g_trigPeriod,0,MODE_SMMA,PRICE_CLOSE); handle = g_hTrigger; }
   else return false;
   if(handle == INVALID_HANDLE) return false;
   for(int tries=0; tries<3; tries++)
   {
      copied = CopyBuffer(handle, buffer_idx, 0, count, dest);
      if(copied > 0) return true;
   }
   return false;
}

int GetCurrentStateIndex()
{
   string chartID = _Symbol+"_"+IntegerToString(_Period)+"_"+IntegerToString(ChartID());
   g_currentChartID = chartID;
   for(int i=0;i<MAX_STATES;i++)
      if(g_states[i].chartID==chartID)
      {
         if(g_states[i].symbol!=_Symbol||g_states[i].period!=_Period)
         {
            Print("XU EFFECT v8.34: [SYSTEM RESET]");
            DeleteHUDObjects(); DeleteButtons();
            if(g_hEMAMain!=INVALID_HANDLE){IndicatorRelease(g_hEMAMain);g_hEMAMain=INVALID_HANDLE;}
            if(g_hEMASignal!=INVALID_HANDLE){IndicatorRelease(g_hEMASignal);g_hEMASignal=INVALID_HANDLE;}
            if(g_hTrigger!=INVALID_HANDLE){IndicatorRelease(g_hTrigger);g_hTrigger=INVALID_HANDLE;}
            if(g_hATR!=INVALID_HANDLE){IndicatorRelease(g_hATR);g_hATR=INVALID_HANDLE;}

            if(g_states[i].swingMem != NULL) { delete g_states[i].swingMem; g_states[i].swingMem = NULL; }

            int newFast = GetScaledPeriod(InpEMA_Main);
            int newSlow = GetScaledPeriod(InpEMA_Signal);
            int newTrig = GetScaledPeriod(InpTriggerPeriod);
            int newShift = GetScaledShift(InpTriggerShift);
            g_emaMainPeriod = newFast; g_emaSignalPeriod = newSlow; g_trigPeriod = newTrig; g_trigShift = newShift;
            g_hEMAMain = iMA(_Symbol, _Period, g_emaMainPeriod, 0, MODE_EMA, PRICE_CLOSE);
            g_hEMASignal = iMA(_Symbol, _Period, g_emaSignalPeriod, 0, MODE_EMA, PRICE_CLOSE);
            g_hTrigger = iMA(_Symbol, _Period, g_trigPeriod, 0, MODE_SMMA, PRICE_CLOSE);
            g_hATR = iATR(_Symbol, _Period, ATR_PERIOD);
            g_symbolPoint=SymbolInfoDouble(_Symbol,SYMBOL_POINT);
            g_tfName=GetTFName(); g_currentPeriod=_Period;
            g_states[i].arraysAllocated=false; g_states[i].AllocateArrays();
            g_states[i].symbol=_Symbol; g_states[i].period=_Period;
            g_states[i].hebbianSeeded=false; g_states[i].atrSeeded=false;
            g_states[i].lastBarTime=0; g_states[i].lastPanelUpdate=0;
            g_states[i].alertsInitialized=false; g_states[i].hebbianMemory=HEBBIAN_SEED_VALUE;
            g_states[i].lastBarHebbian=-1.0; g_states[i].ClearAlertState();
            g_states[i].releasePower=0.0;
            g_states[i].currentZZ = 0;
            if(g_states[i].swingMem == NULL) g_states[i].swingMem = new SwingMemory();

            ArrayInitialize(RibbonInnerUBuf, EMPTY_VALUE); ArrayInitialize(RibbonInnerLBuf, EMPTY_VALUE);
            ArrayInitialize(RibbonOuterUHiBuf, EMPTY_VALUE); ArrayInitialize(RibbonOuterULoBuf, EMPTY_VALUE);
            ArrayInitialize(RibbonOuterLHiBuf, EMPTY_VALUE); ArrayInitialize(RibbonOuterLLoBuf, EMPTY_VALUE);
            ArrayInitialize(VWAPBuf, EMPTY_VALUE); ArrayInitialize(EMA_Main_Buf, EMPTY_VALUE);
            ArrayInitialize(EMA_Signal_Buf, EMPTY_VALUE); ArrayInitialize(TriggerBuf, EMPTY_VALUE);
            ArrayInitialize(VWAPSD1UpperBuf, EMPTY_VALUE); ArrayInitialize(VWAPSD1LowerBuf, EMPTY_VALUE);
            ArrayInitialize(VWAPSDUpperBuf, EMPTY_VALUE); ArrayInitialize(VWAPSDLowerBuf, EMPTY_VALUE);
            ArrayInitialize(CandleOpen, EMPTY_VALUE); ArrayInitialize(CandleHigh, EMPTY_VALUE);
            ArrayInitialize(CandleLow, EMPTY_VALUE); ArrayInitialize(CandleClose, EMPTY_VALUE);
            ArrayInitialize(CandleCol, 2);
         }
         return i;
      }
   for(int i=0;i<MAX_STATES;i++)
      if(g_states[i].chartID=="")
      {
         g_states[i].chartID=chartID; g_states[i].symbol=_Symbol; g_states[i].period=_Period;
         g_states[i].tritMemory=0.0; g_states[i].hebbianMemory=HEBBIAN_SEED_VALUE; g_states[i].hebbianEMA=0.0;
         g_states[i].hebbianSeeded=false; g_states[i].lastBarHebbian=-1.0; g_states[i].lastBarTime=0;
         g_states[i].lastJsonWrite=0; g_states[i].lastJsonColor=-1; g_states[i].lastJsonHebbian=-1.0; g_states[i].lastJsonPrice=0.0;
         g_states[i].lastPanelUpdate=0; g_states[i].lastRedrawTick=0; g_states[i].atrValue=0.0; g_states[i].atrSeeded=false;
         g_states[i].alertsInitialized=false; g_states[i].arraysAllocated=false; g_states[i].AllocateArrays();
         g_states[i].releasePower=0.0;
         g_states[i].currentZZ = 0;
         if(g_states[i].swingMem == NULL) g_states[i].swingMem = new SwingMemory();
         return i;
      }
   return 0;
}

// --- HUD / Panel functions (unchanged from v8.33) ---
bool CreateOrUpdateLabel(string name,int x,int y,string text,string font,int size,color clr)
{
   string un=GetObjectPrefix()+name;
   if(ObjectFind(0,un)>=0)
   {
      ObjectSetInteger(0,un,OBJPROP_XDISTANCE,x); ObjectSetInteger(0,un,OBJPROP_YDISTANCE,y);
      ObjectSetString(0,un,OBJPROP_TEXT,text); ObjectSetString(0,un,OBJPROP_FONT,font);
      ObjectSetInteger(0,un,OBJPROP_FONTSIZE,size +2); ObjectSetInteger(0,un,OBJPROP_COLOR,clr);
      return true;
   }
   if(!ObjectCreate(0,un,OBJ_LABEL,0,0,0)) return false;
   ObjectSetInteger(0,un,OBJPROP_XDISTANCE,x); ObjectSetInteger(0,un,OBJPROP_YDISTANCE,y);
   ObjectSetString(0,un,OBJPROP_TEXT,text); ObjectSetString(0,un,OBJPROP_FONT,font);
   ObjectSetInteger(0,un,OBJPROP_FONTSIZE,size +5); ObjectSetInteger(0,un,OBJPROP_COLOR,clr);
   ObjectSetInteger(0,un,OBJPROP_SELECTABLE,false); return true;
}
bool CreateOrUpdateRect(string name,int x,int y,int w,int h,color bgColor)
{
   string un=GetObjectPrefix()+name;
   if(ObjectFind(0,un)>=0)
   {
      ObjectSetInteger(0,un,OBJPROP_XDISTANCE,x); ObjectSetInteger(0,un,OBJPROP_YDISTANCE,y);
      ObjectSetInteger(0,un,OBJPROP_XSIZE,w); ObjectSetInteger(0,un,OBJPROP_YSIZE,h);
      ObjectSetInteger(0,un,OBJPROP_BGCOLOR,bgColor); return true;
   }
   if(!ObjectCreate(0,un,OBJ_RECTANGLE_LABEL,0,0,0)) return false;
   ObjectSetInteger(0,un,OBJPROP_XDISTANCE,x); ObjectSetInteger(0,un,OBJPROP_YDISTANCE,y);
   ObjectSetInteger(0,un,OBJPROP_XSIZE,w); ObjectSetInteger(0,un,OBJPROP_YSIZE,h);
   ObjectSetInteger(0,un,OBJPROP_BGCOLOR,bgColor); ObjectSetInteger(0,un,OBJPROP_BORDER_TYPE,BORDER_FLAT);
   ObjectSetInteger(0,un,OBJPROP_CORNER,CORNER_LEFT_UPPER); ObjectSetInteger(0,un,OBJPROP_SELECTABLE,false);
   return true;
}
bool UpdateLabelOptimized(string name,string text,color clr=clrNONE)
{
   string un=GetObjectPrefix()+name;
   if(ObjectFind(0,un)<0) return false;
   string cur=ObjectGetString(0,un,OBJPROP_TEXT);
   if(cur!=text) ObjectSetString(0,un,OBJPROP_TEXT,text);
   if(clr!=clrNONE)
   {
      color c=(color)ObjectGetInteger(0,un,OBJPROP_COLOR);
      if(c!=clr) ObjectSetInteger(0,un,OBJPROP_COLOR,clr);
   }
   return true;
}
void DeleteAllObjects(){ObjectsDeleteAll(0,GetObjectPrefix(),-1,-1); ChartRedraw();}
void CreateHeader()
{
   if(!InpShowHeader) return;
   string h=GetObjectPrefix()+"Header_Main";
   if(ObjectFind(0,h)>=0) return;
   if(!ObjectCreate(0,h,OBJ_LABEL,0,0,0)) return;
   ObjectSetInteger(0,h,OBJPROP_CORNER,CORNER_LEFT_UPPER); ObjectSetInteger(0,h,OBJPROP_XDISTANCE,InpHeaderXOffset);
   ObjectSetInteger(0,h,OBJPROP_YDISTANCE,InpHeaderYOffset); ObjectSetInteger(0,h,OBJPROP_FONTSIZE,InpHeaderFontSize);
   ObjectSetString(0,h,OBJPROP_FONT,"Impact"); ObjectSetInteger(0,h,OBJPROP_SELECTABLE,false);
   ObjectSetInteger(0,h,OBJPROP_HIDDEN,true); ObjectSetString(0,h,OBJPROP_TEXT,_Symbol+" "+g_tfName);
}
void UpdateHeader(int c)
{
   if(!InpShowHeader) return;
   string h=GetObjectPrefix()+"Header_Main";
   if(ObjectFind(0,h)<0) return;
   ObjectSetString(0,h,OBJPROP_TEXT,_Symbol+" "+g_tfName); ObjectSetInteger(0,h,OBJPROP_COLOR,StateToColor(c));
}
void CreateButton(string id,string text,int x,int y,color txtColor)
{
   int sub=(InpBtnSubwindow<0)?ChartWindowFind():InpBtnSubwindow;
   ObjectDelete(0,id); ObjectCreate(0,id,OBJ_BUTTON,sub,0,0);
   ObjectSetInteger(0,id,OBJPROP_COLOR,txtColor); ObjectSetInteger(0,id,OBJPROP_BGCOLOR,C'30,30,38');
   ObjectSetInteger(0,id,OBJPROP_BORDER_COLOR,C'60,60,80'); ObjectSetInteger(0,id,OBJPROP_BORDER_TYPE,BORDER_RAISED);
   ObjectSetInteger(0,id,OBJPROP_XSIZE,InpBtnWidth); ObjectSetInteger(0,id,OBJPROP_YSIZE,InpBtnHeight);
   ObjectSetString(0,id,OBJPROP_FONT,"Consolas"); ObjectSetString(0,id,OBJPROP_TEXT,text);
   ObjectSetInteger(0,id,OBJPROP_FONTSIZE,InpBtnFontSize); ObjectSetInteger(0,id,OBJPROP_SELECTABLE,0);
   ObjectSetInteger(0,id,OBJPROP_CORNER,CORNER_LEFT_UPPER); ObjectSetInteger(0,id,OBJPROP_HIDDEN,1);
   ObjectSetInteger(0,id,OBJPROP_XDISTANCE,x); ObjectSetInteger(0,id,OBJPROP_YDISTANCE,y);
   ObjectSetInteger(0,id,OBJPROP_STATE,true);
}
void UpdateButtonColor(string id,bool on){ ObjectSetInteger(0,id,OBJPROP_COLOR,on?TC(TCR_BULL):TC(TCR_BEAR)); }

void InitButtons()
{
   string p=GetObjectPrefix();
   g_btnHudId   = p+"BTN_HUD_"+InpUniqueID;
   int by=InpVCDPanelY-InpBtnHeight-4;
   int x1=InpVCDPanelX;
   if(ObjectFind(0,g_btnHudId)<0) CreateButton(g_btnHudId,"HUD: ON",x1,by,TC(TCR_BULL));
   LoadButtonStates();
   ObjectSetInteger(0, g_btnHudId, OBJPROP_STATE, g_hudVisible);
   UpdateButtonColor(g_btnHudId, g_hudVisible);
   ObjectSetString(0, g_btnHudId, OBJPROP_TEXT, g_hudVisible ? "HUD: ON" : "HUD: OFF");
}

void DeleteButtons(){ if(g_btnHudId!="")ObjectDelete(0,g_btnHudId); }
void DeleteHUDObjects(){ string p=GetObjectPrefix(); ObjectsDeleteAll(0,p+"VCD_",-1,-1); ChartRedraw(); }
void SetLinesVisible(bool v)
{
   if(v) {
      PlotIndexSetInteger(3,PLOT_DRAW_TYPE,InpShowVWAP?DRAW_LINE:DRAW_NONE);
      PlotIndexSetInteger(4,PLOT_DRAW_TYPE,DRAW_COLOR_LINE);
      PlotIndexSetInteger(4,PLOT_COLOR_INDEXES,2);
      PlotIndexSetInteger(5,PLOT_DRAW_TYPE,DRAW_LINE);
      PlotIndexSetInteger(5,PLOT_SHIFT,g_trigShift);
      PlotIndexSetInteger(6,PLOT_DRAW_TYPE,InpShowSD?DRAW_LINE:DRAW_NONE);
      PlotIndexSetInteger(7,PLOT_DRAW_TYPE,InpShowSD?DRAW_LINE:DRAW_NONE);
      PlotIndexSetInteger(8,PLOT_DRAW_TYPE,InpShowSD?DRAW_LINE:DRAW_NONE);
      PlotIndexSetInteger(9,PLOT_DRAW_TYPE,InpShowSD?DRAW_LINE:DRAW_NONE);
      PlotIndexSetInteger(10,PLOT_DRAW_TYPE,DRAW_COLOR_CANDLES);
   }
   else for(int i=0;i<11;i++) PlotIndexSetInteger(i,PLOT_DRAW_TYPE,DRAW_NONE);
   ChartRedraw();
}
void InitThemeColors()
{
   g_themeColors[0][TCR_BULL]=C'0,255,142'; g_themeColors[0][TCR_BEAR]=clrOrangeRed; g_themeColors[0][TCR_NEUT]=C'180,180,180'; g_themeColors[0][TCR_LABEL]=C'180,180,180'; g_themeColors[0][TCR_FRAME]=C'30,41,59'; g_themeColors[0][TCR_BG]=C'25,25,35'; g_themeColors[0][TCR_HDRBG]=C'10,10,12'; g_themeColors[0][TCR_META]=C'255,255,100'; g_themeColors[0][TCR_GENHI]=clrLime; g_themeColors[0][TCR_FOOTER]=C'38,88,125';
   g_themeColors[1][TCR_BULL]=C'0,255,65'; g_themeColors[1][TCR_BEAR]=C'255,60,60'; g_themeColors[1][TCR_NEUT]=C'180,180,180'; g_themeColors[1][TCR_LABEL]=C'0,170,0'; g_themeColors[1][TCR_FRAME]=C'0,90,0'; g_themeColors[1][TCR_BG]=C'0,6,0'; g_themeColors[1][TCR_HDRBG]=C'0,0,0'; g_themeColors[1][TCR_META]=C'0,255,65'; g_themeColors[1][TCR_GENHI]=C'170,255,170'; g_themeColors[1][TCR_FOOTER]=C'0,90,0';
   g_themeColors[2][TCR_BULL]=C'255,215,0'; g_themeColors[2][TCR_BEAR]=C'255,107,53'; g_themeColors[2][TCR_NEUT]=C'180,180,180'; g_themeColors[2][TCR_LABEL]=C'200,160,96'; g_themeColors[2][TCR_FRAME]=C'139,94,0'; g_themeColors[2][TCR_BG]=C'26,18,0'; g_themeColors[2][TCR_HDRBG]=C'10,8,0'; g_themeColors[2][TCR_META]=C'255,215,0'; g_themeColors[2][TCR_GENHI]=C'255,165,0'; g_themeColors[2][TCR_FOOTER]=C'139,94,0';
   g_themeColors[3][TCR_BULL]=C'127,255,255'; g_themeColors[3][TCR_BEAR]=C'255,127,127'; g_themeColors[3][TCR_NEUT]=C'180,180,180'; g_themeColors[3][TCR_LABEL]=C'160,184,208'; g_themeColors[3][TCR_FRAME]=C'42,64,112'; g_themeColors[3][TCR_BG]=C'10,15,32'; g_themeColors[3][TCR_HDRBG]=C'5,8,16'; g_themeColors[3][TCR_META]=C'200,224,255'; g_themeColors[3][TCR_GENHI]=C'255,255,255'; g_themeColors[3][TCR_FOOTER]=C'42,64,112';
   g_themeColors[4][TCR_BULL]=C'255,34,68'; g_themeColors[4][TCR_BEAR]=C'255,140,0'; g_themeColors[4][TCR_NEUT]=C'180,180,180'; g_themeColors[4][TCR_LABEL]=C'204,102,102'; g_themeColors[4][TCR_FRAME]=C'88,0,0'; g_themeColors[4][TCR_BG]=C'16,0,0'; g_themeColors[4][TCR_HDRBG]=C'8,0,0'; g_themeColors[4][TCR_META]=C'255,68,102'; g_themeColors[4][TCR_GENHI]=C'255,0,102'; g_themeColors[4][TCR_FOOTER]=C'88,0,0';
}
color TC(int r){return g_themeColors[InpColorTheme][r];}

int ComputePanelHeight()
{
   int y = InpVCDPanelY + 57;
   y += InpRowHeight; y += InpRowHeight; y += 4;
   y += InpRowHeight; y += InpRowHeight; y += 4;
   y += InpRowHeight; y += InpRowHeight; y += InpRowHeight; y += InpRowHeight; y += 4;
   y += 14; y += 4 * InpRowHeight; y += 4;
   y += 24; y += InpActionFontSize + 16; y += 20;
   return y - InpVCDPanelY + 4 + InpRowHeight;
}
void InitPanelLayout()
{
   g_col1X = InpVCDPanelX + 8; g_col2X = InpVCDPanelX + 8 + InpLabelColWidth + 4; g_col3X = InpVCDPanelX + InpVCDPanelWidth - InpCircleColWidth - 6;
   int y = InpVCDPanelY + 57;
   g_rowY_Candle  = y; y += InpRowHeight;
   g_rowY_Trend   = y; y += InpRowHeight; y += 4;
   g_rowY_Genome  = y; y += InpRowHeight;
   g_rowY_Price   = y; y += InpRowHeight; y += 4;
   g_rowY_Align   = y; y += InpRowHeight;
   g_rowY_Vacuum  = y; y += InpRowHeight;
   g_rowY_Power   = y; y += InpRowHeight;
   g_rowY_Vwap    = y; y += InpRowHeight;
   g_rowY_Trigger = y; y += InpRowHeight; y += 4;
   g_rowY_TernHdr = y; y += 14;
   g_rowY_ST      = y; y += InpRowHeight;
   g_rowY_MT      = y; y += InpRowHeight;
   g_rowY_LT      = y; y += InpRowHeight;
   g_rowY_Cons    = y; y += InpRowHeight; y += 4;
   g_scoreBarY    = y; y += 24;
   g_actionY      = y; y += InpActionFontSize + 16;
   g_footerY      = y;
   g_panelH       = ComputePanelHeight();
}

void CreateVCDPanel()
{
   if(!InpShowVCDPanel||!g_hudVisible) return;
   if(ObjectFind(0,GetObjectPrefix()+"VCD_BG")>=0) return;
   int x=InpVCDPanelX,y=InpVCDPanelY,w=InpVCDPanelWidth; string fnt="Consolas";
   CreateOrUpdateRect("VCD_BG",x,y,w,g_panelH,TC(TCR_BG)); CreateOrUpdateRect("VCD_FRAME",x-1,y-1,w+2,g_panelH+2,TC(TCR_FRAME));
   CreateOrUpdateRect("VCD_HDR_BG",x+2,y+2,w-4,28,TC(TCR_HDRBG));
   string title = "LIVE DATA STREAM // v8.34";
   if(InpM1x4Mode && _Period == PERIOD_M1) title += " (M1×4)";
   if(InpM4x4Mode && _Period == PERIOD_M4) title += " (M4×4)";
   CreateOrUpdateLabel("VCD_Title",x+10,y+7,title,fnt,InpPanelFontSize -3,TC(TCR_LABEL));
   CreateOrUpdateLabel("VCD_Valid",x+w-68,y+6,"ATOMIC",fnt,InpPanelFontSize -1,TC(TCR_FOOTER));
   CreateOrUpdateRect("VCD_TOP_LINE",x+4,y+32,w-8,1,TC(TCR_FRAME));
   CreateOrUpdateLabel("VCD_TF",x+10,y+36-4,"",fnt,InpPanelFontSize+1,TC(TCR_META));
   CreateOrUpdateLabel("VCD_Time",x+w-92,y+36-4,"",fnt,InpPanelFontSize,TC(TCR_BULL));
   CreateOrUpdateRect("VCD_SEP_META",x+4,y+53,w-8,1,TC(TCR_BULL));

   CreateOrUpdateLabel("VCD_L_Candle",g_col1X,g_rowY_Candle-4,"CANDLE",fnt,InpPanelFontSize,TC(TCR_LABEL));
   CreateOrUpdateLabel("VCD_V_Candle",g_col2X,g_rowY_Candle-4,"",fnt,InpPanelFontSize,TC(TCR_NEUT));
   CreateOrUpdateLabel("VCD_C_Candle",g_col3X,g_rowY_Candle-12,"●",fnt,InpPanelFontSize+8,TC(TCR_NEUT));
   CreateOrUpdateLabel("VCD_L_Trend",g_col1X,g_rowY_Trend-4,"TREND",fnt,InpPanelFontSize,TC(TCR_LABEL));
   CreateOrUpdateLabel("VCD_V_Trend",g_col2X,g_rowY_Trend-4,"",fnt,InpPanelFontSize,TC(TCR_NEUT));
   CreateOrUpdateLabel("VCD_C_Trend",g_col3X,g_rowY_Trend-12,"●",fnt,InpPanelFontSize+8,TC(TCR_NEUT));
   CreateOrUpdateRect("VCD_DIV1",x+4,g_rowY_Trend+InpRowHeight,w-8,1,TC(TCR_FRAME));

   CreateOrUpdateLabel("VCD_L_Genome",g_col1X,g_rowY_Genome-4,"GENOME",fnt,InpPanelFontSize,TC(TCR_LABEL));
   CreateOrUpdateLabel("VCD_V_Genome",g_col2X,g_rowY_Genome-4,"",fnt,InpPanelFontSize ,TC(TCR_NEUT));
   CreateOrUpdateLabel("VCD_C_Genome",g_col3X,g_rowY_Genome-12,"●",fnt,InpPanelFontSize+8,TC(TCR_NEUT));
   CreateOrUpdateLabel("VCD_L_Price",g_col1X,g_rowY_Price-4,"PRICE",fnt,InpPanelFontSize,TC(TCR_LABEL));
   CreateOrUpdateLabel("VCD_V_Price",g_col2X,g_rowY_Price-4,"",fnt,InpPanelFontSize,TC(TCR_LABEL));
   CreateOrUpdateRect("VCD_DIV2",x+4,g_rowY_Price+InpRowHeight,w-8,1,TC(TCR_FRAME));

   CreateOrUpdateLabel("VCD_L_Align",g_col1X,g_rowY_Align-4,"POC ALIGN",fnt,InpPanelFontSize,TC(TCR_LABEL));
   CreateOrUpdateLabel("VCD_V_Align",g_col2X,g_rowY_Align-4,"",fnt,InpPanelFontSize,TC(TCR_NEUT));
   CreateOrUpdateLabel("VCD_L_Vacuum",g_col1X,g_rowY_Vacuum-4,"VACUUM",fnt,InpPanelFontSize,TC(TCR_LABEL));
   CreateOrUpdateLabel("VCD_V_Vacuum",g_col2X,g_rowY_Vacuum-4,"",fnt,InpPanelFontSize-2,TC(TCR_NEUT));

   CreateOrUpdateLabel("VCD_L_Power",g_col1X,g_rowY_Power-4,"POWER",fnt,InpPanelFontSize-1,TC(TCR_LABEL));
   CreateOrUpdateLabel("VCD_V_Power",g_col2X,g_rowY_Power-4,"",fnt,InpPanelFontSize-1,TC(TCR_NEUT));

   CreateOrUpdateLabel("VCD_L_VWAP",g_col1X,g_rowY_Vwap-4,"VWAP STAT",fnt,InpPanelFontSize,TC(TCR_LABEL));
   CreateOrUpdateLabel("VCD_V_VWAP",g_col2X,g_rowY_Vwap-4,"",fnt,InpPanelFontSize,TC(TCR_NEUT));
   CreateOrUpdateLabel("VCD_C_VWAP",g_col3X,g_rowY_Vwap-12,"●",fnt,InpPanelFontSize+8,TC(TCR_NEUT));
   CreateOrUpdateLabel("VCD_L_Trigger",g_col1X,g_rowY_Trigger-4,"TRIGGER",fnt,InpPanelFontSize,TC(TCR_LABEL));
   CreateOrUpdateLabel("VCD_V_Trigger",g_col2X,g_rowY_Trigger-4,"",fnt,InpPanelFontSize,TC(TCR_NEUT));
   CreateOrUpdateLabel("VCD_C_Trigger",g_col3X,g_rowY_Trigger-12,"●",fnt,InpPanelFontSize+8,TC(TCR_NEUT));
   CreateOrUpdateRect("VCD_DIV3",x+4,g_rowY_Trigger+InpRowHeight,w-8,1,TC(TCR_BULL));

   CreateOrUpdateLabel("VCD_L_TernHdr",g_col1X,g_rowY_TernHdr-4,"TERNARY",fnt,InpPanelFontSize,TC(TCR_META));
   int subX=g_col1X+10;
   CreateOrUpdateLabel("VCD_L_ST",subX-10,g_rowY_ST,"ST exec",fnt,InpPanelFontSize,TC(TCR_LABEL));
   CreateOrUpdateLabel("VCD_V_ST",g_col2X-10,g_rowY_ST,"",fnt,InpPanelFontSize,TC(TCR_NEUT));
   CreateOrUpdateLabel("VCD_C_ST",g_col3X,g_rowY_ST-12,"●",fnt,InpPanelFontSize+8,TC(TCR_NEUT));
   CreateOrUpdateLabel("VCD_L_MT",subX-10,g_rowY_MT,"MT trend",fnt,InpPanelFontSize,TC(TCR_LABEL));
   CreateOrUpdateLabel("VCD_V_MT",g_col2X-10,g_rowY_MT,"",fnt,InpPanelFontSize,TC(TCR_NEUT));
   CreateOrUpdateLabel("VCD_C_MT",g_col3X,g_rowY_MT-12,"●",fnt,InpPanelFontSize+8,TC(TCR_NEUT));
   CreateOrUpdateLabel("VCD_L_LT",subX-10,g_rowY_LT,"LT inst",fnt,InpPanelFontSize,TC(TCR_LABEL));
   CreateOrUpdateLabel("VCD_V_LT",g_col2X-10,g_rowY_LT,"",fnt,InpPanelFontSize,TC(TCR_NEUT));
   CreateOrUpdateLabel("VCD_C_LT",g_col3X,g_rowY_LT-12,"●",fnt,InpPanelFontSize+8,TC(TCR_NEUT));
   CreateOrUpdateLabel("VCD_L_Cons",subX-10,g_rowY_Cons,"CONSENSUS",fnt,InpPanelFontSize,TC(TCR_LABEL));
   CreateOrUpdateLabel("VCD_V_Cons",g_col2X+30,g_rowY_Cons,"",fnt,InpPanelFontSize,TC(TCR_NEUT));
   CreateOrUpdateLabel("VCD_C_Cons",g_col3X,g_rowY_Cons-12,"●",fnt,InpPanelFontSize+8,TC(TCR_NEUT));

   CreateOrUpdateRect("VCD_SCORE_BG",x+2,g_scoreBarY,w-4,22,TC(TCR_HDRBG));
   CreateOrUpdateLabel("VCD_SCORE_LBL",x+10,g_scoreBarY+1,"CONDITIONS",fnt,InpPanelFontSize-1,TC(TCR_NEUT));
   CreateOrUpdateLabel("VCD_SCORE_DOTS",x+108,g_scoreBarY+1,"",fnt,InpPanelFontSize-2,TC(TCR_NEUT));
   CreateOrUpdateLabel("VCD_SCORE_NUM",x+w-44,g_scoreBarY+1,"0/8",fnt,InpPanelFontSize,TC(TCR_NEUT));
   CreateOrUpdateRect("VCD_ACTION_BG",x+2,g_actionY,w-4,InpActionFontSize+16,TC(TCR_HDRBG));
   CreateOrUpdateLabel("VCD_L_Action",x+25,g_actionY+3,"ACTION",fnt,InpPanelFontSize,TC(TCR_LABEL));
   CreateOrUpdateLabel("VCD_V_Action",g_col2X,g_actionY+3,"",fnt,InpActionFontSize,TC(TCR_NEUT));
   CreateOrUpdateRect("VCD_FOOT_BG",x+2,g_footerY,w-4,20,TC(TCR_HDRBG));
   CreateOrUpdateLabel("VCD_Footer",x+10,g_footerY,"JSON -> HomeLAB",fnt,InpPanelFontSize-1,TC(TCR_FOOTER));
   CreateOrUpdateLabel("VCD_Preset",x+w-110,g_footerY,"VAULT-READY",fnt,InpPanelFontSize-1,TC(TCR_FOOTER));
}

void UpdateVCDPanel(SignalState &sig)
{
   if(!InpShowVCDPanel||!g_hudVisible) return;
   int stateIdx=GetCurrentStateIndex(); if(stateIdx<0) return;
   datetime nowBroker=TimeCurrent();
   if(nowBroker-g_states[stateIdx].lastPanelUpdate<PANEL_UPDATE_SEC) return;
   g_states[stateIdx].lastPanelUpdate=nowBroker;
   CreateVCDPanel();

   datetime displayTime=TimeLocal(); MqlDateTime mdt; TimeToStruct(displayTime,mdt);
   UpdateLabelOptimized("VCD_Time",StringFormat("%02d:%02d:%02d",mdt.hour,mdt.min,mdt.sec),TC(TCR_BULL));
   UpdateLabelOptimized("VCD_TF",_Symbol+"  "+g_tfName,TC(TCR_META));

   string cV; color cC,cR; string circ;
   if(sig.candleColor==0){cV="[BUY]  BULLISH";cC=TC(TCR_BULL);circ="●";cR=TC(TCR_BULL);}
   else if(sig.candleColor==1){cV="[SELL] BEARISH";cC=TC(TCR_BEAR);circ="●";cR=TC(TCR_BEAR);}
   else{cV="[WAIT] NEUTRAL";cC=TC(TCR_NEUT);circ="●";cR=TC(TCR_NEUT);}
   UpdateLabelOptimized("VCD_V_Candle",cV,cC); UpdateLabelOptimized("VCD_C_Candle",circ,cR);
   if(sig.mtTernary==1){cV="[BULLISH]";cC=TC(TCR_BULL);circ="●";cR=TC(TCR_BULL);}
   else if(sig.mtTernary==-1){cV="[BEARISH]";cC=TC(TCR_BEAR);circ="●";cR=TC(TCR_BEAR);}
   else{cV="NEUTRAL";cC=TC(TCR_NEUT);circ="●";cR=TC(TCR_NEUT);}
   UpdateLabelOptimized("VCD_V_Trend",cV,cC); UpdateLabelOptimized("VCD_C_Trend",circ,cR);

   string genomeStr;
   if(sig.hebbian > GENOME_EXTREME_HIGH) genomeStr = StringFormat("%.4f > %.2f %s",sig.hebbian,GENOME_EXTREME_HIGH,"ExtH");
   else if(sig.hebbian > GENOME_HIGH_THRESH) genomeStr = StringFormat("%.4f > %.2f %s",sig.hebbian,GENOME_HIGH_THRESH,"High");
   else if(sig.hebbian < GENOME_EXTREME_LOW) genomeStr = StringFormat("%.4f < %.2f %s",sig.hebbian,GENOME_EXTREME_LOW,"ExtL");
   else if(sig.hebbian < GENOME_LOW_THRESH) genomeStr = StringFormat("%.4f < %.2f %s",sig.hebbian,GENOME_LOW_THRESH,"Low");
   else genomeStr = StringFormat("%.4f = %.2f %s",sig.hebbian,HEBBIAN_SEED_VALUE,"Seed");
   if(sig.hebbian>GENOME_HIGH_THRESH) {cC=TC(TCR_GENHI);circ="●";cR=TC(TCR_GENHI);}
   else if(sig.hebbian>GENOME_MID_THRESH) {cC=TC(TCR_BULL);circ="●";cR=TC(TCR_BULL);}
   else if(sig.hebbian<GENOME_LOW_THRESH) {cC=TC(TCR_BEAR);circ="●";cR=TC(TCR_BEAR);}
   else {cC=TC(TCR_NEUT);circ="●";cR=TC(TCR_NEUT);}
   UpdateLabelOptimized("VCD_V_Genome",genomeStr,cC); UpdateLabelOptimized("VCD_C_Genome",circ,cR);
   UpdateLabelOptimized("VCD_V_Price",DoubleToString(sig.price,_Digits),TC(TCR_LABEL));

   string alignTxt = StringFormat("[S] < %.1f p > [F]", sig.poc_align_pips);
   color alignClr = (sig.poc_align_pips < 5.0) ? clrGold : (sig.poc_align_pips < 15.0) ? TC(TCR_BULL) : TC(TCR_NEUT);
   UpdateLabelOptimized("VCD_V_Align", alignTxt, alignClr);

   int vFill = (int)MathFloor((1.0 - sig.vacuum_density) * 8.0); if(vFill < 0) vFill = 0; if(vFill > 8) vFill = 8;
   string vGauge = "[" + StringFormat("%.*s", vFill, "████████") + StringFormat("%.*s", 8 - vFill, "░░░░░░░░") + "]";
   string vTxt = StringFormat("%s %.1f%% %s", vGauge, (1.0 - sig.vacuum_density) * 100.0, (sig.vacuum_density < 0.2) ? "VACUUM" : "CHURN");
   color vClr = (sig.vacuum_density < 0.2) ? clrGold : TC(TCR_NEUT);
   UpdateLabelOptimized("VCD_V_Vacuum", vTxt, vClr);

   string pwrLabel = GetPowerLabel(sig.coil_power);
   color pwrCol=TC(TCR_NEUT);
   double mult = (InpKineticRegime) ? InpKineticMultiplier : 1.0;

   if(sig.coil_power >= 90.0 * MathMin(1.1, (1.0 + (mult-1.0)/3.0))) pwrCol=clrMagenta;
   else if(sig.coil_power >= 75.0 * mult) pwrCol=TC(TCR_BULL);
   else if(sig.coil_power >= 50.0 * mult) pwrCol=TC(TCR_META);
   else if(sig.coil_power >= 25.0 * mult) pwrCol=TC(TCR_LABEL);

   UpdateLabelOptimized("VCD_V_Power",StringFormat("%s (%.1f%%)",pwrLabel,sig.coil_power),pwrCol);

   string vwapStr = DoubleToString(sig.vwap, _Digits);
   color vwapClr = TC(TCR_NEUT);
   if(sig.vwap_sd2_upper > sig.vwap) {
       double sd_dist = sig.vwap_sd2_upper - sig.vwap;
       if(sig.price > sig.vwap_sd2_upper + (0.125 * sd_dist)) { vwapStr += " !! EXHAUSTED !!"; vwapClr = clrRed; }
       else if(sig.price > sig.vwap_sd2_upper) { vwapStr += " > STRETCHING"; vwapClr = clrGold; }
       else { vwapStr += " < SAFE"; vwapClr = TC(TCR_BULL); }
   }
   UpdateLabelOptimized("VCD_V_VWAP",vwapStr,vwapClr);
   UpdateLabelOptimized("VCD_C_VWAP","●",vwapClr);

   bool trigValid=(sig.trigger!=EMPTY_VALUE&&sig.trigger>0);
   if(trigValid&&sig.price>sig.trigger){cV=DoubleToString(sig.trigger,_Digits)+"  ABOVE";cC=TC(TCR_BULL);circ="●";cR=TC(TCR_BULL);}
   else if(trigValid){cV=DoubleToString(sig.trigger,_Digits)+"  BELOW";cC=TC(TCR_BEAR);circ="●";cR=TC(TCR_BEAR);}
   else{cV="N/A";cC=TC(TCR_NEUT);circ="●";cR=TC(TCR_NEUT);}
   UpdateLabelOptimized("VCD_V_Trigger",cV,cC); UpdateLabelOptimized("VCD_C_Trigger",circ,cR);

   if(sig.stTernary==1){cV="+1  LONG BIAS";cC=TC(TCR_BULL);circ="●";cR=TC(TCR_BULL);}
   else if(sig.stTernary==-1){cV="-1  SHORT BIAS";cC=TC(TCR_BEAR);circ="●";cR=TC(TCR_BEAR);}
   else{cV=" 0  MIXED";cC=TC(TCR_NEUT);circ="●";cR=TC(TCR_NEUT);}
   UpdateLabelOptimized("VCD_V_ST",cV,cC); UpdateLabelOptimized("VCD_C_ST",circ,cR);
   if(sig.mtTernary==1){cV="+1  BULLISH";cC=TC(TCR_BULL);circ="●";cR=TC(TCR_BULL);}
   else if(sig.mtTernary==-1){cV="-1  BEARISH";cC=TC(TCR_BEAR);circ="●";cR=TC(TCR_BEAR);}
   else{cV=" 0  TRENDLESS";cC=TC(TCR_NEUT);circ="●";cR=TC(TCR_NEUT);}
   UpdateLabelOptimized("VCD_V_MT",cV,cC); UpdateLabelOptimized("VCD_C_MT",circ,cR);
   if(sig.ltTernary==1){cV="+1  INST LONG";cC=TC(TCR_BULL);circ="●";cR=TC(TCR_BULL);}
   else if(sig.ltTernary==-1){cV="-1  INST SHORT";cC=TC(TCR_BEAR);circ="●";cR=TC(TCR_BEAR);}
   else{cV=" 0  NEUTRAL";cC=TC(TCR_NEUT);circ="●";cR=TC(TCR_NEUT);}
   UpdateLabelOptimized("VCD_V_LT",cV,cC); UpdateLabelOptimized("VCD_C_LT",circ,cR);

   bool consensus=(sig.stTernary==sig.mtTernary&&sig.mtTernary==sig.ltTernary&&sig.stTernary!=0);
   if(consensus&&sig.stTernary==1){cV="FULL BULL";cC=TC(TCR_BULL);circ="●";cR=TC(TCR_BULL);}
   else if(consensus&&sig.stTernary==-1){cV="FULL BEAR";cC=TC(TCR_BEAR);circ="●";cR=TC(TCR_BEAR);}
   else{cV="MIXED";cC=TC(TCR_NEUT);circ="●";cR=TC(TCR_NEUT);}
   UpdateLabelOptimized("VCD_V_Cons",cV,cC); UpdateLabelOptimized("VCD_C_Cons",circ,cR);

   int score=0;
   if(sig.candleColor!=2)score++; if(sig.mtTernary!=0)score++; if(sig.hebbian>GENOME_MID_THRESH||sig.hebbian<GENOME_VLOW_THRESH)score++;
   if(sig.ltTernary!=0)score++; if(trigValid)score++; if(sig.stTernary!=0)score++;
   if(MathAbs(sig.trit_sum)>=SCORE_COL_THRESHOLD)score++; if(consensus)score++;
   string sBar="["+StringFormat("%.*s",score,"████████")+StringFormat("%.*s",8-score,"░░░░░░░░")+"] "+IntegerToString(score)+"/8";
   color sc;
   if(score >= 6) sc = (sig.candleColor == 1 || sig.trit_sum < -1) ? TC(TCR_BEAR) : (sig.candleColor == 0 || sig.trit_sum > 1) ? TC(TCR_BULL) : TC(TCR_GENHI);
   else if(score >= 4) sc = TC(TCR_NEUT);
   else sc = TC(TCR_BEAR);
   UpdateLabelOptimized("VCD_SCORE_DOTS",sBar,sc); UpdateLabelOptimized("VCD_SCORE_NUM",StringFormat("%d/8",score),sc);
   if(sig.candleColor==0){cV="▲  BUY SIGNAL";cC=TC(TCR_BULL);}
   else if(sig.candleColor==1){cV="▼  SELL SIGNAL";cC=TC(TCR_BEAR);}
   else{cV="—  NEUTRAL WAIT";cC=TC(TCR_NEUT);}
   UpdateLabelOptimized("VCD_V_Action",cV,cC);
}

string GetPowerLabel(double power)
{
   double mult = (InpKineticRegime) ? InpKineticMultiplier : 1.0;
   string r = (InpKineticRegime) ? "[R] " : "";

   if(power >= 90.0 * MathMin(1.1, (1.0 + (mult-1.0)/3.0))) return r + "SPRING RELEASE";
   if(power >= 75.0 * mult) return r + "HIGH";
   if(power >= 50.0 * mult) return r + "MED";
   if(power >= 25.0 * mult) return r + "DRIFT";
   return r + "STALL";
}

string GenerateJSON(SignalState &sig, datetime nowGMT)
{
   bool powerActive = (sig.coil_power >= 50.0 * ((InpKineticRegime) ? InpKineticMultiplier : 1.0));
   return StringFormat(
      "{\"version\":\"8.34-DUALRIBBON\",\"symbol\":\"%s\",\"tf\":\"%s\","
      "\"kinetic_active\":%s,\"kinetic_mult\":%.2f,"
      "\"hebbian\":%.4f,\"hebbian_delta\":%.6f,"
      "\"vwap\":%.*f,\"vwap_sd1_upper\":%.*f,\"vwap_sd1_lower\":%.*f,"
      "\"vwap_sd2_upper\":%.*f,\"vwap_sd2_lower\":%.*f,"
      "\"price\":%.*f,\"vwap_distance\":%.*f,"
      "\"ema_fast\":%.*f,\"ema_slow\":%.*f,\"trigger\":%.*f,"
      "\"coil_tightness\":%.2f,\"coil_power\":%.4f,"
      "\"session_poc\":%.*f,\"fixed_poc\":%.*f,\"vacuum\":%.4f,"
      "\"poc_align\":%.2f,"
      "\"sovereign_bias\":%.1f,\"trit_sum\":%d,\"candle_color\":%d,\"action\":\"%s\","
      "\"timestamp\":%lld,\"st_ternary\":%d,\"mt_ternary\":%d,\"lt_ternary\":%d,"
      "\"consensus\":\"%s\",\"bar_time\":%lld,"
      "\"power_label\":\"%s\",\"power_filter_active\":%s}",
      _Symbol, g_tfName,
      (InpKineticRegime) ? "true" : "false", InpKineticMultiplier,
      sig.hebbian, sig.hebbian_delta,
      _Digits, sig.vwap, _Digits, sig.vwap_sd1_upper, _Digits, sig.vwap_sd1_lower,
      _Digits, sig.vwap_sd2_upper, _Digits, sig.vwap_sd2_lower,
      _Digits, sig.price, _Digits, sig.vwap_distance,
      _Digits, sig.emaMain, _Digits, sig.emaSignal, _Digits, sig.trigger,
      sig.coil_tightness, sig.coil_power,
      _Digits, sig.session_poc, _Digits, sig.fixed_poc, sig.vacuum_density,
      sig.poc_align_pips,
      (sig.candleColor==0 ? 1.0 : sig.candleColor==1 ? -1.0 : 0.0), sig.trit_sum, sig.candleColor, sig.GetActionString(),
      (long)nowGMT, sig.stTernary, sig.mtTernary, sig.ltTernary,
      sig.GetConsensusString(), (long)sig.barTime,
      GetPowerLabel(sig.coil_power), powerActive ? "true" : "false"
   );
}

bool IsSpringCooldownExpired(int stateIdx, datetime currentBarTime)
{
    if(g_states[stateIdx].lastCoilSpringAlertBar <= 0) return true;
    int barsSince = iBarShift(_Symbol, _Period, g_states[stateIdx].lastCoilSpringAlertBar);
    if(barsSince < 0) return true;
    return (barsSince >= InpCoilFireCooldown);
}

void CheckAndFireAlerts(SignalState &current, SignalState &previous, datetime currentBarTime, int stateIdx)
{
   if(!InpUseAlerts||stateIdx<0) return;
   if(!g_states[stateIdx].alertsInitialized) return;

   if(current.candleColor!=previous.candleColor&&currentBarTime!=g_states[stateIdx].lastCandleAlertBar)
   {
      string msg;
      if(current.candleColor==0) msg=StringFormat("XU EFFECT v8.34 %s %s: BULLISH BUY",_Symbol,g_tfName);
      else if(current.candleColor==1) msg=StringFormat("XU EFFECT v8.34 %s %s: BEARISH SELL",_Symbol,g_tfName);
      else msg=StringFormat("XU EFFECT v8.34 %s %s: NEUTRAL WAIT",_Symbol,g_tfName);
      Alert(msg); if(TerminalInfoInteger(TERMINAL_NOTIFICATIONS_ENABLED)) SendNotification(msg);
      g_states[stateIdx].lastCandleAlertBar=currentBarTime;
   }

   bool prevCons=(previous.stTernary==previous.mtTernary&&previous.mtTernary==previous.ltTernary&&previous.stTernary!=0);
   bool currCons=(current.stTernary==current.mtTernary&&current.mtTernary==current.ltTernary&&current.stTernary!=0);
   if(currCons&&currentBarTime!=g_states[stateIdx].lastConsensusAlertBar&&(!prevCons||current.stTernary!=previous.stTernary))
   {
      string msg=StringFormat("XU EFFECT v8.34 %s %s: FULL %s CONSENSUS",_Symbol,g_tfName,current.stTernary==1?"BULL":"BEAR");
      Alert(msg); if(TerminalInfoInteger(TERMINAL_NOTIFICATIONS_ENABLED)) SendNotification(msg);
      g_states[stateIdx].lastConsensusAlertBar=currentBarTime;
   }

   bool extrNow=(current.hebbian>GENOME_EXTREME_HIGH||current.hebbian<GENOME_EXTREME_LOW);
   bool extrPrev=(previous.hebbian>GENOME_EXTREME_HIGH||previous.hebbian<GENOME_EXTREME_LOW);
   if(extrNow&&!extrPrev&&currentBarTime!=g_states[stateIdx].lastGenomeAlertBar)
   {
      string msg=StringFormat("XU EFFECT v8.34 %s %s: GENOME EXTREME %.2f",_Symbol,g_tfName,current.hebbian);
      Alert(msg); if(TerminalInfoInteger(TERMINAL_NOTIFICATIONS_ENABLED)) SendNotification(msg);
      g_states[stateIdx].lastGenomeAlertBar=currentBarTime;
   }

   bool wasTight=(previous.coil_tightness>InpCoilFireHigh);
   bool isLoose=(current.coil_tightness<InpCoilFireLow);
   if(wasTight&&isLoose&&currentBarTime!=g_states[stateIdx].lastCoilFireAlertBar)
   {
      string msg=StringFormat("XU EFFECT v8.34 %s %s: COIL FIRING! (%.1f%% -> %.1f%%)",_Symbol,g_tfName,previous.coil_tightness,current.coil_tightness);
      Alert(msg); if(TerminalInfoInteger(TERMINAL_NOTIFICATIONS_ENABLED)) SendNotification(msg);
      g_states[stateIdx].lastCoilFireAlertBar=currentBarTime;
   }

   double pwrThresh = InpCoilSpringPowerMin * ((InpKineticRegime) ? InpKineticMultiplier : 1.0);
   bool springCondition = (current.coil_power >= pwrThresh) &&
                          (current.vacuum_density < 0.20) &&
                          (current.poc_align_pips < 10.0);
   if(springCondition && IsSpringCooldownExpired(stateIdx, currentBarTime))
   {
      string msg=StringFormat("XU EFFECT v8.34 %s %s: *** SPRING RELEASE! (POC Align=%.1fp, Vacuum=%.0f%%, Power=%.0f%%)",
                             _Symbol,g_tfName,current.poc_align_pips,(1.0-current.vacuum_density)*100.0,current.coil_power);
      Alert(msg); if(TerminalInfoInteger(TERMINAL_NOTIFICATIONS_ENABLED)) SendNotification(msg);
      g_states[stateIdx].lastCoilSpringAlertBar=currentBarTime;
      g_states[stateIdx].lastSpringCooldownBars=0;
   }
}

int GetCandleColor(double price, double vwap, double emaM, double emaSig, int cZZ)
{
   if(cZZ == 1 && emaSig >= emaM) return 0;
   if(cZZ == -1 && emaSig <= emaM) return 1;
   return 2;
}

bool ValidateInputs()
{
   if(InpEMA_Main<=0||InpEMA_Main>200) return false;
   if(InpEMA_Signal<=0||InpEMA_Signal>200) return false;
   if(InpTriggerPeriod<=0||InpTriggerPeriod>100) return false;
   if(InpTriggerShift<0||InpTriggerShift>50) return false;
   if(InpHebbianPeriod<1||InpHebbianPeriod>100) return false;
   if(InpTRITSensitivity<=0||InpTRITSensitivity>100) return false;
   if(InpTRITDeadZone<0||InpTRITDeadZone>0.5) return false;
   if(InpTRITMemoryPeriod<1||InpTRITMemoryPeriod>100) return false;
   if(InpMinScale<0.1||InpMinScale>50) return false;
   if(InpMaxScale<0.5||InpMaxScale>100) return false;
   if(InpMaxSessionGapHours<0||InpMaxSessionGapHours>48) return false;
   if(InpCoilFireHigh<=0||InpCoilFireHigh>100) return false;
   if(InpCoilFireLow<=0||InpCoilFireLow>100) return false;
   if(InpCoilFireHigh<=InpCoilFireLow){Print("ERROR: Coil High > Low"); return false;}
   if(InpCoilFireCooldown<0||InpCoilFireCooldown>20){Print("ERROR: Cooldown 0-20"); return false;}
   if(InpEMA_Main<=0){Print("ERROR: Main <= 0"); return false;}
   if(InpMinScale>=InpMaxScale){Print("ERROR: Min < Max"); return false;}
   if(ZZ_Depth <= 0 || ZZ_Depth > 2000) { Print("ERROR: ZZ_Depth range 1-2000"); return false; }
   if(InpCoilSpringPowerMin < 0 || InpCoilSpringPowerMin > 100) { Print("ERROR: SpringPowerMin 0-100"); return false; }
   if(InpKineticMultiplier < 0.1 || InpKineticMultiplier > 5.0) { Print("ERROR: KineticMultiplier 0.1-5.0"); return false; }
   if(InpInnerSD <= 0 || InpInnerSD > 10.0) { Print("ERROR: InnerSD range 0-10"); return false; }
   if(InpOuterSD <= 0 || InpOuterSD > 10.0) { Print("ERROR: OuterSD range 0-10"); return false; }
   if(InpInnerSD >= InpOuterSD) { Print("ERROR: InnerSD must be < OuterSD"); return false; }
   return true;
}

int OnInit()
{
   Print("XU EFFECT v8.34 Initializing...");
   g_symbolPoint=SymbolInfoDouble(_Symbol,SYMBOL_POINT);
   MathSrand((uint)TimeLocal());

   g_emaMainPeriod = GetScaledPeriod(InpEMA_Main);
   g_emaSignalPeriod = GetScaledPeriod(InpEMA_Signal);
   g_trigPeriod    = GetScaledPeriod(InpTriggerPeriod);
   g_trigShift     = GetScaledShift(InpTriggerShift);
   DeleteAllObjects();
   if(!ValidateInputs()) return(INIT_PARAMETERS_INCORRECT);
   InitThemeColors(); InitPanelLayout(); InitButtons();
   g_tfName=GetTFName(); int stateIdx=GetCurrentStateIndex();

   if(stateIdx>=0)
     {
      g_states[stateIdx].AllocateArrays();
      if(g_states[stateIdx].swingMem == NULL) g_states[stateIdx].swingMem = new SwingMemory();
     }

   // Plot 0-2: Ribbon fills
   SetIndexBuffer(0,  RibbonInnerUBuf,   INDICATOR_DATA);
   SetIndexBuffer(1,  RibbonInnerLBuf,   INDICATOR_DATA);
   SetIndexBuffer(2,  RibbonOuterUHiBuf, INDICATOR_DATA);
   SetIndexBuffer(3,  RibbonOuterULoBuf, INDICATOR_DATA);
   SetIndexBuffer(4,  RibbonOuterLHiBuf, INDICATOR_DATA);
   SetIndexBuffer(5,  RibbonOuterLLoBuf, INDICATOR_DATA);
   // Plot 3: VWAP
   SetIndexBuffer(6,  VWAPBuf,           INDICATOR_DATA);
   // Plot 4: EMA 36
   SetIndexBuffer(7,  EMA_Main_Buf,      INDICATOR_DATA);
   SetIndexBuffer(8,  EMA_Main_Col,      INDICATOR_COLOR_INDEX);
   // Plot 5: Trigger
   SetIndexBuffer(9,  TriggerBuf,        INDICATOR_DATA);
   // Plot 6-7: Inner SD lines
   SetIndexBuffer(10, VWAPSD1UpperBuf,   INDICATOR_DATA);
   SetIndexBuffer(11, VWAPSD1LowerBuf,   INDICATOR_DATA);
   // Plot 8-9: Outer SD lines
   SetIndexBuffer(12, VWAPSDUpperBuf,    INDICATOR_DATA);
   SetIndexBuffer(13, VWAPSDLowerBuf,    INDICATOR_DATA);
   // Plot 10: Candles (5 buffers)
   SetIndexBuffer(14, CandleOpen,        INDICATOR_DATA);
   SetIndexBuffer(15, CandleHigh,        INDICATOR_DATA);
   SetIndexBuffer(16, CandleLow,         INDICATOR_DATA);
   SetIndexBuffer(17, CandleClose,       INDICATOR_DATA);
   SetIndexBuffer(18, CandleCol,         INDICATOR_COLOR_INDEX);
   // Calculation buffers
   SetIndexBuffer(19, EMA_Signal_Buf,    INDICATOR_CALCULATIONS);
   SetIndexBuffer(20, zzUp,              INDICATOR_CALCULATIONS);
   SetIndexBuffer(21, zzDown,            INDICATOR_CALCULATIONS);
   SetIndexBuffer(22, highMap,           INDICATOR_CALCULATIONS);
   SetIndexBuffer(23, lowMap,            INDICATOR_CALCULATIONS);

   ArrayInitialize(RibbonInnerUBuf,   EMPTY_VALUE);
   ArrayInitialize(RibbonInnerLBuf,   EMPTY_VALUE);
   ArrayInitialize(RibbonOuterUHiBuf, EMPTY_VALUE);
   ArrayInitialize(RibbonOuterULoBuf, EMPTY_VALUE);
   ArrayInitialize(RibbonOuterLHiBuf, EMPTY_VALUE);
   ArrayInitialize(RibbonOuterLLoBuf, EMPTY_VALUE);
   ArrayInitialize(VWAPBuf,           EMPTY_VALUE);
   ArrayInitialize(EMA_Main_Buf,      EMPTY_VALUE);
   ArrayInitialize(EMA_Signal_Buf,    EMPTY_VALUE);
   ArrayInitialize(TriggerBuf,        EMPTY_VALUE);
   ArrayInitialize(VWAPSD1UpperBuf,   EMPTY_VALUE);
   ArrayInitialize(VWAPSD1LowerBuf,   EMPTY_VALUE);
   ArrayInitialize(VWAPSDUpperBuf,    EMPTY_VALUE);
   ArrayInitialize(VWAPSDLowerBuf,    EMPTY_VALUE);
   ArrayInitialize(CandleOpen,        EMPTY_VALUE);
   ArrayInitialize(CandleHigh,        EMPTY_VALUE);
   ArrayInitialize(CandleLow,         EMPTY_VALUE);
   ArrayInitialize(CandleClose,       EMPTY_VALUE);
   ArrayInitialize(CandleCol,         2);
   ArrayInitialize(EMA_Main_Col,      0);

   ArraySetAsSeries(RibbonInnerUBuf,   true);
   ArraySetAsSeries(RibbonInnerLBuf,   true);
   ArraySetAsSeries(RibbonOuterUHiBuf, true);
   ArraySetAsSeries(RibbonOuterULoBuf, true);
   ArraySetAsSeries(RibbonOuterLHiBuf, true);
   ArraySetAsSeries(RibbonOuterLLoBuf, true);
   ArraySetAsSeries(VWAPBuf,           true);
   ArraySetAsSeries(EMA_Main_Buf,      true);
   ArraySetAsSeries(EMA_Signal_Buf,    true);
   ArraySetAsSeries(TriggerBuf,        true);
   ArraySetAsSeries(VWAPSD1UpperBuf,   true);
   ArraySetAsSeries(VWAPSD1LowerBuf,   true);
   ArraySetAsSeries(VWAPSDUpperBuf,    true);
   ArraySetAsSeries(VWAPSDLowerBuf,    true);
   ArraySetAsSeries(CandleOpen,        true);
   ArraySetAsSeries(CandleHigh,        true);
   ArraySetAsSeries(CandleLow,         true);
   ArraySetAsSeries(CandleClose,       true);
   ArraySetAsSeries(CandleCol,         true);
   ArraySetAsSeries(EMA_Main_Col,      true);
   ArraySetAsSeries(zzUp,              true);
   ArraySetAsSeries(zzDown,            true);
   ArraySetAsSeries(highMap,           true);
   ArraySetAsSeries(lowMap,            true);

   PlotIndexSetInteger(0, PLOT_DRAW_TYPE, InpShowInnerRibbon ? DRAW_FILLING : DRAW_NONE);
   PlotIndexSetInteger(1, PLOT_DRAW_TYPE, InpShowOuterRibbon ? DRAW_FILLING : DRAW_NONE);
   PlotIndexSetInteger(2, PLOT_DRAW_TYPE, InpShowOuterRibbon ? DRAW_FILLING : DRAW_NONE);
   PlotIndexSetInteger(3, PLOT_DRAW_TYPE, InpShowVWAP ? DRAW_LINE : DRAW_NONE);
   PlotIndexSetInteger(4, PLOT_DRAW_TYPE, DRAW_COLOR_LINE);
   PlotIndexSetInteger(4, PLOT_COLOR_INDEXES, 2);
   PlotIndexSetInteger(5, PLOT_DRAW_TYPE, DRAW_LINE);
   PlotIndexSetInteger(5, PLOT_SHIFT, g_trigShift);
   PlotIndexSetInteger(6, PLOT_DRAW_TYPE, InpShowSD ? DRAW_LINE : DRAW_NONE);
   PlotIndexSetInteger(7, PLOT_DRAW_TYPE, InpShowSD ? DRAW_LINE : DRAW_NONE);
   PlotIndexSetInteger(8, PLOT_DRAW_TYPE, InpShowSD ? DRAW_LINE : DRAW_NONE);
   PlotIndexSetInteger(9, PLOT_DRAW_TYPE, InpShowSD ? DRAW_LINE : DRAW_NONE);
   PlotIndexSetInteger(10, PLOT_DRAW_TYPE, DRAW_COLOR_CANDLES);

   for(int i = 0; i < 11; i++)
      PlotIndexSetDouble(i, PLOT_EMPTY_VALUE, EMPTY_VALUE);

   g_hEMAMain=iMA(_Symbol,_Period,g_emaMainPeriod,0,MODE_EMA,PRICE_CLOSE);
   g_hEMASignal=iMA(_Symbol,_Period,g_emaSignalPeriod,0,MODE_EMA,PRICE_CLOSE);
   g_hTrigger=iMA(_Symbol,_Period,g_trigPeriod,0,MODE_SMMA,PRICE_CLOSE);
   g_hATR=iATR(_Symbol,_Period,ATR_PERIOD);
   if(g_hEMAMain==INVALID_HANDLE || g_hEMASignal==INVALID_HANDLE || g_hTrigger==INVALID_HANDLE || g_hATR==INVALID_HANDLE)
   {
      Print("XU EFFECT v8.34: FAILED to create EMA/Trigger/ATR handles");
      return(INIT_FAILED);
   }
   CreateHeader(); CreateVCDPanel(); EventSetTimer(1); g_timerActive = true;

   SignalState dummy; dummy.Clear();
   dummy.price=SymbolInfoDouble(_Symbol,SYMBOL_BID); dummy.hebbian=HEBBIAN_SEED_VALUE;
   dummy.vwap=dummy.price-10*_Point; dummy.vwap_sd1_upper=dummy.vwap+10*_Point; dummy.vwap_sd1_lower=dummy.vwap-10*_Point;
   dummy.vwap_sd2_upper=dummy.vwap+20*_Point; dummy.vwap_sd2_lower=dummy.vwap-20*_Point;
   dummy.candleColor=2; dummy.coil_tightness=50.0; dummy.coil_power=50.0; dummy.prev_coil_tightness=50.0;
   dummy.session_poc=dummy.price; dummy.fixed_poc=dummy.price; dummy.vacuum_density=0.5; dummy.poc_align_pips=0.0;
   UpdateVCDPanel(dummy);
   SetLinesVisible(true); ChartRedraw();
   Print("XU EFFECT v8.34 Initialized | InnerSD=±", DoubleToString(InpInnerSD,1),
         " OuterSD=±", DoubleToString(InpOuterSD,1),
         " InnerRibbon=", InpShowInnerRibbon ? "ON" : "OFF",
         " OuterRibbon=", InpShowOuterRibbon ? "ON" : "OFF");
   return(INIT_SUCCEEDED);
}

void OnDeinit(const int reason)
{
   Print("XU EFFECT v8.34 UNLOADING, reason: ", reason);
   if(g_timerActive) { EventKillTimer(); g_timerActive = false; }

   if(g_hEMAMain!=INVALID_HANDLE) IndicatorRelease(g_hEMAMain);
   if(g_hEMASignal!=INVALID_HANDLE) IndicatorRelease(g_hEMASignal);
   if(g_hTrigger!=INVALID_HANDLE) IndicatorRelease(g_hTrigger);
   if(g_hATR!=INVALID_HANDLE) IndicatorRelease(g_hATR);

   string chartID = _Symbol + "_" + IntegerToString(_Period) + "_" + IntegerToString(ChartID());
   for(int i = 0; i < MAX_STATES; i++)
   {
      if(g_states[i].chartID == chartID)
      {
         if(g_states[i].swingMem != NULL) { delete g_states[i].swingMem; g_states[i].swingMem = NULL; }
         if(g_states[i].arraysAllocated)
         {
            ArrayInitialize(g_states[i].pvAccum, 0.0); ArrayInitialize(g_states[i].pv2Accum, 0.0);
            ArrayInitialize(g_states[i].vAccum, 0.0); ArrayInitialize(g_states[i].atrBuf, 0.0);
            ArrayFree(g_states[i].pvAccum); ArrayFree(g_states[i].pv2Accum);
            ArrayFree(g_states[i].vAccum); ArrayFree(g_states[i].atrBuf);
         }
         g_states[i].chartID = ""; g_states[i].arraysAllocated = false; break;
      }
   }
   DeleteAllObjects(); DeleteButtons(); ChartRedraw();
   Print("XU EFFECT v8.34 UNLOADED");
}

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<MIN_BARS_REQUIRED) return 0;
   ArraySetAsSeries(time,true);ArraySetAsSeries(open,true);ArraySetAsSeries(high,true);
   ArraySetAsSeries(low,true);ArraySetAsSeries(close,true);ArraySetAsSeries(tick_volume,true);
   ArraySetAsSeries(volume,true);ArraySetAsSeries(spread,true);
   int stateIdx=GetCurrentStateIndex(); if(stateIdx<0) return 0;
   g_states[stateIdx].AllocateArrays();

   bool isNewBar = (prev_calculated > 0 && rates_total > prev_calculated);
   int limit = (prev_calculated == 0 || isNewBar) ? MathMin(rates_total, MAX_BARS) : 1;

   if(!ReliableCopyBuffer(g_hEMAMain, 0, limit, EMA_Main_Buf))
      return (prev_calculated > 0 && limit == 1) ? prev_calculated : 0;
   if(!ReliableCopyBuffer(g_hEMASignal, 0, limit, EMA_Signal_Buf))
      return (prev_calculated > 0 && limit == 1) ? prev_calculated : 0;
   if(!ReliableCopyBuffer(g_hTrigger, 0, limit, TriggerBuf))
      return (prev_calculated > 0 && limit == 1) ? prev_calculated : 0;
   SanitizeBuffers(limit, close);

   if(g_hATR != INVALID_HANDLE)
   {
      double atrCopy[];
      ArrayResize(atrCopy, limit);
      int copied = CopyBuffer(g_hATR, 0, 0, limit, atrCopy);
      if(copied > 0)
      {
         for(int j = 0; j < copied && j < MAX_BARS; j++)
            g_states[stateIdx].atrBuf[j] = atrCopy[j];
         g_states[stateIdx].atrValue = atrCopy[0];
         g_states[stateIdx].atrSeeded = true;
      }
   }

   if(limit > 1 || prev_calculated == 0)
      GetZigZagSeries(zzUp, zzDown, highMap, lowMap, limit, rates_total, ZZ_Depth, high, low);

   for(int i = limit-1; i >= 0; i--)
   {
      if(i >= MAX_BARS) continue;
      CandleOpen[i] = open[i]; CandleHigh[i] = high[i]; CandleLow[i] = low[i]; CandleClose[i] = close[i];

      if(zzUp[i] != EMPTY_VALUE && zzUp[i] != 0) { g_states[stateIdx].currentZZ = 1; }
      if(zzDown[i] != EMPTY_VALUE && zzDown[i] != 0) { g_states[stateIdx].currentZZ = -1; }

      double typical = (high[i] + low[i] + close[i]) / 3.0;
      double vol = (double)tick_volume[i];

      bool isAnchor = ((prev_calculated == 0 || isNewBar) && i == limit-1);
      if(i >= MAX_BARS - 1 || isAnchor || (i+1 < MAX_BARS && IsSessionGap(time[i], time[i+1])))
      {
          g_states[stateIdx].pvAccum[i] = typical * vol;
          g_states[stateIdx].pv2Accum[i] = typical * typical * vol;
          g_states[stateIdx].vAccum[i] = vol;
          if(i+1 < MAX_BARS) g_states[stateIdx].releasePower = 0.0;
      }
      else if(i+1 < MAX_BARS)
      {
          g_states[stateIdx].pvAccum[i] = g_states[stateIdx].pvAccum[i+1] + typical * vol;
          g_states[stateIdx].pv2Accum[i] = g_states[stateIdx].pv2Accum[i+1] + (typical * typical * vol);
          g_states[stateIdx].vAccum[i] = g_states[stateIdx].vAccum[i+1] + vol;
      }

      if(g_states[stateIdx].vAccum[i] > 0)
      {
          double vwap = g_states[stateIdx].pvAccum[i] / g_states[stateIdx].vAccum[i];
          VWAPBuf[i] = vwap;
          double variance = (g_states[stateIdx].pv2Accum[i] / g_states[stateIdx].vAccum[i]) - (vwap * vwap);
          variance = MathMax(variance, g_symbolPoint * g_symbolPoint);
          double sd = MathSqrt(variance);

          VWAPSD1UpperBuf[i] = vwap + (InpInnerSD * sd);
          VWAPSD1LowerBuf[i] = vwap - (InpInnerSD * sd);
          VWAPSDUpperBuf[i]  = vwap + (InpOuterSD * sd);
          VWAPSDLowerBuf[i]  = vwap - (InpOuterSD * sd);

          RibbonInnerUBuf[i]   = InpShowInnerRibbon ? VWAPSD1UpperBuf[i] : EMPTY_VALUE;
          RibbonInnerLBuf[i]   = InpShowInnerRibbon ? VWAPSD1LowerBuf[i] : EMPTY_VALUE;
          RibbonOuterUHiBuf[i] = InpShowOuterRibbon ? VWAPSDUpperBuf[i]  : EMPTY_VALUE;
          RibbonOuterULoBuf[i] = InpShowOuterRibbon ? VWAPSD1UpperBuf[i] : EMPTY_VALUE;
          RibbonOuterLHiBuf[i] = InpShowOuterRibbon ? VWAPSD1LowerBuf[i] : EMPTY_VALUE;
          RibbonOuterLLoBuf[i] = InpShowOuterRibbon ? VWAPSDLowerBuf[i]  : EMPTY_VALUE;
      }
      else
      {
          VWAPBuf[i] = close[i];
          VWAPSD1UpperBuf[i] = close[i]; VWAPSD1LowerBuf[i] = close[i];
          VWAPSDUpperBuf[i]  = close[i]; VWAPSDLowerBuf[i]  = close[i];
          RibbonInnerUBuf[i]   = EMPTY_VALUE; RibbonInnerLBuf[i]   = EMPTY_VALUE;
          RibbonOuterUHiBuf[i] = EMPTY_VALUE; RibbonOuterULoBuf[i] = EMPTY_VALUE;
          RibbonOuterLHiBuf[i] = EMPTY_VALUE; RibbonOuterLLoBuf[i] = EMPTY_VALUE;
      }

      EMA_Main_Col[i] = (EMA_Signal_Buf[i] > EMA_Main_Buf[i]) ? 1 : 0;

      CandleCol[i] = GetCandleColor(close[i], VWAPBuf[i], EMA_Main_Buf[i],
                                    EMA_Signal_Buf[i], g_states[stateIdx].currentZZ);
   }

   if(rates_total <= 0) return rates_total;
   {
      if(time[0] != g_states[stateIdx].lastBarTime)
         g_states[stateIdx].prevBarSignal = g_states[stateIdx].lastSignalForTimer;

      double atr = g_states[stateIdx].atrValue; if(atr <= 0) atr = g_symbolPoint * 100;
      if(g_states[stateIdx].lastBarTime > 0 && IsSessionGap(time[0], g_states[stateIdx].lastBarTime))
         g_states[stateIdx].hebbianSeeded = false;

      if(!g_states[stateIdx].hebbianSeeded) {
         g_states[stateIdx].hebbianEMA = close[0];
         g_states[stateIdx].hebbianMemory = HEBBIAN_SEED_VALUE;
         g_states[stateIdx].tritMemory = 0.0;
         g_states[stateIdx].hebbianSeeded = true;
      } else {
         double pe = MathAbs(close[0] - g_states[stateIdx].hebbianEMA);
         double ne = MathMin(1.0, pe / MathMax(close[0], g_symbolPoint * 100));
         double lr = InpTRITSensitivity * 0.01;
         double alpha = 2.0 / (GetScaledPeriod(InpHebbianPeriod) + 1.0);
         g_states[stateIdx].hebbianEMA = alpha * close[0] + (1 - alpha) * g_states[stateIdx].hebbianEMA;
         double hu = lr * ne * (TARGET_BIAS - g_states[stateIdx].hebbianMemory);
         g_states[stateIdx].hebbianMemory = MathMax(0, MathMin(1, g_states[stateIdx].hebbianMemory + hu));
         if(ne < 0.01) {
            double re = lr * 0.1 * (g_states[stateIdx].hebbianMemory - TARGET_BIAS);
            g_states[stateIdx].hebbianMemory = MathMax(0, MathMin(1, g_states[stateIdx].hebbianMemory + re));
         }
      }

      double gv = HEBBIAN_SEED_VALUE;
      double prevGenome = (g_states[stateIdx].lastBarHebbian > 0) ? g_states[stateIdx].lastBarHebbian : HEBBIAN_SEED_VALUE;

      if(InpUseTRITGenome) {
         double T = TriggerBuf[0], I = EMA_Signal_Buf[0];
         if(MathIsValidNumber(I) && MathIsValidNumber(T) && MathAbs(I) > DBL_EPSILON * 1000) {
            double den = MathMax(MathAbs(I) + MathAbs(T), g_symbolPoint * 10);
            double trit = MathMax(-2, MathMin(2, (T - I) / den * 2));
            if(InpAutoScale) {
               double pct = MathAbs(T - I) / MathMax(MathAbs(I), g_symbolPoint * 100);
               double agg = MathMin(InpMaxScale, MathMax(InpMinScale, 1 / (MathMax(pct, 0.0001) * 100 + 0.0005)));
               double bw = 1 / (1 + MathExp(100 * (MathAbs(trit) - 0.03)));
               trit *= bw * agg + (1 - bw);
            }
            trit = MathMax(-8, MathMin(8, trit));
            double ta = 2.0 / (GetScaledPeriod(InpTRITMemoryPeriod) + 1.0);
            g_states[stateIdx].tritMemory = ta * trit + (1 - ta) * g_states[stateIdx].tritMemory;
            double surp = trit - g_states[stateIdx].tritMemory;
            double raw = HEBBIAN_SEED_VALUE;
            double deadzone = GetAdaptiveDeadZone();
            if(MathAbs(surp) > deadzone)
               raw = HEBBIAN_SEED_VALUE + surp * InpTRITSensitivity * 0.01;

            double vd_coil = MathAbs(close[0] - VWAPBuf[0]);
            double ad_coil = MathMax(atr * COIL_ATR_MULTIPLIER, g_symbolPoint * 10);

            if(InpDynamicSensitivity) {
               double prox = MathMax(0, MathMin(100, 100 * (1 - MathMin(vd_coil / ad_coil, 1))));
               double aNow = g_states[stateIdx].atrValue;
               double aPrev = (1 < MAX_BARS) ? g_states[stateIdx].atrBuf[1] : aNow;
               double ratio = (aPrev > 0) ? aNow / aPrev : 1;
               double contr = MathMax(0, MathMin(100, (1 - ratio) * 150));
               double nc2 = MathMax(0, MathMin(100, prox * 0.6 + contr * 0.4));
               double tensionFactor = MathMin(1.0, nc2 / 100.0);
               double sensitivity = 1.0 + (tensionFactor - 0.5) * 2.0;
               if(tensionFactor < 0.5) sensitivity *= 0.3;
               sensitivity = MathMax(MIN_SENSITIVITY, sensitivity);
               if(tensionFactor < 0.5 && MathAbs(raw - HEBBIAN_SEED_VALUE) < InpGenomeNeutralWidth)
                  raw = HEBBIAN_SEED_VALUE + (raw - HEBBIAN_SEED_VALUE) * 0.2;
               double dev = (raw - HEBBIAN_SEED_VALUE) * sensitivity;
               raw = HEBBIAN_SEED_VALUE + dev;
            }

            double cf = MathMax(0, MathMin(COIL_CONFIDENCE_MAX, COIL_CONFIDENCE_MAX * (1 - MathMin(vd_coil / ad_coil, 1))));
            double bias = 0;
            if(cf > COIL_CONFIDENCE_MAX * 0.5) {
               bias = COIL_BIAS_FACTOR * (raw - HEBBIAN_SEED_VALUE) * (cf / COIL_CONFIDENCE_MAX);
               if(InpUseCoilRandomization) bias += (MathRand() / 32767.0 - 0.5) * 0.08;
            }
            gv = MathMax(0, MathMin(1, raw + bias));
         } else gv = HEBBIAN_SEED_VALUE;
         gv = 0.9 * gv + 0.1 * (0.5 + g_states[stateIdx].tritMemory);
         gv = MathMax(0, MathMin(1, gv));
         double maxStep = InpGenomeMaxStep;
         if(gv > prevGenome + maxStep) gv = prevGenome + maxStep;
         if(gv < prevGenome - maxStep) gv = prevGenome - maxStep;
      } else if(g_states[stateIdx].hebbianEMA > 0) {
         double d = (close[0] - g_states[stateIdx].hebbianEMA) / g_states[stateIdx].hebbianEMA;
         gv = MathMax(0, MathMin(1, HEBBIAN_SEED_VALUE + d * HEBBIAN_SEED_DELTA));
         double maxStep = InpGenomeMaxStep;
         if(gv > prevGenome + maxStep) gv = prevGenome + maxStep;
         if(gv < prevGenome - maxStep) gv = prevGenome - maxStep;
      }

      double vd_coil = MathAbs(close[0] - VWAPBuf[0]);
      double ad_coil = MathMax(atr * COIL_ATR_MULTIPLIER, g_symbolPoint * 10);
      double prox_coil = MathMax(0, MathMin(100, 100 * (1 - MathMin(vd_coil / ad_coil, 1))));
      double aNow2 = g_states[stateIdx].atrValue;
      double aPrev2 = (1 < MAX_BARS) ? g_states[stateIdx].atrBuf[1] : aNow2;
      double ratio2 = (aPrev2 > 0) ? aNow2 / aPrev2 : 1;
      double contr2 = MathMax(0, MathMin(100, (1 - ratio2) * 150));
      double nc = MathMax(0, MathMin(100, prox_coil * 0.6 + contr2 * 0.4));
      g_currentSignal.prev_coil_tightness = g_currentSignal.coil_tightness;
      g_currentSignal.coil_tightness = nc;

      double hd = gv - prevGenome;
      g_currentSignal.hebbian = gv;
      g_currentSignal.hebbian_delta = hd;
      g_states[stateIdx].lastBarHebbian = gv;

      g_states[stateIdx].sessionProfile.Calculate(0, 24, high, low, close, volume);
      g_states[stateIdx].fixedProfile.Calculate(0, FIXED_WINDOW_SIZE, high, low, close, volume);

      g_currentSignal.session_poc = g_states[stateIdx].sessionProfile.pocPrice;
      g_currentSignal.fixed_poc = g_states[stateIdx].fixedProfile.pocPrice;
      g_currentSignal.vacuum_density = g_states[stateIdx].fixedProfile.GetDensity(close[0]);
      g_currentSignal.poc_align_pips = MathAbs(g_currentSignal.session_poc - g_currentSignal.fixed_poc) / (g_symbolPoint * 10);

      double alignFact = MathMax(0, 1.0 - (g_currentSignal.poc_align_pips / 50.0));
      double vacuumFact = 1.0 - g_currentSignal.vacuum_density;
      double rawPower = (alignFact * 0.4 + vacuumFact * 0.6) * 100.0;
      double p_alpha = (rawPower > g_states[stateIdx].releasePower) ? 0.8 : 0.1;
      g_states[stateIdx].releasePower = p_alpha * rawPower + (1.0 - p_alpha) * g_states[stateIdx].releasePower;
      g_currentSignal.coil_power = g_states[stateIdx].releasePower;
      g_currentSignal.hebbian = gv;

      g_currentSignal.Calculate(close[0], VWAPBuf[0],
                                VWAPSD1UpperBuf[0], VWAPSD1LowerBuf[0],
                                VWAPSDUpperBuf[0], VWAPSDLowerBuf[0],
                                EMA_Main_Buf[0], EMA_Signal_Buf[0],
                                TriggerBuf[0], time[0], g_states[stateIdx].currentZZ);
      CandleCol[0] = g_currentSignal.candleColor;

      UpdateHeader(g_currentSignal.candleColor);
      UpdateVCDPanel(g_currentSignal);

      if(!g_states[stateIdx].alertsInitialized)
         g_states[stateIdx].alertsInitialized = true;
      else
         CheckAndFireAlerts(g_currentSignal, g_states[stateIdx].prevBarSignal, time[0], stateIdx);

      g_states[stateIdx].lastSignalForTimer = g_currentSignal;
      g_states[stateIdx].atomicSignal = g_currentSignal;
      g_states[stateIdx].lastBarTime = time[0];
   }

   ChartRedraw();
   return rates_total;
}

void OnTimer()
{
   if(!InpFileOutput) return;
   int stateIdx=GetCurrentStateIndex(); if(stateIdx<0) return;
   datetime nowGMT=TimeGMT();
   if(nowGMT-g_states[stateIdx].lastJsonWrite>=JSON_UPDATE_SEC && g_states[stateIdx].atomicSignal.barTime>0) {
      g_states[stateIdx].lastJsonWrite=nowGMT;
      string json=GenerateJSON(g_states[stateIdx].atomicSignal,nowGMT);
      uint checksum=ComputeCRC32(json);
      string base="HomeLAB_Signal_"+_Symbol+"_"+g_tfName+"_ID"+IntegerToString(ChartID());
      string tmp=base+".tmp", fin=base+".json", chk=base+".chk";
      int hChk=FileOpen(chk,FILE_WRITE|FILE_TXT|FILE_ANSI|FILE_COMMON);
      if(hChk!=INVALID_HANDLE) { FileWriteString(hChk,IntegerToString(checksum)); FileClose(hChk); }
      int h=FileOpen(tmp,FILE_WRITE|FILE_TXT|FILE_ANSI|FILE_COMMON);
      if(h!=INVALID_HANDLE)
      {
         uint written = FileWriteString(h,json);
         FileClose(h);
         if(written > 0)
         {
            FileDelete(fin, FILE_COMMON);
            if(!FileMove(tmp,FILE_COMMON,fin,FILE_COMMON))
            {
               if(FileCopy(tmp, FILE_COMMON, fin, FILE_COMMON))
                  FileDelete(tmp, FILE_COMMON);
               else
                  Print("XU EFFECT v8.34: FileMove/Copy failed, err=", GetLastError());
            }
         }
         else
         {
            Print("XU EFFECT v8.34: FileWriteString failed (disk full?)");
            FileDelete(tmp, FILE_COMMON);
         }
      }
      else Print("XU EFFECT v8.34: FileOpen failed, err=", GetLastError());
   }
}

void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
{
   if(id==CHARTEVENT_OBJECT_CREATE||id==CHARTEVENT_OBJECT_DELETE||id==CHARTEVENT_MOUSE_MOVE||id==CHARTEVENT_MOUSE_WHEEL) return;
   if(id==CHARTEVENT_OBJECT_CLICK)
   {
      if(sparam==g_btnHudId)
      {
         g_hudVisible=(bool)ObjectGetInteger(0,g_btnHudId,OBJPROP_STATE);
         UpdateButtonColor(g_btnHudId,g_hudVisible);
         ObjectSetString(0,g_btnHudId,OBJPROP_TEXT,g_hudVisible?"HUD: ON":"HUD: OFF");
         if(g_hudVisible){ CreateVCDPanel(); }
         else{ DeleteHUDObjects(); }
         SaveButtonStates(); ChartRedraw(); return;
      }
   }
}
//+------------------------------------------------------------------+
