Update RSI_Series to check for period != 0 before calculating RSI

This commit is contained in:
Miha Kralj
2023-04-27 22:23:50 -07:00
parent c80f57ddab
commit abdcbf5f20
145 changed files with 4826 additions and 4207 deletions
-34
View File
@@ -1,34 +0,0 @@
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);
}
}
-39
View File
@@ -1,39 +0,0 @@
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 readonly 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
@@ -1,44 +0,0 @@
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);
}
}
@@ -1,57 +0,0 @@
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);
}
}
-38
View File
@@ -1,38 +0,0 @@
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
@@ -1,42 +0,0 @@
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
@@ -1,44 +0,0 @@
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
@@ -1,33 +0,0 @@
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
@@ -1,39 +0,0 @@
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=0, 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
@@ -1,33 +0,0 @@
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
@@ -1,39 +0,0 @@
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
@@ -1,38 +0,0 @@
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
@@ -1,38 +0,0 @@
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
@@ -1,40 +0,0 @@
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
@@ -1,46 +0,0 @@
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);
}
}