Download MetaTrader 5

Linear Regression Class

To add comments, please log in or register
Have you found an interesting application? Publish it in Code Base - millions of traders will appreciate that!
imamushroom
157
imamushroom 2016.07.26 12:02 

Hi,

I've translated a Linear Regression Class from this site: http://david.swaim.com/cpp/linreg.htm written in C++. 

However, I'm getting some warnings when I compile my code and I don't know why or how to get rid of them. Can someone help please?

Here's my translated code:

//+------------------------------------------------------------------+
//|                                                      LRClass.mqh |
//|                        Copyright 2016, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class CPoint2D
{
   private:
      double _x, _y;
      
   public:
      void CPoint2D(double pX = 0.0, double pY = 0.0) { _x = pX; _y = pY; }

      void setPoint(double pX, double pY) { _x = pX; _y = pY; }
      void setX(double pX) { _x = pX; }
      void setY(double pY) { _y = pY; }

      double getX() const { return _x; }
      double getY() const { return _y; }
};

class CLinearRegression
{
   protected:
      long _n;             // number of data points input so far
      double _sumX, _sumY; // sums of x and y
      double _sumXsquared, // sum of x squares
             _sumYsquared; // sum y squares
      double _sumXY;       // sum of x*y
      double _a, _b;       // coefficients of f(x) = a + b*x
      double _coefD,       // coefficient of determination
             _coefC,       // coefficient of correlation
             _stdError;    // standard error of estimate

      void Calculate();   // calculate coefficients

   public:
      // Constructor using an array of CPoint2D objects
      // This is also the default constructor
      void CLinearRegression(CPoint2D& pP[], long size = 0);

      // Constructor using arrays of x values and y values
      void CLinearRegression(double& pX[], double& pY[], long pSize = 0);

      virtual void addXY(const double pX, const double pY);
      void addPoint(const CPoint2D& pP) { addXY(pP.getX(), pP.getY()); }

      // Must have at least 3 points to calculate
      // standard error of estimate.  Do we have enough data?
      int haveData() const { return (_n > 2 ? true : false); }
      long items() const { return _n; }

      virtual double getA() const { return _a; }
      virtual double getB() const { return _b; }

      double getCoefDeterm() const { return _coefD; }
      double getCoefCorrel() const { return _coefC; }
      double getStdErrorEst() const { return _stdError; }
      virtual double estimateY(double pX) const { return (_a + _b * pX); }
};

void CLinearRegression::CLinearRegression(CPoint2D& pP[], long pSize)
{
    long i;
    _a = _b = _sumX = _sumY = _sumXsquared = _sumYsquared = _sumXY = 0.0;
    _n = 0;

    if (pSize > 0) // if size greater than zero there are data arrays
        for (_n = 0, i = 0; i < pSize; i++)
            addPoint(pP[i]);
}

void CLinearRegression::CLinearRegression(double& pX[], double& pY[], long pSize)
{
    long i;
    _a = _b = _sumX = _sumY = _sumXsquared = _sumYsquared = _sumXY = 0.0;
    _n = 0;

    if (pSize > 0) // if size greater than zero there are data arrays
        for (_n = 0, i = 0; i < pSize; i++)
            addXY((double)pX[i], (double)pY[i]);
}

void CLinearRegression::addXY(const double pX, const double pY)
{
    _n++;
    _sumX += pX;
    _sumY += pY;
    _sumXsquared += pX * pX;
    _sumYsquared += pY * pY;
    _sumXY += pX * pY;
    Calculate();
}

void CLinearRegression::Calculate()
{
    if (haveData())
    {
        if (MathAbs( double(_n) * _sumXsquared - _sumX * _sumX) > DBL_EPSILON)
        {
            _b = ( (double)(_n) * _sumXY - _sumY * _sumX) /
                ( (double)(_n) * _sumXsquared - _sumX * _sumX);
            _a = (_sumY - _b * _sumX) / (double)(_n);

            double sx = _b * ( _sumXY - _sumX * _sumY / (double)(_n) );
            double sy2 = _sumYsquared - _sumY * _sumY / (double)(_n);
            double sy = sy2 - sx;

            _coefD = sx / sy2;
            _coefC = MathSqrt(_coefD);
            _stdError = MathSqrt(sy / (double)(_n - 2));
        }
        else
        {
            _a = _b = _coefD = _coefC = _stdError = 0.0;
        }
    }
}

 The warnings that I'm receiving are:

possible loss of data due to type conversion    LRClass.mqh     77      25
possible loss of data due to type conversion    LRClass.mqh     88      30
possible loss of data due to type conversion    LRClass.mqh     88      45
0 error(s), 3 warning(s), compile time: 6 msec          1       4


 Thanks in advance

Ernst Van Der Merwe
4735
Ernst Van Der Merwe 2016.07.26 12:56  

Array indices can only be of integer type.

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class CPoint2D
{
   private:
      double _x, _y;
      
   public:
      void CPoint2D(double pX = 0.0, double pY = 0.0) { _x = pX; _y = pY; }

      void setPoint(double pX, double pY) { _x = pX; _y = pY; }
      void setX(double pX) { _x = pX; }
      void setY(double pY) { _y = pY; }

      double getX() const { return _x; }
      double getY() const { return _y; }
};

class CLinearRegression
{
   protected:
      int _n;              // number of data points input so far
      double _sumX, _sumY; // sums of x and y
      double _sumXsquared, // sum of x squares
             _sumYsquared; // sum y squares
      double _sumXY;       // sum of x*y
      double _a, _b;       // coefficients of f(x) = a + b*x
      double _coefD,       // coefficient of determination
             _coefC,       // coefficient of correlation
             _stdError;    // standard error of estimate

      void Calculate();   // calculate coefficients

   public:
      // Constructor using an array of CPoint2D objects
      // This is also the default constructor
      void CLinearRegression(CPoint2D& pP[], int size = 0);

      // Constructor using arrays of x values and y values
      void CLinearRegression(double& pX[], double& pY[], int pSize = 0);

      virtual void addXY(const double pX, const double pY);
      void addPoint(const CPoint2D& pP) { addXY(pP.getX(), pP.getY()); }

      // Must have at least 3 points to calculate
      // standard error of estimate.  Do we have enough data?
      int haveData() const { return (_n > 2 ? true : false); }
      long items() const { return _n; }

      virtual double getA() const { return _a; }
      virtual double getB() const { return _b; }

      double getCoefDeterm() const { return _coefD; }
      double getCoefCorrel() const { return _coefC; }
      double getStdErrorEst() const { return _stdError; }
      virtual double estimateY(double pX) const { return (_a + _b * pX); }
};

void CLinearRegression::CLinearRegression(CPoint2D& pP[], int pSize)
{
    int i;
    _a = _b = _sumX = _sumY = _sumXsquared = _sumYsquared = _sumXY = 0.0;
    _n = 0;

    if (pSize > 0) // if size greater than zero there are data arrays
        for (_n = 0, i = 0; i < pSize; i++)
            addPoint(pP[i]);
}

void CLinearRegression::CLinearRegression(double& pX[], double& pY[], int pSize)
{
    int i;
    _a = _b = _sumX = _sumY = _sumXsquared = _sumYsquared = _sumXY = 0.0;
    _n = 0;

    if (pSize > 0) // if size greater than zero there are data arrays
        for (_n = 0, i = 0; i < pSize; i++)
            addXY((double)pX[i], (double)pY[i]);
}

void CLinearRegression::addXY(const double pX, const double pY)
{
    _n++;
    _sumX += pX;
    _sumY += pY;
    _sumXsquared += pX * pX;
    _sumYsquared += pY * pY;
    _sumXY += pX * pY;
    Calculate();
}

void CLinearRegression::Calculate()
{
    if (haveData())
    {
        if (MathAbs( double(_n) * _sumXsquared - _sumX * _sumX) > DBL_EPSILON)
        {
            _b = ( (double)(_n) * _sumXY - _sumY * _sumX) /
                ( (double)(_n) * _sumXsquared - _sumX * _sumX);
            _a = (_sumY - _b * _sumX) / (double)(_n);

            double sx = _b * ( _sumXY - _sumX * _sumY / (double)(_n) );
            double sy2 = _sumYsquared - _sumY * _sumY / (double)(_n);
            double sy = sy2 - sx;

            _coefD = sx / sy2;
            _coefC = MathSqrt(_coefD);
            _stdError = MathSqrt(sy / (double)(_n - 2));
        }
        else
        {
            _a = _b = _coefD = _coefC = _stdError = 0.0;
        }
    }
}
imamushroom
157
imamushroom 2016.07.26 14:14  
Thanks very much. Kind of obvious when you see it!! Thanks again!
To add comments, please log in or register