PaPP v2 indicatore: Cluster contestualizzato con percentile storico (stretto/normale/largo) + valore tipico
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
+40
-5
@@ -17,6 +17,7 @@ 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[];
|
||||
@@ -25,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
|
||||
|
||||
@@ -199,6 +201,38 @@ void ScaleMetrics(double &velo,double &acc,double &vol)
|
||||
velo=MedArr(va,cv); acc=MedArr(aa,ca); vol=MedArr(wa,cw);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
// Contestualizza il cluster: percentile dell'ampiezza attuale sugli ultimi 'win' giorni D1
|
||||
// cur = cluster oggi, pctl = posizione 0..1 nella storia, typ = ampiezza tipica (mediana storica)
|
||||
void ClusterStats(int win,double &cur,double &pctl,double &typ)
|
||||
{
|
||||
cur=0; pctl=0.5; typ=0;
|
||||
int need=win+1;
|
||||
PBuf mb[7];
|
||||
for(int m=0;m<7;m++)
|
||||
{
|
||||
ArraySetAsSeries(mb[m].v,true);
|
||||
if(CopyBuffer(hMA[m],0,0,need,mb[m].v)!=need) return;
|
||||
}
|
||||
double cl[]; int cc=0; ArrayResize(cl,win);
|
||||
for(int j=1;j<=win;j++)
|
||||
{
|
||||
double vals[7]; int vc=0;
|
||||
for(int m=0;m<7;m++){ double v=mb[m].v[j]; if(IsVal(v)) vals[vc++]=v; }
|
||||
if(vc<2) continue;
|
||||
double md=MedArr(vals,vc);
|
||||
if(md<=0) continue;
|
||||
double ds=0;
|
||||
for(int m=0;m<vc;m++) ds+=MathAbs(vals[m]-md)/md*100.0;
|
||||
cl[cc++]=ds/vc;
|
||||
}
|
||||
if(cc<=0) return;
|
||||
cur=cl[0]; // j=1 = ultima barra D1 chiusa
|
||||
typ=MedArr(cl,cc);
|
||||
int below=0; for(int k=0;k<cc;k++) if(cl[k]<=cur) below++;
|
||||
pctl=(double)below/cc;
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
// interpolazione lineare con fallback se uno dei valori manca
|
||||
double Interp(double vStart,double vEnd,double frac)
|
||||
@@ -343,11 +377,12 @@ 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;
|
||||
|
||||
//--- Cluster (dispersione media delle MA dalla mediana)
|
||||
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 clu = (dc>0)?ds/dc:0;
|
||||
Lbl("V","Cluster +/-"+DoubleToString(clu,3)+"%",x,y,FontSize,clrGray,false); y+=lh;
|
||||
//--- Cluster contestualizzato: valore + percentile storico (stretto/normale/largo)
|
||||
double clu_cur,clu_pctl,clu_typ; ClusterStats(CLWIN,clu_cur,clu_pctl,clu_typ);
|
||||
string clab = (clu_pctl<0.33)?"stretto":((clu_pctl>0.66)?"largo":"normale");
|
||||
color cclr = (clu_pctl<0.33)?clrLimeGreen:((clu_pctl>0.66)?clrTomato:clrSilver);
|
||||
Lbl("V",StringFormat("Cluster %.3f%% P%.0f %s (tip %.3f%%)",clu_cur,clu_pctl*100,clab,clu_typ),
|
||||
x,y,FontSize,cclr,false); y+=lh;
|
||||
|
||||
//--- Velocita'/Accelerazione/Volatilita' = mediana delle 7 scale (dalle nostre MA)
|
||||
double velo,acc,volat; ScaleMetrics(velo,acc,volat);
|
||||
|
||||
Reference in New Issue
Block a user