CORR - Pearson's Correlation Coefficient

This commit is contained in:
Miha Kralj
2022-11-15 21:12:03 -08:00
parent 80d82e5863
commit 73b41ac0a0
9 changed files with 1242 additions and 1141 deletions
+70
View File
@@ -0,0 +1,70 @@
namespace QuanTAlib;
using System;
/* <summary>
CORR: Pearson's Correlation Coefficient
PCC is a measure of linear correlation between two sets of data.
It is the ratio between the covariance of two variables and the product of
their standard deviations; it is essentially a normalized measurement of
the covariance, such that the result always has a value between 1 and 1.
Sources:
https://en.wikipedia.org/wiki/Pearson_correlation_coefficient
</summary> */
public class CORR_Series : Pair_TSeries_Indicator
{
public CORR_Series(TSeries d1, TSeries d2, int period, bool useNaN = false) : base(d1, d2, period, useNaN)
{
if (base._d1.Count > 0 && base._d2.Count > 0) { for (int i = 0; i < base._d1.Count; i++) { this.Add(base._d1[i], base._d2[i], false); } }
}
private readonly System.Collections.Generic.List<double> _x = new();
private readonly System.Collections.Generic.List<double> _xx = new();
private readonly System.Collections.Generic.List<double> _y = new();
private readonly System.Collections.Generic.List<double> _yy = new();
private readonly System.Collections.Generic.List<double> _xy = new();
public override void Add((System.DateTime t, double v) TValue1, (System.DateTime t, double v) TValue2, bool update)
{
if (update)
{
_x[_x.Count - 1] = TValue1.v;
_xx[_xx.Count - 1] = TValue1.v * TValue1.v;
_y[_y.Count - 1] = TValue2.v;
_y[_yy.Count - 1] = TValue2.v * TValue2.v;
_xy[_xy.Count - 1] = TValue1.v * TValue2.v;
}
else
{
_x.Add(TValue1.v);
_xx.Add(TValue1.v * TValue1.v);
_y.Add(TValue2.v);
_yy.Add(TValue2.v * TValue2.v);
_xy.Add(TValue1.v * TValue2.v);
}
if (_x.Count > this._p) { _x.RemoveAt(0); }
if (_xx.Count > this._p) { _xx.RemoveAt(0); }
if (_y.Count > this._p) { _y.RemoveAt(0); }
if (_yy.Count > this._p) { _yy.RemoveAt(0); }
if (_xy.Count > this._p) { _xy.RemoveAt(0); }
double _sumx = 0;
for (int i = 0; i < _x.Count; i++) { _sumx += _x[i]; }
double _sumxx = 0;
for (int i = 0; i < _xx.Count; i++) { _sumxx += _xx[i]; }
double _sumy = 0;
for (int i = 0; i < _y.Count; i++) { _sumy += _y[i]; }
double _sumyy = 0;
for (int i = 0; i < _yy.Count; i++) { _sumyy += _yy[i]; }
double _sumxy = 0;
for (int i = 0; i < _xy.Count; i++) { _sumxy += _xy[i]; }
double _div = (_sumxx - _sumx * _sumx / _p) * (_sumyy - _sumy * _sumy / _p);
double _cor = (_div != 0) ? (_sumxy - _sumx * _sumy / _p) / Math.Sqrt(_div) : 0.0;
var result = (TValue1.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _cor);
if (update) { base[base.Count - 1] = result; } else { base.Add(result); }
}
}
+92 -92
View File
@@ -1,93 +1,93 @@
namespace QuanTAlib;
using System;
/* <summary>
LINREG: Linear Regression (using Least Square Method)
Linear Regression provides a slope of a straight line that is the best approximation of the given set of data.
The method of least squares is a standard approach in linear regression analysis to approximate the solution
by minimizing the sum of the squares of the residuals made in the results of each individual equation.
Additional outputs provided by LINREG:
.Intercept - y-intercept point of the best fit line
.RSquared - R-Squared (R²), Coefficient of Determination
.StdDev - Standard Deviation of data over given periods
y = Slope * x + Intercept
Sources:
https://en.wikipedia.org/wiki/Least_squares
</summary> */
public class LINREG_Series : Single_TSeries_Indicator
{
public readonly TSeries Intercept = new();
public readonly TSeries RSquared = new();
public readonly TSeries StdDev = new();
private readonly System.Collections.Generic.List<double> _buffer = new();
public LINREG_Series(TSeries source, int period, bool useNaN = false)
: base(source, period, useNaN)
{
if (this._data.Count > 0) { base.Add(this._data); }
}
public override void Add((System.DateTime t, double v) TValue, bool update)
{
if (update) { this._buffer[this._buffer.Count - 1] = TValue.v; }
else { this._buffer.Add(TValue.v); }
if (this._buffer.Count > this._p) { this._buffer.RemoveAt(0); }
int _len = this._buffer.Count;
// get averages for period
double sumX = 0;
double sumY = 0;
for (int p = 0; p < _len; p++)
{
sumX += this.Count - _len + 2 + p;
sumY += _buffer[p];
}
double avgX = sumX / _len;
double avgY = sumY / _len;
// least squares method
double sumSqX = 0;
double sumSqY = 0;
double sumSqXY = 0;
for (int p = 0; p < _len; p++)
{
double devX = this.Count - _len + 2 + p - avgX;
double devY = _buffer[p] - avgY;
sumSqX += devX * devX;
sumSqY += devY * devY;
sumSqXY += devX * devY;
}
double _slope = sumSqXY / sumSqX;
double _intercept = avgY - (_slope * avgX);
// calculate Standard Deviation and R-Squared
double stdDevX = Math.Sqrt(sumSqX / _len);
double stdDevY = Math.Sqrt(sumSqY / _len);
double _StdDev = stdDevY;
double arrr = (stdDevX * stdDevY != 0) ? sumSqXY / (stdDevX * stdDevY) / _len : 0;
double _RSquared = arrr * arrr;
var ret = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _slope);
base.Add(ret, update);
ret = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _intercept);
Intercept.Add(ret, update);
ret = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _StdDev);
StdDev.Add(ret, update);
ret = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _RSquared);
RSquared.Add(ret, update);
}
namespace QuanTAlib;
using System;
/* <summary>
LINREG: Linear Regression (using Least Square Method)
Linear Regression provides a slope of a straight line that is the best approximation of the given set of data.
The method of least squares is a standard approach in linear regression analysis to approximate the solution
by minimizing the sum of the squares of the residuals made in the results of each individual equation.
Additional outputs provided by LINREG:
.Intercept - y-intercept point of the best fit line
.RSquared - R-Squared (R²), Coefficient of Determination
.StdDev - Standard Deviation of data over given periods
y = Slope * x + Intercept
Sources:
https://en.wikipedia.org/wiki/Least_squares
</summary> */
public class LINREG_Series : Single_TSeries_Indicator
{
public readonly TSeries Intercept = new();
public readonly TSeries RSquared = new();
public readonly TSeries StdDev = new();
private readonly System.Collections.Generic.List<double> _buffer = new();
public LINREG_Series(TSeries source, int period, bool useNaN = false)
: base(source, period, useNaN)
{
if (this._data.Count > 0) { base.Add(this._data); }
}
public override void Add((System.DateTime t, double v) TValue, bool update)
{
if (update) { this._buffer[this._buffer.Count - 1] = TValue.v; }
else { this._buffer.Add(TValue.v); }
if (this._buffer.Count > this._p) { this._buffer.RemoveAt(0); }
int _len = this._buffer.Count;
// get averages for period
double sumX = 0;
double sumY = 0;
for (int p = 0; p < _len; p++)
{
sumX += this.Count - _len + 2 + p;
sumY += _buffer[p];
}
double avgX = sumX / _len;
double avgY = sumY / _len;
// least squares method
double sumSqX = 0;
double sumSqY = 0;
double sumSqXY = 0;
for (int p = 0; p < _len; p++)
{
double devX = this.Count - _len + 2 + p - avgX;
double devY = _buffer[p] - avgY;
sumSqX += devX * devX;
sumSqY += devY * devY;
sumSqXY += devX * devY;
}
double _slope = sumSqXY / sumSqX;
double _intercept = avgY - (_slope * avgX);
// calculate Standard Deviation and R-Squared
double stdDevX = Math.Sqrt(sumSqX / _len);
double stdDevY = Math.Sqrt(sumSqY / _len);
double _StdDev = stdDevY;
double arrr = (stdDevX * stdDevY != 0) ? sumSqXY / (stdDevX * stdDevY) / _len : 0;
double _RSquared = arrr * arrr;
var ret = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _slope);
base.Add(ret, update);
ret = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _intercept);
Intercept.Add(ret, update);
ret = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _StdDev);
StdDev.Add(ret, update);
ret = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _RSquared);
RSquared.Add(ret, update);
}
}
+50 -50
View File
@@ -1,51 +1,51 @@
namespace QuanTAlib;
using System;
/* <summary>
ZSCORE: number of standard deviations from SMA
Z-score describes a value's relationship to the mean of a series, as measured in
terms of standard deviations from the mean. If a Z-score is 0, it indicates that
the data point's score is identical to the mean score. A Z-score of 1.0 would
indicate a value that is one standard deviation from the mean. Z-scores may be
positive or negative, with a positive value indicating the score is above the
mean and a negative score indicating it is below the mean.
Sources:
https://en.wikipedia.org/wiki/Z-score
https://www.investopedia.com/terms/z/zscore.asp
Calculation:
std = std * STDEV(close, length)
mean = SMA(close, length)
ZSCORE = (close - mean) / std
</summary> */
public class ZSCORE_Series : Single_TSeries_Indicator
{
public ZSCORE_Series(TSeries source, int period, bool useNaN = false) : base(source, period, useNaN)
{
if (base._data.Count > 0) { base.Add(base._data); }
}
private readonly System.Collections.Generic.List<double> _buffer = new();
public override void Add((System.DateTime t, double v) TValue, bool update)
{
if (update) { _buffer[_buffer.Count - 1] = TValue.v; }
else { _buffer.Add(TValue.v); }
if (_buffer.Count > this._p && this._p != 0) { _buffer.RemoveAt(0); }
double _sma = 0;
for (int i = 0; i < _buffer.Count; i++) { _sma += _buffer[i]; }
_sma /= this._buffer.Count;
double _pvar = 0;
for (int i = 0; i < _buffer.Count; i++) { _pvar += (_buffer[i] - _sma) * (_buffer[i] - _sma); }
_pvar /= this._buffer.Count;
double _psdev = Math.Sqrt(_pvar);
double _zscore = (_psdev == 0) ? double.NaN : (TValue.v - _sma) / _psdev;
var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _zscore);
base.Add(result, update);
}
namespace QuanTAlib;
using System;
/* <summary>
ZSCORE: number of standard deviations from SMA
Z-score describes a value's relationship to the mean of a series, as measured in
terms of standard deviations from the mean. If a Z-score is 0, it indicates that
the data point's score is identical to the mean score. A Z-score of 1.0 would
indicate a value that is one standard deviation from the mean. Z-scores may be
positive or negative, with a positive value indicating the score is above the
mean and a negative score indicating it is below the mean.
Sources:
https://en.wikipedia.org/wiki/Z-score
https://www.investopedia.com/terms/z/zscore.asp
Calculation:
std = std * STDEV(close, length)
mean = SMA(close, length)
ZSCORE = (close - mean) / std
</summary> */
public class ZSCORE_Series : Single_TSeries_Indicator
{
public ZSCORE_Series(TSeries source, int period, bool useNaN = false) : base(source, period, useNaN)
{
if (base._data.Count > 0) { base.Add(base._data); }
}
private readonly System.Collections.Generic.List<double> _buffer = new();
public override void Add((System.DateTime t, double v) TValue, bool update)
{
if (update) { _buffer[_buffer.Count - 1] = TValue.v; }
else { _buffer.Add(TValue.v); }
if (_buffer.Count > this._p && this._p != 0) { _buffer.RemoveAt(0); }
double _sma = 0;
for (int i = 0; i < _buffer.Count; i++) { _sma += _buffer[i]; }
_sma /= this._buffer.Count;
double _pvar = 0;
for (int i = 0; i < _buffer.Count; i++) { _pvar += (_buffer[i] - _sma) * (_buffer[i] - _sma); }
_pvar /= this._buffer.Count;
double _psdev = Math.Sqrt(_pvar);
double _zscore = (_psdev == 0) ? double.NaN : (TValue.v - _sma) / _psdev;
var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _zscore);
base.Add(result, update);
}
}