//+------------------------------------------------------------------+
//| EliteAlgo_Modded.mq5                                             |
//| MT5 port of TradingView Pine v5 script [Elite Algo Modded]       |
//| Buy/Sell labels replaced by arrows (blue = buy, red = sell)      |
//+------------------------------------------------------------------+
#property copyright "Port of [Elite Algo Modded]"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 33
#property indicator_plots   18

#property indicator_label1  "Buy"
#property indicator_type1   DRAW_ARROW
#property indicator_color1  C'41,98,255'
#property indicator_width1  3
#property indicator_label2  "Sell"
#property indicator_type2   DRAW_ARROW
#property indicator_color2  C'235,50,60'
#property indicator_width2  3
#property indicator_label3  "TP long"
#property indicator_type3   DRAW_ARROW
#property indicator_color3  C'0,221,0'
#property indicator_width3  1
#property indicator_label4  "TP short"
#property indicator_type4   DRAW_ARROW
#property indicator_color4  C'221,0,0'
#property indicator_width4  1
#property indicator_label5  "Cloud EMA150;Cloud EMA250"
#property indicator_type5   DRAW_FILLING
#property indicator_color5  C'36,69,48',C'90,41,48'
#property indicator_label6  "Fast cloud A;Fast cloud B"
#property indicator_type6   DRAW_FILLING
#property indicator_color6  C'0,221,0',C'221,0,0'
#property indicator_label7  "Trailing SL long"
#property indicator_type7   DRAW_LINE
#property indicator_color7  C'0,221,0'
#property indicator_width7  1
#property indicator_label8  "Trailing SL short"
#property indicator_type8   DRAW_LINE
#property indicator_color8  C'221,0,0'
#property indicator_width8  1
#property indicator_label9  "EMA 5"
#property indicator_type9   DRAW_COLOR_LINE
#property indicator_color9  C'45,91,55',C'125,50,56'
#property indicator_width9  1
#property indicator_label10 "EMA 9"
#property indicator_type10  DRAW_COLOR_LINE
#property indicator_color10 C'50,107,59',C'149,55,60'
#property indicator_width10 1
#property indicator_label11 "EMA 21"
#property indicator_type11  DRAW_COLOR_LINE
#property indicator_color11 C'56,122,64',C'172,61,65'
#property indicator_width11 1
#property indicator_label12 "Scalper fill 1A;Scalper fill 1B"
#property indicator_type12  DRAW_FILLING
#property indicator_color12 C'28,46,41',C'54,32,41'
#property indicator_label13 "Scalper fill 2A;Scalper fill 2B"
#property indicator_type13  DRAW_FILLING
#property indicator_color13 C'30,53,43',C'66,35,44'
#property indicator_label14 "Scalper fill 3A;Scalper fill 3B"
#property indicator_type14  DRAW_FILLING
#property indicator_color14 C'33,61,46',C'78,38,46'
#property indicator_label15 "Trend cloud line"
#property indicator_type15  DRAW_COLOR_LINE
#property indicator_color15 C'76,175,80',C'255,82,82'
#property indicator_width15 1
#property indicator_label16 "Trend cloud up A;Trend cloud up B"
#property indicator_type16  DRAW_FILLING
#property indicator_color16 C'25,38,39',C'25,38,39'
#property indicator_label17 "Trend cloud dn A;Trend cloud dn B"
#property indicator_type17  DRAW_FILLING
#property indicator_color17 C'43,29,39',C'43,29,39'
#property indicator_label18 "Candle colors"
#property indicator_type18  DRAW_COLOR_CANDLES
#property indicator_color18 C'0,221,0',C'221,0,0',C'120,123,134',C'156,39,176'
#property indicator_width18 1

enum ENUM_EA_STRATEGY
{
   EA_STRAT_NORMAL,    // Normal
   EA_STRAT_CONFIRMED, // Confirmed
   EA_STRAT_SCALPER    // Trend scalper
};
enum ENUM_EA_CLOUD
{
   EA_CLOUD_SHORT, // Short term
   EA_CLOUD_LONG,  // Long term
   EA_CLOUD_NEW    // New
};
enum ENUM_EA_DASHLOC
{
   EA_DL_TOP_RIGHT,    // Top right
   EA_DL_TOP_LEFT,     // Top left
   EA_DL_MIDDLE_RIGHT, // Middle right
   EA_DL_MIDDLE_LEFT,  // Middle left
   EA_DL_BOTTOM_RIGHT, // Bottom right
   EA_DL_BOTTOM_LEFT   // Bottom left
};
enum ENUM_EA_DASHSIZE
{
   EA_DS_TINY,   // Tiny
   EA_DS_SMALL,  // Small
   EA_DS_NORMAL  // Normal
};

input group "ENTRY / STOP LOSS / TAKE PROFIT"
input bool             InpTpSlAreas       = true;                 // Entry / SL / TP levels on chart
input bool             InpUseTP1          = true;                 // Use TP 1
input double           InpMultTP1         = 1.0;                  // TP 1 multiplier
input bool             InpUseTP2          = true;                 // Use TP 2
input double           InpMultTP2         = 2.0;                  // TP 2 multiplier
input bool             InpUseTP3          = true;                 // Use TP 3
input double           InpMultTP3         = 3.0;                  // TP 3 multiplier

input group "DASHBOARD SETTINGS"
input bool             InpEnableDashboard = true;                 // Enable Dashboard
input ENUM_EA_DASHLOC  InpDashLocation    = EA_DL_MIDDLE_RIGHT;   // Location
input ENUM_EA_DASHSIZE InpDashSize        = EA_DS_TINY;           // Size
input color            InpColBackground   = C'42,46,57';          // Background color
input color            InpColFrame        = C'42,46,57';          // Frame color
input color            InpColBorder       = C'54,58,69';          // Border color
input int              InpDashMarginX     = 70;                   // Horizontal margin (px)
input int              InpDashMarginY     = 20;                   // Vertical margin (px)

input group "BUY AND SELL SIGNALS SETTINGS"
input bool             InpShowSignals     = true;                 // Buy & Sell signals
input ENUM_EA_STRATEGY InpStrategy        = EA_STRAT_NORMAL;      // Strategy
input double           InpSensitivity     = 1.8;                  // Sensitivity (only when Auto is OFF)
input bool             InpAutoSens        = true;                 // Auto Sensitivity
input bool             InpConsFilter      = false;                // Consolidation signals filter (ADX>20)
input bool             InpSmartOnly       = false;                // Smart signals only
input bool             InpCandleColors    = false;                // Candle colors
input bool             InpMomentumCandles = false;                // Momentum candles
input bool             InpHighVolOnly     = false;                // High volume signals only

input group "RISK MANAGEMENT"
input bool             InpTrailingSL      = false;                // Trailing stop loss
input bool             InpUsePercSL       = false;                // Use percentage SL
input double           InpPercSL          = 1.0;                  // Percentage SL
input bool             InpTPLabels        = true;                 // Take profit labels

input group "TREND CLOUD"
input bool             InpShowTrendCloud  = false;                // Trend cloud (green/red band) ON/OFF
input ENUM_EA_CLOUD    InpCloudPeriod     = EA_CLOUD_NEW;         // Trend cloud period
input bool             InpTrendOnly       = false;                // Signals only in trend cloud direction
input bool             InpFastCloud       = false;                // Fast trend cloud (HMA)
input int              InpFastCloudLen    = 55;                   // Fast trend cloud length

input group "AUTO TRENDLINES"
input bool             InpAutoTrend       = false;                // Auto trendlines
input ENUM_APPLIED_PRICE InpTrendSrc      = PRICE_CLOSE;          // Source
input int              InpTrendLen        = 200;                  // Length

input group "MT5 SETTINGS"
input color            InpColBuy          = C'41,98,255';         // Buy arrow color (medium blue)
input color            InpColSell         = C'235,50,60';         // Sell arrow color (medium red)
input bool             InpShowText        = true;                 // Show text next to arrows
input double           InpArrowOffset     = 0.7;                  // Arrow distance from candle (x ATR)
input int              InpMaxTextBars     = 2000;                 // Text only on last N bars
input bool             InpUseRealVolume   = false;                // Use real volume (else tick volume)
input bool             InpChartForeground = false;                // Chart on foreground (keep OFF so the panel stays on top)
input bool             InpAlertPopup      = true;                 // Signal alert: popup + sound
input bool             InpAlertPush       = false;                // Signal alert: push notification
input bool             InpAlertEmail      = false;                // Signal alert: email

//====================================================================
// GLOBALS
//====================================================================
double   g_nan=0.0, g_lambda=0.0, g_sqrtAnnual=0.0;
string   g_pfx="EAM_", g_pfxT="EAM_T_", g_pfxD="EAM_D_", g_pfxL="EAM_L_";
string   g_star="*";
datetime g_lastAlertTime=0;
int      g_lastW=0, g_lastH=0;
int      g_x0=0,g_y0=0,g_pW=0,g_pH=0,g_rh=16,g_btnX=0,g_grabX=0,g_grabY=0;
bool     g_dup=false,g_posSet=false,g_min=false,g_drag=false,g_prevBtn=false,g_alInit=false;
datetime g_alBull=0,g_alBear=0;
string   g_short="Elite Algo Modded";
ENUM_TIMEFRAMES g_tf[11];
int      g_hMA[11];

// plot buffers
double bBuy[],bSell[],bTPUp[],bTPDn[],bCloudA[],bCloudB[],bFastA[],bFastB[],bTrL[],bTrS[];
double bE5[],bE5c[],bE9[],bE9c[],bE21[],bE21c[];
double bF1a[],bF1b[],bF2a[],bF2b[],bF3a[],bF3b[];
double bSTl[],bSTc[],bSTgA[],bSTgB[],bSTrA[],bSTrB[];
double bCO[],bCH[],bCL[],bCC[],bCclr[];

// calculation arrays
double a_ewma[],a_hv[],a_avghv[],a_sens[],a_tr[],a_trH[],a_atr10[],a_atr14[],a_atrC[];
double a_e200[],a_e150[],a_e250[],a_w1[],a_w2[],a_wd[],a_hma55[],a_fw1[],a_fw2[],a_fwd[],a_hmaF[];
double a_e12[],a_e26[],a_macdL[],a_macdS[],a_macd[];
double a_gain[],a_loss[],a_rsiU[],a_rsiD[],a_rsi[];
double a_obv[],a_obvE[],a_vosc[],a_bs[],a_acc[],a_accS[],a_mfU[],a_mfL[],a_mfi[],a_mfiS[];
double a_mom[],a_lrm[],a_hao[],a_t1[],a_t2[],a_t3[],a_v25[],a_v26[],a_hh[],a_ll[];
double a_tUp[],a_tLo[],a_tSt[];
int    a_mt[],a_cb[],a_cs[],a_bsTL[],a_bsTS[],a_lstr[],a_sstr[];
int    a_bA[],a_bB[],a_bC[],a_bD[],a_bE[],a_sA[],a_sB[],a_sC[],a_sD[],a_sE[];
bool   a_xo[],a_xu[],a_cbull[],a_cbear[],a_bull[],a_bear[],a_trg[];
bool   a_bf1[],a_bf2[],a_bf3[],a_sf1[],a_sf2[],a_sf3[];

//====================================================================
// HELPERS (Pine na semantics)
//====================================================================
bool   isNA(const double x){ return !MathIsValidNumber(x); }
double nz(const double x,const double r=0.0){ return isNA(x)?r:x; }
bool   gt(const double a,const double b){ return (!isNA(a)&&!isNA(b)&&a>b); }
bool   lt(const double a,const double b){ return (!isNA(a)&&!isNA(b)&&a<b); }
double EV(const double x){ return isNA(x)?EMPTY_VALUE:x; }
bool   CrossOver(const double a,const double a1,const double lvl){ return (!isNA(a)&&!isNA(a1)&&a>lvl&&a1<=lvl); }
bool   CrossUnder(const double a,const double a1,const double lvl){ return (!isNA(a)&&!isNA(a1)&&a<lvl&&a1>=lvl); }

double SmaAt(const double &src[],const int i,const int len)
{
   if(i<len-1) return g_nan;
   double s=0.0;
   for(int k=0;k<len;k++){ double v=src[i-k]; if(isNA(v)) return g_nan; s+=v; }
   return s/len;
}
double WmaAt(const double &src[],const int i,const int len)
{
   if(i<len-1) return g_nan;
   double num=0.0, den=len*(len+1)/2.0;
   for(int k=0;k<len;k++){ double v=src[i-k]; if(isNA(v)) return g_nan; num+=v*(len-k); }
   return num/den;
}
double RmaAt(const double &src[],const double &out[],const int i,const int len)
{
   if(i>0 && !isNA(out[i-1]))
   {
      if(isNA(src[i])) return g_nan;
      return (src[i]+(len-1)*out[i-1])/len;
   }
   if(i<len-1) return g_nan;
   double s=0.0;
   for(int k=0;k<len;k++){ double v=src[i-k]; if(isNA(v)) return g_nan; s+=v; }
   return s/len;
}
double EmaStep(const double src,const double prev,const int len)
{
   if(isNA(prev)) return src;
   double a=2.0/(len+1.0);
   return a*src+(1.0-a)*prev;
}
double HighestAt(const double &src[],const int i,const int len)
{
   if(i<len-1) return g_nan;
   double m=src[i];
   for(int k=1;k<len;k++) if(src[i-k]>m) m=src[i-k];
   return m;
}
double LowestAt(const double &src[],const int i,const int len)
{
   if(i<len-1) return g_nan;
   double m=src[i];
   for(int k=1;k<len;k++) if(src[i-k]<m) m=src[i-k];
   return m;
}
double LinRegAt(const double &src[],const int i,const int len)
{
   if(i<len-1) return g_nan;
   double sx=0,sy=0,sxy=0,sxx=0;
   for(int k=0;k<len;k++)
   {
      double y=src[i-(len-1)+k];
      if(isNA(y)) return g_nan;
      double x=k;
      sx+=x; sy+=y; sxy+=x*y; sxx+=x*x;
   }
   double n=len, den=n*sxx-sx*sx;
   if(den==0.0) return g_nan;
   double slope=(n*sxy-sx*sy)/den;
   double icpt=(sy-slope*sx)/n;
   return icpt+slope*(n-1.0);
}
void HmaStep(const int i,const int len,const double &src[],double &w1[],double &w2[],double &wd[],double &out[])
{
   int half=len/2; if(half<1) half=1;
   int sq=(int)MathRound(MathSqrt((double)len)); if(sq<1) sq=1;
   w1[i]=WmaAt(src,i,half);
   w2[i]=WmaAt(src,i,len);
   wd[i]=(isNA(w1[i])||isNA(w2[i]))?g_nan:2.0*w1[i]-w2[i];
   out[i]=WmaAt(wd,i,sq);
}
string Num2Str(const double x)
{
   string s=DoubleToString(x,8);
   if(StringFind(s,".")>=0)
   {
      while(StringLen(s)>0 && StringGetCharacter(s,StringLen(s)-1)=='0') s=StringSubstr(s,0,StringLen(s)-1);
      if(StringLen(s)>0 && StringGetCharacter(s,StringLen(s)-1)=='.') s=StringSubstr(s,0,StringLen(s)-1);
   }
   return s;
}

//====================================================================
// SUPERTREND (exact port of the Pine function, incl. nz/na behaviour)
//====================================================================
class CSuperTrend
{
public:
   double up[],lo[],st[];
   void Resize(const int n){ ArrayResize(up,n,8192); ArrayResize(lo,n,8192); ArrayResize(st,n,8192); }
   void Step(const int i,const double &close[],const double src,const double factor,const double atr)
   {
      double upper=src+factor*atr;
      double lower=src-factor*atr;
      double prevLo=(i>0)?nz(lo[i-1]):0.0;
      double prevUp=(i>0)?nz(up[i-1]):0.0;
      double c1=(i>0)?close[i-1]:g_nan;
      bool condL=(gt(lower,prevLo)) || (!isNA(c1) && c1<prevLo);
      double lowerF=condL?lower:prevLo;
      bool condU=(lt(upper,prevUp)) || (!isNA(c1) && c1>prevUp);
      double upperF=condU?upper:prevUp;
      double prevST=(i>0)?st[i-1]:g_nan;
      int dir;
      if(!isNA(prevST) && prevST==prevUp) dir=gt(close[i],upperF)?1:-1;
      else                                dir=lt(close[i],lowerF)?-1:1;
      up[i]=upperF; lo[i]=lowerF;
      st[i]=(dir==1)?lowerF:upperF;
   }
};

//====================================================================
// DMI / ADX (Pine ta.dmi formulation)
//====================================================================
class CDMI
{
public:
   int len,sig; bool dmNaFirst;
   double dmP[],dmM[],rP[],rM[],rT[],pl[],mi[],dx[],rA[],adx[];
   void Init(const int l,const int s,const bool nf){ len=l; sig=s; dmNaFirst=nf; }
   void Resize(const int n)
   {
      ArrayResize(dmP,n,8192); ArrayResize(dmM,n,8192); ArrayResize(rP,n,8192); ArrayResize(rM,n,8192);
      ArrayResize(rT,n,8192);  ArrayResize(pl,n,8192);  ArrayResize(mi,n,8192); ArrayResize(dx,n,8192);
      ArrayResize(rA,n,8192);  ArrayResize(adx,n,8192);
   }
   void Step(const int i,const double &high[],const double &low[],const double &tr[])
   {
      if(i==0){ dmP[i]=dmNaFirst?g_nan:0.0; dmM[i]=dmNaFirst?g_nan:0.0; }
      else
      {
         double u=high[i]-high[i-1];
         double d=-(low[i]-low[i-1]);
         dmP[i]=(u>d && u>0.0)?u:0.0;
         dmM[i]=(d>u && d>0.0)?d:0.0;
      }
      rP[i]=RmaAt(dmP,rP,i,len);
      rM[i]=RmaAt(dmM,rM,i,len);
      rT[i]=RmaAt(tr,rT,i,len);
      double p=(isNA(rP[i])||isNA(rT[i])||rT[i]==0.0)?g_nan:100.0*rP[i]/rT[i];
      double m=(isNA(rM[i])||isNA(rT[i])||rT[i]==0.0)?g_nan:100.0*rM[i]/rT[i];
      pl[i]=(isNA(p)&&i>0)?pl[i-1]:p;
      mi[i]=(isNA(m)&&i>0)?mi[i-1]:m;
      double sum=pl[i]+mi[i];
      dx[i]=isNA(sum)?g_nan:MathAbs(pl[i]-mi[i])/(sum==0.0?1.0:sum);
      rA[i]=RmaAt(dx,rA,i,sig);
      adx[i]=isNA(rA[i])?g_nan:100.0*rA[i];
   }
};

CSuperTrend g_st1,g_st2;
CDMI        g_dmi14,g_dmi21;

#define RSZ(a) ArrayResize(a,n,8192)
void ResizeAll(const int n)
{
   RSZ(a_ewma);RSZ(a_hv);RSZ(a_avghv);RSZ(a_sens);RSZ(a_tr);RSZ(a_trH);RSZ(a_atr10);RSZ(a_atr14);RSZ(a_atrC);
   RSZ(a_e200);RSZ(a_e150);RSZ(a_e250);RSZ(a_w1);RSZ(a_w2);RSZ(a_wd);RSZ(a_hma55);RSZ(a_fw1);RSZ(a_fw2);RSZ(a_fwd);RSZ(a_hmaF);
   RSZ(a_e12);RSZ(a_e26);RSZ(a_macdL);RSZ(a_macdS);RSZ(a_macd);
   RSZ(a_gain);RSZ(a_loss);RSZ(a_rsiU);RSZ(a_rsiD);RSZ(a_rsi);
   RSZ(a_obv);RSZ(a_obvE);RSZ(a_vosc);RSZ(a_bs);RSZ(a_acc);RSZ(a_accS);RSZ(a_mfU);RSZ(a_mfL);RSZ(a_mfi);RSZ(a_mfiS);
   RSZ(a_mom);RSZ(a_lrm);RSZ(a_hao);RSZ(a_t1);RSZ(a_t2);RSZ(a_t3);RSZ(a_v25);RSZ(a_v26);RSZ(a_hh);RSZ(a_ll);
   RSZ(a_tUp);RSZ(a_tLo);RSZ(a_tSt);
   RSZ(a_mt);RSZ(a_cb);RSZ(a_cs);RSZ(a_bsTL);RSZ(a_bsTS);RSZ(a_lstr);RSZ(a_sstr);
   RSZ(a_bA);RSZ(a_bB);RSZ(a_bC);RSZ(a_bD);RSZ(a_bE);RSZ(a_sA);RSZ(a_sB);RSZ(a_sC);RSZ(a_sD);RSZ(a_sE);
   RSZ(a_xo);RSZ(a_xu);RSZ(a_cbull);RSZ(a_cbear);RSZ(a_bull);RSZ(a_bear);RSZ(a_trg);
   RSZ(a_bf1);RSZ(a_bf2);RSZ(a_bf3);RSZ(a_sf1);RSZ(a_sf2);RSZ(a_sf3);
   g_st1.Resize(n); g_st2.Resize(n); g_dmi14.Resize(n); g_dmi21.Resize(n);
}

//====================================================================
// OBJECT HELPERS
//====================================================================
void PutText(const string name,const datetime t,const double price,const string txt,const color clr,const ENUM_ANCHOR_POINT anc,const int fs)
{
   if(ObjectFind(0,name)<0)
   {
      if(!ObjectCreate(0,name,OBJ_TEXT,0,t,price)) return;
      ObjectSetInteger(0,name,OBJPROP_SELECTABLE,false);
      ObjectSetInteger(0,name,OBJPROP_HIDDEN,true);
      ObjectSetString(0,name,OBJPROP_FONT,"Arial");
   }
   ObjectMove(0,name,0,t,price);
   ObjectSetString(0,name,OBJPROP_TEXT,txt);
   ObjectSetInteger(0,name,OBJPROP_COLOR,clr);
   ObjectSetInteger(0,name,OBJPROP_FONTSIZE,fs);
   ObjectSetInteger(0,name,OBJPROP_ANCHOR,anc);
}
void PutLine(const string name,const datetime t1,const double p1,const datetime t2,const double p2,const color clr,const ENUM_LINE_STYLE style,const bool rayRight)
{
   if(ObjectFind(0,name)<0)
   {
      if(!ObjectCreate(0,name,OBJ_TREND,0,t1,p1,t2,p2)) return;
      ObjectSetInteger(0,name,OBJPROP_SELECTABLE,false);
      ObjectSetInteger(0,name,OBJPROP_HIDDEN,true);
      ObjectSetInteger(0,name,OBJPROP_WIDTH,1);
   }
   ObjectMove(0,name,0,t1,p1);
   ObjectMove(0,name,1,t2,p2);
   ObjectSetInteger(0,name,OBJPROP_COLOR,clr);
   ObjectSetInteger(0,name,OBJPROP_STYLE,style);
   ObjectSetInteger(0,name,OBJPROP_RAY_RIGHT,rayRight);
}

//====================================================================
// DASHBOARD (table emulated with label objects)
//====================================================================
#define DB_ROWS 20
string g_rowLbl[DB_ROWS];
color  g_cellBg[DB_ROWS];
string g_cellTxt[DB_ROWS];
color  g_cGreen=C'76,175,80', g_cRed=C'255,82,82', g_cOrange=C'255,152,0';

string DbName(const int r,const int c,const string kind){ return g_pfxD+IntegerToString(r)+"_"+IntegerToString(c)+"_"+kind; }

void DbRect(const string name,const int x,const int y,const int w,const int h,const color bg,const color border)
{
   if(ObjectFind(0,name)<0)
   {
      ObjectCreate(0,name,OBJ_RECTANGLE_LABEL,0,0,0);
      ObjectSetInteger(0,name,OBJPROP_CORNER,CORNER_LEFT_UPPER);
      ObjectSetInteger(0,name,OBJPROP_BORDER_TYPE,BORDER_FLAT);
      ObjectSetInteger(0,name,OBJPROP_SELECTABLE,false);
      ObjectSetInteger(0,name,OBJPROP_HIDDEN,true);
      ObjectSetInteger(0,name,OBJPROP_BACK,false);
   }
   ObjectSetInteger(0,name,OBJPROP_XDISTANCE,x);
   ObjectSetInteger(0,name,OBJPROP_YDISTANCE,y);
   ObjectSetInteger(0,name,OBJPROP_XSIZE,w);
   ObjectSetInteger(0,name,OBJPROP_YSIZE,h);
   ObjectSetInteger(0,name,OBJPROP_BGCOLOR,bg);
   ObjectSetInteger(0,name,OBJPROP_COLOR,border);
}
void DbText(const string name,const int cx,const int cy,const string txt,const int fs)
{
   if(ObjectFind(0,name)<0)
   {
      ObjectCreate(0,name,OBJ_LABEL,0,0,0);
      ObjectSetInteger(0,name,OBJPROP_CORNER,CORNER_LEFT_UPPER);
      ObjectSetInteger(0,name,OBJPROP_ANCHOR,ANCHOR_CENTER);
      ObjectSetInteger(0,name,OBJPROP_SELECTABLE,false);
      ObjectSetInteger(0,name,OBJPROP_HIDDEN,true);
      ObjectSetString(0,name,OBJPROP_FONT,"Arial");
      ObjectSetInteger(0,name,OBJPROP_COLOR,clrWhite);
   }
   ObjectSetInteger(0,name,OBJPROP_XDISTANCE,cx);
   ObjectSetInteger(0,name,OBJPROP_YDISTANCE,cy);
   ObjectSetInteger(0,name,OBJPROP_FONTSIZE,fs);
   if(txt!="") ObjectSetString(0,name,OBJPROP_TEXT,txt);
}
void DbButton(const string name,const int x,const int y,const int w,const int h,const string txt,const int fs)
{
   if(ObjectFind(0,name)<0)
   {
      ObjectCreate(0,name,OBJ_BUTTON,0,0,0);
      ObjectSetInteger(0,name,OBJPROP_CORNER,CORNER_LEFT_UPPER);
      ObjectSetInteger(0,name,OBJPROP_SELECTABLE,false);
      ObjectSetInteger(0,name,OBJPROP_HIDDEN,true);
      ObjectSetString(0,name,OBJPROP_FONT,"Arial");
      ObjectSetInteger(0,name,OBJPROP_COLOR,clrWhite);
      ObjectSetInteger(0,name,OBJPROP_BGCOLOR,InpColBorder);
      ObjectSetInteger(0,name,OBJPROP_BORDER_COLOR,InpColBackground);
   }
   ObjectSetInteger(0,name,OBJPROP_XDISTANCE,x);
   ObjectSetInteger(0,name,OBJPROP_YDISTANCE,y);
   ObjectSetInteger(0,name,OBJPROP_XSIZE,w);
   ObjectSetInteger(0,name,OBJPROP_YSIZE,h);
   ObjectSetInteger(0,name,OBJPROP_FONTSIZE,fs);
   ObjectSetString(0,name,OBJPROP_TEXT,txt);
   ObjectSetInteger(0,name,OBJPROP_STATE,false);
}
void DbVis(const string name,const bool vis)
{
   ObjectSetInteger(0,name,OBJPROP_TIMEFRAMES,vis?OBJ_ALL_PERIODS:OBJ_NO_PERIODS);
}
void SavePos()
{
   string k=g_pfx+IntegerToString((long)ChartID());
   GlobalVariableSet(k+"_x",g_x0);
   GlobalVariableSet(k+"_y",g_y0);
   GlobalVariableSet(k+"_m",g_min?1.0:0.0);
}
void LoadPos()
{
   string k=g_pfx+IntegerToString((long)ChartID());
   if(GlobalVariableCheck(k+"_x") && GlobalVariableCheck(k+"_y"))
   {
      g_x0=(int)GlobalVariableGet(k+"_x");
      g_y0=(int)GlobalVariableGet(k+"_y");
      g_posSet=true;
   }
   if(GlobalVariableCheck(k+"_m")) g_min=(GlobalVariableGet(k+"_m")>0.5);
}
void DashLayout()
{
   if(!InpEnableDashboard) return;
   int fs,rh,w0,w1;
   switch(InpDashSize)
   {
      case EA_DS_TINY:  fs=7;  rh=16; w0=120; w1=90;  break;
      case EA_DS_SMALL: fs=8;  rh=19; w0=138; w1=104; break;
      default:          fs=10; rh=24; w0=170; w1=128; break;
   }
   int W=w0+w1;
   int Hfull=(DB_ROWS+1)*rh;
   int H=g_min?rh:Hfull;
   int cw=(int)ChartGetInteger(0,CHART_WIDTH_IN_PIXELS);
   int chh=(int)ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS);
   if(!g_posSet)
   {
      bool right=(InpDashLocation==EA_DL_TOP_RIGHT||InpDashLocation==EA_DL_MIDDLE_RIGHT||InpDashLocation==EA_DL_BOTTOM_RIGHT);
      bool top=(InpDashLocation==EA_DL_TOP_RIGHT||InpDashLocation==EA_DL_TOP_LEFT);
      bool mid=(InpDashLocation==EA_DL_MIDDLE_RIGHT||InpDashLocation==EA_DL_MIDDLE_LEFT);
      g_x0=right?(cw-W-InpDashMarginX):10;
      g_y0=top?InpDashMarginY:(mid?(chh-Hfull)/2:(chh-Hfull-InpDashMarginY-20));
   }
   if(g_x0>cw-W) g_x0=cw-W;
   if(g_y0>chh-H) g_y0=chh-H;
   if(g_x0<0) g_x0=0;
   if(g_y0<0) g_y0=0;
   g_pW=W; g_pH=H; g_rh=rh;
   int x0=g_x0, y0=g_y0;
   DbRect(g_pfxD+"FRAME",x0-2,y0-2,W+4,H+4,InpColFrame,InpColFrame);
   // header: title + minimize + close
   int bw=rh;
   g_btnX=x0+W-2*bw;
   DbRect(g_pfxD+"HDR_BG",x0,y0,W-2*bw,rh,InpColBackground,InpColBorder);
   DbText(g_pfxD+"HDR_TX",x0+(W-2*bw)/2,y0+rh/2,"Elite Algo",fs);
   DbRect(g_pfxD+"HDR_MIN",x0+W-2*bw,y0,bw,rh,InpColBorder,InpColBackground);
   DbText(g_pfxD+"HDR_MINT",x0+W-2*bw+bw/2,y0+rh/2,g_min?"+":"-",fs);
   DbRect(g_pfxD+"HDR_CLOSE",x0+W-bw,y0,bw,rh,InpColBorder,InpColBackground);
   DbText(g_pfxD+"HDR_CLOSET",x0+W-bw+bw/2,y0+rh/2,"X",fs);
   for(int r=0;r<DB_ROWS;r++)
   {
      int y=y0+(r+1)*rh;
      if(r==8)
      {
         DbRect(DbName(r,0,"BG"),x0,y,W,rh,InpColBackground,InpColBorder);
         DbText(DbName(r,0,"TX"),x0+W/2,y+rh/2,"Timeframe trends",fs);
      }
      else
      {
         DbRect(DbName(r,0,"BG"),x0,y,w0,rh,InpColBackground,InpColBorder);
         DbText(DbName(r,0,"TX"),x0+w0/2,y+rh/2,g_rowLbl[r],fs);
         DbRect(DbName(r,1,"BG"),x0+w0,y,w1,rh,g_cellBg[r],InpColBorder);
         DbText(DbName(r,1,"TX"),x0+w0+w1/2,y+rh/2,g_cellTxt[r],fs);
      }
      bool vis=!g_min;
      DbVis(DbName(r,0,"BG"),vis); DbVis(DbName(r,0,"TX"),vis);
      if(r!=8){ DbVis(DbName(r,1,"BG"),vis); DbVis(DbName(r,1,"TX"),vis); }
   }
}
void CloseIndicator()
{
   int tot=ChartIndicatorsTotal(0,0);
   for(int k=0;k<tot;k++)
   {
      string n=ChartIndicatorName(0,0,k);
      if(StringFind(n,g_short)==0){ ChartIndicatorDelete(0,0,n); return; }
   }
}
void DbSet(const int r,const string txt,const color bg)
{
   g_cellBg[r]=bg; g_cellTxt[r]=txt;
   ObjectSetString(0,DbName(r,1,"TX"),OBJPROP_TEXT,txt);
   ObjectSetInteger(0,DbName(r,1,"BG"),OBJPROP_BGCOLOR,bg);
}
void DashUpdate(const int L)
{
   if(!InpEnableDashboard) return;
   int w=(int)ChartGetInteger(0,CHART_WIDTH_IN_PIXELS);
   int h=(int)ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS);
   if(w!=g_lastW||h!=g_lastH){ g_lastW=w; g_lastH=h; DashLayout(); }
   color bg=InpColBackground;
   string sn="Normal";
   if(InpStrategy==EA_STRAT_CONFIRMED) sn="Confirmed";
   if(InpStrategy==EA_STRAT_SCALPER)   sn="Trend scalper";
   DbSet(0,sn,bg);
   DbSet(1,Num2Str(a_sens[L]),bg);
   if(InpStrategy!=EA_STRAT_SCALPER) DbSet(2,a_trg[L]?"Buy":"Sell",a_trg[L]?g_cGreen:g_cRed);
   else DbSet(2,"",bg);
   double c0=iClose(_Symbol,_Period,0);
   bool emaBull=(c0>a_e200[L]);
   DbSet(3,emaBull?"Bullish":"Bearish",emaBull?g_cGreen:g_cRed);
   DbSet(4,DoubleToString(a_bs[L],1)+" %",bg);
   bool vb=(a_vosc[L]>0.0);
   DbSet(5,vb?"Bullish":"Bearish",vb?g_cGreen:g_cRed);
   bool trending=gt(g_dmi14.adx[L],20.0);
   DbSet(6,trending?"Trending":"Ranging",trending?g_cGreen:g_cOrange);
   bool mb=gt(a_rsi[L],50.0);
   DbSet(7,mb?"Bullish":"Bearish",mb?g_cGreen:g_cRed);
   for(int k=0;k<11;k++)
   {
      double ma[1];
      if(g_hMA[k]!=INVALID_HANDLE && CopyBuffer(g_hMA[k],0,0,1,ma)==1)
      {
         double cc=iClose(_Symbol,g_tf[k],0);
         bool bu=(cc>ma[0]);
         DbSet(9+k,bu?"Bullish":"Bearish",bu?g_cGreen:g_cRed);
      }
      else DbSet(9+k,"n/a",bg);
   }
}

//====================================================================
// INIT / DEINIT
//====================================================================
int OnInit()
{
   g_nan=MathSqrt(-1.0);
   g_lambda=(10.0-1.0)/(10.0+1.0);
   g_sqrtAnnual=MathSqrt(365.0)*100.0;
   g_star=ShortToString(0x2605);

   SetIndexBuffer(0,bBuy,INDICATOR_DATA);   SetIndexBuffer(1,bSell,INDICATOR_DATA);
   SetIndexBuffer(2,bTPUp,INDICATOR_DATA);  SetIndexBuffer(3,bTPDn,INDICATOR_DATA);
   SetIndexBuffer(4,bCloudA,INDICATOR_DATA);SetIndexBuffer(5,bCloudB,INDICATOR_DATA);
   SetIndexBuffer(6,bFastA,INDICATOR_DATA); SetIndexBuffer(7,bFastB,INDICATOR_DATA);
   SetIndexBuffer(8,bTrL,INDICATOR_DATA);   SetIndexBuffer(9,bTrS,INDICATOR_DATA);
   SetIndexBuffer(10,bE5,INDICATOR_DATA);   SetIndexBuffer(11,bE5c,INDICATOR_COLOR_INDEX);
   SetIndexBuffer(12,bE9,INDICATOR_DATA);   SetIndexBuffer(13,bE9c,INDICATOR_COLOR_INDEX);
   SetIndexBuffer(14,bE21,INDICATOR_DATA);  SetIndexBuffer(15,bE21c,INDICATOR_COLOR_INDEX);
   SetIndexBuffer(16,bF1a,INDICATOR_DATA);  SetIndexBuffer(17,bF1b,INDICATOR_DATA);
   SetIndexBuffer(18,bF2a,INDICATOR_DATA);  SetIndexBuffer(19,bF2b,INDICATOR_DATA);
   SetIndexBuffer(20,bF3a,INDICATOR_DATA);  SetIndexBuffer(21,bF3b,INDICATOR_DATA);
   SetIndexBuffer(22,bSTl,INDICATOR_DATA);  SetIndexBuffer(23,bSTc,INDICATOR_COLOR_INDEX);
   SetIndexBuffer(24,bSTgA,INDICATOR_DATA); SetIndexBuffer(25,bSTgB,INDICATOR_DATA);
   SetIndexBuffer(26,bSTrA,INDICATOR_DATA); SetIndexBuffer(27,bSTrB,INDICATOR_DATA);
   SetIndexBuffer(28,bCO,INDICATOR_DATA);   SetIndexBuffer(29,bCH,INDICATOR_DATA);
   SetIndexBuffer(30,bCL,INDICATOR_DATA);   SetIndexBuffer(31,bCC,INDICATOR_DATA);
   SetIndexBuffer(32,bCclr,INDICATOR_COLOR_INDEX);

   for(int p=0;p<18;p++) PlotIndexSetDouble(p,PLOT_EMPTY_VALUE,EMPTY_VALUE);
   PlotIndexSetInteger(0,PLOT_ARROW,233);
   PlotIndexSetInteger(1,PLOT_ARROW,234);
   PlotIndexSetInteger(2,PLOT_ARROW,251);
   PlotIndexSetInteger(3,PLOT_ARROW,251);
   PlotIndexSetInteger(0,PLOT_LINE_COLOR,InpColBuy);
   PlotIndexSetInteger(1,PLOT_LINE_COLOR,InpColSell);

   g_dmi14.Init(14,14,true);
   g_dmi21.Init(21,21,false);

   string lbl[DB_ROWS]={"Current strategy","Current sensitivity","Current Position","Current trend","Trend strength",
      "Volume","Volatility","Momentum","Timeframe trends","1 min","3 min","5 min","10 min","15 min","30 min",
      "1 Hour","2 Hour","4 Hour","12 Hour","Daily"};
   for(int r=0;r<DB_ROWS;r++){ g_rowLbl[r]=lbl[r]; g_cellBg[r]=InpColBackground; g_cellTxt[r]=""; }

   ENUM_TIMEFRAMES tfs[11]={PERIOD_M1,PERIOD_M3,PERIOD_M5,PERIOD_M10,PERIOD_M15,PERIOD_M30,PERIOD_H1,PERIOD_H2,PERIOD_H4,PERIOD_H12,PERIOD_D1};
   for(int k=0;k<11;k++)
   {
      g_tf[k]=tfs[k];
      g_hMA[k]=iMA(_Symbol,g_tf[k],200,0,MODE_EMA,PRICE_CLOSE);
   }
   ChartSetInteger(0,CHART_FOREGROUND,InpChartForeground);
   IndicatorSetString(INDICATOR_SHORTNAME,g_short);
   int cnt=0, tot=ChartIndicatorsTotal(0,0);
   for(int q=0;q<tot;q++) if(StringFind(ChartIndicatorName(0,0,q),g_short)==0) cnt++;
   if(cnt>1)
   {
      g_dup=true;
      Alert("Elite Algo Modded is already on this chart. Remove the extra copy.");
      return INIT_FAILED;
   }
   ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,true);
   ObjectsDeleteAll(0,g_pfxD);
   EventSetTimer(1);
   LoadPos();
   IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
   DashLayout();
   return INIT_SUCCEEDED;
}
void OnDeinit(const int reason)
{
   if(g_dup) return;
   EventKillTimer();
   ChartSetInteger(0,CHART_MOUSE_SCROLL,true);
   ObjectsDeleteAll(0,g_pfx);
   for(int k=0;k<11;k++) if(g_hMA[k]!=INVALID_HANDLE) IndicatorRelease(g_hMA[k]);
   ChartRedraw();
}
void OnTimer()
{
   // other programs may switch mouse events off; keep them on
   ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,true);
}
void OnChartEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
{
   if(id==CHARTEVENT_CHART_CHANGE)
   {
      int w=(int)ChartGetInteger(0,CHART_WIDTH_IN_PIXELS);
      int h=(int)ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS);
      if(w!=g_lastW||h!=g_lastH){ g_lastW=w; g_lastH=h; DashLayout(); ChartRedraw(); }
      return;
   }
   if(!InpEnableDashboard) return;
   if(id!=CHARTEVENT_MOUSE_MOVE) return;
   int mx=(int)lparam, my=(int)dparam;
   bool down=((StringToInteger(sparam)&1)==1);
   bool inHdr=(my>=g_y0 && my<=g_y0+g_rh);
   bool onMin=(inHdr && mx>=g_btnX && mx<g_btnX+g_rh);
   bool onClose=(inHdr && mx>=g_btnX+g_rh && mx<=g_btnX+2*g_rh);
   if(down && !g_prevBtn)
   {
      if(onMin)
      {
         g_prevBtn=true;
         g_min=!g_min; SavePos(); DashLayout(); ChartRedraw();
         return;
      }
      if(onClose)
      {
         g_prevBtn=true;
         CloseIndicator();
         return;
      }
   }
   if(down)
   {
      bool inPanel=(mx>=g_x0 && mx<=g_x0+g_pW && my>=g_y0 && my<=g_y0+g_pH);
      bool onBtn=(inHdr && mx>=g_btnX);
      if(!g_drag && !g_prevBtn && inPanel && !onBtn)
      {
         g_drag=true; g_grabX=mx-g_x0; g_grabY=my-g_y0;
         ChartSetInteger(0,CHART_MOUSE_SCROLL,false);
      }
      if(g_drag)
      {
         g_x0=mx-g_grabX; g_y0=my-g_grabY; g_posSet=true;
         DashLayout(); ChartRedraw();
      }
   }
   else if(g_drag)
   {
      g_drag=false;
      ChartSetInteger(0,CHART_MOUSE_SCROLL,true);
      SavePos();
   }
   g_prevBtn=down;
}

//====================================================================
// TAKE-PROFIT LOGIC (one side)
//====================================================================
void TpSide(const int i,const bool r1,const bool r2,const bool r3,const int cnt,
            int &A[],int &B[],int &C[],int &D[],int &E[],bool &f1[],bool &f2[],bool &f3[])
{
   int pA=(i>0)?A[i-1]:-1, pB=(i>0)?B[i-1]:-1, pC=(i>0)?C[i-1]:-1, pD=(i>0)?D[i-1]:-1, pE=(i>0)?E[i-1]:-1;
   A[i]=r1?0:(pA>=0?pA+1:-1);
   bool v1=r1 && cnt>=0 && ((pA<0?9999:pA)>cnt);
   B[i]=v1?0:(pB>=0?pB+1:-1);
   bool m2=r2 && cnt>=0 && pB>=0 && pB<=cnt;
   C[i]=m2?0:(pC>=0?pC+1:-1);
   bool v2=m2 && cnt>=0 && ((pC<0?9999:pC)>cnt);
   D[i]=v2?0:(pD>=0?pD+1:-1);
   bool m3=r3 && cnt>=0 && pD>=0 && pD<=cnt;
   E[i]=m3?0:(pE>=0?pE+1:-1);
   bool v3=m3 && cnt>=0 && ((pE<0?9999:pE)>cnt);
   f1[i]=v1; f2[i]=v2; f3[i]=v3;
}

void InitBuf(const int i)
{
   bBuy[i]=EMPTY_VALUE; bSell[i]=EMPTY_VALUE; bTPUp[i]=EMPTY_VALUE; bTPDn[i]=EMPTY_VALUE;
   bCloudA[i]=EMPTY_VALUE; bCloudB[i]=EMPTY_VALUE; bFastA[i]=EMPTY_VALUE; bFastB[i]=EMPTY_VALUE;
   bTrL[i]=EMPTY_VALUE; bTrS[i]=EMPTY_VALUE;
   bE5[i]=EMPTY_VALUE; bE9[i]=EMPTY_VALUE; bE21[i]=EMPTY_VALUE; bE5c[i]=0; bE9c[i]=0; bE21c[i]=0;
   bF1a[i]=EMPTY_VALUE; bF1b[i]=EMPTY_VALUE; bF2a[i]=EMPTY_VALUE; bF2b[i]=EMPTY_VALUE; bF3a[i]=EMPTY_VALUE; bF3b[i]=EMPTY_VALUE;
   bSTl[i]=EMPTY_VALUE; bSTc[i]=0; bSTgA[i]=EMPTY_VALUE; bSTgB[i]=EMPTY_VALUE; bSTrA[i]=EMPTY_VALUE; bSTrB[i]=EMPTY_VALUE;
   bCO[i]=EMPTY_VALUE; bCH[i]=EMPTY_VALUE; bCL[i]=EMPTY_VALUE; bCC[i]=EMPTY_VALUE; bCclr[i]=0;
}

//====================================================================
// PER-BAR CALCULATION
//====================================================================
void CalcBar(const int i,const int total,const datetime &time[],const double &open[],const double &high[],
             const double &low[],const double &close[],const long &tickv[],const long &realv[])
{
   InitBuf(i);
   double o=open[i],h=high[i],l=low[i],c=close[i];
   double vol=InpUseRealVolume?(double)realv[i]:(double)tickv[i];
   double ohlc4=(o+h+l+c)/4.0;
   double na_=g_nan;

   //--- auto sensitivity (EWMA historical volatility)
   double logr=(i>0 && close[i-1]>0.0 && c>0.0)?MathLog(c/close[i-1]):na_;
   double sq=isNA(logr)?na_:logr*logr;
   double pv=(i>0)?a_ewma[i-1]:na_;
   a_ewma[i]=isNA(sq)?na_:g_lambda*nz(pv,sq)+(1.0-g_lambda)*sq;
   a_hv[i]=isNA(a_ewma[i])?na_:g_sqrtAnnual*MathSqrt(a_ewma[i]);
   a_avghv[i]=SmaAt(a_hv,i,55);
   double avg=a_avghv[i], hv=a_hv[i], volty=0.0;
   if(!isNA(avg) && !isNA(hv))
   {
      double maa=avg/100.0*140.0, mab=avg/100.0*180.0, mac=avg/100.0*240.0, mad=avg/100.0*60.0, mae=avg/100.0*20.0;
      if(hv<maa && hv>avg)       volty=3.15;
      else if(hv<mab && hv>maa)  volty=3.5;
      else if(hv<mac && hv>mab)  volty=3.6;
      else if(hv>mac)            volty=4.0;
      else if(hv<maa && hv>mad)  volty=3.0;
      else if(hv<mad && hv>mae)  volty=2.85;
      else if(hv<mae)            volty=3.0;
   }
   a_sens[i]=InpAutoSens?volty:InpSensitivity;

   //--- true range / ATR
   double trv=(i>0)?MathMax(h-l,MathMax(MathAbs(h-close[i-1]),MathAbs(l-close[i-1]))):na_;
   a_tr[i]=trv;
   a_trH[i]=(i>0)?trv:(h-l);
   a_atr10[i]=RmaAt(a_trH,a_atr10,i,10);
   a_atr14[i]=RmaAt(a_trH,a_atr14,i,14);
   if(i==0) a_atrC[i]=na_;
   else { double pa=a_atrC[i-1]; a_atrC[i]=isNA(pa)?trv:pa+(trv-pa)/14.0; }

   //--- supertrends
   g_st1.Step(i,close,ohlc4,a_sens[i],a_atr10[i]);
   g_st2.Step(i,close,ohlc4,(InpCloudPeriod==EA_CLOUD_LONG)?7.0:4.0,a_atr10[i]);

   //--- moving averages
   a_e200[i]=EmaStep(c,(i>0)?a_e200[i-1]:na_,200);
   a_e150[i]=EmaStep(c,(i>0)?a_e150[i-1]:na_,150);
   a_e250[i]=EmaStep(c,(i>0)?a_e250[i-1]:na_,250);
   HmaStep(i,55,close,a_w1,a_w2,a_wd,a_hma55);
   if(InpFastCloud) HmaStep(i,InpFastCloudLen,close,a_fw1,a_fw2,a_fwd,a_hmaF); else a_hmaF[i]=na_;

   //--- MACD histogram
   a_e12[i]=EmaStep(c,(i>0)?a_e12[i-1]:na_,12);
   a_e26[i]=EmaStep(c,(i>0)?a_e26[i-1]:na_,26);
   a_macdL[i]=a_e12[i]-a_e26[i];
   a_macdS[i]=EmaStep(a_macdL[i],(i>0)?a_macdS[i-1]:na_,9);
   a_macd[i]=a_macdL[i]-a_macdS[i];

   //--- RSI 14
   double chg=(i>0)?c-close[i-1]:na_;
   a_gain[i]=isNA(chg)?na_:MathMax(chg,0.0);
   a_loss[i]=isNA(chg)?na_:-MathMin(chg,0.0);
   a_rsiU[i]=RmaAt(a_gain,a_rsiU,i,14);
   a_rsiD[i]=RmaAt(a_loss,a_rsiD,i,14);
   if(isNA(a_rsiU[i])||isNA(a_rsiD[i])) a_rsi[i]=na_;
   else if(a_rsiD[i]==0.0) a_rsi[i]=100.0;
   else if(a_rsiU[i]==0.0) a_rsi[i]=0.0;
   else a_rsi[i]=100.0-100.0/(1.0+a_rsiU[i]/a_rsiD[i]);

   //--- OBV oscillator, trend strength
   double sgn=0.0;
   if(i>0){ if(c>close[i-1]) sgn=1.0; else if(c<close[i-1]) sgn=-1.0; }
   a_obv[i]=((i>0)?a_obv[i-1]:0.0)+sgn*vol;
   a_obvE[i]=EmaStep(a_obv[i],(i>0)?a_obvE[i-1]:na_,20);
   a_vosc[i]=a_obv[i]-a_obvE[i];
   double rawbs=(h-l)!=0.0?MathAbs((o-c)/(h-l)*100.0):0.0;
   a_bs[i]=EmaStep(rawbs,(i>0)?a_bs[i-1]:na_,3);

   //--- ADX
   g_dmi14.Step(i,high,low,a_tr);
   g_dmi21.Step(i,high,low,a_tr);

   //--- signal strength components
   double s14=SmaAt(close,i,14);
   bool tmL=!isNA(s14)&&(c-s14)>0.0, tmS=!isNA(s14)&&(c-s14)<0.0;
   bool adxL=gt(g_dmi21.adx[i],34.0)&&gt(g_dmi21.pl[i],g_dmi21.mi[i]);
   bool adxS=gt(g_dmi21.adx[i],34.0)&&gt(g_dmi21.mi[i],g_dmi21.pl[i]);
   double adv=((c==h&&c==l)||h==l)?0.0:((2.0*c-l-h)/(h-l))*vol;
   a_acc[i]=((i>0)?a_acc[i-1]:0.0)+adv;
   a_accS[i]=SmaAt(a_acc,i,34);
   bool accL=gt(a_acc[i],a_accS[i]), accS=lt(a_acc[i],a_accS[i]);
   double ch2=(i>0)?c-close[i-1]:na_;
   a_mfU[i]=vol*((!isNA(ch2)&&ch2<=0.0)?0.0:c);
   a_mfL[i]=vol*((!isNA(ch2)&&ch2>=0.0)?0.0:c);
   double sU=SmaAt(a_mfU,i,21), sL=SmaAt(a_mfL,i,21);
   if(isNA(sU)||isNA(sL)) a_mfi[i]=na_;
   else if(sL==0.0) a_mfi[i]=(sU==0.0)?na_:100.0;
   else a_mfi[i]=100.0-100.0/(1.0+sU/sL);
   a_mfiS[i]=SmaAt(a_mfi,i,13);
   bool mfiL=gt(a_mfi[i],a_mfiS[i]), mfiS=lt(a_mfi[i],a_mfiS[i]);
   a_mom[i]=(i>=21)?c-close[i-21]:na_;
   a_lrm[i]=LinRegAt(a_mom,i,28);
   bool momL=(i>0)&&gt(a_lrm[i],a_lrm[i-1]), momS=(i>0)&&lt(a_lrm[i],a_lrm[i-1]);
   int ls=0,ss=0;
   if(tmL)ls++;  if(adxL)ls++; if(accL)ls++; if(mfiL)ls++; if(momL)ls++;
   if(tmS)ss++;  if(adxS)ss++; if(accS)ss++; if(mfiS)ss++; if(momS)ss++;
   a_lstr[i]=ls; a_sstr[i]=ss;

   //--- trend scalper (Heikin-Ashi open EMAs)
   double avgOC=(o+c)/2.0;
   double hao=(i==0)?avgOC:(a_hao[i-1]+(open[i-1]+high[i-1]+low[i-1]+close[i-1])/4.0)/2.0;
   a_hao[i]=hao;
   a_t1[i]=EmaStep(hao,(i>0)?a_t1[i-1]:na_,5);
   a_t2[i]=EmaStep(hao,(i>0)?a_t2[i-1]:na_,9);
   a_t3[i]=EmaStep(hao,(i>0)?a_t3[i-1]:na_,21);

   //--- volume filter, Donchian trend
   a_v25[i]=EmaStep(vol,(i>0)?a_v25[i-1]:na_,25);
   a_v26[i]=EmaStep(vol,(i>0)?a_v26[i-1]:na_,26);
   bool volF=(a_v26[i]!=0.0)&&((a_v25[i]-a_v26[i])/a_v26[i]>0.0);
   a_hh[i]=HighestAt(high,i,30);
   a_ll[i]=LowestAt(low,i,30);
   int tprev=(i>0)?a_mt[i-1]:0;
   double hh1=(i>0)?a_hh[i-1]:na_, ll1=(i>0)?a_ll[i-1]:na_;
   a_mt[i]=gt(c,hh1)?1:(lt(c,ll1)?-1:tprev);

   //--- crossovers vs supertrend
   double st=g_st1.st[i], st1=(i>0)?g_st1.st[i-1]:na_;
   bool xo=(i>0)&&!isNA(st)&&!isNA(st1)&&c>st&&close[i-1]<=st1;
   bool xu=(i>0)&&!isNA(st)&&!isNA(st1)&&c<st&&close[i-1]>=st1;
   a_xo[i]=xo; a_xu[i]=xu;
   double m0=a_macd[i], m1=(i>0)?a_macd[i-1]:na_;
   double hm=a_hma55[i], hm2=(i>=2)?a_hma55[i-2]:na_;
   bool cbull=(xo||(i>0&&a_xo[i-1]&&a_mt[i-1]<0))&&gt(m0,0.0)&&gt(m0,m1)&&gt(a_e150[i],a_e250[i])&&gt(hm,hm2)&&a_mt[i]>0;
   bool cbear=(xu||(i>0&&a_xu[i-1]&&a_mt[i-1]>0))&&lt(m0,0.0)&&lt(m0,m1)&&lt(a_e150[i],a_e250[i])&&lt(hm,hm2)&&a_mt[i]<0;
   a_cbull[i]=cbull; a_cbear[i]=cbear;

   //--- final signals
   bool bullB=(InpStrategy==EA_STRAT_NORMAL)?xo:(cbull&&!(i>0&&a_cbull[i-1]));
   bool bearB=(InpStrategy==EA_STRAT_NORMAL)?xu:(cbear&&!(i>0&&a_cbear[i-1]));
   double smartF=a_e200[i];
   bool adxOK=gt(g_dmi14.adx[i],20.0);
   bool cloudUp=(InpCloudPeriod==EA_CLOUD_NEW)?gt(a_e150[i],a_e250[i]):gt(c,g_st2.st[i]);
   bool cloudDn=(InpCloudPeriod==EA_CLOUD_NEW)?lt(a_e150[i],a_e250[i]):lt(c,g_st2.st[i]);
   bool notSc=(InpStrategy!=EA_STRAT_SCALPER);
   bool bull=bullB&&notSc&&(!InpSmartOnly||gt(c,smartF))&&(!InpConsFilter||adxOK)&&(!InpHighVolOnly||volF)&&(!InpTrendOnly||cloudUp);
   bool bear=bearB&&notSc&&(!InpSmartOnly||lt(c,smartF))&&(!InpConsFilter||adxOK)&&(!InpHighVolOnly||volF)&&(!InpTrendOnly||cloudDn);
   a_bull[i]=bull; a_bear[i]=bear;
   int pb=(i>0)?a_cb[i-1]:-1, ps=(i>0)?a_cs[i-1]:-1;
   a_cb[i]=bull?0:(pb>=0?pb+1:-1);
   a_cs[i]=bear?0:(ps>=0?ps+1:-1);
   int cbv=(a_cb[i]<0)?i:a_cb[i], csv=(a_cs[i]<0)?i:a_cs[i];
   bool trg=(cbv<csv);
   a_trg[i]=trg;

   //--- trailing stop
   {
      double atrv=a_atrC[i];
      double upper=h+(InpUsePercSL?h*(InpPercSL/100.0):2.2*atrv);
      double lower=l-(InpUsePercSL?l*(InpPercSL/100.0):2.2*atrv);
      double pLo=(i>0)?nz(a_tLo[i-1]):0.0, pUp=(i>0)?nz(a_tUp[i-1]):0.0;
      double lowerF=(gt(lower,pLo)||bull)?lower:pLo;
      double upperF=(lt(upper,pUp)||bear)?upper:pUp;
      double prevS=(i>0)?a_tSt[i-1]:na_;
      int dir;
      if(!isNA(prevS)&&prevS==pUp) dir=bull?1:-1; else dir=bear?-1:1;
      a_tLo[i]=lowerF; a_tUp[i]=upperF;
      a_tSt[i]=(dir==1)?lowerF:upperF;
      int q1=(i>0)?a_bsTL[i-1]:-1, q2=(i>0)?a_bsTS[i-1]:-1;
      a_bsTL[i]=lt(l,a_tSt[i])?0:(q1>=0?q1+1:-1);
      a_bsTS[i]=gt(h,a_tSt[i])?0:(q2>=0?q2+1:-1);
      if(InpTrailingSL && !isNA(a_tSt[i]))
      {
         if(trg && a_cb[i]>=0 && ((a_bsTL[i]<0)?i:a_bsTL[i])>a_cb[i]) bTrL[i]=a_tSt[i];
         if(!trg && a_cs[i]>=0 && ((a_bsTS[i]<0)?i:a_bsTS[i])>a_cs[i]) bTrS[i]=a_tSt[i];
      }
   }

   //--- take profit conditions (RSI 70/75/80 and 30/25/20)
   double r0=a_rsi[i], r1=(i>0)?a_rsi[i-1]:na_;
   TpSide(i,CrossOver(r0,r1,70),CrossOver(r0,r1,75),CrossOver(r0,r1,80),a_cb[i],a_bA,a_bB,a_bC,a_bD,a_bE,a_bf1,a_bf2,a_bf3);
   TpSide(i,CrossUnder(r0,r1,30),CrossUnder(r0,r1,25),CrossUnder(r0,r1,20),a_cs[i],a_sA,a_sB,a_sC,a_sD,a_sE,a_sf1,a_sf2,a_sf3);

   //--- plots: signals + text
   double atrOff=isNA(a_atr14[i])?(h-l):a_atr14[i];
   if(atrOff<=0.0) atrOff=_Point*10.0;
   bool inTxt=(i>=total-InpMaxTextBars);
   string nmS=g_pfxT+"S_"+IntegerToString((long)time[i]);
   if(InpShowSignals && (bull||bear))
   {
      if(bull) bBuy[i]=l-InpArrowOffset*atrOff;
      if(bear) bSell[i]=h+InpArrowOffset*atrOff;
      if(InpShowText && inTxt)
      {
         if(bull)
         {
            string tx=(gt(c,smartF)?"Smart Buy ":"Buy ")+IntegerToString(ls)+g_star;
            PutText(nmS,time[i],l-(InpArrowOffset+0.45)*atrOff,tx,InpColBuy,ANCHOR_UPPER,8);
         }
         else
         {
            string tx=IntegerToString(ss)+g_star+(lt(c,smartF)?" Smart Sell":" Sell");
            PutText(nmS,time[i],h+(InpArrowOffset+0.45)*atrOff,tx,InpColSell,ANCHOR_LOWER,8);
         }
      }
   }
   else if(i>=total-3) ObjectDelete(0,nmS);

   //--- plots: TP crosses
   bool tpOn=(InpTPLabels&&notSc);
   for(int n=1;n<=3;n++)
   {
      bool fb=(n==1)?a_bf1[i]:((n==2)?a_bf2[i]:a_bf3[i]);
      bool fs=(n==1)?a_sf1[i]:((n==2)?a_sf2[i]:a_sf3[i]);
      bool cnd=tpOn&&(trg?fb:fs);
      string nm=g_pfxT+"TP"+IntegerToString(n)+"_"+IntegerToString((long)time[i]);
      if(cnd)
      {
         double st2=(0.8+0.45*(n-1))*atrOff;
         if(trg)
         {
            bTPUp[i]=h+0.35*atrOff;
            if(inTxt) PutText(nm,time[i],h+st2,"TP "+IntegerToString(n),C'0,221,0',ANCHOR_LOWER,7);
         }
         else
         {
            bTPDn[i]=l-0.35*atrOff;
            if(inTxt) PutText(nm,time[i],l-st2,"TP "+IntegerToString(n),C'221,0,0',ANCHOR_UPPER,7);
         }
      }
      else if(i>=total-3) ObjectDelete(0,nm);
   }

   //--- plots: trend clouds
   if(InpShowTrendCloud && InpCloudPeriod==EA_CLOUD_NEW)
   {
      bCloudA[i]=a_e150[i]; bCloudB[i]=a_e250[i];
   }
   if(InpFastCloud)
   {
      double hf=a_hmaF[i], hf2=(i>=2)?a_hmaF[i-2]:na_;
      if(!isNA(hf)&&!isNA(hf2)){ bFastA[i]=hf; bFastB[i]=hf2; }
   }
   if(InpShowTrendCloud && InpCloudPeriod!=EA_CLOUD_NEW)
   {
      double tc=g_st2.st[i];
      if(!isNA(tc) && tc!=0.0)
      {
         if(c>tc)      { bSTl[i]=tc; bSTc[i]=0; bSTgA[i]=tc; bSTgB[i]=avgOC; }
         else if(c<tc) { bSTl[i]=tc; bSTc[i]=1; bSTrA[i]=tc; bSTrB[i]=avgOC; }
      }
   }

   //--- plots: trend scalper ribbon
   if(InpStrategy==EA_STRAT_SCALPER)
   {
      double e1=a_t1[i],e2=a_t2[i],e3=a_t3[i];
      double p1=(i>0)?a_t1[i-1]:na_, p2=(i>0)?a_t2[i-1]:na_, p3=(i>0)?a_t3[i-1]:na_;
      if(gt(e1,p1)){ bE5[i]=e1; bE5c[i]=0; } else if(lt(e1,p1)){ bE5[i]=e1; bE5c[i]=1; }
      if(gt(e2,p2)){ bE9[i]=e2; bE9c[i]=0; } else if(lt(e2,p2)){ bE9[i]=e2; bE9c[i]=1; }
      if(gt(e3,p3)){ bE21[i]=e3; bE21c[i]=0; } else if(lt(e3,p3)){ bE21[i]=e3; bE21c[i]=1; }
      bF1a[i]=avgOC; bF1b[i]=e1;
      bF2a[i]=e1;    bF2b[i]=e2;
      bF3a[i]=e2;    bF3b[i]=e3;
   }

   //--- plots: candle colors
   bool momC=(gt(m0,0.0)&&gt(m0,m1))||(lt(m0,0.0)&&lt(m0,m1));
   int ci=-1;
   if(InpMomentumCandles && momC) ci=3;
   else if(InpCandleColors)
   {
      if(InpStrategy==EA_STRAT_SCALPER) ci=(lt(c,a_t1[i])&&lt(c,a_t2[i]))?1:0;
      else if(a_cb[i]<0 && a_cs[i]<0)   ci=2;
      else                               ci=trg?0:1;
   }
   if(ci>=0){ bCO[i]=o; bCH[i]=h; bCL[i]=l; bCC[i]=c; bCclr[i]=ci; }
}

//====================================================================
// TP / SL AREAS (drawn on the last bar only, like the original)
//====================================================================
void UpdateTpSl(const int last,const datetime &time[],const double &high[],const double &low[],const double &close[])
{
   string key[5]={"ENTRY","SL","TP1","TP2","TP3"};
   if(!InpTpSlAreas)
   {
      for(int k=0;k<5;k++){ ObjectDelete(0,g_pfxL+"LN_"+key[k]); ObjectDelete(0,g_pfxL+"LB_"+key[k]); }
      return;
   }
   bool trg=a_trg[last];
   int cnt=trg?a_cb[last]:a_cs[last];
   if(cnt<0 || cnt>last) return;
   int sig=last-cnt;
   bool sigBull=a_bull[sig];
   if(isNA(a_atr14[sig])&&!InpUsePercSL) return;
   double entry=close[sig];
   double bandS=InpUsePercSL?(sigBull?low[sig]:high[sig])*(InpPercSL/100.0):a_atr14[sig]*2.2;
   double stopY=sigBull?low[sig]-bandS:high[sig]+bandS;
   double bandC=InpUsePercSL?(trg?low[last]:high[last])*(InpPercSL/100.0):nz(a_atr14[last])*2.2;
   double stopC=trg?low[last]-bandC:high[last]+bandC;   // label text uses current-bar value (as in the original)
   datetime t1=time[sig], t2=time[last]+PeriodSeconds();
   double ys[5]; bool on[5]; string tx[5]; color cl[5]; ENUM_LINE_STYLE ls[5];
   ys[0]=entry; ys[1]=stopY;
   ys[2]=(entry-stopY)*InpMultTP1+entry; ys[3]=(entry-stopY)*InpMultTP2+entry; ys[4]=(entry-stopY)*InpMultTP3+entry;
   on[0]=true; on[1]=true;
   on[2]=(InpUseTP1&&InpMultTP1!=0.0); on[3]=(InpUseTP2&&InpMultTP2!=0.0); on[4]=(InpUseTP3&&InpMultTP3!=0.0);
   tx[0]="Entry : "+DoubleToString(entry,_Digits);
   tx[1]="Stop loss : "+DoubleToString(stopC,_Digits);
   tx[2]="TP 1 : "+DoubleToString(ys[2],_Digits);
   tx[3]="TP 2 : "+DoubleToString(ys[3],_Digits);
   tx[4]="TP 3 : "+DoubleToString(ys[4],_Digits);
   cl[0]=g_cOrange; cl[1]=g_cRed; cl[2]=g_cGreen; cl[3]=g_cGreen; cl[4]=g_cGreen;
   ls[0]=STYLE_DASH; ls[1]=STYLE_SOLID; ls[2]=STYLE_DOT; ls[3]=STYLE_DOT; ls[4]=STYLE_DOT;
   for(int k=0;k<5;k++)
   {
      string nl=g_pfxL+"LN_"+key[k], nb=g_pfxL+"LB_"+key[k];
      if(on[k])
      {
         PutLine(nl,t1,ys[k],t2,ys[k],cl[k],ls[k],false);
         PutText(nb,t2,ys[k],tx[k],cl[k],ANCHOR_LEFT,8);
      }
      else { ObjectDelete(0,nl); ObjectDelete(0,nb); }
   }
}

//====================================================================
// AUTO TRENDLINES (regression channel, last bar only)
//====================================================================
double PriceAt(const int i,const double &o[],const double &h[],const double &l[],const double &c[])
{
   switch(InpTrendSrc)
   {
      case PRICE_OPEN:     return o[i];
      case PRICE_HIGH:     return h[i];
      case PRICE_LOW:      return l[i];
      case PRICE_MEDIAN:   return (h[i]+l[i])/2.0;
      case PRICE_TYPICAL:  return (h[i]+l[i]+c[i])/3.0;
      case PRICE_WEIGHTED: return (h[i]+l[i]+2.0*c[i])/4.0;
   }
   return c[i];
}
void UpdateTrendLines(const int last,const datetime &time[],const double &o[],const double &h[],const double &l[],const double &c[])
{
   if(!InpAutoTrend || InpTrendLen<3)
   {
      for(int k=0;k<3;k++) ObjectDelete(0,g_pfxL+"TL"+IntegerToString(k));
      return;
   }
   int len=InpTrendLen;
   if(last<len) return;
   double wsum=0.0, ssum=0.0, den=len*(len+1)/2.0;
   for(int k=0;k<len;k++){ double p=PriceAt(last-k,o,h,l,c); wsum+=p*(len-k); ssum+=p; }
   double aA=wsum/den, b=ssum/len;
   double A=4.0*b-3.0*aA, B=3.0*aA-2.0*b;
   double m=(A-B)/(len-1);
   double d=0.0;
   for(int k=0;k<len;k++){ double df=PriceAt(last-k,o,h,l,c)-(B+m*k); d+=df*df; }
   double rmse=MathSqrt(d/(len-1))*2.0;
   double ks[3]; ks[0]=rmse; ks[1]=0.0; ks[2]=-rmse;
   for(int k=0;k<3;k++)
      PutLine(g_pfxL+"TL"+IntegerToString(k),time[last-len+1],A+ks[k],time[last],B+ks[k],C'41,98,255',STYLE_SOLID,true);
}

//====================================================================
// ALERTS (only: signal appeared)
//====================================================================
void Notify(const string msg)
{
   if(InpAlertPopup) Alert(msg);
   if(InpAlertPush)  SendNotification(msg);
   if(InpAlertEmail) SendMail("Elite Algo Modded",msg);
}
void CheckSignalAlert(const int last,const datetime &time[],const double &close[])
{
   if(!(InpAlertPopup||InpAlertPush||InpAlertEmail)) return;
   if(!g_alInit)
   {
      g_alInit=true;
      if(a_bull[last]) g_alBull=time[last];
      if(a_bear[last]) g_alBear=time[last];
      return;
   }
   string pre=_Symbol+" "+StringSubstr(EnumToString((ENUM_TIMEFRAMES)_Period),7)+" : ";
   double sf=a_e200[last];
   if(a_bull[last] && g_alBull!=time[last])
   {
      g_alBull=time[last];
      Notify(pre+(close[last]>sf?"Smart Buy":"Buy"));
   }
   if(a_bear[last] && g_alBear!=time[last])
   {
      g_alBear=time[last];
      Notify(pre+(close[last]<sf?"Smart Sell":"Sell"));
   }
}

//====================================================================
// MAIN
//====================================================================
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<3) return 0;
   ResizeAll(rates_total);
   if(prev_calculated==0) ObjectsDeleteAll(0,g_pfxT);
   int start=(prev_calculated>1)?prev_calculated-1:0;
   for(int i=start;i<rates_total;i++)
      CalcBar(i,rates_total,time,open,high,low,close,tick_volume,volume);
   int last=rates_total-1;
   ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,true);
   DashUpdate(last);
   UpdateTpSl(last,time,high,low,close);
   UpdateTrendLines(last,time,open,high,low,close);
   CheckSignalAlert(last,time,close);
   ChartRedraw();
   return rates_total;
}
//+------------------------------------------------------------------+
