//+------------------------------------------------------------------+ //| PaPP_CrossExport.mq5 | //| PaPP v2 | //| Esporta in CSV TUTTI gli incroci tra le 9 linee (prezzo+Mediana | //| +7 MA), calcolati ANCORATI a D1 (come l'indicatore), con il | //| contesto di ogni incrocio e gli esiti futuri a 1/3/5/10/20 g. | //| Si puo' esportare un intervallo di date oppure tutto lo storico. | //+------------------------------------------------------------------+ #property copyright "PaPP v2" #property version "1.00" #property script_show_inputs //--- input input string InpSymbol = ""; // simbolo ("" = simbolo del grafico) input bool InpAllHistory = true; // true = tutto lo storico D1 input datetime InpStart = D'2010.01.01'; // inizio intervallo (se AllHistory=false) input datetime InpEnd = D'2100.01.01'; // fine intervallo (se AllHistory=false) input string InpFileName = ""; // nome file ("" = automatico) input bool InpBaseline = true; // crea anche il file baseline (tutte le barre D1) //--- costanti (stesse 7 MA dell'indicatore) #define ANCHOR_TF PERIOD_D1 #define NSER 9 // PRICE, MED, MA365..MA3 #define KSLOPE 5 // barre D1 per velocita'/accelerazione #define NVOL 14 // barre D1 per la volatilita' #define MAXH 20 // orizzonte massimo per gli esiti int gDays[7] = {365,182,121,30,14,7,3}; string SER[NSER]= {"PRICE","MED","MA365","MA182","MA121","MA30","MA14","MA7","MA3"}; int gHor[5] = {1,3,5,10,20}; //--- contenitore per un buffer MA dinamico (MQL5 non permette double ma[7][]) struct MABuf { double v[]; }; //+------------------------------------------------------------------+ int TimeToBarsD1(string sym,int d) { datetime n = TimeCurrent(); if(n==0) return MathMax(1,(int)((long)d*86400L/PeriodSeconds(ANCHOR_TF))); return MathMax(1,Bars(sym,ANCHOR_TF,n-(long)d*86400,n)); } //+------------------------------------------------------------------+ // valore valido = positivo e finito (MT5 usa EMPTY_VALUE=DBL_MAX nei warmup) bool IsVal(double v) { return (v>0.0 && v<1.0e12); } //+------------------------------------------------------------------+ double Median7(double &v[]) // mediana dei valori validi in v[0..6] { double a[]; int c=0; ArrayResize(a,7); for(int m=0;m<7;m++) if(IsVal(v[m])) { a[c]=v[m]; c++; } if(c==0) return 0; ArrayResize(a,c); ArraySort(a); if((c&1)==1) return a[c/2]; return 0.5*(a[c/2-1]+a[c/2]); } //+------------------------------------------------------------------+ // 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 mean=0; for(int j=0;jcmax)cmax=v; if(vcmaxP)cmaxP=v; if(vma365)?1:-1; //--- velocita'/accelerazione/volatilita': mediana delle 7 scale (no ATR di MT5) double vel_med = VelMed(S,i,KSLOPE); double acc_med = AccMed(S,i,KSLOPE); double vol_med = VolMed(S,i,NVOL); MqlDateTime dt; TimeToStruct(tm[i],dt); //--- traiettoria forward (rendimento cumulato a +1..+MAXH), calcolata una volta per barra string bpath=""; for(int b=1;b<=MAXH;b++) { int iB=i+b; if(iB>n-1) bpath += ","; else bpath += ","+DoubleToString((cl[iB]-cl[i])/cl[i]*100.0,5); } //--- esito globale: ritorno alla Mediana entro MAXH int side = (price>med)?1:-1; int b2rev=-1; double discMax=0; int jmax = MathMin(i+MAXH,n-1); for(int j=i+1;j<=jmax;j++) { if(!IsVal(S[j][0]) || !IsVal(S[j][1])) continue; int sj=(S[j][0]>S[j][1])?1:-1; if(b2rev<0 && sj!=side) b2rev=j-i; double d=(S[j][0]-S[j][1])/S[j][1]*100.0; if(MathAbs(d)>MathAbs(discMax)) discMax=d; } //--- riga baseline (barra qualunque, indipendente dagli incroci) if(fhB!=INVALID_HANDLE) { string br = TimeToString(tm[i],TIME_DATE)+","+sym+"," +DoubleToString(price,digits)+","+DoubleToString(med,digits)+"," +DoubleToString(dist_med,5)+","+DoubleToString(cluster,5)+"," +DoubleToString(cluster_exp,5)+","+IntegerToString(trend)+"," +DoubleToString(vel_med,5)+","+DoubleToString(acc_med,5)+"," +DoubleToString(vol_med,5)+","+IntegerToString(dt.day_of_week)+"," +IntegerToString(dt.mon)+"," +(b2rev>0?IntegerToString(b2rev):"")+","+DoubleToString(discMax,5) +bpath; FileWriteString(fhB,br+"\r\n"); brows++; } //--- controllo ogni coppia (a,b) for(int a=0;a0) dir=1; else if(d0>=0 && d1<0) dir=-1; if(dir==0) continue; double slope_a = (S[i][a]-S[i-KSLOPE][a])/S[i-KSLOPE][a]*100.0; double slope_b = (S[i][b]-S[i-KSLOPE][b])/S[i-KSLOPE][b]*100.0; double thr = 0.25*vol_med; string row = StringFormat("%s,%s,%sx%s,%s,%s,%d,", TimeToString(tm[i],TIME_DATE),sym,SER[a],SER[b],SER[a],SER[b],dir); row += DoubleToString(price,digits)+","+DoubleToString(med,digits)+","; for(int k=2;kn-1 || S[i][0]<=0) { row += ",,,,,"; continue; } double ret=(cl[iH]-cl[i])/cl[i]*100.0; double mxh=-1e18,mnl=1e18; for(int j=i+1;j<=iH;j++){ if(hi[j]>mxh)mxh=hi[j]; if(lo[j]thr)?1:((ret<-thr)?-1:0); int rev=(b2rev>0 && b2rev<=h)?1:0; row += ","+DoubleToString(ret,5)+","+DoubleToString(mfe,5)+"," +DoubleToString(mae,5)+","+IntegerToString(dlab)+","+IntegerToString(rev); } row += bpath; // traiettoria forward (uguale per ogni coppia di questa barra) row += ","+(b2rev>0?IntegerToString(b2rev):"")+","+DoubleToString(discMax,5); FileWriteString(fh,row+"\r\n"); rows++; } if((i%200)==0) Comment(StringFormat("PaPP export: %d/%d barre, %d eventi",i-iStart,iEnd-iStart,(int)rows)); } FileClose(fh); if(fhB!=INVALID_HANDLE) FileClose(fhB); for(int m=0;m<7;m++) IndicatorRelease(hMA[m]); Comment(""); PrintFormat("PaPP export COMPLETATO: %d incroci -> %s (cartella MQL5\\Files)",(int)rows,fname); if(InpBaseline) PrintFormat("Baseline: %d barre -> PaPP_bars_%s_D1.csv",(int)brows,sym); Print("Periodo: ",TimeToString(tm[iStart])," -> ",TimeToString(tm[iEnd])); } //+------------------------------------------------------------------+