From f62e9c76b87eeb4a0554a6afc0fbc069727c6457 Mon Sep 17 00:00:00 2001 From: Miha Kralj Date: Wed, 9 Nov 2022 14:00:47 -0800 Subject: [PATCH] Documentation update --- Quantower/Indicators/PSDEV_chart.cs | 53 --- Quantower/Indicators/PSDEV_chart.cs~HEAD | 53 --- ...art.cs~parent of 32615af... for dev branch | 53 --- Quantower/Indicators/PVAR_chart.cs | 54 --- Quantower/Indicators/SDEV_chart.cs | 4 +- Quantower/Indicators/VAR_chart.cs | 2 +- .../{ADO_Series.cs => ADOSC_Series.cs} | 4 +- Source/Indicators/ATRP_Series.cs | 23 +- Source/Indicators/ATR_Series.cs | 23 +- Source/Statistics/PVAR_Series.cs | 43 --- Source/Statistics/SVAR_Series.cs | 43 +++ Source/Statistics/VAR_Series.cs | 24 +- Tests/Statistics/PVAR_Test .cs | 4 +- Tests/Statistics/VAR_Test.cs | 4 +- Tests/Tests.csproj | 1 + Tests/Validations/Pandas_TA.cs | 148 ++++---- Tests/Validations/TA_LIB.cs | 47 ++- docs/coverage.md | 315 +++++++++--------- 18 files changed, 366 insertions(+), 532 deletions(-) delete mode 100644 Quantower/Indicators/PSDEV_chart.cs delete mode 100644 Quantower/Indicators/PSDEV_chart.cs~HEAD delete mode 100644 Quantower/Indicators/PSDEV_chart.cs~parent of 32615af... for dev branch delete mode 100644 Quantower/Indicators/PVAR_chart.cs rename Source/Indicators/{ADO_Series.cs => ADOSC_Series.cs} (89%) delete mode 100644 Source/Statistics/PVAR_Series.cs create mode 100644 Source/Statistics/SVAR_Series.cs diff --git a/Quantower/Indicators/PSDEV_chart.cs b/Quantower/Indicators/PSDEV_chart.cs deleted file mode 100644 index d3cc5bec..00000000 --- a/Quantower/Indicators/PSDEV_chart.cs +++ /dev/null @@ -1,53 +0,0 @@ -using System.Drawing; -using TradingPlatform.BusinessLayer; -namespace QuanTAlib; - -public class PSDEV_chart : Indicator -{ - #region Parameters - - [InputParameter("Smoothing period", 0, 1, 999, 1, 1)] - private int Period = 10; - - [InputParameter("Data source", 1, variants: new object[] - { "Open", 0, "High", 1, "Low", 2, "Close", 3, "HL2", 4, "OC2", 5, - "OHL3", 6, "HLC3", 7, "OHLC4", 8, "Weighted (HLCC4)", 9 })] - private int DataSource = 8; - - #endregion Parameters - - private TBars bars; - - ///////dotnet - private SDEV_Series indicator; - /////// - - public PSDEV_chart() - { - this.SeparateWindow = true; - this.Name = "PSDEV - Population Standard Deviation (Biased)"; - this.Description = "PSDEV description"; - this.AddLineSeries("PSDEV", Color.RoyalBlue, 3, LineStyle.Solid); - } - - protected override void OnInit() - { - this.bars = new(); - this.ShortName = - "PSDEV (" + TBars.SelectStr(this.DataSource) + ", " + this.Period + ")"; - this.indicator = new(source: bars.Select(this.DataSource), - period: this.Period, useNaN: true); - } - protected override void OnUpdate(UpdateArgs args) - { - bool update = !(args.Reason == UpdateReason.NewBar || - args.Reason == UpdateReason.HistoricalBar); - this.bars.Add(this.Time(), this.GetPrice(PriceType.Open), - this.GetPrice(PriceType.High), this.GetPrice(PriceType.Low), - this.GetPrice(PriceType.Close), - this.GetPrice(PriceType.Volume), update); - double result = this.indicator[this.indicator.Count - 1].v; - - this.SetValue(result, 0); - } -} diff --git a/Quantower/Indicators/PSDEV_chart.cs~HEAD b/Quantower/Indicators/PSDEV_chart.cs~HEAD deleted file mode 100644 index 91b45426..00000000 --- a/Quantower/Indicators/PSDEV_chart.cs~HEAD +++ /dev/null @@ -1,53 +0,0 @@ -using System.Drawing; -using TradingPlatform.BusinessLayer; -namespace QuanTAlib; - -public class PSDEV_chart : Indicator -{ - #region Parameters - - [InputParameter("Smoothing period", 0, 1, 999, 1, 1)] - private int Period = 10; - - [InputParameter("Data source", 1, variants: new object[] - { "Open", 0, "High", 1, "Low", 2, "Close", 3, "HL2", 4, "OC2", 5, - "OHL3", 6, "HLC3", 7, "OHLC4", 8, "Weighted (HLCC4)", 9 })] - private int DataSource = 8; - - #endregion Parameters - - private TBars bars; - - ///////dotnet - private PSDEV_Series indicator; - /////// - - public PSDEV_chart() - { - this.SeparateWindow = true; - this.Name = "PSDEV - Population Standard Deviation (Biased)"; - this.Description = "PSDEV description"; - this.AddLineSeries("PSDEV", Color.RoyalBlue, 3, LineStyle.Solid); - } - - protected override void OnInit() - { - this.bars = new(); - this.ShortName = - "PSDEV (" + TBars.SelectStr(this.DataSource) + ", " + this.Period + ")"; - this.indicator = new(source: bars.Select(this.DataSource), - period: this.Period, useNaN: true); - } - protected override void OnUpdate(UpdateArgs args) - { - bool update = !(args.Reason == UpdateReason.NewBar || - args.Reason == UpdateReason.HistoricalBar); - this.bars.Add(this.Time(), this.GetPrice(PriceType.Open), - this.GetPrice(PriceType.High), this.GetPrice(PriceType.Low), - this.GetPrice(PriceType.Close), - this.GetPrice(PriceType.Volume), update); - double result = this.indicator[this.indicator.Count - 1].v; - - this.SetValue(result, 0); - } -} diff --git a/Quantower/Indicators/PSDEV_chart.cs~parent of 32615af... for dev branch b/Quantower/Indicators/PSDEV_chart.cs~parent of 32615af... for dev branch deleted file mode 100644 index 91b45426..00000000 --- a/Quantower/Indicators/PSDEV_chart.cs~parent of 32615af... for dev branch +++ /dev/null @@ -1,53 +0,0 @@ -using System.Drawing; -using TradingPlatform.BusinessLayer; -namespace QuanTAlib; - -public class PSDEV_chart : Indicator -{ - #region Parameters - - [InputParameter("Smoothing period", 0, 1, 999, 1, 1)] - private int Period = 10; - - [InputParameter("Data source", 1, variants: new object[] - { "Open", 0, "High", 1, "Low", 2, "Close", 3, "HL2", 4, "OC2", 5, - "OHL3", 6, "HLC3", 7, "OHLC4", 8, "Weighted (HLCC4)", 9 })] - private int DataSource = 8; - - #endregion Parameters - - private TBars bars; - - ///////dotnet - private PSDEV_Series indicator; - /////// - - public PSDEV_chart() - { - this.SeparateWindow = true; - this.Name = "PSDEV - Population Standard Deviation (Biased)"; - this.Description = "PSDEV description"; - this.AddLineSeries("PSDEV", Color.RoyalBlue, 3, LineStyle.Solid); - } - - protected override void OnInit() - { - this.bars = new(); - this.ShortName = - "PSDEV (" + TBars.SelectStr(this.DataSource) + ", " + this.Period + ")"; - this.indicator = new(source: bars.Select(this.DataSource), - period: this.Period, useNaN: true); - } - protected override void OnUpdate(UpdateArgs args) - { - bool update = !(args.Reason == UpdateReason.NewBar || - args.Reason == UpdateReason.HistoricalBar); - this.bars.Add(this.Time(), this.GetPrice(PriceType.Open), - this.GetPrice(PriceType.High), this.GetPrice(PriceType.Low), - this.GetPrice(PriceType.Close), - this.GetPrice(PriceType.Volume), update); - double result = this.indicator[this.indicator.Count - 1].v; - - this.SetValue(result, 0); - } -} diff --git a/Quantower/Indicators/PVAR_chart.cs b/Quantower/Indicators/PVAR_chart.cs deleted file mode 100644 index f2be74e7..00000000 --- a/Quantower/Indicators/PVAR_chart.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System.Drawing; -using TradingPlatform.BusinessLayer; -namespace QuanTAlib; - -public class PVAR_chart : Indicator -{ - #region Parameters - - [InputParameter("Smoothing period", 0, 1, 999, 1, 1)] - private int Period = 10; - - [InputParameter("Data source", 1, variants: new object[] - { "Open", 0, "High", 1, "Low", 2, "Close", 3, "HL2", 4, "OC2", 5, - "OHL3", 6, "HLC3", 7, "OHLC4", 8, "Weighted (HLCC4)", 9 })] - private int DataSource = 8; - - #endregion Parameters - - private TBars bars; - - ///////dotnet - private PVAR_Series indicator; - /////// - - public PVAR_chart() - { - this.SeparateWindow = true; - this.Name = "PVAR - Population Variance (Biased)"; - this.Description = "PVAR description"; - this.AddLineSeries("PVAR", Color.RoyalBlue, 3, LineStyle.Solid); - } - - protected override void OnInit() - { - this.bars = new(); - this.ShortName = - "PVAR (" + TBars.SelectStr(this.DataSource) + ", " + this.Period + ")"; - this.indicator = new(source: bars.Select(this.DataSource), - period: this.Period, useNaN: true); - } - - protected override void OnUpdate(UpdateArgs args) - { - bool update = !(args.Reason == UpdateReason.NewBar || - args.Reason == UpdateReason.HistoricalBar); - this.bars.Add(this.Time(), this.GetPrice(PriceType.Open), - this.GetPrice(PriceType.High), this.GetPrice(PriceType.Low), - this.GetPrice(PriceType.Close), - this.GetPrice(PriceType.Volume), update); - double result = this.indicator[this.indicator.Count - 1].v; - - this.SetValue(result, 0); - } -} diff --git a/Quantower/Indicators/SDEV_chart.cs b/Quantower/Indicators/SDEV_chart.cs index 55e267f2..0e220570 100644 --- a/Quantower/Indicators/SDEV_chart.cs +++ b/Quantower/Indicators/SDEV_chart.cs @@ -19,13 +19,13 @@ public class SDEV_chart : Indicator private TBars bars; ///////dotnet - private SSDEV_Series indicator; + private SDEV_Series indicator; /////// public SDEV_chart() { this.SeparateWindow = true; - this.Name = "SDEV - Sample Standard Deviation (Unbiased)"; + this.Name = "SDEV - Standard Deviation"; this.Description = "SDEV description"; this.AddLineSeries("SDEV", Color.RoyalBlue, 3, LineStyle.Solid); } diff --git a/Quantower/Indicators/VAR_chart.cs b/Quantower/Indicators/VAR_chart.cs index 8e316e73..9d22a14d 100644 --- a/Quantower/Indicators/VAR_chart.cs +++ b/Quantower/Indicators/VAR_chart.cs @@ -25,7 +25,7 @@ public class VAR_chart : Indicator public VAR_chart() { this.SeparateWindow = true; - this.Name = "VAR - Sample Variance (Unbiased)"; + this.Name = "VAR - Variance"; this.Description = "VAR description"; this.AddLineSeries("VAR", Color.RoyalBlue, 3, LineStyle.Solid); } diff --git a/Source/Indicators/ADO_Series.cs b/Source/Indicators/ADOSC_Series.cs similarity index 89% rename from Source/Indicators/ADO_Series.cs rename to Source/Indicators/ADOSC_Series.cs index 25db4a3f..08c4750a 100644 --- a/Source/Indicators/ADO_Series.cs +++ b/Source/Indicators/ADOSC_Series.cs @@ -13,7 +13,7 @@ Sources: */ -public class ADO_Series : Single_TBars_Indicator +public class ADOSC_Series : Single_TBars_Indicator { private readonly ADL_Series _TSadl; @@ -21,7 +21,7 @@ public class ADO_Series : Single_TBars_Indicator private readonly EMA_Series _TSfast; private readonly SUB_Series _TSado; - public ADO_Series(TBars source, bool useNaN = false) : base(source, period: 0, useNaN) + public ADOSC_Series(TBars source, bool useNaN = false) : base(source, period: 0, useNaN) { _TSadl = new(source: source, useNaN: false); _TSslow = new(source: _TSadl, period: 10, useNaN: false); diff --git a/Source/Indicators/ATRP_Series.cs b/Source/Indicators/ATRP_Series.cs index 70ec3c90..a50916e6 100644 --- a/Source/Indicators/ATRP_Series.cs +++ b/Source/Indicators/ATRP_Series.cs @@ -2,31 +2,28 @@ using System; /* -ATR: wildeR Moving Average - The average true range (ATR) is a price volatility indicator - showing the average price variation of assets within a given time period. +ATRP: Average True Range Percent + Average True Range Percent is (ATR/Close Price)*100. + This normalizes so it can be compared to other stocks. Sources: - https://en.wikipedia.org/wiki/Average_true_range - https://www.tradingview.com/wiki/Average_True_Range_(ATR) - https://www.investopedia.com/terms/a/atr.asp + https://www.fidelity.com/learning-center/trading-investing/technical-analysis/technical-indicator-guide/atrp */ - -public class ATR_Series : Single_TBars_Indicator +public class ATRP_Series : Single_TBars_Indicator { private readonly System.Collections.Generic.List _buffer = new(); private readonly double _k, _k1m; private double _lastema, _lastlastema, _lastcm1; private double _cm1 = double.NaN; - public ATR_Series(TBars source, int period, bool useNaN = false) : base(source, period, useNaN) + public ATRP_Series(TBars source, int period, bool useNaN = false) : base(source, period, useNaN) { this._k = 1.0 / (double)(this._p); this._k1m = 1.0 - this._k; this._lastema = this._lastlastema = double.NaN; - if (this._bars.Count > 0) { base.Add(this._bars); } + if (_bars.Count > 0) { base.Add(_bars); } } public override void Add((DateTime t, double o, double h, double l, double c, double v) TBar, bool update) @@ -36,7 +33,7 @@ public class ATR_Series : Single_TBars_Indicator this._cm1 = this._lastcm1; } - if (this._cm1 is double.NaN) { this._cm1 = TBar.c; } + if (_cm1 is double.NaN) { _cm1 = TBar.c; } double d1 = Math.Abs(TBar.h - TBar.l); double d2 = Math.Abs(_cm1 - TBar.h); double d3 = Math.Abs(_cm1 - TBar.l); @@ -58,7 +55,9 @@ public class ATR_Series : Single_TBars_Indicator this._lastlastema = this._lastema; this._lastema = _ema; - var ret = (d.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _ema); + double _atrp = 100 * (_ema / TBar.c); + + var ret = (d.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _atrp); base.Add(ret, update); } } \ No newline at end of file diff --git a/Source/Indicators/ATR_Series.cs b/Source/Indicators/ATR_Series.cs index a50916e6..70ec3c90 100644 --- a/Source/Indicators/ATR_Series.cs +++ b/Source/Indicators/ATR_Series.cs @@ -2,28 +2,31 @@ using System; /* -ATRP: Average True Range Percent - Average True Range Percent is (ATR/Close Price)*100. - This normalizes so it can be compared to other stocks. +ATR: wildeR Moving Average + The average true range (ATR) is a price volatility indicator + showing the average price variation of assets within a given time period. Sources: - https://www.fidelity.com/learning-center/trading-investing/technical-analysis/technical-indicator-guide/atrp + https://en.wikipedia.org/wiki/Average_true_range + https://www.tradingview.com/wiki/Average_True_Range_(ATR) + https://www.investopedia.com/terms/a/atr.asp */ -public class ATRP_Series : Single_TBars_Indicator + +public class ATR_Series : Single_TBars_Indicator { private readonly System.Collections.Generic.List _buffer = new(); private readonly double _k, _k1m; private double _lastema, _lastlastema, _lastcm1; private double _cm1 = double.NaN; - public ATRP_Series(TBars source, int period, bool useNaN = false) : base(source, period, useNaN) + public ATR_Series(TBars source, int period, bool useNaN = false) : base(source, period, useNaN) { this._k = 1.0 / (double)(this._p); this._k1m = 1.0 - this._k; this._lastema = this._lastlastema = double.NaN; - if (_bars.Count > 0) { base.Add(_bars); } + if (this._bars.Count > 0) { base.Add(this._bars); } } public override void Add((DateTime t, double o, double h, double l, double c, double v) TBar, bool update) @@ -33,7 +36,7 @@ public class ATRP_Series : Single_TBars_Indicator this._cm1 = this._lastcm1; } - if (_cm1 is double.NaN) { _cm1 = TBar.c; } + if (this._cm1 is double.NaN) { this._cm1 = TBar.c; } double d1 = Math.Abs(TBar.h - TBar.l); double d2 = Math.Abs(_cm1 - TBar.h); double d3 = Math.Abs(_cm1 - TBar.l); @@ -55,9 +58,7 @@ public class ATRP_Series : Single_TBars_Indicator this._lastlastema = this._lastema; this._lastema = _ema; - double _atrp = 100 * (_ema / TBar.c); - - var ret = (d.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _atrp); + var ret = (d.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _ema); base.Add(ret, update); } } \ No newline at end of file diff --git a/Source/Statistics/PVAR_Series.cs b/Source/Statistics/PVAR_Series.cs deleted file mode 100644 index 7f0d1b72..00000000 --- a/Source/Statistics/PVAR_Series.cs +++ /dev/null @@ -1,43 +0,0 @@ -namespace QuanTAlib; -using System; - -/* -PVAR: 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: - PVAR (Population Variance) is also known as a biased Sample Variance. For unbiased - sample variance use SVAR instead. - - */ - -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 _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; - - var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _pvar); - base.Add(result, update); - } -} \ No newline at end of file diff --git a/Source/Statistics/SVAR_Series.cs b/Source/Statistics/SVAR_Series.cs new file mode 100644 index 00000000..3d149809 --- /dev/null +++ b/Source/Statistics/SVAR_Series.cs @@ -0,0 +1,43 @@ +namespace QuanTAlib; +using System; + +/* +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. + + */ + +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 _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 _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 = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _svar); + base.Add(result, update); + } +} \ No newline at end of file diff --git a/Source/Statistics/VAR_Series.cs b/Source/Statistics/VAR_Series.cs index 23621096..929e8ea7 100644 --- a/Source/Statistics/VAR_Series.cs +++ b/Source/Statistics/VAR_Series.cs @@ -2,16 +2,16 @@ using System; /* -VAR: Sample Variance - Sample variance uses Bessel's correction to correct the bias in the estimation of population variance. +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 is also known as the Unbiased Sample Variance, while PVAR (Population Variance) is known as - the Biased Sample Variance. + VAR (Population Variance) is also known as a biased Sample Variance. For unbiased + sample variance use SVAR instead. */ @@ -25,19 +25,19 @@ public class VAR_Series : Single_TSeries_Indicator 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); } + 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 < this._buffer.Count; i++) { _sma += this._buffer[i]; } + for (int i = 0; i < _buffer.Count; i++) { _sma += _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 _pvar = 0; + for (int i = 0; i < _buffer.Count; i++) { _pvar += (_buffer[i] - _sma) * (_buffer[i] - _sma); } + _pvar /= this._buffer.Count; - var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _svar); + var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _pvar); base.Add(result, update); } } \ No newline at end of file diff --git a/Tests/Statistics/PVAR_Test .cs b/Tests/Statistics/PVAR_Test .cs index c1ee0d9a..67b4563d 100644 --- a/Tests/Statistics/PVAR_Test .cs +++ b/Tests/Statistics/PVAR_Test .cs @@ -9,7 +9,7 @@ public class PVAR_Test public void Add_Test() { TSeries a = new() { 0, 1, 2, 3, 4, 5 }; - PVAR_Series c = new(a, 3); + SVAR_Series c = new(a, 3); Assert.Equal(6, c.Count); a.Add(5); Assert.Equal(a.Count, c.Count); @@ -21,7 +21,7 @@ public class PVAR_Test public void Edge_Test() { TSeries a = new() { double.NaN, double.Epsilon, double.PositiveInfinity, double.MaxValue }; - PVAR_Series c = new(a, 3); + SVAR_Series c = new(a, 3); Assert.Equal(a.Count, c.Count); a.Add(double.NaN); Assert.Equal(a.Count, c.Count); diff --git a/Tests/Statistics/VAR_Test.cs b/Tests/Statistics/VAR_Test.cs index eea72271..38384d58 100644 --- a/Tests/Statistics/VAR_Test.cs +++ b/Tests/Statistics/VAR_Test.cs @@ -9,7 +9,7 @@ public class VAR_Test public void Add_Test() { TSeries a = new() { 0, 1, 2, 3, 4, 5 }; - VAR_Series c = new(a, 3); + SVAR_Series c = new(a, 3); Assert.Equal(6, c.Count); a.Add(5); Assert.Equal(a.Count, c.Count); @@ -21,7 +21,7 @@ public class VAR_Test public void Edge_Test() { TSeries a = new() { double.NaN, double.Epsilon, double.PositiveInfinity, double.MaxValue }; - VAR_Series c = new(a, 3); + SVAR_Series c = new(a, 3); Assert.Equal(a.Count, c.Count); a.Add(double.NaN); Assert.Equal(a.Count, c.Count); diff --git a/Tests/Tests.csproj b/Tests/Tests.csproj index 1eb34dd7..b73a43f1 100644 --- a/Tests/Tests.csproj +++ b/Tests/Tests.csproj @@ -33,6 +33,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/Tests/Validations/Pandas_TA.cs b/Tests/Validations/Pandas_TA.cs index 641b6cb7..38bffb2d 100644 --- a/Tests/Validations/Pandas_TA.cs +++ b/Tests/Validations/Pandas_TA.cs @@ -1,4 +1,4 @@ -/* + using Xunit; using System; @@ -20,6 +20,8 @@ public class PandasTA this.bars = new(1000); this.period = this.rnd.Next(28) + 3; + Runtime.PythonDLL = @"python310.dll"; + Installer.InstallPath = Path.GetFullPath("."); Installer.SetupPython().Wait(); Installer.TryInstallPip(); Installer.PipInstallModule("numpy"); @@ -34,91 +36,89 @@ public class PandasTA { PythonEngine.Shutdown(); } + /* + [Fact] + void SMA() + { + SMA_Series QL = new(this.bars.Close, this.period, false); + var pta = this.ta.sma(close: this.df[0], length: this.period); - [Fact] - void SMA() - { - SMA_Series QL = new(this.bars.Close, this.period, false); - var pta = this.ta.sma(close: this.df[0], length: this.period); - - Assert.Equal(System.Math.Round((double)pta.tail(1), 7), Math.Round(QL.Last().v, 7)); - } - + Assert.Equal(System.Math.Round((double)pta.tail(1), 7), Math.Round(QL.Last().v, 7)); + } - [Fact] - void EMA() - { - EMA_Series QL = new(this.bars.Close, this.period, false); - var pta = this.ta.ema(close: this.df[0], length: this.period); - - Assert.Equal(System.Math.Round((double)pta.tail(1), 7), Math.Round(QL.Last().v, 7)); - } + [Fact] + void EMA() + { + EMA_Series QL = new(this.bars.Close, this.period, false); + var pta = this.ta.ema(close: this.df[0], length: this.period); + + Assert.Equal(System.Math.Round((double)pta.tail(1), 7), Math.Round(QL.Last().v, 7)); + } - [Fact] - void TEMA() - { - TEMA_Series QL = new(this.bars.Close, this.period, false); - var pta = this.ta.tema(close: this.df[0], length: this.period); + [Fact] + void TEMA() + { + TEMA_Series QL = new(this.bars.Close, this.period, false); + var pta = this.ta.tema(close: this.df[0], length: this.period); - Assert.Equal(System.Math.Round((double)pta.tail(1), 7), Math.Round(QL.Last().v, 7)); - } + Assert.Equal(System.Math.Round((double)pta.tail(1), 7), Math.Round(QL.Last().v, 7)); + } - [Fact] - void ENTP() - { - ENTP_Series QL = new(this.bars.Close, this.period, useNaN:false); - var pta = this.ta.entropy(close: this.df[0], length: this.period); + [Fact] + void ENTP() + { + ENTP_Series QL = new(this.bars.Close, this.period, useNaN:false); + var pta = this.ta.entropy(close: this.df[0], length: this.period); - Assert.Equal(System.Math.Round((double)pta.tail(1), 7), Math.Round(QL.Last().v, 7)); - } + Assert.Equal(System.Math.Round((double)pta.tail(1), 7), Math.Round(QL.Last().v, 7)); + } - [Fact] - void WMA() - { - WMA_Series QL = new(this.bars.Close, this.period, false); - var pta = this.ta.wma(close: this.df[0], length: this.period); - - Assert.Equal(System.Math.Round((double)pta.tail(1), 7), Math.Round(QL.Last().v, 7)); - } - - [Fact] - void DEMA() - { - DEMA_Series QL = new(this.bars.Close, this.period, false); - var pta = this.ta.dema(close: this.df[0], length: this.period); - - Assert.Equal(System.Math.Round((double)pta.tail(1), 7), Math.Round(QL.Last().v, 7)); - } - - [Fact] - void BIAS() - { - BIAS_Series QL = new(this.bars.Close, this.period, false); - var pta = this.ta.bias(close: this.df[0], length: this.period); + [Fact] + void WMA() + { + WMA_Series QL = new(this.bars.Close, this.period, false); + var pta = this.ta.wma(close: this.df[0], length: this.period); - Assert.Equal(System.Math.Round((double)pta.tail(1), 7), Math.Round(QL.Last().v, 7)); - } + Assert.Equal(System.Math.Round((double)pta.tail(1), 7), Math.Round(QL.Last().v, 7)); + } - [Fact] - void KURT() - { - KURT_Series QL = new(this.bars.Close, this.period, useNaN: false); - var pta = this.ta.kurtosis(close: this.df[0], length: this.period); + [Fact] + void DEMA() + { + DEMA_Series QL = new(this.bars.Close, this.period, false); + var pta = this.ta.dema(close: this.df[0], length: this.period); - Assert.Equal(System.Math.Round((double)pta.tail(1), 4), Math.Round(QL.Last().v, 4)); - } + Assert.Equal(System.Math.Round((double)pta.tail(1), 7), Math.Round(QL.Last().v, 7)); + } - [Fact] - void MAD() - { - MAD_Series QL = new(this.bars.Close, this.period, useNaN: false); - var pta = this.ta.mad(close: this.df[0], length: this.period); + [Fact] + void BIAS() + { + BIAS_Series QL = new(this.bars.Close, this.period, false); + var pta = this.ta.bias(close: this.df[0], length: this.period); - Assert.Equal(System.Math.Round((double)pta.tail(1), 7), Math.Round(QL.Last().v, 7)); - } - -} + Assert.Equal(System.Math.Round((double)pta.tail(1), 7), Math.Round(QL.Last().v, 7)); + } -*/ \ No newline at end of file + [Fact] + void KURT() + { + KURT_Series QL = new(this.bars.Close, this.period, useNaN: false); + var pta = this.ta.kurtosis(close: this.df[0], length: this.period); + + Assert.Equal(System.Math.Round((double)pta.tail(1), 4), Math.Round(QL.Last().v, 4)); + } + + [Fact] + void MAD() + { + MAD_Series QL = new(this.bars.Close, this.period, useNaN: false); + var pta = this.ta.mad(close: this.df[0], length: this.period); + + Assert.Equal(System.Math.Round((double)pta.tail(1), 7), Math.Round(QL.Last().v, 7)); + } + */ + +} \ No newline at end of file diff --git a/Tests/Validations/TA_LIB.cs b/Tests/Validations/TA_LIB.cs index e4f97f60..076a17d0 100644 --- a/Tests/Validations/TA_LIB.cs +++ b/Tests/Validations/TA_LIB.cs @@ -30,6 +30,42 @@ public class TA_LIB ///////////////////////////////////////// + [Fact] + public void ADD() + { + ADD_Series QL = new(this.bars.Open, this.bars.Close); + Core.Add(this.inopen, this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _); + + Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8)); + } + + [Fact] + public void SUB() + { + SUB_Series QL = new(this.bars.Open, this.bars.Close); + Core.Sub(this.inopen, this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _); + + Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8)); + } + + [Fact] + public void MUL() + { + MUL_Series QL = new(this.bars.Open, this.bars.Close); + Core.Mult(this.inopen, this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _); + + Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8)); + } + + [Fact] + public void DIV() + { + DIV_Series QL = new(this.bars.Open, this.bars.Close); + Core.Div(this.inopen, this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _); + + Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8)); + } + [Fact] public void SDEV() { @@ -39,6 +75,7 @@ public class TA_LIB Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8)); } + [Fact] public void SMA() { @@ -112,9 +149,9 @@ public class TA_LIB } [Fact] - public void ADO() + public void ADOSC() { - ADO_Series QL = new(this.bars, false); + ADOSC_Series QL = new(this.bars, false); Core.AdOsc(this.inhigh, this.inlow, this.inclose, this.involume, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _); Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8)); @@ -175,9 +212,9 @@ public class TA_LIB double[] outLower = new double[this.bars.Count]; BBANDS_Series QL = new(this.bars.Close, period:26, multiplier:2.0, false); Core.Bbands(this.inclose, 0, this.bars.Count - 1, outRealUpperBand: outUpper, outRealMiddleBand: outMiddle, outRealLowerBand: outLower, out int outBegIdx, out _, optInTimePeriod:26, optInNbDevUp:2.0, optInNbDevDn:2.0); - Assert.Equal(Math.Round(outUpper[outUpper.Length - outBegIdx - 1], 8), Math.Round(QL.Upper.Last().v, 8)); - Assert.Equal(Math.Round(outMiddle[outMiddle.Length - outBegIdx - 1], 8), Math.Round(QL.Mid.Last().v, 8)); - Assert.Equal(Math.Round(outLower[outLower.Length - outBegIdx - 1], 8), Math.Round(QL.Lower.Last().v, 8)); + Assert.Equal(Math.Round(outUpper[outUpper.Length - outBegIdx - 1], 7), Math.Round(QL.Upper.Last().v, 7)); + Assert.Equal(Math.Round(outMiddle[outMiddle.Length - outBegIdx - 1], 7), Math.Round(QL.Mid.Last().v, 7)); + Assert.Equal(Math.Round(outLower[outLower.Length - outBegIdx - 1], 7), Math.Round(QL.Lower.Last().v, 7)); } diff --git a/docs/coverage.md b/docs/coverage.md index ee5e3cb7..feb47805 100644 --- a/docs/coverage.md +++ b/docs/coverage.md @@ -1,155 +1,164 @@ # Coverage of indicators -| Indicator | QuanTAlib | TA-LIB | Skender | Pandas-TA | -|--|:--:|:--:|:--:|:--:| -| **Basics** ||||| -| OC2 - (Open+Close)/2 |✔️|||✔️| -| HL2 - (High+Low)/2 |✔️|||✔️| -| HLC3 - Typical Price |✔️|||✔️| -| OHL3 - (Open+High+Low)/3 |✔️|||✔️| -| OHLC4 - (O+H+L+C)/4 |✔️|||✔️| -| HLCC4 - Weighted Price |✔️||✔️|✔️| -| ZL - Zero Lag - De-lagged price |✔️|||✔️| -| ADD - Addition |✔️|✔️||| -| SUB - Subtraction |✔️|✔️||| -| MUL - Multiplication |✔️|✔️||| -| DIV - Division |✔️|✔️||| -|||||| -| **Statistics** ||||| -| BETA - Beta coefficient |||✔️|| -| BIAS - Bias |✔️|||✔️| -| ENTR - Entropy |✔️|||✔️| -| KUR - Kurtosis |✔️|||✔️| -| LINREG - Linear Regression |✔️|✔️|✔️|| -| MAD - Mean Absolute Deviation |✔️||✔️|✔️| -| MAPE - Mean Absolute Percent Error |✔️||✔️|| -| MAX - Max value |✔️|✔️||| -| MIN - Min value |✔️|✔️||| -| MED - Median value |✔️|✔️||✔️| -| MSE - Mean Squared Error |✔️||✔️|| -| PSDEV - Population Standard Deviation |✔️|||| -| PVAR - Population Variance |✔️|||| -| QUANTILE ||||✔️| -| SKEW - Skewness ||||✔️| -| SMAPE - Symmetric Mean Absolute Percent Error |✔️|||| -| SDEV - Sample Standard Deviation |✔️|✔️|✔️|✔️| -| VAR - Sample Variance |✔️|||✔️| -| WMAPE - Weighted Mean Absolute Percent Error |✔️|||| -| ZSCORE |||✔️|✔️| -|||||| -| **Moving Averages** ||||| -| AFIRMA - Autoregressive Finite Impulse Response Moving Average ||||| -| ALMA - Arnaud Legoux Moving Average |✔️||✔️|✔️| -| ARIMA - Autoregressive Integrated Moving Average ||||| -| ATR - Average True Range |✔️|✔️|✔️|✔️| -| ATRP - Average True Range Percent |✔️||✔️|| -| DEMA - Double EMA |✔️|✔️|✔️|✔️| -| EMA - Exponential Moving Average |✔️|✔️|✔️|✔️| -| EPMA - Endpoint Moving Average |||✔️|| -| FWMA - Fibonacci's Weighted Moving Average ||||✔️| -| HEMA - Hull Exponential Moving Average |✔️|||| -| HMA - Hull Moving Average |✔️||✔️|✔️| -| HWMA - Holt-Winter Moving Average ||||✔️| -| JMA - Jurik Moving Average |✔️|||✔️| -| KAMA - Kaufman's Adaptive Moving Average |✔️|✔️|✔️|✔️| -| LSMA - Least Squares Moving Average |||✔️|| -| MACD - Moving Average Convergence/Divergence |✔️|✔️|✔️|✔️| -| MAMA - MESA Adaptive Moving Average ||✔️|✔️|| -| MMA - Modified Moving Average |||✔️|| -| NATR - Normalized Average True Range ||✔️|✔️|✔️| -| PPMA - Pivot Point Moving Average |||✔️|| -| PWMA - Pascal's Weighted Moving Average ||||✔️| -| RMA - WildeR's Moving Average |✔️|||✔️| -| SINWMA - Sine Weighted Moving Average ||||✔️| -| SMA - Simple Moving Average |✔️|✔️|✔️|✔️| -| SMMA - Smoothed Moving Average |✔️||✔️|| -| STOCH - Stochastic Oscillator ||✔️|✔️|✔️| -| SSF - Ehler's Super Smoother Filter ||||✔️| -| SUP - Supertrend |||✔️|✔️| -| SWMA - Symmetric Weighted Moving Average ||||✔️| -| T3 - Tillson T3 Moving Average ||✔️|✔️|✔️| -| TEMA - Triple EMA |✔️|✔️|✔️|✔️| -| TRIMA - Triangular Moving Average ||✔️||✔️| -| VIDYA - Variable Index Dynamic Average ||||✔️| -| VWAP - Volume Weighted Average Price |||✔️|✔️| -| VWMA - Volume Weighted Moving Average |||✔️|✔️| -| WMA - Weighted Moving Average |✔️|✔️|✔️|✔️| -| ZLEMA - Zero Lag EMA |✔️|||✔️| -|||||| -| **Oscillators and Indices** ||||| -| AC - Acceleration Oscillator ||||✔️| -| AD - Chaikin Accumulation Distribution ||✔️|✔️|✔️| -| ADOSC - Chaikin Accumulation Distribution Oscillator ||✔️|✔️|| -| ADX - Average Directional Movement Index ||✔️|✔️|✔️| -| ADXR - Average Directional Movement Index Rating ||✔️|✔️|| -| AO - Awesome Oscillator |||✔️|✔️| -| APO - Absolute Price Oscillator ||✔️||✔️| -| AROON - Aroon oscillator ||✔️|✔️|✔️| -| BBANDS - Bollinger Bands ||✔️|✔️|✔️| -| BOP - Balance of Power ||✔️|✔️|✔️| -| CCI - Commodity Channel Index |✔️|✔️|✔️|✔️| -| CFO - Chande Forcast Oscillator ||||✔️| -| CMF - Chaikin Money Flow |||✔️|✔️| -| CMO - Chande Momentum Oscillator ||✔️||✔️| -| COG - Center of Gravity ||||✔️| -| CRSI - Connor RSI |||✔️|| -| CTI - Ehler's Correlation Trend Indicator ||||✔️| -| DMI - Directional Movement Index ||✔️|✔️|✔️| -| EFI - Elder Ray's Force Index |||✔️|✔️| -| GAT - Alligator oscillator |||✔️|| -| KRI - Kairi Relative Index ||||| -| KVO - Klinger Volume Oscillator |||✔️|✔️| -| MFI - Money Flow Index ||✔️|✔️|✔️| -| MOM - Momentum |||✔️|✔️| -| NVI - Negative Volume Index ||||✔️| -| PO - Price Oscillator ||||✔️| -| PPO - Percentage Price Oscillator ||✔️||✔️| -| PVI - Positive Volume Index ||||✔️| -| RSI - Relative Strength Index |✔️|✔️|✔️|✔️| -| RVGI - Relative Vigor Index ||||✔️| -| SRSI - Stochastic RSI |||✔️|✔️| -| TRIX - 1-day ROC of TEMA ||✔️|✔️|✔️| -| TSI - True Strength Index |||✔️|✔️| -| UI - Ulcer Index |||✔️|✔️| -| UO - Ultimate Oscillator ||✔️|✔️|✔️| -| WGAT - Williams Alligator |||✔️|| -|||||| -| **Volume** ||||| -| AOBV - Archer On-Balance Volume ||||✔️| -| OBV - On-Balance Volume ||✔️|✔️|✔️| -| PRS - Price Relative Strength |||✔️|| -| PVOL - Price-Volume ||||| -| PVR - Price Volume Rank ||||✔️| -| PVT - Price Volume Trend ||||✔️| -| VP - Volume Profile ||||✔️| -|||||| -|**Unsorted**||||| -| CHN - Price Channel |||✔️|| -| COPPOCK - Coppock Curve ||||✔️| -| CORREL - Pearson's Correlation Coefficient ||✔️|✔️|| -| EOM - Ease of Movement ||||✔️| -| HILO - Gann High-Low Activator ||||✔️| -| HV - Historical Volatility |||✔️|| -| HT - HT Trendline |||✔️|| -| ICH - Ichimoku |||✔️|✔️| -| MCGD - McGinley Dynamic ||||✔️| -| ROC - Rate of Change ||✔️|✔️|✔️| -| SAR - Parabolic Stop and Reverse ||✔️|✔️|✔️| -| STC - Schaff Trend Cycle |||✔️|✔️| -| TR - True Range ||✔️|✔️|✔️| -| WILLR - Larry Williams' %R ||✔️|✔️|✔️| -| HURST - Hurst Exponent |||✔️|| -| VOR - Vortex Indicator |||✔️|✔️| -| DON - Donchian Channels |||✔️|✔️| -| FCB - Fractal Chaos Bands |||✔️|| -| KEL - Keltner Channels |||✔️|✔️| -| PVT - Pivot Points |||✔️|| -| STARC - Starc Bands |||✔️|| -| DPO - De-trended Price Oscillator |||✔️|✔️| -| KDJ - KDJ Index |||✔️|✔️| -| SMI - Stochastic Momentum Index |||✔️|✔️| -| CHAND - Chandelier Exit |||✔️|| -| VSTOP - Volatility Stop |||✔️|| -| PVO - Percentage Volume Oscillator |||✔️|✔️| -| Hilbert Transform Instantaneous Trendline ||||| -| PMO - Price Momentum Oscillator |||✔️|| +✔️= Calculation exists in QuanTAlib + +⭐= Calculation is validated against other TA libraries + +⛔= Not implemented in QuanTAlib (yet) + +| **BASIC TRANSFORMS** | **QuanTAlib** | **TA-LIB** | **Skender** | +|--|:--:|:--:|:--:| +| ✔️ OC2 - (Open+Close)/2 |️ .OC2 || ️GetBaseQuote | +| ⭐ HL2 - Median Price | .HL2 | MEDPRICE | ️GetBaseQuote | +| ⭐ HLC3 - Typical Price | .HLC3 | TYPPRICE || +| ✔️ OHL3 - (Open+High+Low)/3 | .OHL3 ||| +| ⭐ OHLC4 - Average Price | .OHLC4 | AVGPRICE |️ GetBaseQuote | +| ⭐ HLCC4 - Weighted Price | .HLCC4 | WCLPRICE || +| ✔️ ZL - De-lagged price (Zero-Lag) | ZL_Series ||| +| ⭐ MAX - Max value | MAX_Series | MAX || +| ⛔ MID - Midpoint value || MIDPOINT || +| ⛔ MIDP - Midpoint price || MIDPRICE || +| ⭐ MIN - Min value | MIN_Series | MIN || +| ⭐ ADD - Addition | ADD_Series | ADD || +| ⭐ SUB - Subtraction | SUB_Series | SUB || +| ⭐ MUL - Multiplication | MUL_Series | MUL || +| ⭐ DIV - Division | DIV_Series | DIV || +||||| +| **STATISTICS & NUMERICAL ANALYSIS** | **QuanTAlib** | **TA-LIB** | **Skender** | +| ✔️ BIAS - Bias | BIAS_Series ||| +| ⛔ CORREL - Pearson's Correlation Coefficient || CORREL | GetCorrelation | +| ⛔ COVAR - Covariance ||| GetCorrelation | +| ✔️ ENTP - Entropy | ENTP_Series ||| +| ✔️ KURT - Kurtosis | KURT_Series ||| +| ⭐ LINREG - Linear Regression | LINREG_Series || GetSlope | +| ⭐ MAD - Mean Absolute Deviation | MAD_Series || GetSma | +| ⭐ MAPE - Mean Absolute Percent Error | MAPE_Series || GetSma | +| ✔️ MED - Median value | MED_Series ||| +| ✔️ MSE - Mean Squared Error | MSE_Series || GetSma | +| ⛔ SKEW - Skewness |||| +| ⭐ SDEV - Standard Deviation (Volatility) | SDEV_Series ||| +| ✔️ SSDEV - Sample Standard Deviation | SSDEV_Series ||| +| ✔️ SMAPE - Symmetric Mean Absolute Percent Error | SMAPE_Series ||| +| ✔️ VAR - Population Variance | VAR_Series ||| +| ✔️ SVAR - Sample Variance | SVAR_Series ||| +| ⛔ QUANT - Quantile |||| +| ✔️ WMAPE - Weighted Mean Absolute Percent Error | WMAPE_Series ||| +| ⛔ ZSCORE - Number of standard deviations from mean |||| +||||| +| **TREND INDICATORS & AVERAGES** | **QuanTAlib** | **TA-LIB** | **Skender** | +| ⛔ AFIRMA - Autoregressive Finite Impulse Response Moving Average |||| +| ⭐ ALMA - Arnaud Legoux Moving Average | ALMA_Series || GetAlma | +| ⛔ ARIMA - Autoregressive Integrated Moving Average |||| +| ⭐ DEMA - Double EMA Average | DEMA_Series | DEMA | GetDema | +| ⭐ EMA - Exponential Moving Average | EMA_Series || GetEma | +| ⛔ EPMA - Endpoint Moving Average ||| GetEpma | +| ⛔ FWMA - Fibonacci's Weighted Moving Average |||| +| ✔️ HEMA - Hull/EMA Average | HEMA_Series ||| +| ⛔ Hilbert Transform Instantaneous Trendline || HT_TRENDLINE | GetHtTrendline | +| ⭐ HMA - Hull Moving Average | HMA_Series || GetHma | +| ⛔ HWMA - Holt-Winter Moving Average |||| +| ✔️ JMA - Jurik Moving Average | JMA_Series ||| +| ⭐ KAMA - Kaufman's Adaptive Moving Average | KAMA_Series | KAMA | GetKama | +| ⛔ LSMA - Least Squares Moving Average |||| +| ⭐ MACD - Moving Average Convergence/Divergence | MACD_Series | MACD | GetMacd | +| ⛔ MAMA - MESA Adaptive Moving Average || MAMA | GetMama | +| ⛔ MMA - Modified Moving Average |||| +| ⛔ PPMA - Pivot Point Moving Average |||| +| ⛔ PWMA - Pascal's Weighted Moving Average |||| +| ✔️ RMA - WildeR's Moving Average | RMA__Series ||| +| ⛔ SINWMA - Sine Weighted Moving Average |||| +| ⭐ SMA - Simple Moving Average | SMA_Series ||| +| ⭐ SMMA - Smoothed Moving Average | SMMA_Series ||| +| ⛔ SSF - Ehler's Super Smoother Filter |||| +| ⛔ SUP - Supertrend |||| +| ⛔ SWMA - Symmetric Weighted Moving Average |||| +| ⛔ T3 - Tillson T3 Moving Average |||| +| ⭐ TEMA - Triple EMA Average | TEMA_Series ||| +| ⛔ TRIMA - Triangular Moving Average |||| +| ⛔ VIDYA - Variable Index Dynamic Average |||| +| ⭐ WMA - Weighted Moving Average | WMA_Series ||| +| ✔️ ZLEMA - Zero Lag EMA Average | ZLEMA_Series ||| +||||| +| **VOLATILITY INDICATORS** | **QuanTAlib** | **TA-LIB** | **Skender** | +| ⭐ ADL - Chaikin Accumulation Distribution Line | ADL_Series | AD | GetAdl | +| ⭐ ADOSC - Chaikin Accumulation Distribution Oscillator | ADOSC_Series | ADOSC| GetAdl | +| ⭐ ATR - Average True Range | ATR_Series | ATR | GetAtr | +| ⭐ ATRP - Average True Range Percent | ATRP_Series || GetAtr | +| ✔️ BETA - Beta coefficient || BETA | GetBeta | +| ⭐ BBANDS - Bollinger Bands® | BBANDS_Series | BBANDS | GetBollingerBands | +| ⛔ CRSI - Connor RSI ||| GetConnorsRsi | +| ⛔ DON - Donchian Channels ||| GetDonchian | +| ⛔ FCB - Fractal Chaos Bands ||| GetFcb | +| ⛔ HV - Historical Volatility |||| +| ⛔ ICH - Ichimoku ||| GetIchimoku | +| ⛔ KEL - Keltner Channels ||| GetKeltner | +| ⛔ NATR - Normalized Average True Range || NATR | GetAtr | +| ⭐ RSI - Relative Strength Index | RSI_Series || +| ⛔ SAR - Parabolic Stop and Reverse || SAR | GetParabolicSar | +| ⛔ SRSI - Stochastic RSI |||| +| ⛔ STARC - Starc Bands |||| +| ⭐ TR - True Range | TR_Series ||| +| ⛔ UI - Ulcer Index |||| +| ⛔ VSTOP - Volatility Stop |||| +||||| +| **MOMENTUM INDICATORS & OSCILLATORS** | **QuanTAlib** | **TA-LIB** | **Skender** | +| ⛔ AC - Acceleration Oscillator |||| +| ⛔ ADX - Average Directional Movement Index || ADX | GetAdx | +| ⛔ ADXR - Average Directional Movement Index Rating || ADXR | GetAdx | +| ⛔ AO - Awesome Oscillator ||| GetAwesome | +| ⛔ APO - Absolute Price Oscillator || APO || +| ⛔ AROON - Aroon oscillator || AROON | GetAroon | +| ⛔ BOP - Balance of Power || BOP | GetBop | +| ⭐ CCI - Commodity Channel Index | CCI_Series | CCI | GetCci | +| ⛔ CFO - Chande Forcast Oscillator |||| +| ⛔ CMF - Chaikin Money Flow |||| +| ⛔ CMO - Chande Momentum Oscillator || CMO | GetCmo | +| ⛔ COG - Center of Gravity |||| +| ⛔ CTI - Ehler's Correlation Trend Indicator |||| +| ⛔ DPO - Detrended Price Oscillator ||| GetDpo | +| ⛔ DMI - Directional Movement Index || DX | GetAdx | +| ⛔ EFI - Elder Ray's Force Index ||| GetElderRay | +| ⛔ GAT - Alligator oscillator ||| GetGator | +| ⛔ HURST - Hurst Exponent ||| GetHurst | +| ⛔ KRI - Kairi Relative Index |||| +| ⛔ KVO - Klinger Volume Oscillator |||| +| ⛔ MFI - Money Flow Index || MFI | GetMfi | +| ⛔ ROC - Rate of Change (Momentum) || MOM | GetRoc | +| ⛔ NVI - Negative Volume Index |||| +| ⛔ PO - Price Oscillator |||| +| ⛔ PPO - Percentage Price Oscillator || PPO || +| ⛔ PMO - Price Momentum Oscillator |||| +| ⛔ PVI - Positive Volume Index |||| +| ⛔ RVGI - Relative Vigor Index |||| +| ⛔ SMI - Stochastic Momentum Index |||| +| ⛔ STOCH - Stochastic Oscillator |||| +| ⛔ TRIX - 1-day ROC of TEMA |||| +| ⛔ TSI - True Strength Index |||| +| ⛔ UO - Ultimate Oscillator |||| +| ⛔ WGAT - Williams Alligator |||| +||||| +| **VOLUME INDICATORS** | **QuanTAlib** | **TA-LIB** | **Skender** | +| ⛔ AOBV - Archer On-Balance Volume |||| +| ⛔ OBV - On-Balance Volume || OBV | GetObv | +| ⛔ PRS - Price Relative Strength ||| +| ⛔ PVOL - Price-Volume |||| +| ⛔ PVO - Percentage Volume Oscillator |||| +| ⛔ PVR - Price Volume Rank |||| +| ⛔ PVT - Price Volume Trend |||| +| ⛔ VP - Volume Profile |||| +| ⛔ VWAP - Volume Weighted Average Price |||| +| ⛔ VWMA - Volume Weighted Moving Average |||| +||||| +|**Unsorted** | **QuanTAlib** | **TA-LIB** | **Skender** | +| ⛔ CHN - Price Channel |||| +| ⛔ COPPOCK - Coppock Curve |||| +| ⛔ EOM - Ease of Movement |||| +| ⛔ HILO - Gann High-Low Activator |||| +| ⛔ HT - HT Trendline |||| +| ⛔ MCGD - McGinley Dynamic |||| +| ⛔ STC - Schaff Trend Cycle |||| +| ⛔ WILLR - Larry Williams' %R |||| +| ⛔ VOR - Vortex Indicator |||| +| ⛔ PVT - Pivot Points |||| +| ⛔ KDJ - KDJ Index |||| +| ⛔ CHAND - Chandelier Exit ||||