Indicadores: Indicador de correlação de Pearson - página 2

 
Aqui, aproximadamente assim - https://www.mql5.com/pt/code/183. A questão é que a cópia de dados de outros símbolos não é realizada de uma só vez, mas uma barra de cada vez. Durante essa cópia, a partir de outros símbolos, a barra será copiada exatamente de acordo com o tempo da barra do gráfico, na qual o indicador é exibido. Se não houver uma barra correspondente, ela será copiada de uma barra anterior (como a função iBarShift() em MQL4). Nesse indicador, é copiada uma barra de cada vez, mas, para a correlação, pode ser necessário copiar o número correspondente ao período de correlação. Você pode fazer isso de outra forma: copie uma barra de cada vez e coloque-a no buffer do indicador. Usando o buffer, você pode fazer tudo o mais rápido possível (obviamente, às custas de um maior consumo de memória). Você pode fazer isso sem um buffer extra, com algumas variáveis estáticas.... A explicação é longa, provavelmente será necessário escrever um artigo:)
 
pusheax:

Ok, ontem ficamos um pouco empolgados demais, acho que você também comemorou o "Dia do Guarda de Fronteira" como eu.

Você pode me fornecer um link para a sincronização correta dos compassos, porque eu também uso esse método de sincronização pelo último compasso e pronto?

Não lhe darei um link (porque ainda não o encontrei), mas descreverei o método.

O método se refere à sincronização de diferentes instrumentos, embora possa ser usado para a sincronização de diferentes TFs.

Venho lidando com esse problema há bastante tempo, e até mesmo o SD fez uma correção dos bugs desse método que identifiquei.

O problema de sincronização está relacionado ao fato de que diferentes instrumentos têm um número diferente de barras. Aproximadamente o mesmo é um critério falso, tudo deve ser exato. Barra a barra. Caso contrário, o significado da sincronização se perde.

O segundo aspecto desse problema é como exibir uma barra se não houver nenhuma barra no instrumento atual?

Portanto, a essência do método é simples: os dados do instrumento são solicitados estritamente por horários...

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

e a amostra de tempo é retirada do buffer padrão do indicador time[]. Assim, você sempre terá certeza de que está diante de uma barra que veio em sincronia com uma barra em outro instrumento.

Novamente, se não houver tal barra no instrumento atual, você não a solicitará. E se o instrumento solicitado não tiver essa barra como amostra, você receberá um zero na contagem e poderá lidar normalmente com essa exceção, dependendo da lógica do seu programa.

 

Implementação da sincronização (em MQL4) para qualquer número de FIs(daqui):

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;
}

Por analogia para dois símbolos(a partir daqui):

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;
}
Ou seja, tudo é bastante simples. Outra coisa é que a representação barométrica clássica (discretização de tempo constante) dos preços dos BPs não é a única, muito menos sempre correta. Às vezes, é extremamente útil sincronizar os preços dos BPs de outra dimensão de tempo. Ou seja, introduzindo distorções que não são lineares do ponto de vista do tempo clássico. De forma correspondente, a correlação mostrará inter-relações não lineares de dois VRs clássicos.
 

Obrigado por sua ajuda!

Eu estava errado, admito, não achei que a sincronização fosse tão complicada.

Vou tentar descobrir e sincronizar as barras diretamente nesse indicador, pois preciso muito disso.

 

Obrigado a todos pelas informações!

Reescrevi um pouco o indicador. Agora, supostamente, ele deve pular partes ruins do histórico.

Já que começamos, por favor, verifique se há erros :)

Arquivos anexados:
 
Vou falar mais uma vez sobre a necessidade de otimização algorítmica para todos os indicadores. E também pelo mecanismo embutido de cálculo dos valores do indicador na memória (arquivo), de modo que, durante a otimização do testador, o indicador não calcule a mesma coisa, mas pegue valores prontos de lá.
 
hrenfx:
Vou falar mais uma vez sobre a necessidade de otimização algorítmica para todos os indicadores. E também por um mecanismo embutido de cálculo dos valores do indicador na memória (arquivo), de modo que, durante a otimização do testador, o indicador não calcule a mesma coisa, mas pegue valores prontos de lá.
Você poderia mostrar um exemplo em que isso já tenha sido feito?
 

A otimização algorítmica para cada indicador é diferente. Para diferentes formas de usar a correlação, fiz, por exemplo, isto e isto.

A leitura de memória dos valores dos indicadores calculados antecipadamente para todo o histórico foi feita apenas em minha calculadora. Ou seja, não tenho um mecanismo universal, porque uso apenas minhas próprias soluções, que não são nada bonitas. Mas, como sou a favor do aprimoramento de tudo, seria ótimo ter esse mecanismo universal no caso do otimizador do testador do MT5, porque ele oferece aceleração de várias ordens de magnitude (experiência de uso em minha calculadora), ou seja, ele supera o Cloud em termos de eficiência.

 

Olá,

Às vezes, passo o tempo distorcendo os códigos de outras pessoas, geralmente os resultados de um programa incompleto ou incompleto, tanto por falta de tempo quanto por falta de habilidade.

Dessa vez, eu tentaria distorcer esse maravilhoso indicador, e tentei fazer algo assim:

- Desenhar apenas uma linha, não uma linha de plotagem pontilhada



#property indicator_type1 DRAW_COLOR_LINE
#property indicator_width1 2

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

- Para adicionar vários símbolos, como

//--- parâmetros de entrada
input string _SecondSymbol="EURGBP"; // Símbolo

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

Em seguida, criar duas variantes do código-fonte:

- Variante visual: uma linha colorida para cada correlação de pares de moedas 1 linha grossa que é apenas a média de 7 linhas ((A+B+C+D+E+F+G)/7)

- Sem variante visual: Apenas 1 linha, que é o resultado da fórmula acima ((A+B+C+D+D+E+F+G)/7)

É quase como adicionar 7 (ou 8) indicadores de correlação originais, mas todos somados, de modo que apenas a média, como na versão com 7 linhas + 1 (média) e a outra versão com 1 linha (apenas média).

Algo parecido com isso:

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; // média simples de valores.


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

Por vários motivos, o código distorcido não faz o que eu quero por causa de erros completamente lógicos.

O principal problema é com os buffers, a sincronização e a parte de indentação recursiva do código:

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

+ além de outros erros lógicos.

Algumas funções Print() foram adicionadas para ajudar no caso de rastreamento de valores de variáveis e as instruções de retorno 0 foram comentadas para localizar onde o código falha logicamente.

 

código e arquivo

//+------------------------------------------------------------------+
//| Correlação.mq5 |
//|| Copyright 2012, iC |
//| http://www.icreator.biz/ |
//+------------------------------------------------------------------+
#property copyright "Copyright 2012, iC"
#property link "http://www.icreator.biz/"
#property version "1.00"
//--- configurações do indicador
#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
// #property indicator_style2 STYLE_DOT
// #property 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
#property indicator_width5 2

#property indicator_type6 DRAW_COLOR_LINE
#property indicator_width6 2

#property indicator_type7 DRAW_COLOR_LINE
#property indicator_width7 2

#property indicator_type8 DRAW_COLOR_LINE
#property indicator_width8 2

*/

//--- define
#define MAX_COL 64
//--- estruturas
struct CRGB
{
int r;
int g;
int b;
};
//--- parâmetros de entrada
input string _SecondSymbol="EURGBP"; // Símbolo

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

input int _SettPeriod=100; // Período
input ENUM_APPLIED_PRICE _AppliedPrice=PRICE_CLOSE; // Preço
input color _Color1=clrLightGray; // Correlação mínima.
input color _Color2=clrLime; // Correlação máxima.

//--- buffers de indicadores
double buf[],buf2[]
,buf3[],buf4[],buf5[],buf6[],buf7[],buf8[];

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

double colors1[],colors2[];

//--- Alças MA
int h1,h2,
h3,h4,h5,h6,h7,h8;
//+------------------------------------------------------------------+
//| Função de inicialização do indicador personalizado
//+------------------------------------------------------------------+
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); // primeiro símbolo
SetIndexBuffer(5,arr2,INDICATOR_CALCULATIONS); // segundo símbolo


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,colours3,INDICATOR_COLOR_INDEX);

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

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

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

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

// etc....
*/

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)+","); // etc...

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);

// valores adicionados.
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;
}
//+------------------------------------------------------------------+
//| Função de iteração de indicador personalizado
//+------------------------------------------------------------------+
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];
//--- símbolos de sincronização
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!");
// retornar 0;
}
//--- verificar se há dados

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);

// recuar os if entre si até que o minBars seja encontrado. // para verificar se a lógica está correta

if(bars1>bars2)
{
minBars=bars2;
bars2=bars1-bars2;
bars1=0;
Print("bars1>bars2; minBars(",minBars,"),=bars2(",bars2,")=bars1(",bars1,")-bars2(",bars2,");");
// }
//caso contrário 
if(bars1>bars3)
{
minBars=bars3;
bars3=bars1-bars3;
bars1=0;
Print("bars1>bars3; minBars(",minBars,"),=bars3(",bars3,")=bars1(",bars1,")-bars3(",bars3,");");
// } 
//caso contrário 
if(bars1>bars4)
{
minBars=bars4;
bars4=bars1-bars4;
bars1=0;
Print("bars1>bars4; minBars(",minBars,"),=bars4(",bars4,")=bars1(",bars1,")-bars4(",bars4,");");
// } 
//caso contrário 
if(bars1>bars5)
{
minBars=bars5;
bars5=bars1-bars5;
bars1=0;
Print("bars1>bars5; minBars(",minBars,"),=bars5(",bars5,")=bars1(",bars1,")-bars5(",bars5,");");
// } 
//caso contrário 
if(bars1>bars6)
{
minBars=bars6;
bars6=bars1-bars6;
bars1=0;
Print("bars1>bars6; minBars(",minBars,"),=bars6(",bars6,")=bars1(",bars1,")-bars6(",bars6,");");
// } 
//caso contrário 
if(bars1>bars7)
{
minBars=bars7;
bars7=bars1-bars7;
bars1=0;
Print("bars1>bars7; minBars(",minBars,"),=bars7(",bars7,")=bars1(",bars1,")-bars7(",bars7,");");
// } 
//caso contrário 
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!");
// retornar 0;
}
if(BarsCalculated(h1)<minBars)
{
Print("Not all data of MA1 is calculated. Error ",GetLastError());
// retornar 0;
}
if(BarsCalculated(h2)<minBars)
{
Print("Not all data of MA2 is calculated. Error ",GetLastError());
// retornar 0;
}
if(BarsCalculated(h3)<minBars)
{
Print("Not all data of MA3 is calculated. Error ",GetLastError());
// retornar 0;
}
if(BarsCalculated(h4)<minBars)
{
Print("Not all data of MA4 is calculated. Error ",GetLastError());
// retornar 0;
}
if(BarsCalculated(h5)<minBars)
{
Print("Not all data of MA5 is calculated. Error ",GetLastError());
// retornar 0;
}
if(BarsCalculated(h6)<minBars)
{
Print("Not all data of MA6 is calculated. Error ",GetLastError());
// retornar 0;
}
if(BarsCalculated(h7)<minBars)
{
Print("Not all data of MA7 is calculated. Error ",GetLastError());
// retornar 0;
}
if(BarsCalculated(h8)<minBars)
{
Print("Not all data of MA8 is calculated. Error ",GetLastError());
// retornar 0;
} 

//--- podemos copiar nem todos os dados
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());
// retornar 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; // média simples de valores.


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);
}
//+------------------------------------------------------------------+
Arquivos anexados: