Indicators Used
Miscellaneous
0
Views
0
Downloads
0
Favorites
Regression_Analysis_Alert
//+--------------------------------------------------------------------------------------------------+
//| Regression_Analysis_Alert.mq5 |
//| Copyright © 2012, figurelli |
//| https://login.mql5.com/en/users/figurelli |
//+--------------------------------------------------------------------------------------------------+
//| Original Code: http://www.mql5.com/en/code/352 - Copyright © 2011, barmenteros |
//+--------------------------------------------------------------------------------------------------+
#property copyright "Copyright © 2012, figurelli"
#property link "https://login.mql5.com/en/users/figurelli"
#property version "1.00"
#property description "Change Alert for barmenteros original indicator that compares four types of regression (linear, quadratic,"
#property description "logarithmic and exponential) and chooses the one that best fits the data analyzed."
//--- indicator settings
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_plots 3
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrGray
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrRed
#property indicator_type3 DRAW_LINE
#property indicator_color3 clrRed
#property indicator_label1 "Regression"
#property indicator_label2 "Upper Band"
#property indicator_label3 "Lower Band"
static string last_reg="?";
static string old_reg="?";
//+--------------------------------------------------------------------------------------------------+
//| Enumerations |
//+--------------------------------------------------------------------------------------------------+
enum inputs_switch
{
On,
Off
};
//--- input parameters
// dp_limiter It should be >2 . If not it will be autoset to default value
input ushort dp_limiter =100; // Number of data points
input uint endpos =0; // Last value position
input double multStdDev =1.96; // Bands separation
input inputs_switch comments =On; // Comments switch
input inputs_switch record =Off; // Record info into a file text
//--- global variables
ushort Extdp_limiter;
//--- indicator buffers
double RegBfr[];
double BandUpBfr[];
double BandDwBfr[];
//+--------------------------------------------------------------------------------------------------+
//| TimeDayMQL4 |
//+--------------------------------------------------------------------------------------------------+
int TimeDayMQL4(datetime date)
{
MqlDateTime tm;
TimeToStruct(date,tm);
return(tm.day);
}
//+--------------------------------------------------------------------------------------------------+
//| TimeYearMQL4 |
//+--------------------------------------------------------------------------------------------------+
int TimeYearMQL4(datetime date)
{
MqlDateTime tm;
TimeToStruct(date,tm);
return(tm.year);
}
//+--------------------------------------------------------------------------------------------------+
//| TimeMonthMQL4 |
//+--------------------------------------------------------------------------------------------------+
int TimeMonthMQL4(datetime date)
{
MqlDateTime tm;
TimeToStruct(date,tm);
return(tm.mon);
}
//+--------------------------------------------------------------------------------------------------+
//| TimeHourMQL4 |
//+--------------------------------------------------------------------------------------------------+
int TimeHourMQL4(datetime date)
{
MqlDateTime tm;
TimeToStruct(date,tm);
return(tm.hour);
}
//+--------------------------------------------------------------------------------------------------+
//| TimeMinuteMQL4 |
//+--------------------------------------------------------------------------------------------------+
int TimeMinuteMQL4(datetime date)
{
MqlDateTime tm;
TimeToStruct(date,tm);
return(tm.min);
}
//+--------------------------------------------------------------------------------------------------+
//| TimeSecondsMQL4 |
//+--------------------------------------------------------------------------------------------------+
int TimeSecondsMQL4(datetime date)
{
MqlDateTime tm;
TimeToStruct(date,tm);
return(tm.sec);
}
//+--------------------------------------------------------------------------------------------------+
//| Polynomial Regression |
//+--------------------------------------------------------------------------------------------------+
void iPolReg(int datapoints,int grade,double &array1[],double &array2[])
{
// y=c0+c1x+c2x^2+c3x^3...cnx^n
// grade+1 número de funciones y de coeficientes a calcular
// 2*grade valor del mayor exponente
// datapoints número de valores a considerar
// pos first value position (left to right direction)
int pos,expon,k,row,col,
initialrow,initialcol,
loop,i,j;
double sumx,sumyx,sum;
double sumxvalues[],
sumyxvalues[],
matrix[][10],
constant[];
pos=datapoints-1;
ArrayResize(sumxvalues,2*grade+1);
ArrayResize(sumyxvalues,grade+1);
ArrayInitialize(sumxvalues,0.0);
ArrayInitialize(sumyxvalues,0.0);
sumxvalues[0]=datapoints;
for(expon=1;expon<=2*grade;expon++)
{
sumx=0.0;
sumyx=0.0;
for(k=1;k<=datapoints;k++)
{
sumx+=MathPow(k,expon);
if(expon==1)
sumyx+=array1[pos-k+1];
else if(expon<=grade+1)
sumyx+=array1[pos-k+1]*MathPow(k,expon-1);
}
sumxvalues[expon]=sumx;
if(sumyx!=0.0)
sumyxvalues[expon-1]=sumyx;
}
ArrayResize(matrix,grade+1);
ArrayInitialize(matrix,0.0);
for(row=0;row<=grade;row++)
for(col=0;col<=grade;col++)
matrix[row][col]=sumxvalues[row+col];
initialrow=1;
initialcol=1;
for(loop=1;loop<=grade;loop++)
{
for(row=initialrow;row<=grade;row++)
{
sumyxvalues[row]=sumyxvalues[row]-(matrix[row][loop-1]/matrix[loop-1][loop-1])*sumyxvalues[loop-1];
for(col=initialcol;col<=grade;col++)
matrix[row][col]=matrix[row][col]-(matrix[row][loop-1]/matrix[loop-1][loop-1])*matrix[loop-1][col];
}
initialrow++;
initialcol++;
}
ArrayResize(constant,grade+1);
ArrayInitialize(constant,0.0);
j=0;
for(i=grade;i>=0;i--)
{
if(j==0)
constant[i]=sumyxvalues[i]/matrix[i][i];
else
{
sum=0.0;
for(k=j;k>0;k--)
sum+=constant[i+k]*matrix[i][i+k];
constant[i]=(sumyxvalues[i]-sum)/matrix[i][i];
}
j++;
}
ArrayResize(array2,datapoints);
ArrayInitialize(array2,EMPTY_VALUE);
k=1;
for(i=datapoints-1;i>=0;i--)
{
sum=0.0;
for(j=0;j<=grade;j++)
sum+=constant[j]*MathPow(k,j);
array2[i]=sum;
k++;
}
}
//+--------------------------------------------------------------------------------------------------+
//| Logarithmic Regression |
//+--------------------------------------------------------------------------------------------------+
void iLogReg(int datapoints,double &array1[],double &array2[])
{
// y=c0*x^c1
// lny=lnc0+c1lnx <=> y=a+bx
// c0=e^a
// c1=b
int pos,expon,k,
row,col,i;
double sumx,sumyx,
lnx,a;
double sumxvalues[],
sumyxvalues[],
matrix[][10],
constant[];
pos=datapoints-1;
ArrayResize(sumxvalues,3);
ArrayResize(sumyxvalues,2);
ArrayInitialize(sumxvalues,0.0);
ArrayInitialize(sumyxvalues,0.0);
sumxvalues[0]=datapoints;
for(expon=1;expon<=2;expon++)
{
sumx=0.0;
sumyx=0.0;
for(k=1;k<=datapoints;k++)
{
lnx=MathLog(k);
sumx+=MathPow(lnx,expon);
if(expon==1)
sumyx+=MathLog(array1[pos-k+1]);
else
sumyx+=MathLog(array1[pos-k+1])*MathPow(lnx,expon-1);
}
sumxvalues[expon]=sumx;
if(sumyx!=0.0)
sumyxvalues[expon-1]=sumyx;
}
ArrayResize(matrix,2);
ArrayInitialize(matrix,0.0);
for(row=0;row<=1;row++)
for(col=0;col<=1;col++)
matrix[row][col]=sumxvalues[row+col];
sumyxvalues[1]=sumyxvalues[1]-(matrix[1][0]/matrix[0][0])*sumyxvalues[0];
matrix[1][1]=matrix[1][1]-(matrix[1][0]/matrix[0][0])*matrix[0][1];
ArrayResize(constant,2);
ArrayInitialize(constant,0.0);
constant[1]=sumyxvalues[1]/matrix[1][1];
a=(sumyxvalues[0]-(constant[1]*matrix[0][1]))/matrix[0][0];
constant[0]=MathExp(a);
ArrayResize(array2,datapoints);
ArrayInitialize(array2,EMPTY_VALUE);
k=1;
for(i=datapoints-1;i>=0;i--)
{
array2[i]=constant[0]*MathPow(k,constant[1]);
k++;
}
}
//+--------------------------------------------------------------------------------------------------+
//| Exponential Regression |
//+--------------------------------------------------------------------------------------------------+
void iExpReg(int datapoints,double &array1[],double &array2[])
{
// y=c0*e^(xc1)
// lny=lnc0+c1x <=> y=a+bx
// c0=e^a
// c1=b
int pos,expon,k,
row,col,i;
double sumx,sumyx,a;
double sumxvalues[],
sumyxvalues[],
matrix[][10],
constant[];
pos=datapoints-1;
ArrayResize(sumxvalues,3);
ArrayResize(sumyxvalues,2);
ArrayInitialize(sumxvalues,0.0);
ArrayInitialize(sumyxvalues,0.0);
sumxvalues[0]=datapoints;
for(expon=1;expon<=2;expon++)
{
sumx=0.0;
sumyx=0.0;
for(k=1;k<=datapoints;k++)
{
sumx+=MathPow(k,expon);
if(expon==1)
sumyx+=MathLog(array1[pos-k+1]);
else
sumyx+=MathLog(array1[pos-k+1])*MathPow(k,expon-1);
}
sumxvalues[expon]=sumx;
if(sumyx!=0.0)
sumyxvalues[expon-1]=sumyx;
}
ArrayResize(matrix,2);
ArrayInitialize(matrix,0.0);
for(row=0;row<=1;row++)
for(col=0;col<=1;col++)
matrix[row][col]=sumxvalues[row+col];
sumyxvalues[1]=sumyxvalues[1]-(matrix[1][0]/matrix[0][0])*sumyxvalues[0];
matrix[1][1]=matrix[1][1]-(matrix[1][0]/matrix[0][0])*matrix[0][1];
ArrayResize(constant,2);
ArrayInitialize(constant,0.0);
constant[1]=sumyxvalues[1]/matrix[1][1];
a=(sumyxvalues[0]-(constant[1]*matrix[0][1]))/matrix[0][0];
constant[0]=MathExp(a);
ArrayResize(array2,datapoints);
ArrayInitialize(array2,EMPTY_VALUE);
k=1;
for(i=datapoints-1;i>=0;i--)
{
array2[i]=constant[0]*MathExp(k*constant[1]);
k++;
}
}
//+--------------------------------------------------------------------------------------------------+
//| iStdDevOnArray |
//+--------------------------------------------------------------------------------------------------+
double iStdDevOnArray(double &array1[],int datapoints)
{
int i;
double sum,arithmean,stddev;
sum=0.0;
for(i=datapoints-1;i>=0;i--)
sum+=array1[i];
if(datapoints<=0) datapoints=1;
arithmean=sum/datapoints;
sum=0.0;
for(i=datapoints-1;i>=0;i--)
sum+=(array1[i]-arithmean)*(array1[i]-arithmean);
if(datapoints<=0) datapoints=1;
stddev=MathSqrt(sum/datapoints);
return(stddev);
}
//+--------------------------------------------------------------------------------------------------+
//| BestReg |
//+--------------------------------------------------------------------------------------------------+
void BestReg(const int rates_total,double &array1[],double &array2[],double &array3[])
{
string short_name;
double currentstddev;
int c_stddevindex,i;
if(comments==On)
Comment("LinReg=",DoubleToString(array1[0],_Digits),
" || QuadReg=",DoubleToString(array1[1],_Digits),
" || LogReg=",DoubleToString(array1[2],_Digits),
" || ExpReg=",DoubleToString(array1[3],_Digits));
currentstddev=array1[0];
c_stddevindex=0;
for(i=1;i<=3;i++)
{
if(array1[i]<currentstddev)
{
currentstddev=array1[i];
c_stddevindex=i;
}
}
switch(c_stddevindex)
{
case 0 : iPolReg(dp_limiter,1,array2,array3); short_name="LinReg(";
if(last_reg!="LinReg")
{
old_reg=last_reg;
last_reg="LinReg";
if(old_reg!=last_reg && old_reg!="?") Alert("Regression_Analysis: ",Symbol()," - Change from [",old_reg,"] to [",last_reg,"]");
}
Comment("***** LinReg=",DoubleToString(array1[0],_Digits),
" ***** || QuadReg=",DoubleToString(array1[1],_Digits),
" || LogReg=",DoubleToString(array1[2],_Digits),
" || ExpReg=",DoubleToString(array1[3],_Digits)," --- ",old_reg," ----> LinReg");
break;
case 1 : iPolReg(dp_limiter,2,array2,array3); short_name="QuadReg(";
if(last_reg!="QuadReg")
{
old_reg=last_reg;
last_reg="QuadReg";
if(old_reg!=last_reg && old_reg!="?") Alert("Regression_Analysis: ",Symbol()," - Change from [",old_reg,"] to [",last_reg,"]");
}
Comment("LinReg=",DoubleToString(array1[0],_Digits),
" || ***** QuadReg=",DoubleToString(array1[1],_Digits),
" ***** || LogReg=",DoubleToString(array1[2],_Digits),
" || ExpReg=",DoubleToString(array1[3],_Digits)," --- ",old_reg," ----> QuadReg");
break;
case 2 : iLogReg(dp_limiter,array2,array3); short_name="LogReg(";
if(last_reg!="LogReg")
{
old_reg=last_reg;
last_reg="LogReg";
if(old_reg!=last_reg && old_reg!="?") Alert("Regression_Analysis: ",Symbol()," - Change from [",old_reg,"] to [",last_reg,"]");
}
Comment("LinReg=",DoubleToString(array1[0],_Digits),
" || QuadReg=",DoubleToString(array1[1],_Digits),
" || ***** LogReg=",DoubleToString(array1[2],_Digits),
" ***** || ExpReg=",DoubleToString(array1[3],_Digits)," --- ",old_reg," ----> LogReg");
break;
case 3 : iExpReg(dp_limiter,array2,array3); short_name="ExpReg(";
if(last_reg!="ExpReg")
{
old_reg=last_reg;
last_reg="ExpReg";
if(old_reg!=last_reg && old_reg!="?") Alert("Regression_Analysis: ",Symbol()," - Change from [",old_reg,"] to [",last_reg,"]");
}
Comment("LinReg=",DoubleToString(array1[0],_Digits),
" || QuadReg=",DoubleToString(array1[1],_Digits),
" || LogReg=",DoubleToString(array1[2],_Digits),
" || ***** ExpReg=",DoubleToString(array1[3],_Digits)," ***** --- ",old_reg," ----> ExpReg");
break;
default :iPolReg(dp_limiter,1,array2,array3); short_name="LinReg(";
if(last_reg!="LinReg")
{
old_reg=last_reg;
last_reg="LinReg";
if(old_reg!=last_reg && old_reg!="?") Alert("Regression_Analysis: ",Symbol()," - Change from [",old_reg,"] to [",last_reg,"]");
}
Comment("***** LinReg=",DoubleToString(array1[0],_Digits),
" ***** || QuadReg=",DoubleToString(array1[1],_Digits),
" || LogReg=",DoubleToString(array1[2],_Digits),
" || ExpReg=",DoubleToString(array1[3],_Digits)," --- ",old_reg," ----> LinReg");
break;
}
IndicatorSetString(INDICATOR_SHORTNAME,short_name+string(dp_limiter)+")");
PlotIndexSetString(0,PLOT_LABEL,short_name+string(dp_limiter)+")");
ArrayInitialize(RegBfr,EMPTY_VALUE);
for(i=dp_limiter-1;i>=0;i--)
RegBfr[rates_total-1-endpos-i]=array3[i];
}
//+--------------------------------------------------------------------------------------------------+
//| ConfidenceBands |
//+--------------------------------------------------------------------------------------------------+
void ConfidenceBands(const int rates_total,double &array1[])
{
int i;
double sum,variance;
sum=0.0;
for(i=dp_limiter-1;i>=0;i--)
sum+=(array1[i]-RegBfr[rates_total-1-endpos-i])*(array1[i]-RegBfr[rates_total-1-endpos-i]);
variance=MathSqrt(sum/dp_limiter);
ArrayInitialize(BandUpBfr,EMPTY_VALUE);
ArrayInitialize(BandDwBfr,EMPTY_VALUE);
for(i=dp_limiter-1;i>=0;i--)
{
BandUpBfr[rates_total-1-endpos-i]=RegBfr[rates_total-1-endpos-i]+(multStdDev*variance);
BandDwBfr[rates_total-1-endpos-i]=RegBfr[rates_total-1-endpos-i]-(multStdDev*variance);
}
}
//+--------------------------------------------------------------------------------------------------+
//| Custom indicator initialization function |
//+--------------------------------------------------------------------------------------------------+
void OnInit()
{
//--- check for input values
if(dp_limiter<=2)
{
Extdp_limiter=3;
printf("Incorrect value for input variable dp_limiter=%d. Indicator will use value=%d for calculations.",
dp_limiter,Extdp_limiter);
}
else Extdp_limiter=dp_limiter;
//--- indicator buffers mapping
SetIndexBuffer(0,RegBfr);
SetIndexBuffer(1,BandUpBfr);
SetIndexBuffer(2,BandDwBfr);
//--- set accuracy
IndicatorSetInteger(INDICATOR_DIGITS,_Digits+1);
//--- name for DataWindow and indicator subwindow label
PlotIndexSetString(1,PLOT_LABEL,"UpperBand");
PlotIndexSetString(2,PLOT_LABEL,"LowerBand");
//--- initialization done
}
//+--------------------------------------------------------------------------------------------------+
//| Custom indicator iteration function |
//+--------------------------------------------------------------------------------------------------+
int OnCalculate(const int rates_total, // size of the price[] array
const int prev_calculated,// bars handled on a previous call
const int begin, // where the significant data start from
const double &price[]) // array to calculate
{
//--- local variables
static int current_day,previous_day;
static int c_filehandle,p_filehandle;
string filename,timetext;
int i;
double errorstddev[4],
data[],
regression[],
regressionerror[];
//--- file recording
if(record==On)
{
previous_day=current_day;
current_day=TimeDayMQL4(TimeCurrent());
if(current_day!=previous_day)
{
StringConcatenate(filename,TimeYearMQL4(TimeCurrent()),"-",
TimeMonthMQL4(TimeCurrent()),"-",
current_day,"-",_Symbol,
"-b_Regression_Analysis.txt");
p_filehandle=c_filehandle;
ResetLastError();
c_filehandle=FileOpen(filename,FILE_CSV|FILE_READ|FILE_WRITE,';');
if(c_filehandle!=INVALID_HANDLE && c_filehandle!=p_filehandle)
FileWrite(c_filehandle,"time","error[LinReg]","error[QuadReg]",
"error[LogReg]","error[ExpReg]");
else Print("Operation FileOpen failed, error ",GetLastError());
}
}
// ---- resize arrays
ArrayResize(data,Extdp_limiter);
ArrayResize(regression,Extdp_limiter);
ArrayResize(regressionerror,Extdp_limiter);
// ----
ArrayInitialize(data,EMPTY_VALUE);
for(i=0;i<dp_limiter;i++)
data[i]=price[rates_total-1-endpos-i];
// ----
ArrayInitialize(regression,EMPTY_VALUE);
iPolReg(dp_limiter,1,data,regression);
ArrayInitialize(regressionerror,EMPTY_VALUE);
for(i=0;i<dp_limiter;i++)
regressionerror[i]=MathAbs(data[i]-regression[i]);
errorstddev[0]=iStdDevOnArray(regressionerror,dp_limiter);
// ----
ArrayInitialize(regression,EMPTY_VALUE);
iPolReg(dp_limiter,2,data,regression);
for(i=0;i<dp_limiter;i++)
regressionerror[i]=MathAbs(data[i]-regression[i]);
errorstddev[1]=iStdDevOnArray(regressionerror,dp_limiter);
// ----
ArrayInitialize(regression,EMPTY_VALUE);
iLogReg(dp_limiter,data,regression);
for(i=0;i<dp_limiter;i++)
regressionerror[i]=MathAbs(data[i]-regression[i]);
errorstddev[2]=iStdDevOnArray(regressionerror,dp_limiter);
// ----
ArrayInitialize(regression,EMPTY_VALUE);
iExpReg(dp_limiter,data,regression);
for(i=0;i<dp_limiter;i++)
regressionerror[i]=MathAbs(data[i]-regression[i]);
errorstddev[3]=iStdDevOnArray(regressionerror,dp_limiter);
// ----
if(record==On)
if(c_filehandle!=INVALID_HANDLE)
{
StringConcatenate(timetext,TimeHourMQL4(TimeCurrent()),":",
TimeMinuteMQL4(TimeCurrent()),":",TimeSecondsMQL4(TimeCurrent()));
FileWrite(c_filehandle,timetext,
DoubleToString(errorstddev[0],_Digits),
DoubleToString(errorstddev[1],_Digits),
DoubleToString(errorstddev[2],_Digits),
DoubleToString(errorstddev[3],_Digits));
}
// ----
BestReg(rates_total,errorstddev,data,regression);
ConfidenceBands(rates_total,data);
//--- return value of prev_calculated for next call
return(rates_total);
}
//+--------------------------------------------------------------------------------------------------+
Comments
Markdown Formatting Guide
# H1
## H2
### H3
**bold text**
*italicized text*
[title](https://www.example.com)

`code`
```
code block
```
> blockquote
- Item 1
- Item 2
1. First item
2. Second item
---