This commit is contained in:
Miha
2022-04-19 15:46:34 -07:00
commit 50ed6f6504
120 changed files with 16787 additions and 0 deletions
+40
View File
@@ -0,0 +1,40 @@
/**
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
**/
using System;
namespace QuanTAlib;
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)
{
if (update) { this._buffer[this._buffer.Count - 1] = TValue.v; }
else { this._buffer.Add(TValue.v); }
if (this._buffer.Count > this._p && this._p != 0) { this._buffer.RemoveAt(0); }
double _sma = 0;
for (int i = 0; i < this._buffer.Count; i++) { _sma += this._buffer[i]; }
_sma /= this._buffer.Count;
double _bias = (this._buffer[this._buffer.Count - 1] / ((_sma != 0) ? _sma : 1)) - 1;
var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _bias);
base.Add(result, update);
}
}
+51
View File
@@ -0,0 +1,51 @@
/**
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
**/
namespace QuanTAlib;
using System;
public class ENTP_Series : Single_TSeries_Indicator
{
public ENTP_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 = 2.0;
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)
{
if (update) { this._buffer[this._buffer.Count - 1] = TValue.v; }
else { this._buffer.Add(TValue.v); }
if (this._buffer.Count > this._p && this._p != 0) { this._buffer.RemoveAt(0); }
double _sum = 0;
for (int i = 0; i < this._buffer.Count; i++) { _sum += this._buffer[i]; }
double _pp = this._buffer[this._buffer.Count - 1] / _sum;
double _ppp = -_pp * Math.Log(_pp) / Math.Log(this._logbase);
if (update) { this._buff2[this._buff2.Count - 1] = _ppp; }
else { this._buff2.Add(_ppp); }
if (this._buff2.Count > this._p && this._p != 0) { this._buff2.RemoveAt(0); }
double _entp = 0;
for (int i = 0; i < this._buff2.Count; i++) { _entp += this._buff2[i]; }
var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _entp);
base.Add(result, update);
}
}
+65
View File
@@ -0,0 +1,65 @@
/**
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/
**/
using System;
namespace QuanTAlib;
// https://stats.oarc.ucla.edu/other/mult-pkg/faq/general/faq-whats-with-the-different-formulas-for-kurtosis/
public class KURT_Series : Single_TSeries_Indicator
{
public KURT_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 = 2.0;
private readonly System.Collections.Generic.List<double> _buffer = new();
public override void Add((System.DateTime t, double v) d, bool update)
{
if (update) { this._buffer[this._buffer.Count - 1] = d.v; }
else { this._buffer.Add(d.v); }
if (this._buffer.Count > this._p && this._p != 0) { this._buffer.RemoveAt(0); }
double _n = this._buffer.Count;
double _avg = 0;
for (int i = 0; i < this._buffer.Count; i++) { _avg += this._buffer[i]; }
_avg /= _n;
double _s2 = 0;
double _s4 = 0;
for (int i = 0; i < this._buffer.Count; i++)
{
_s2 += (this._buffer[i] - _avg) * (this._buffer[i] - _avg);
_s4 += (this._buffer[i] - _avg) * (this._buffer[i] - _avg) * (this._buffer[i] - _avg) * (this._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 = (d.t, (this.Count < this._p - 1 && this._NaN) ? Double.NaN : _kurt);
base.Add(result, update);
}
}
+43
View File
@@ -0,0 +1,43 @@
/**
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
**/
using System;
namespace QuanTAlib;
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) d, bool update)
{
if (update) { this._buffer[this._buffer.Count - 1] = d.v; }
else { _buffer.Add(d.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 _mad = 0;
for (int i = 0; i < _buffer.Count; i++) { _mad += Math.Abs(_buffer[i] - _sma); }
_mad /= this._buffer.Count;
var result = (d.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _mad);
base.Add(result, update);
}
}
+45
View File
@@ -0,0 +1,45 @@
/**
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
**/
using System;
namespace QuanTAlib;
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) d, bool update)
{
if (update) { _buffer[_buffer.Count - 1] = d.v; }
else { _buffer.Add(d.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 _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 /= this._buffer.Count;
var result = (d.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _mape);
base.Add(result, update);
}
}
+33
View File
@@ -0,0 +1,33 @@
namespace QuanTAlib;
/*
MAX - Maximum value in the given period in the series.
If period = 0 => period = full length of the series
*/
using System;
using System.Collections.Generic;
public class MAX_Series : Single_TSeries_Indicator
{
public MAX_Series(TSeries source, int period, bool useNaN = false) : base(source, period, useNaN)
{
if (base._data.Count > 0) { base.Add(base._data); }
}
private readonly List<double> _buffer = new();
public override void Add((DateTime t, double v) d, bool update)
{
if (update) { this._buffer[this._buffer.Count - 1] = d.v; }
else { this._buffer.Add(d.v); }
if (this._buffer.Count > this._p && this._p != 0) { this._buffer.RemoveAt(0); }
double _max = d.v;
for (int i = 0; i < this._buffer.Count; i++)
{ _max = this._buffer[i] > _max ? this._buffer[i] : _max; }
var result = (d.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _max);
base.Add(result, update);
}
}
+48
View File
@@ -0,0 +1,48 @@
/*
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
*/
using System;
namespace QuanTAlib;
public class MED_Series : Single_TSeries_Indicator
{
public MED_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) d, bool update)
{
if (update) { this._buffer[this._buffer.Count - 1] = d.v; }
else { this._buffer.Add(d.v); }
if (this._buffer.Count > this._p && this._p != 0) { this._buffer.RemoveAt(0); }
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;
var result = (d.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _med);
base.Add(result, update);
}
}
+33
View File
@@ -0,0 +1,33 @@
/*
MIN - Minimum value in the given period in the series.
If period = 0 => period = full length of the series
*/
using System;
namespace QuanTAlib;
public class MIN_Series : Single_TSeries_Indicator
{
public MIN_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) d, bool update)
{
if (update) { this._buffer[this._buffer.Count - 1] = d.v; }
else { this._buffer.Add(d.v); }
if (this._buffer.Count > this._p && this._p != 0) { this._buffer.RemoveAt(0); }
double _min = d.v;
for (int i = 0; i < this._buffer.Count; i++)
{ _min = (this._buffer[i] < _min) ? this._buffer[i] : _min; }
var result = (d.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _min);
base.Add(result, update);
}
}
+41
View File
@@ -0,0 +1,41 @@
/**
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
Remark:
**/
using System;
namespace QuanTAlib;
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) d, bool update)
{
if (update) { _buffer[_buffer.Count - 1] = d.v; }
else { _buffer.Add(d.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 _mse = 0;
for (int i = 0; i < _buffer.Count; i++) { _mse += (_buffer[i] - _sma) * (_buffer[i] - _sma); }
_mse /= this._buffer.Count;
var result = (d.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _mse);
base.Add(result, update);
}
}
+45
View File
@@ -0,0 +1,45 @@
/**
PSDEV: 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:
PSDEV (Population Standard Deviation) is also known as a biased/uncorrected Standard Deviation.
For unbiased version that uses Bessel's correction, use SDEV instead.
**/
using System;
namespace QuanTAlib;
public class PSDEV_Series : Single_TSeries_Indicator
{
public PSDEV_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) d, bool update)
{
if (update) { _buffer[_buffer.Count - 1] = d.v; }
else { _buffer.Add(d.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);
var result = (d.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _psdev);
base.Add(result, update);
}
}
+44
View File
@@ -0,0 +1,44 @@
/**
PVAR: Population Variance
Population variance....
Sources:
https://en.wikipedia.org/wiki/Variance
Bessel's correction: https://en.wikipedia.org/wiki/Bessel%27s_correction
Remark:
PVAR (Population Variance) is also known as a biased Sample Variance. For unbiased
sample variance use SVAR instead.
**/
using System;
namespace QuanTAlib;
public class PVAR_Series : Single_TSeries_Indicator
{
public PVAR_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) d, bool update)
{
if (update) { _buffer[_buffer.Count - 1] = d.v; }
else { _buffer.Add(d.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;
var result = (d.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _pvar);
base.Add(result, update);
}
}
+46
View File
@@ -0,0 +1,46 @@
/**
SDEV: (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
**/
using System;
namespace QuanTAlib;
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) d, bool update)
{
if (update) { this._buffer[this._buffer.Count - 1] = d.v; }
else { this._buffer.Add(d.v); }
if (this._buffer.Count > this._p && this._p != 0) { this._buffer.RemoveAt(0); }
double _sma = 0;
for (int i = 0; i < this._buffer.Count; i++) { _sma += this._buffer[i]; }
_sma /= this._buffer.Count;
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
double _ssdev = Math.Sqrt(_svar);
var result = (d.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _ssdev);
base.Add(result, update);
}
}
+39
View File
@@ -0,0 +1,39 @@
/**
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
**/
using System;
namespace QuanTAlib;
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) d, bool update)
{
if (update) { _buffer[_buffer.Count - 1] = d.v; }
else { _buffer.Add(d.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 _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;
var result = (d.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _smape);
base.Add(result, update);
}
}
+44
View File
@@ -0,0 +1,44 @@
/**
VAR: 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:
VAR is also known as the Unbiased Sample Variance, while PVAR (Population Variance) is known as
the Biased Sample Variance.
**/
using System;
namespace QuanTAlib;
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) d, bool update)
{
if (update) { this._buffer[this._buffer.Count - 1] = d.v; }
else { this._buffer.Add(d.v); }
if (this._buffer.Count > this._p && this._p != 0) { this._buffer.RemoveAt(0); }
double _sma = 0;
for (int i = 0; i < this._buffer.Count; i++) { _sma += this._buffer[i]; }
_sma /= this._buffer.Count;
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
var result = (d.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _svar);
base.Add(result, update);
}
}
+44
View File
@@ -0,0 +1,44 @@
/**
WMAPE: Weighted Mean Absolute Percentage Error
Measures the size of the error in percentage terms
Sources:
https://en.wikipedia.org/wiki/WMAPE
**/
using System;
namespace QuanTAlib;
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) d, bool update)
{
if (update) { _buffer[_buffer.Count - 1] = d.v; }
else { _buffer.Add(d.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 _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;
var result = (d.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _wmape);
base.Add(result, update);
}
}