diff --git a/PaPP v2/PaPP_Median.mq5 b/PaPP v2/PaPP_Median.mq5 index cef4aa6..981f552 100644 --- a/PaPP v2/PaPP_Median.mq5 +++ b/PaPP v2/PaPP_Median.mq5 @@ -15,6 +15,9 @@ input bool Smooth = true; // interpola tra i valori D1 -> linea morbida input bool ShowMA = true; // mostra anche le 7 MA (oltre alla mediana) #define ANCHOR_TF PERIOD_D1 // calcolo ancorato a D1: linea identica su ogni TF +#define KSLOPE 5 // barre D1 per velocita'/accelerazione +#define NVOL 14 // barre D1 per la volatilita' +#define CLWIN 252 // finestra D1 (~1 anno) per il percentile del cluster double Buff_Median[]; double B0[],B1[],B2[],B3[],B4[],B5[],B6[]; @@ -23,6 +26,7 @@ int gDays[7] = {365,182,121,30,14,7,3}; color gCol[7] = {clrDodgerBlue,clrDeepSkyBlue,clrTurquoise,clrLimeGreen,clrOrange,clrTomato,clrRed}; int hMA[7]; int bars[7]; +struct PBuf { double v[]; }; // buffer dinamico per copiare una MA string _pfx = "PM_"; // oggetti pannello string _pfx2 = "PME_"; // etichette a fine linea @@ -154,6 +158,126 @@ double MedianAtD1(int d1shift) return Median(vals,cnt); } +//+------------------------------------------------------------------+ +// valore valido = positivo e finito (esclude EMPTY_VALUE di warmup) +bool IsVal(double v) { return (v>0.0 && v<1.0e12); } + +//+------------------------------------------------------------------+ +// mediana dei primi c valori di src +double MedArr(double &src[],int c) + { + if(c<=0) return 0; + double a[]; ArrayResize(a,c); + for(int j=0;j=2) + { + double mn=0; for(int q=0;q0) cA[cc++]=cv; + vA[vc++]=MathAbs(VelAtJ(mb,j,KSLOPE)); + aA[ac++]=MathAbs(AccAtJ(mb,j,KSLOPE)); + double ov=VolAtJ(mb,j,NVOL); if(ov>0) oA[oc++]=ov; + } + cluCur=ClusterAtJ(mb,1); velCur=VelAtJ(mb,1,KSLOPE); + accCur=AccAtJ(mb,1,KSLOPE); volCur=VolAtJ(mb,1,NVOL); + cluPct=PctlOf(cA,cc,cluCur); + volPct=PctlOf(oA,oc,volCur); + velPct=PctlOf(vA,vc,MathAbs(velCur)); // forza (su |valore|) + accPct=PctlOf(aA,ac,MathAbs(accCur)); + } + +//+------------------------------------------------------------------+ +// descrizione a parole per una grandezza di sola ampiezza (cluster, volatilita') +string MagWord(double pct,string w0,string w1,string w2,string w3,string w4) + { + if(pct<0.20) return w0; + if(pct<0.40) return w1; + if(pct<0.60) return w2; + if(pct<0.80) return w3; + return w4; + } +//+------------------------------------------------------------------+ +// descrizione a parole per un segnale con segno (velocita', accelerazione) +string DirWord(double val,double absPct,string up,string down,string flat) + { + if(absPct<0.15) return flat; + string forza = (absPct<0.40)?"lieve":((absPct<0.70)?"moderata":"forte"); + return (val>0?up:down)+" "+forza; + } + //+------------------------------------------------------------------+ // interpolazione lineare con fallback se uno dei valori manca double Interp(double vStart,double vEnd,double frac) @@ -298,11 +422,23 @@ void DrawInfo() Lbl("M","Median: "+DoubleToString(median,_Digits),x,y,FontSize,clrGold,false); y+=lh; Lbl("D","Dist: "+distS,x,y,FontSize,distC,true); y+=lh+2; - //--- Dispersione MA e bande (info) - double ds=0; int dc=0; - for(int m=0;m<7;m++) { double v=GetMA(m,1); if(v>0) { ds+=MathAbs(v-median)/median*100; dc++; } } - double vol = (dc>0)?ds/dc:0; - Lbl("V","Cluster +/-"+DoubleToString(vol,3)+"%",x,y,FontSize,clrGray,false); y+=lh+2; + //--- Cluster/Velocita'/Accelerazione/Volatilita' con percentile storico + descrizione a parole + double cluCur,cluPct,velCur,velPct,accCur,accPct,volCur,volPct; + AllMetrics(CLWIN,cluCur,cluPct,velCur,velPct,accCur,accPct,volCur,volPct); + + string cluTxt = MagWord(cluPct,"molto stretto","stretto","normale","largo","molto largo"); + color cluC = (cluPct<0.40)?clrLimeGreen:((cluPct>0.60)?clrTomato:clrSilver); + Lbl("V",StringFormat("Cluster %.3f%% - %s (P%.0f)",cluCur,cluTxt,cluPct*100),x,y,FontSize,cluC,false); y+=lh; + + string velTxt = DirWord(velCur,velPct,"in salita","in discesa","quasi piatta"); + Lbl("VEL",StringFormat("Velocita' %+.3f%% - %s",velCur,velTxt),x,y,FontSize,(velCur>0)?clrLimeGreen:clrTomato,false); y+=lh; + + string accTxt = DirWord(accCur,accPct,"in accelerazione","in decelerazione","stabile"); + Lbl("ACC",StringFormat("Accel %+.4f%% - %s",accCur,accTxt),x,y,FontSize,(accCur>0)?clrLimeGreen:clrTomato,false); y+=lh; + + string volTxt = MagWord(volPct,"molto bassa","bassa","normale","alta","molto alta"); + color volC = (volPct<0.40)?clrLimeGreen:((volPct>0.60)?clrTomato:clrAqua); + Lbl("VOL",StringFormat("Volatilita' %.4f%% - %s (P%.0f)",volCur,volTxt,volPct*100),x,y,FontSize,volC,false); y+=lh+2; //--- Valori delle 7 MA (giorni : valore) con colore = linea for(int m=0;m<7;m++)