Indicatori: Indicatore di correlazione - pagina 2

 
Qui, all'incirca così - https://www.mql5.com/it/code/183. Il punto è che la copia dei dati da altri simboli non viene eseguita tutta in una volta, ma una barra alla volta. Durante tale copia, da altri simboli, la barra verrà copiata esattamente in corrispondenza del momento della barra del grafico su cui è visualizzato l'indicatore. Se non c'è una barra corrispondente, allora da una barra precedente (come la funzione iBarShift() in MQL4). In questo indicatore viene copiata una barra alla volta, ma per la correlazione potrebbe essere necessario copiare il numero corrispondente al periodo di correlazione. Si può fare diversamente: copiare una barra alla volta e metterla nel buffer dell'indicatore. Utilizzando il buffer si può fare tutto il più velocemente possibile (naturalmente a scapito di un maggiore consumo di memoria). È possibile farlo senza un buffer aggiuntivo, con un paio di variabili statiche.... È lungo da spiegare, probabilmente è necessario scrivere un articolo:)
 
pusheax:

Ok, ieri ci siamo un po' sovraeccitati, immagino che anche tu abbia festeggiato come me la "Giornata delle guardie di frontiera".

Puoi darmi un link per la corretta sincronizzazione delle battute, perché anch'io uso questo metodo di sincronizzazione con l'ultima battuta e basta?

Non le darò un link (perché non l'ho ancora incontrato), ma le descriverò il metodo.

Il metodo riguarda la sincronizzazione di strumenti diversi, anche se può essere utilizzato per la sincronizzazione di TF diversi.

Mi sono occupato di questo problema per molto tempo e persino SD ha realizzato un bug-fix per i bug di questo metodo che ho identificato.

Il problema della sincronizzazione è legato al fatto che strumenti diversi hanno un numero diverso di barre. Approssimativamente lo stesso è un falso criterio, tutto deve essere esatto. Da barra a barra. Altrimenti si perde il significato di sincronizzazione.

Il secondo aspetto di questo problema è come visualizzare una barra se non c'è nessuna barra sullo strumento corrente?

L'essenza del metodo è semplice: i dati sullo strumento vengono richiesti rigorosamente per tempo...

count=CopyRates(symbol,tf,time0,time1,rates); если нужно несколько баров
или
count=CopyRates(symbol,tf,time0,1,rates); если нужен один

e il campione di tempo viene preso dal buffer standard dell'indicatore time[]. In questo modo, si ha sempre la certezza di trovarsi di fronte a una barra che è arrivata in sincronia con una barra su un altro strumento.

Anche in questo caso, se non esiste una barra di questo tipo nello strumento corrente, non verrà richiesta. E se lo strumento richiesto non ha una barra di questo tipo come campione, si otterrà uno zero nel conteggio e si potrà normalmente gestire questa eccezione, a seconda della logica del programma.

 

Implementazione della sincronizzazione (in MQL4) per un numero qualsiasi di IF(da qui):

double GetPrice( string Symb, int time )
{
  double Price;
 
  Price = iClose(Symb, Period(), iBarShift(Symb, Period(), time));
 
  return(Price);
}
 
int GetNextTime( int CurrTime )
{
  static int Pos[MAX_AMOUNTSYMBOLS];
  int i, MinTime, Tmp = -1;
 
  for (i = 0; i < AmountSymbols; i++)
  {
    Pos[i] = iBarShift(Symbols[i], Period(), CurrTime) - 1;
 
    if (Pos[i] >= 0)
      Tmp = i;
  }
 
  if (Tmp < 0)
    return(Time[0]);
 
  MinTime = iTime(Symbols[Tmp], Period(), Pos[Tmp]);
 
  i = Tmp - 1;
 
  while (i >= 0)
  {
    if (Pos[i] >= 0)
    {
      Tmp = iTime(Symbols[i], Period(), Pos[i]);
 
      if (Tmp < MinTime)
        MinTime = Tmp;
    }
 
    i--;
  }
 
  return(MinTime);
}
 
void GetBaseMatrix()
{
  int i, NextTime;
 
  NextTime = GetNextTime(CurrTime);
 
  while (NextTime < Time[0])
  {
    CurrTime = NextTime;
 
    for (i = 0; i < AmountSymbols; i++)
      BaseMatrix[i][MatrixRows] = 1000 * MathLog(GetPrice(Symbols[i], CurrTime));
 
    Times[MatrixRows] = CurrTime;
 
    MatrixRows++;
 
    NextTime = GetNextTime(CurrTime);
  }
 
  return;
}

Per analogia per due simboli(da qui):

double GetPrice( string Symb, int time )
{
  double Price;
 
  Price = iClose(Symb, Period(), iBarShift(Symb, Period(), time));
 
  return(Price);
}
 
int GetNextTime( int CurrTime )
{
  static int Pos[TWO_SYMBOLS];
  int i, MinTime, Tmp = -1;
 
  for (i = 0; i < TWO_SYMBOLS; i++)
  {
    Pos[i] = iBarShift(Symbols[i], Period(), CurrTime) - 1;
 
    if (Pos[i] >= 0)
      Tmp = i;
  }
 
  if (Tmp < 0)
    return(Time[0]);
 
  MinTime = iTime(Symbols[Tmp], Period(), Pos[Tmp]);
 
  i = Tmp - 1;
 
  while (i >= 0)
  {
    if (Pos[i] >= 0)
    {
      Tmp = iTime(Symbols[i], Period(), Pos[i]);
 
      if (Tmp < MinTime)
        MinTime = Tmp;
    }
 
    i--;
  }
 
  return(MinTime);
}
 
void GetBaseMatrix()
{
  int i, NextTime;
 
  NextTime = GetNextTime(CurrTime);
 
  while (NextTime < Time[0])
  {
    CurrTime = NextTime;
 
    for (i = 0; i < TWO_SYMBOLS; i++)
      BaseMatrix[i][MatrixRows + Shifts[i]] = MathLog(GetPrice(Symbols[i], CurrTime));
 
    Times[MatrixRows] = CurrTime;
 
    MatrixRows++;
 
    NextTime = GetNextTime(CurrTime);
  }
 
  return;
}
Cioè tutto è abbastanza semplice. Un'altra cosa è che la classica rappresentazione barometrica (discretizzazione a tempo costante) dei prezzi BP non è l'unica, e tanto meno è sempre corretta. A volte è estremamente utile sincronizzare i prezzi BP di un'altra dimensione temporale. Cioè, introducendo distorsioni non lineari dal punto di vista del tempo classico. Di conseguenza, la correlazione mostrerà interrelazioni non lineari di due VR classici.
 

Grazie per l'aiuto!

Mi sono sbagliato, lo ammetto, non pensavo che la sincronizzazione fosse così complicata.

Cercherò di capirlo e di sincronizzare le barre direttamente su questo indicatore, dato che ne ho molto bisogno.

 

Grazie a tutti per le informazioni!

Ho riscritto un po'l'indicatore. Ora, presumibilmente, dovrebbe saltare le parti negative della storia.

Visto che abbiamo iniziato, vi prego di controllare gli errori :)

File:
 
Ribadisco la necessità di un'ottimizzazione algoritmica per tutti gli indicatori. E anche per il meccanismo integrato di calcolo dei valori dell'indicatore in memoria (file), in modo che durante l'ottimizzazione del tester l'indicatore non calcoli la stessa cosa, ma prenda valori già pronti da lì.
 
hrenfx:
Ribadisco la necessità di un'ottimizzazione algoritmica per tutti gli indicatori. E anche per un meccanismo integrato di calcolo dei valori dell'indicatore in memoria (file), in modo che durante l'ottimizzazione del tester l'indicatore non calcoli la stessa cosa, ma prenda valori già pronti da lì.
Potreste mostrare un esempio in cui ciò è già stato fatto?
 

L'ottimizzazione algoritmica per ogni indicatore è diversa. Per i diversi modi di utilizzare la correlazione, ho fatto, ad esempio, questo e questo.

La lettura a memoria dei valori degli indicatori calcolati in anticipo per l'intera storia è stata effettuata solo nella mia calcolatrice. Cioè, non ho un meccanismo universale, perché uso solo le mie soluzioni, che non sono affatto belle. Ma poiché sono per il miglioramento di tutto, sarebbe bello avere un meccanismo universale nel caso dell'ottimizzatore del tester MT5, perché dà un'accelerazione di diversi ordini di grandezza (esperienza di utilizzo nella mia calcolatrice), cioè supera Cloud in termini di efficienza.

 

Ciao a tutti

A volte passo il tempo a distorcere i codici di altri, di solito i risultati di un programma incompleto o incompleto, sia per mancanza di tempo che per mancanza di abilità.

Questa volta avrei cercato di distorcere questo meraviglioso indicatore, e ho provato a fare qualcosa del genere:

- Disegnare solo una linea, non una linea tratteggiata di tracciatura



#property indicator_type1 DRAW_COLOR_LINE
#property indicator_width1 2

// #property indicator_type2 DRAW_COLOR_HISTOGRAM
// #proprietà indicator_style2 STYLE_DOT
// #proprietà indicator_width2 1

- Per aggiungere un sacco di simboli come

//--- parametri di ingresso
input string _SecondSymbol="EURGBP"; // Simbolo

input string _ThirdSymbol="EURAUD"; // Simbolo
input string _FourthSymbol="EURCAD"; // Simbolo
input string _FifthSymbol="EURCHF"; // Simbolo
input string _SixthSymbol="EURNZD"; // Simbolo
input string _SeventhSymbol="EURHKD"; // Simbolo
input string _EighthSymbol="EURTRY"; // Simbolo

Poi ho creato 2 varianti del codice sorgente:

- Variante visiva: una linea colorata per ciascuna delle coppie di valute correlazione 1 linea spessa che è solo la media di 7 linee ((A+B+C+D+E+F+G)/7)

- Nessuna variante visiva: 1 sola linea, che è il risultato della formula di cui sopra ((A+B+C+D+D+E+F+G)/7)

Quasi come se si aggiungessero 7 (o 8) indicatori di correlazione originali, ma tutti sommati in modo da ottenere solo le medie come con la versione, una delle quali è costituita da 7 linee + 1 (media), e l'altra versione con 1 linea (solo media).

Qualcosa del genere:

buf[i]= (
(v1/sqrt(v2*v3))+
(v4/sqrt(v2*v6))+
(v7/sqrt(v2*v9))+
(v10/sqrt(v2*v12))+
(v13/sqrt(v2*v15))+
(v16/sqrt(v2*v18))+
(v19/sqrt(v2*v21)) 
)/7; // media semplice dei valori.


buf2[i]=buf[i];
c=getPlotColor(buf[i]);
colors1[i]=c;
colors2[i]=c;

Per una serie di ragioni il codice confuso non fa quello che voglio a causa di errori completamente logici.

Il problema principale riguarda i buffer, la sincronizzazione e la rientranza ricorsiva del codice:

if(bars1>bars2)
{
minBars=bars2;
bars2=bars1-bars2;
etc...

+ oltre ad altri errori logici.

sono state aggiunte alcune funzioni Print() per aiutare nel caso di tracciamento dei valori delle variabili e sono state commentate le istruzioni return 0 per trovare dove il codice fallisce logicamente.

 

codice e file

//+------------------------------------------------------------------+
//| Correlazione.mq5 |
//|| Copyright 2012, iC |
//| http://www.icreator.biz/ |
//+------------------------------------------------------------------+
#property copyright "Copyright 2012, iC"
#property link "http://www.icreator.biz/"
#property version "1.00"
//--- impostazioni dell'indicatore
#property indicator_separate_window

#property indicator_minimum -1
#property indicator_maximum 1

#property indicator_buffers 25
#property indicator_plots 2

#property indicator_type1 DRAW_COLOR_LINE
#property indicator_width1 2

// #property indicator_type2 DRAW_COLOR_HISTOGRAM
// #proprietà indicator_style2 STYLE_DOT
// #proprietà indicator_width2 1

/*

#property indicator_type2 DRAW_COLOR_LINE
#property indicator_width2 2

#property indicator_type3 DRAW_COLOR_LINE
#property indicator_width3 2

#property indicator_type4 DRAW_COLOR_LINE
#property indicator_width4 2

#property indicator_type5 DRAW_COLOR_LINE
#indicatore_di_proprietà_larghezza5 2

#indicatore_di_proprietà_tipo6 DRAW_COLOR_LINE
#indicatore_di_proprietà_larghezza6 2

#indicatore_di_proprietà_tipo7 DRAW_COLOR_LINE
#indicatore_di_proprietà_larghezza7 2

#indicatore_di_proprietà_tipo8 DRAW_COLOR_LINE
#indicatore_di_proprietà_larghezza8 2

*/

//--- definisce
#define MAX_COL 64
//--- strutture
struct CRGB
{
int r;
int g;
int b;
};
//--- parametri di ingresso
input string _SecondSymbol="EURGBP"; // Simbolo

input string _ThirdSymbol="EURAUD"; // Simbolo
input string _FourthSymbol="EURCAD"; // Simbolo
input string _FifthSymbol="EURCHF"; // Simbolo
input string _SixthSymbol="EURNZD"; // Simbolo
input string _SeventhSymbol="EURHKD"; // Simbolo
input string _EighthSymbol="EURTRY"; // Simbolo

input int _SettPeriod=100; // Periodo
input ENUM_APPLIED_PRICE _AppliedPrice=PRICE_CLOSE; // Prezzo
input color _Color1=clrLightGray; // Correlazione minima.
input color _Color2=clrLime; // Correlazione massima.

//--- buffer di indicatori
double buf[],buf2[]
,buf3[],buf4[],buf5[],buf6[],buf7[],buf8[];

double arr1[],arr2[]
,arr3[],arr4[],arr5[],arr6[],arr7[],arr8[];

double colors1[],colors2[];

//--- Maniglie MA
int h1,h2,
h3,h4,h5,h6,h7,h8;
//+------------------------------------------------------------------+
//| Funzione di inizializzazione dell'indicatore personalizzata |
//+------------------------------------------------------------------+
int OnInit()
{
SetIndexBuffer(0,buf);
SetIndexBuffer(1,colors1,INDICATOR_COLOR_INDEX);

SetIndexBuffer(2,buf2);
SetIndexBuffer(3,colors2,INDICATOR_COLOR_INDEX);

SetIndexBuffer(4,arr1,INDICATOR_CALCULATIONS); // primo simbolo
SetIndexBuffer(5,arr2,INDICATOR_CALCULATIONS); // secondo simbolo


SetIndexBuffer(6,arr3,INDICATOR_CALCULATIONS); //3°
SetIndexBuffer(7,arr4,INDICATOR_CALCULATIONS); //4

SetIndexBuffer(8,arr5,INDICATOR_CALCULATIONS); //5°
SetIndexBuffer(9,arr6,INDICATOR_CALCULATIONS); //6

SetIndexBuffer(10,arr7,INDICATOR_CALCULATIONS); //7

SetIndexBuffer(11,arr8,INDICATOR_CALCULATIONS); //8

/* 
SetIndexBuffer(12,arr9,INDICATOR_CALCULATIONS);
SetIndexBuffer(13,arr10,INDICATOR_CALCULATIONS);

SetIndexBuffer(14,arr11,INDICATOR_CALCULATIONS);
SetIndexBuffer(15,arr12,INDICATOR_CALCULATIONS);

SetIndexBuffer(16,buf3);
SetIndexBuffer(17,colors3,INDICATOR_COLOR_INDEX);

SetIndexBuffer(18,buf4);
SetIndexBuffer(19,colori4,INDICATOR_COLOR_INDEX);

SetIndexBuffer(20,buf5);
SetIndexBuffer(21,colori5,INDICATOR_COLOR_INDEX);

SetIndexBuffer(22,buf6);
SetIndexBuffer(23,colori6,INDICATOR_COLOR_INDEX);

SetIndexBuffer(24,buf7);
SetIndexBuffer(25,colori7,INDICATOR_COLOR_INDEX);

// ecc...
*/

PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0);
PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,0);

PlotIndexSetInteger(0,PLOT_SHOW_DATA,0);
IndicatorSetInteger(INDICATOR_DIGITS,3); 

IndicatorSetString(INDICATOR_SHORTNAME,_Symbol+"/"+_SecondSymbol+", "+IntegerToString(_SettPeriod)+", "+EnumToString(_AppliedPrice)+","); // ecc.

setPlotColor(0,_Color1,_Color2);
setPlotColor(1,_Color1,_Color2);

h1=iMA(_Symbol,0,1,0,MODE_EMA,_AppliedPrice);
h2=iMA(_SecondSymbol,0,1,0,MODE_EMA,_AppliedPrice);

// valori aggiunti.
h3=iMA(_ThirdSymbol,0,1,0,MODE_EMA,_AppliedPrice);
h4=iMA(_FourthSymbol,0,1,0,MODE_EMA,_AppliedPrice);
h5=iMA(_FifthSymbol,0,1,0,MODE_EMA,_AppliedPrice);
h6=iMA(_SixthSymbol,0,1,0,MODE_EMA,_AppliedPrice);
h7=iMA(_SeventhSymbol,0,1,0,MODE_EMA,_AppliedPrice);
h8=iMA(_EighthSymbol,0,1,0,MODE_EMA,_AppliedPrice);

return 0;
}
//+------------------------------------------------------------------+
//| Funzione di iterazione dell'indicatore personalizzata |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const int begin,
const double &price[])
{
int i,j,c,limit,bars1,bars2
,bars3,bars4,bars5,bars6,bars7,bars8, 
minBars,toCopy;
double averX1=0,averX2=0
,averX3=0,averX4=0,averX5=0,averX6=0,averX7=0,averX8=0,
v1=0,v2=0,v3=0
,v4=0,v5=0,v6=0,v7=0,v8=0
,v9=0,v10=0,v11=0,v12=0
,v13=0,v14=0,v15=0,v16=0,v17=0
,v18=0,v19=0,v20=0,v21=0;
datetime t1[1],t2[1],
t3[1],t4[1],t5[1],t6[1],t7[1],t8[1];
//--- simboli di sincronizzazione
if( 
(
CopyTime(_Symbol,0,0,1,t1)<1 || 
CopyTime(_SecondSymbol,0,0,1,t2)<1 || 

CopyTime(_ThirdSymbol,0,0,1,t3)<1 || 
CopyTime(_FourthSymbol,0,0,1,t4)<1 || 
CopyTime(_FifthSymbol,0,0,1,t5)<1 || 
CopyTime(_SixthSymbol,0,0,1,t6)<1 || 
CopyTime(_SeventhSymbol,0,0,1,t7)<1 || 
CopyTime(_EighthSymbol,0,0,1,t8)<1
) 
|| 

(
t1[0]!=t2[0]
|| t1[0]!=t3[0]
|| t1[0]!=t4[0]
|| t1[0]!=t5[0]
|| t1[0]!=t6[0]
|| t1[0]!=t7[0]
|| t1[0]!=t8[0]
)
) 
{
Print("Synchronization failed!");
// restituire 0;
}
//--- controllo dei dati

bars1=rates_total;
bars2=Bars(_SecondSymbol,0);

bars3=Bars(_ThirdSymbol,0);
bars4=Bars(_FourthSymbol,0);
bars5=Bars(_FifthSymbol,0);
bars6=Bars(_SixthSymbol,0);
bars7=Bars(_SeventhSymbol,0);
bars8=Bars(_EighthSymbol,0);

// indentare i if l'uno con l'altro finché non viene trovato il minBars. // per verificare se la logica è corretta

if(bars1>bars2)
{
minBars=bars2;
bars2=bars1-bars2;
bars1=0;
Print("bars1>bars2; minBars(",minBars,"),=bars2(",bars2,")=bars1(",bars1,")-bars2(",bars2,");");
// }
//altrimenti 
if(bars1>bars3)
{
minBars=bars3;
bars3=bars1-bars3;
bars1=0;
Print("bars1>bars3; minBars(",minBars,"),=bars3(",bars3,")=bars1(",bars1,")-bars3(",bars3,");");
// } 
//altrimenti 
if(bars1>bars4)
{
minBars=bars4;
bars4=bars1-bars4;
bars1=0;
Print("bars1>bars4; minBars(",minBars,"),=bars4(",bars4,")=bars1(",bars1,")-bars4(",bars4,");");
// } 
//altrimenti 
if(bars1>bars5)
{
minBars=bars5;
bars5=bars1-bars5;
bars1=0;
Print("bars1>bars5; minBars(",minBars,"),=bars5(",bars5,")=bars1(",bars1,")-bars5(",bars5,");");
// } 
//altrimenti 
if(bars1>bars6)
{
minBars=bars6;
bars6=bars1-bars6;
bars1=0;
Print("bars1>bars6; minBars(",minBars,"),=bars6(",bars6,")=bars1(",bars1,")-bars6(",bars6,");");
// } 
//altrimenti 
if(bars1>bars7)
{
minBars=bars7;
bars7=bars1-bars7;
bars1=0;
Print("bars1>bars7; minBars(",minBars,"),=bars7(",bars7,")=bars1(",bars1,")-bars7(",bars7,");");
// } 
//altrimenti 
if(bars1>bars8)
{
minBars=bars8;
bars8=bars1-bars8;
bars1=0;
Print("bars1>bars8; minBars(",minBars,"),=bars8(",bars8,")=bars1(",bars1,")-bars8(",bars8,");");
} }}}}}} 

else
{
minBars=bars1;
bars1=bars2-bars1;
bars2=0;
Print("bars1!>bars2,3,4,5,6,7,8; minBars(",minBars,"),=bars1(",bars1,")=bars2(",bars2,")-bars1(",bars1,");");
}
if(minBars<_SettPeriod)
{
Print("Bars is not enough to calculate!");
// restituire 0;
}
if(BarsCalculated(h1)<minBars)
{
Print("Not all data of MA1 is calculated. Error ",GetLastError());
// restituire 0;
}
if(BarsCalculated(h2)<minBars)
{
Print("Not all data of MA2 is calculated. Error ",GetLastError());
// restituire 0;
}
if(BarsCalculated(h3)<minBars)
{
Print("Not all data of MA3 is calculated. Error ",GetLastError());
// restituire 0;
}
if(BarsCalculated(h4)<minBars)
{
Print("Not all data of MA4 is calculated. Error ",GetLastError());
// restituire 0;
}
if(BarsCalculated(h5)<minBars)
{
Print("Not all data of MA5 is calculated. Error ",GetLastError());
// restituire 0;
}
if(BarsCalculated(h6)<minBars)
{
Print("Not all data of MA6 is calculated. Error ",GetLastError());
// restituire 0;
}
if(BarsCalculated(h7)<minBars)
{
Print("Not all data of MA7 is calculated. Error ",GetLastError());
// restituire 0;
}
if(BarsCalculated(h8)<minBars)
{
Print("Not all data of MA8 is calculated. Error ",GetLastError());
// restituire 0;
} 

//--- possiamo copiare non tutti i dati
if(prev_calculated>rates_total || 
prev_calculated<=0)
toCopy=minBars;
else
toCopy=rates_total-prev_calculated+1;

if(CopyBuffer(h1,0,0,minBars,arr1)<minBars || 
CopyBuffer(h2,0,0,minBars,arr2)<minBars || 

CopyBuffer(h3,0,0,minBars,arr3)<minBars || 
CopyBuffer(h4,0,0,minBars,arr4)<minBars || 
CopyBuffer(h5,0,0,minBars,arr5)<minBars || 
CopyBuffer(h6,0,0,minBars,arr6)<minBars || 
CopyBuffer(h7,0,0,minBars,arr7)<minBars || 
CopyBuffer(h8,0,0,minBars,arr8)<minBars) 

{
Print("Getting MA buffer failed. Error ",GetLastError());
// restituire 0;
}
if(prev_calculated>rates_total || 
prev_calculated<=0)
limit=bars1+bars2+_SettPeriod-1
+bars3+bars4+bars5+bars6+bars7+bars8;

else
limit=prev_calculated-1;
//--- 
for(i=limit;i<rates_total;i++)
{
averX1=0; averX2=0; 
averX3=0;averX4=0;averX5=0;averX6=0;averX7=0;averX8=0;
for(j=0;j<_SettPeriod;j++)
{
averX1+=arr1[i-j-bars1]/_SettPeriod;
averX2+=arr2[i-j-bars2]/_SettPeriod;

averX3+=arr3[i-j-bars3]/_SettPeriod;
averX4+=arr4[i-j-bars4]/_SettPeriod;
averX5+=arr5[i-j-bars5]/_SettPeriod;
averX6+=arr6[i-j-bars6]/_SettPeriod;
averX7+=arr7[i-j-bars7]/_SettPeriod;
averX8+=arr8[i-j-bars8]/_SettPeriod;
}

v1=0; v2=0; v3=0;
v4=0;v5=0;v6=0;v7=0;v8=0;
v9=0;v10=0;v11=0;v12=0;v13=0;
v14=0;v15=0;v16=0;v17=0;v18=0;
v19=0;v20=0;v21=0; 
for(j=0;j<_SettPeriod;j++)
{
v1+=(arr1[i-j-bars1]-averX1)*(arr2[i-j-bars2]-averX2);
v2+=pow((arr1[i-j-bars1]-averX1),2);
v3+=pow((arr2[i-j-bars2]-averX2),2);

v4+=(arr1[i-j-bars1]-averX2)*(arr3[i-j-bars3]-averX3);
// v5+=pow((arr1[i-j-bars1]-averX1),2);
v6+=pow((arr3[i-j-bars3]-averX3),2);

v7+=(arr1[i-j-bars1]-averX1)*(arr4[i-j-bars4]-averX4);
// v8+=pow((arr1[i-j-bars1]-averX1),2);
v9+=pow((arr4[i-j-bars4]-averX4),2);

v10+=(arr1[i-j-bars1]-averX1)*(arr5[i-j-bars5]-averX5);
// v11+=pow((arr1[i-j-bars1]-averX1),2);
v12+=pow((arr5[i-j-bars5]-averX5),2);

v13+=(arr1[i-j-bars1]-averX1)*(arr6[i-j-bars6]-averX6);
// v14+=pow((arr1[i-j-bars1]-averX1),2);
v15+=pow((arr6[i-j-bars6]-averX6),2);

v16+=(arr1[i-j-bars1]-averX1)*(arr7[i-j-bars7]-averX7);
// v17+=pow((arr1[i-j-bars1]-averX1),2);
v18+=pow((arr7[i-j-bars7]-averX7),2);

v19+=(arr1[i-j-bars1]-averX1)*(arr8[i-j-bars8]-averX8);
// v20+=pow((arr1[i-j-bars1]-averX1),2);
v21+=pow((arr8[i-j-bars8]-averX8),2);

}
buf[i]= (
(v1/sqrt(v2*v3))+
(v4/sqrt(v2*v6))+
(v7/sqrt(v2*v9))+
(v10/sqrt(v2*v12))+
(v13/sqrt(v2*v15))+
(v16/sqrt(v2*v18))+
(v19/sqrt(v2*v21)) 
)/7; // media semplice dei valori.


buf2[i]=buf[i];
c=getPlotColor(buf[i]);
colors1[i]=c;
colors2[i]=c;
}
return rates_total;
}

//+------------------------------------------------------------------+
//| setPlotColour |
//+------------------------------------------------------------------+
void setPlotColor(int plot,color col1,color col2)
{
int i;
CRGB c1,c2;
double dr,dg,db;
string s;
//--- 
PlotIndexSetInteger(plot,PLOT_COLOR_INDEXES,MAX_COL);
ColorToRGB(col1,c1);
ColorToRGB(col2,c2);
dr=(double)(c2.r-c1.r)/MAX_COL;
dg=(double)(c2.g-c1.g)/MAX_COL;
db=(double)(c2.b-c1.b)/MAX_COL;
for(i=0;i<MAX_COL;i++)
{
s=StringFormat("%i,%i,%i",
c1.r+(int)NormalizeDouble(dr*(i+1),0),
c1.g+(int)NormalizeDouble(dg*(i+1),0),
c1.b+(int)NormalizeDouble(db*(i+1),0));
PlotIndexSetInteger(plot,PLOT_LINE_COLOR,i,StringToColor(s));
}
}
//+------------------------------------------------------------------+
//| getPlotColor |
//+------------------------------------------------------------------+
int getPlotColor(double current)
{
return((int)NormalizeDouble((MAX_COL-1)*fabs(current),0));
}
//+------------------------------------------------------------------+
//| ColorToRGB |
//+------------------------------------------------------------------+
void ColorToRGB(color col,CRGB &res)
{
string s,s2;
int n;
//---
s=ColorToString(col);
n=StringFind(s,",");
s2=StringSubstr(s,0,n);
res.r=(int)StringToInteger(s2);
s=StringSubstr(s,n+1);
n=StringFind(s,",");
s2=StringSubstr(s,0,n);
res.g=(int)StringToInteger(s2);
s=StringSubstr(s,n+1);
s2=StringSubstr(s,0);
res.b=(int)StringToInteger(s2);
}
//+------------------------------------------------------------------+
File: