Refactoring the structure, upgrading to .NET 6.0/7.0/8.0

This commit is contained in:
Miha Kralj
2023-04-01 17:05:05 -07:00
parent 468ea7a0af
commit 05f423c965
108 changed files with 3370 additions and 3080 deletions
+34
View File
@@ -0,0 +1,34 @@
namespace QuanTAlib;
using System;
using System.Linq;
/* <summary>
BIAS: Rate of change between the source and a moving average.
Bias is a statistical term which means a systematic deviation from the actual value.
BIAS = (close - SMA) / SMA
= (close / SMA) - 1
Sources:
https://en.wikipedia.org/wiki/Bias_of_an_estimator
</summary> */
public class BIAS_Series : Single_TSeries_Indicator
{
public BIAS_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)
{
Add_Replace_Trim(_buffer, TValue.v, _p, update);
double _sma = _buffer.Average();
double _bias = (_buffer[_buffer.Count - 1] / ((_sma != 0) ? _sma : 1)) - 1;
base.Add((TValue.t, _bias), update, _NaN);
}
}
+52
View File
@@ -0,0 +1,52 @@
namespace QuanTAlib;
using System;
using System.Collections.Generic;
using System.Linq;
/* <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)
{
Add_Replace_Trim(_x, TValue1.v, _p, update);
Add_Replace_Trim(_xx, TValue1.v * TValue1.v, _p, update);
Add_Replace_Trim(_y, TValue2.v, _p, update);
Add_Replace_Trim(_yy, TValue2.v * TValue2.v, _p, update);
Add_Replace_Trim(_xy, TValue1.v * TValue2.v, _p, update);
double _sumx = _x.Sum();
double _sumxx = _xx.Sum();
double _sumy = _y.Sum();
double _sumyy = _yy.Sum();
double _sumxy = _xy.Sum();
double _covar = (_sumxx - _sumx * _sumx / _p) * (_sumyy - _sumy * _sumy / _p);
double _cor = (_covar != 0) ? (_sumxy - _sumx * _sumy / _p) / Math.Sqrt(_covar) : 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); }
}
}
+40
View File
@@ -0,0 +1,40 @@
namespace QuanTAlib;
using System;
using System.Linq;
/* <summary>
COVAR: Covariance
Covariance is defined as the expected value (or mean) of the product
of their deviations from their individual expected values.
Sources:
https://en.wikipedia.org/wiki/Covariance
</summary> */
public class COVAR_Series : Pair_TSeries_Indicator
{
public COVAR_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> _y = 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)
{
Add_Replace_Trim(_x, TValue1.v, _p, update);
Add_Replace_Trim(_y, TValue2.v, _p, update);
Add_Replace_Trim(_xy, TValue1.v * TValue2.v, _p, update);
double _avgx = _x.Average();
double _avgy = _y.Average();
double _avgxy = _xy.Average();
double _covar = _avgxy - (_avgx * _avgy);
var result = (TValue1.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _covar);
if (update) { base[base.Count - 1] = result; } else { base.Add(result); }
}
}
+39
View File
@@ -0,0 +1,39 @@
namespace QuanTAlib;
using System;
using System.Collections.Generic;
/* <summary>
DECAY:
Linear decay can be modeled by a straight line with a negative slope of 1/period.
The value decreases in a straight line from the last maximum to 0.
Decay = Last Max - distance/period
Exponential decay is modeled as an exponential curve with diminishing factor of
1-1/p
</summary> */
public class DECAY_Series : Single_TSeries_Indicator {
private bool _exp;
private double _pdecay, _ppdecay;
private readonly double _dfactor;
public DECAY_Series(TSeries source, int period = 10, bool exponential= false, bool useNaN = false) : base(source, period, false) {
_exp = exponential;
_dfactor = (_exp)? 1.0 - 1.0 / (double)_p : 1/(double)_p;
_pdecay = _ppdecay = 0;
if (source.Count > 0) { base.Add(this._data); }
}
public override void Add((DateTime t, double v) TValue, bool update) {
if (update) { _pdecay = _ppdecay; }
else { _ppdecay = _pdecay; }
if (this.Count == 0) { _pdecay = TValue.v; }
double _decay = Math.Max(TValue.v, Math.Max((_exp)?_pdecay*_dfactor:_pdecay-_dfactor, 0));
_pdecay = _decay;
base.Add((TValue.t, _decay), update, _NaN);
}
}
+44
View File
@@ -0,0 +1,44 @@
namespace QuanTAlib;
using System;
using System.Linq;
/* <summary>
ENTP: Entropy
Introduced by Claude Shannon in 1948, entropy measures the unpredictability
of the data, or equivalently, of its average information.
Calculation:
P = close / Σ(close)
ENTP = Σ(-P * Log(P) / Log(base))
Sources:
https://en.wikipedia.org/wiki/Entropy_(information_theory)
https://math.stackexchange.com/questions/3428693/how-to-calculate-entropy-from-a-set-of-correlated-samples
</summary> */
public class ENTROPY_Series : Single_TSeries_Indicator
{
public ENTROPY_Series(TSeries source, int period, double logbase = 2.0, bool useNaN = false) : base(source, period, useNaN)
{
this._logbase = logbase;
if (base._data.Count > 0) { base.Add(base._data); }
}
private readonly double _logbase;
private readonly System.Collections.Generic.List<double> _buffer = new();
private readonly System.Collections.Generic.List<double> _buff2 = new();
public override void Add((System.DateTime t, double v) TValue, bool update)
{
Add_Replace_Trim(_buffer, TValue.v, _p, update);
double _sum = _buffer.Sum();
double _pp = this._buffer[this._buffer.Count - 1] / _sum;
double _ppp = -_pp * Math.Log(_pp) / Math.Log(this._logbase);
Add_Replace_Trim(_buff2, _ppp, _p, update);
double _entp = _buff2.Sum();
base.Add((TValue.t, _entp), update, _NaN);
}
}
@@ -0,0 +1,57 @@
namespace QuanTAlib;
using System;
using System.Linq;
/* <summary>
KURT: Kurtosis of population
Kurtosis characterizes the relative peakedness or flatness of a distribution
compared with the normal distribution. Positive kurtosis indicates a relatively
peaked distribution. Negative kurtosis indicates a relatively flat distribution.
The normal curve is called Mesokurtic curve. If the curve of a distribution is
more outlier prone (or heavier-tailed) than a normal or mesokurtic curve then
it is referred to as a Leptokurtic curve. If a curve is less outlier prone (or
lighter-tailed) than a normal curve, it is called as a platykurtic curve.
Calculation:
sum4 = Σ(close-SMA)^4
sum2 = (Σ(close-SMA)^2)^2
KURT = length * (sum4/sum2)
Sources:
https://en.wikipedia.org/wiki/Kurtosis
https://stats.oarc.ucla.edu/other/mult-pkg/faq/general/faq-whats-with-the-different-formulas-for-kurtosis/
</summary> */
public class KURTOSIS_Series : Single_TSeries_Indicator
{
public KURTOSIS_Series(TSeries source, int period, double logbase = 2.0, bool useNaN = false) : base(source, period, useNaN)
{
this._logbase = logbase;
if (base._data.Count > 0) { base.Add(base._data); }
}
protected double _logbase;
private readonly System.Collections.Generic.List<double> _buffer = new();
public override void Add((System.DateTime t, double v) TValue, bool update)
{
Add_Replace_Trim(_buffer, TValue.v, _p, update);
double _n = this._buffer.Count;
double _avg = _buffer.Average();
double _s2 = 0;
double _s4 = 0;
for (int i = 0; i < this._buffer.Count; i++)
{
_s2 += (_buffer[i] - _avg) * (_buffer[i] - _avg);
_s4 += (_buffer[i] - _avg) * (_buffer[i] - _avg) * (_buffer[i] - _avg) * (_buffer[i] - _avg);
}
double _Vx = _s2 / (_n - 1);
double _kurt = (_n > 3) ? ((((_n * (_n + 1)) / (((_n - 1) * (_n - 2)) * (_n - 3))) * (_s4 / (_Vx * _Vx))) - (3 * (((_n - 1) * (_n - 1)) / ((_n - 2) * (_n - 3))))) : Double.NaN;
var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? Double.NaN : _kurt);
base.Add(result, update);
}
}
+91
View File
@@ -0,0 +1,91 @@
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)
{
Add_Replace_Trim(_buffer, TValue.v, _p, update);
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, _NaN);
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);
}
}
+38
View File
@@ -0,0 +1,38 @@
namespace QuanTAlib;
using System;
using System.Linq;
/* <summary>
MAD: Mean Absolute Deviation
Also known as AAD - Average Absolute Deviation, to differentiate it from Median Absolute Deviation
MAD defines the degree of variation across the series.
Calculation:
MAD = Σ(|close-SMA|) / period
Sources:
https://en.wikipedia.org/wiki/Average_absolute_deviation
</summary> */
public class MAD_Series : Single_TSeries_Indicator
{
public MAD_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)
{
Add_Replace_Trim(_buffer, TValue.v, _p, update);
double _sma = _buffer.Average();
double _mad = 0;
for (int i = 0; i < _buffer.Count; i++) { _mad += Math.Abs(_buffer[i] - _sma); }
_mad /= this._buffer.Count;
base.Add((TValue.t, _mad), update, _NaN);
}
}
+42
View File
@@ -0,0 +1,42 @@
namespace QuanTAlib;
using System;
using System.Linq;
/* <summary>
MAPE: Mean Absolute Percentage Error
Measures the size of the error in percentage terms
Calculation:
MAPE = Σ(|close SMA| / |close|) / n
Sources:
https://en.wikipedia.org/wiki/Mean_absolute_percentage_error
Remark:
returns infinity if any of observations is 0.
Use SMAPE or WMAPE instead to avoid division-by-zero in MAPE
</summary> */
public class MAPE_Series : Single_TSeries_Indicator
{
public MAPE_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)
{
Add_Replace_Trim(_buffer, TValue.v, _p, update);
double _sma = _buffer.Average();
double _mape = 0;
for (int i = 0; i < _buffer.Count; i++) {
_mape += (_buffer[i] != 0) ? Math.Abs(_buffer[i] - _sma) / Math.Abs(_buffer[i]) : double.PositiveInfinity;
}
_mape /= (_buffer.Count>0) ? _buffer.Count : 1;
base.Add((TValue.t, _mape), update, _NaN);
}
}
+44
View File
@@ -0,0 +1,44 @@
namespace QuanTAlib;
using System;
using static System.Net.Mime.MediaTypeNames;
/* <summary>
MED - Median value
Median of numbers is the middlemost value of the given set of numbers.
It separates the higher half and the lower half of a given data sample.
At least half of the observations are smaller than or equal to median
and at least half of the observations are greater than or equal to the median.
If the number of values is odd, the middlemost observation of the sorted
list is the median of the given data. If the number of values is even,
median is the average of (n/2)th and [(n/2) + 1]th values of the sorted list.
If period = 0 => period is max
Sources:
https://corporatefinanceinstitute.com/resources/knowledge/other/median/
https://en.wikipedia.org/wiki/Median
</summary> */
public class MEDIAN_Series : Single_TSeries_Indicator
{
public MEDIAN_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)
{
Add_Replace_Trim(_buffer, TValue.v, _p, update);
System.Collections.Generic.List<double> _s = new(this._buffer);
_s.Sort();
int _p1 = _s.Count / 2;
int _p2 = Math.Max(0, (_s.Count / 2) - 1);
double _med = (_s.Count % 2 != 0) ? _s[_p1] : (_s[_p1] + _s[_p2]) / 2;
base.Add((TValue.t, _med), update, _NaN);
}
}
+33
View File
@@ -0,0 +1,33 @@
namespace QuanTAlib;
using System;
using System.Linq;
/* <summary>
MSE: Mean Square Error
Defined as a Mean (Average) of the Square of the difference between actual and estimated values.
Sources:
https://en.wikipedia.org/wiki/Mean_squared_error
</summary> */
public class MSE_Series : Single_TSeries_Indicator
{
public MSE_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)
{
Add_Replace_Trim(_buffer, TValue.v, _p, update);
double _sma = _buffer.Average();
double _mse = 0;
for (int i = 0; i < _buffer.Count; i++) { _mse += (_buffer[i] - _sma) * (_buffer[i] - _sma); }
_mse /= this._buffer.Count;
base.Add((TValue.t, _mse), update, _NaN);
}
}
+39
View File
@@ -0,0 +1,39 @@
namespace QuanTAlib;
using System;
using System.Linq;
/* <summary>
SDEV: Population Standard Deviation
Population Standard Deviation is the square root of the biased variance, also knons as
Uncorrected Sample Standard Deviation
Sources:
https://en.wikipedia.org/wiki/Standard_deviation#Uncorrected_sample_standard_deviation
Remark:
SDEV (Population Standard Deviation) is also known as a biased/uncorrected Standard Deviation.
For unbiased version that uses Bessel's correction, use SDEV instead.
</summary> */
public class SDEV_Series : Single_TSeries_Indicator
{
public SDEV_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)
{
Add_Replace_Trim(_buffer, TValue.v, _p, update);
double _sma = _buffer.Average();
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);
base.Add((TValue.t, _psdev), update, _NaN);
}
}
+33
View File
@@ -0,0 +1,33 @@
namespace QuanTAlib;
using System;
using System.Linq;
/* <summary>
SMAPE: Symmetric Mean Absolute Percentage Error
Measures the size of the error in percentage terms
Sources:
https://en.wikipedia.org/wiki/Symmetric_mean_absolute_percentage_error
</summary> */
public class SMAPE_Series : Single_TSeries_Indicator
{
public SMAPE_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)
{
Add_Replace_Trim(_buffer, TValue.v, _p, update);
double _sma = _buffer.Average();
double _smape = 0;
for (int i = 0; i < _buffer.Count; i++) { _smape += Math.Abs(_buffer[i] - _sma) / (Math.Abs(_buffer[i]) + Math.Abs(_sma)); }
_smape /= this._buffer.Count;
base.Add((TValue.t, _smape), update, _NaN);
}
}
+39
View File
@@ -0,0 +1,39 @@
namespace QuanTAlib;
using System;
using System.Linq;
/* <summary>
SSDEV: (Corrected) Sample Standard Deviation
Sample Standard Deviaton uses Bessel's correction to correct the bias in the variance.
Sources:
https://en.wikipedia.org/wiki/Standard_deviation#Corrected_sample_standard_deviation
Bessel's correction: https://en.wikipedia.org/wiki/Bessel%27s_correction
Remark:
SSDEV (Sample Standard Deviation) is also known as a unbiased/corrected Standard Deviation.
For a population/biased/uncorrected Standard Deviation, use PSDEV instead
</summary> */
public class SSDEV_Series : Single_TSeries_Indicator
{
public SSDEV_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)
{
Add_Replace_Trim(_buffer, TValue.v, _p, update);
double _sma = _buffer.Average();
double _svar = 0;
for (int i = 0; i < this._buffer.Count; i++) { _svar += (_buffer[i] - _sma) * (_buffer[i] - _sma); }
_svar /= (_buffer.Count > 1) ? _buffer.Count - 1 : 1; // Bessel's correction
double _ssdev = Math.Sqrt(_svar);
base.Add((TValue.t, _ssdev), update, _NaN);
}
}
+38
View File
@@ -0,0 +1,38 @@
namespace QuanTAlib;
using System;
using System.Linq;
/* <summary>
SVAR: Sample Variance
Sample variance uses Bessel's correction to correct the bias in the estimation of population variance.
Sources:
https://en.wikipedia.org/wiki/Variance
Bessel's correction: https://en.wikipedia.org/wiki/Bessel%27s_correction
Remark:
SVAR is also known as the Unbiased Sample Variance, while VAR (Population Variance) is known as
the Biased Sample Variance.
</summary> */
public class SVAR_Series : Single_TSeries_Indicator
{
public SVAR_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)
{
Add_Replace_Trim(_buffer, TValue.v, _p, update);
double _sma = _buffer.Average();
double _svar = 0;
for (int i = 0; i < this._buffer.Count; i++) { _svar += (this._buffer[i] - _sma) * (this._buffer[i] - _sma); }
_svar /= (this._buffer.Count > 1) ? this._buffer.Count - 1 : 1; // Bessel's correction
base.Add((TValue.t, _svar), update, _NaN);
}
}
+38
View File
@@ -0,0 +1,38 @@
namespace QuanTAlib;
using System;
using System.Linq;
/* <summary>
VAR: Population Variance
Population variance without Bessel's correction
Sources:
https://en.wikipedia.org/wiki/Variance
Bessel's correction: https://en.wikipedia.org/wiki/Bessel%27s_correction
Remark:
VAR (Population Variance) is also known as a biased Sample Variance. For unbiased
sample variance use SVAR instead.
</summary> */
public class VAR_Series : Single_TSeries_Indicator
{
public VAR_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)
{
Add_Replace_Trim(_buffer, TValue.v, _p, update);
double _sma = _buffer.Average();
double _pvar = 0;
for (int i = 0; i < _buffer.Count; i++) { _pvar += (_buffer[i] - _sma) * (_buffer[i] - _sma); }
_pvar /= this._buffer.Count;
base.Add((TValue.t, _pvar), update, _NaN);
}
}
+40
View File
@@ -0,0 +1,40 @@
namespace QuanTAlib;
using System;
using System.Linq;
/* <summary>
WMAPE: Weighted Mean Absolute Percentage Error
Measures the size of the error in percentage terms. Improves problems with MAPE
when there are zero or close-to-zero values because there would be a division by zero
or values of MAPE tending to infinity.
Sources:
https://en.wikipedia.org/wiki/WMAPE
</summary> */
public class WMAPE_Series : Single_TSeries_Indicator
{
public WMAPE_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)
{
Add_Replace_Trim(_buffer, TValue.v, _p, update);
double _sma = _buffer.Average();
double _div = 0;
double _wmape = 0;
for (int i = 0; i < _buffer.Count; i++)
{
_wmape += Math.Abs(_buffer[i] - _sma);
_div += Math.Abs(_buffer[i]);
}
_wmape = (_div!=0) ? _wmape/_div : double.PositiveInfinity;
base.Add((TValue.t, _wmape), update, _NaN);
}
}
+46
View File
@@ -0,0 +1,46 @@
namespace QuanTAlib;
using System;
using System.Linq;
/* <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)
{
Add_Replace_Trim(_buffer, TValue.v, _p, update);
double _sma = _buffer.Average();
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;
base.Add((TValue.t, _zscore), update, _NaN);
}
}