Standard Deviation Channel - Least Squares Method

 

Hi everyone,

I am trying to draw a standard deviation channel as part of my EA using the Least Squares Method: https://www.mathsisfun.com/data/least-squares-regression.html

But I am getting some strange values. Can anyone spot something in the code that I am doing wrong? Or is it just because iTime and iClose are real time values and that I am getting random errors when calling them?

The code below creates the white line in the attached screenshot. This line is suppose to be the same as the center line of the red standard deviation channel in the image

void TrendStandardDeviation ()
{
   //Ensuring all arrays are set as series
   ArraySetAsSeries(TrendX_Array,true);
   ArraySetAsSeries(TrendY_Array,true);
   ArraySetAsSeries(TrendXsqr_Array,true);
   ArraySetAsSeries(TrendXY_Array,true);
   ArraySetAsSeries(AnchorClose,true);
   ArraySetAsSeries(AnchorTime,true);
   
   //All arrays cleared
   ArrayRemove(TrendX_Array,0,WHOLE_ARRAY);
   ArrayRemove(TrendY_Array,0,WHOLE_ARRAY);
   ArrayRemove(TrendXsqr_Array,0,WHOLE_ARRAY);
   ArrayRemove(TrendXY_Array,0,WHOLE_ARRAY);
   ArrayRemove(AnchorClose,0,WHOLE_ARRAY);
   ArrayRemove(AnchorTime,0,WHOLE_ARRAY); 
   
   //Ensures that all arrays have "enough space"
   ArrayResize(TrendX_Array,4,0);
   ArrayResize(TrendY_Array,4,0);
   ArrayResize(TrendXsqr_Array,4,0);
   ArrayResize(TrendXY_Array,4,0);
   ArrayResize(AnchorClose,4,0);
   ArrayResize(AnchorTime,4,0); 
   
   //Assigning values to arrays
   AnchorTime [0] = iTime(_Symbol,PERIOD_H1,40);
   AnchorClose [0] = iClose(_Symbol,PERIOD_H1,40);
   
   AnchorTime [1] = iTime(_Symbol,PERIOD_H1,20);
   AnchorClose [1] = iClose(_Symbol,PERIOD_H1,20);
   
   AnchorTime [2] = iTime(_Symbol,PERIOD_H1,1);
   AnchorClose [2] = iClose(_Symbol,PERIOD_H1,1);
   
   TrendXsqr_Array[0] = MathPow(AnchorTime[0],2);
   TrendXsqr_Array[1] = MathPow(AnchorTime[1],2);
   TrendXsqr_Array[2] = MathPow(AnchorTime[2],2);
   
   TrendXY_Array[0] = AnchorTime[0]*AnchorClose[0];
   TrendXY_Array[1] = AnchorTime[1]*AnchorClose[1];
   TrendXY_Array[2] = AnchorTime[2]*AnchorClose[2];
  
   // Calculating required variables for the Least Squares Method
   StDTrend = MathStandardDeviation(AnchorClose);
   SumX = MathSum(AnchorTime);
   SumY = MathSum(AnchorClose);
   SumXsqr = MathSum(TrendXsqr_Array);
   SumXY = MathSum(TrendXY_Array);

   //Using Least Squares Method to calculate the regression line
   TrendGradient =(((3*SumXY)-(SumX*SumY))/((3*SumXsqr)-(MathPow(SumX,2))));
   TrendCut = ((SumY)-(TrendGradient*SumX))/3;

   //Getting anchor points using y=mx+c
   TrendAnchorPoint2X = AnchorTime[2];
   TrendAnchorPoint2Y = ((TrendGradient*(AnchorTime[2]))+TrendCut);
   TrendAnchorPoint1X = AnchorTime[0];
   TrendAnchorPoint1Y = ((TrendGradient*(AnchorTime[0]))+TrendCut);
   
   //Creating Channel
   ObjectCreate(_Symbol,"StD",OBJ_TREND,0,TrendAnchorPoint1X,TrendAnchorPoint1Y,TrendAnchorPoint2X,TrendAnchorPoint2Y);
   ObjectSetInteger(_Symbol, "StD",OBJPROP_COLOR,clrWhite);
  

}
Standard Deviation - Trend Indicators - MetaTrader 5 Help
Standard Deviation - Trend Indicators - MetaTrader 5 Help
  • www.metatrader5.com
Standard Deviation — value of the market volatility measurement. This indicator describes the range of price fluctuations relative to Moving...
Files:
 
Jan-HarmZ63:

Hi everyone,

I am trying to draw a standard deviation channel as part of my EA using the Least Squares Method: https://www.mathsisfun.com/data/least-squares-regression.html

But I am getting some strange values. Can anyone spot something in the code that I am doing wrong? Or is it just because iTime and iClose are real time values and that I am getting random errors when calling them?

The code below creates the white line in the attached screenshot. This line is suppose to be the same as the center line of the red standard deviation channel in the image

Hi   I've looked through and the maths looks okay assuming your MathSum function is correct and all the data types are correct.

However, you might try the following:

  • use the index number for the X axis instead of time, that way you will avoid any casting issues 
  • do not use ArraySetAsSeries it is not necessary
  • store the points in X ascending order as that is how the x-axis works so  X[0] = 1  X[1] = 20  X[2] = 40  and the corresponding Y values in same order 
  • substitute the real index time when you plot the line at the end
  • make sure you use type double for everything except X can be an integer and the index time for the object plot should be datetime
regards
 
Paul Anscombe:

Hi   I've looked through and the maths looks okay assuming your MathSum function is correct and all the data types are correct.

However, you might try the following:

  • use the index number for the X axis instead of time, that way you will avoid any casting issues 
  • do not use ArraySetAsSeries it is not necessary
  • store the points in X ascending order as that is how the x-axis works so  X[0] = 1  X[1] = 20  X[2] = 40  and the corresponding Y values in same order 
  • substitute the real index time when you plot the line at the end
  • make sure you use type double for everything except X can be an integer and the index time for the object plot should be datetime
regards

Hi Paul,

Thank you for taking the time to look through the code.

The MathSum that I am using is the subclass in the standard library.

I will work on those suggestions and get back to you.

Regards

Jan-Harm

 

@Paul Anscombe,

I did the MathSum calculations and it turned out that the function does not work correctly. As soon as I assigned the values that I calculated by hand everything worked.

Any idea why the MathSum is not working?

https://www.mql5.com/en/docs/standardlibrary/mathematics/stat/mathsubfunctions/statmathsum


Update: It seems that a random value is added to the Arrays at the [3] position even though I am not assigning something to it. So because the MathSum function is looking at the whole array it is considering the [3] position as well.

If I try and limit the array size to 3 ([0],[1] and [2]) the EA removes itself from the chart.

   //Ensures that all arrays have "enough space"
   ArrayResize(TrendX_Array,3,0);
   ArrayResize(TrendY_Array,3,0);
   ArrayResize(TrendXsqr_Array,3,0);
   ArrayResize(TrendXY_Array,3,0);
   ArrayResize(AnchorClose,3,0);
   ArrayResize(AnchorTime,3,0);
Documentation on MQL5: Standard Library / Mathematics / Statistics / Subfunctions / MathSum
Documentation on MQL5: Standard Library / Mathematics / Statistics / Subfunctions / MathSum
  • www.mql5.com
MathSum(const double&) - Subfunctions - Statistics - Mathematics - Standard Library - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5
 
Jan-HarmZ63:

@Paul Anscombe,

I did the MathSum calculations and it turned out that the function does not work correctly. As soon as I assigned the values that I calculated by hand everything worked.

Any idea why the MathSum is not working?

https://www.mql5.com/en/docs/standardlibrary/mathematics/stat/mathsubfunctions/statmathsum


Update: It seems that a random value is added to the Arrays at the [3] position even though I am not assigning something to it. So because the MathSum function is looking at the whole array it is considering the [3] position as well.

If I try and limit the array size to 3 ([0],[1] and [2]) the EA removes itself from the chart.

Ok that is understandable, MQL does not initialise anything by default, so you can get random values in newly declared variables. You could simply fill the arrays with zero at the start to solve that.

Why the EA closes I can't guess at without all the code,  try checking the Experts tab for error messages.