Atom2/Indicators/Regressao.mq5

135 lines
9.9 KiB
MQL5
Raw Permalink Normal View History

2025-05-30 14:41:58 +02:00
<EFBFBD><EFBFBD>//+------------------------------------------------------------------+
//| Thiago Oliveira - Olimbot |
//| contato@olimbot.com.br |
//+------------------------------------------------------------------+
#property copyright "Thiago Oliveira - OlimBot"
#property link "olimbot.com.br"
#property version "1.00"
#property description "<00>ltima atualiza<00><00>o em 22/Junho/2021"
#property description " "
#property description "Este indicador calcula a regress<00>o linear entre o pre<00>o de fechamento e uma m<00>dia m<00>vel exponencial"
#property description "<00> exibido a dist<00>ncia do pre<00>o em rela<00><00>o a regress<00>o"
#property description "A regress<00>o <00> dividida por uma m<00>dia simples do desvio padr<00>o do pre<00>o"
#property description "Este procedimento suaviza o movimento do indicador"
#property description "O indicador pode ser usado para mostrar for<00>a do movimento ou movimentos discrepantes"
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots 1
#property indicator_label1 "Ratio"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrRed
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
input int m_periodo_media = 20; // Per<EFBFBD>odo M<EFBFBD>dio
input double m_desvio = 2.0; // Coeficiente de Desvio
int periodo_media = m_periodo_media;
int handle_ema;
int handle_std;
double RatioBuffer[]; // Buffer dos dados verdadeiros da regress<EFBFBD>o
//+------------------------------------------------------------------+
//| Inicializa<EFBFBD><EFBFBD>o das variav<EFBFBD>is do indicador |
//+------------------------------------------------------------------+
int OnInit(){
if(m_periodo_media < 2) // Garantido que pelo input o valor do per<EFBFBD>odo ter<EFBFBD> um valor m<EFBFBD>nimo
periodo_media = 2;
// Indicadores usados no c<EFBFBD>lculo da regress<EFBFBD>o
handle_std = iStdDev(_Symbol,_Period,periodo_media,0,MODE_EMA,PRICE_CLOSE);
handle_ema = iMA(_Symbol,_Period,periodo_media,0,MODE_EMA,PRICE_CLOSE);
if(handle_ema == INVALID_HANDLE){
printf("Falha em obter o handle da EMA");
return INIT_FAILED;
}
if(handle_std== INVALID_HANDLE){
printf("Falha em obter o handle do desvio padr<00>o");
return INIT_FAILED;
}
// Selecionando as linhas fixas atrav<EFBFBD>s do desvioselecionado
IndicatorSetInteger(INDICATOR_LEVELS,2);
IndicatorSetDouble(INDICATOR_LEVELVALUE,0,m_desvio);
IndicatorSetDouble(INDICATOR_LEVELVALUE,1,-m_desvio);
SetIndexBuffer(0,RatioBuffer,INDICATOR_DATA); // Indicando o buffer dos valores
ArraySetAsSeries(RatioBuffer,true);
IndicatorSetInteger(INDICATOR_DIGITS,5);
// Nome dado ao indicador
IndicatorSetString(INDICATOR_SHORTNAME,"Regress<00>o Linear ("+
IntegerToString(periodo_media)+"/"+
DoubleToString(m_desvio,1)+")");
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| C<EFBFBD>lculo do indicador, utilizar como base o fechamento |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const int begin,
const double& price[]){
if(IsStopped())
return 0;
int pos = 0;
int limit_ema = periodo_media+1;
double ema[];
double std[];
if(prev_calculated == 0){
pos = rates_total-1;
limit_ema = rates_total;
}
ArraySetAsSeries(ema,true);
ArraySetAsSeries(price,true);
ArraySetAsSeries(std,true);
CopyBuffer(handle_ema,0,0,limit_ema,ema);
CopyBuffer(handle_std,0,0,limit_ema,std);
for(int i=pos; i>=0 && !IsStopped(); i--)
if(i < rates_total-periodo_media){
// Dados para calculo da regress<EFBFBD>o linear
int cnt = 0; // Contador do loop
double mediaX = 0;
double mediaY = 0;
double xy = 0;
double x2 = 0;
double X = 0;
double Y = 0;
double media_std = 0; // M<EFBFBD>dia do desvio padr<EFBFBD>o
for(int k=periodo_media-1; k>=0; k--){ // Verificando valores para c<EFBFBD>lculo da regress<EFBFBD>o sobre a m<EFBFBD>dia
X = ema[i+k];
Y = price[i+k];
mediaX += X;
mediaY += Y;
xy += (X*Y);
x2 += MathPow(X,2);
media_std += std[i+k]; // M<EFBFBD>dia do desvio padr<EFBFBD>o
cnt++; // Contador de loop para confirma<EFBFBD><EFBFBD>o
}
// <EFBFBD>nicio dos c<EFBFBD>lculos da regress<EFBFBD>o
mediaX = (cnt == 0) ? 0.0 : mediaX/cnt;
mediaY = (cnt == 0) ? 0.0 : mediaY/cnt;
media_std /= ((periodo_media == 0) ? 0.0 : periodo_media); // Finalizando a m<EFBFBD>dia do desvio padr<EFBFBD>o
double divisor = x2-(cnt*MathPow(mediaX,2));
double b = (divisor == 0) ? 0.0 : (xy-(cnt*mediaX*mediaY))/divisor;
double a = mediaY-(b*mediaX);
double res = a+(b*X); // C<EFBFBD>lculo do residuo da regress<EFBFBD>o
RatioBuffer[i] = Y-res; // Verificando dist<EFBFBD>ncia do pre<EFBFBD>o em rela<EFBFBD><EFBFBD>o <EFBFBD> regress<EFBFBD>o
RatioBuffer[i] /= (media_std > 0 ? media_std : DBL_MIN); // Estacionarizando a m<EFBFBD>dia dividindo pelo desvio padr<EFBFBD>o
}
return(rates_total-1);
}
//+------------------------------------------------------------------+