diff --git a/Source/Basics/TR_Series.cs b/Source/Basics/TR_Series.cs
index 65b1a54c..6f4c2391 100644
--- a/Source/Basics/TR_Series.cs
+++ b/Source/Basics/TR_Series.cs
@@ -19,14 +19,16 @@ Sources:
public class TR_Series : Single_TBars_Indicator
{
- private double _cm1 = double.NaN;
+ private double _cm1, _cm1_o;
public TR_Series(TBars source, bool useNaN = false) : base(source, period:0, useNaN:useNaN) {
+ _cm1 =_cm1_o = double.NaN;
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)
{
- if (_cm1 is double.NaN) { _cm1 = TBar.c; }
+ if (update) {_cm1 = _cm1_o; } else { _cm1_o = _cm1; }
+ if (_cm1 is double.NaN) { _cm1 = TBar.c; } //first bar
double d1 = Math.Abs(TBar.h - TBar.l);
double d2 = Math.Abs(_cm1 - TBar.h);
diff --git a/Source/Feeds/RND_Feed.cs b/Source/Feeds/RND_Feed.cs
index c30881e7..1d17840d 100644
--- a/Source/Feeds/RND_Feed.cs
+++ b/Source/Feeds/RND_Feed.cs
@@ -11,18 +11,18 @@ Random Bars generator - used for testing, validation and fun
public class RND_Feed : TBars
{
- public RND_Feed(int bars, double volatility = 0.05, double startvalue = 100.0)
+ public RND_Feed(int Bars, double Volatility = 0.05, double Startvalue = 100.0)
{
Random rnd = new();
- double c = startvalue;
- for (int i = 0; i < bars; i++)
+ double c = Startvalue;
+ for (int i = 0; i < Bars; i++)
{
- double o = Math.Round(c + (c * (((volatility * 0.1) * rnd.NextDouble()) - 0.005)), 2);
- double h = Math.Round(o + (c * volatility * rnd.NextDouble()), 2);
- double l = Math.Round(o - (c * volatility * rnd.NextDouble()), 2);
+ double o = Math.Round(c + (c * (((Volatility * 0.1) * rnd.NextDouble()) - 0.005)), 2);
+ double h = Math.Round(o + (c * Volatility * rnd.NextDouble()), 2);
+ double l = Math.Round(o - (c * Volatility * rnd.NextDouble()), 2);
c = Math.Round(l + ((h - l) * rnd.NextDouble()), 2);
double v = Math.Round(1000 * rnd.NextDouble(), 2);
- this.Add(DateTime.Today.AddDays(i - bars), o, h, l, c, v);
+ this.Add(DateTime.Today.AddDays(i - Bars), o, h, l, c, v);
}
}
}
\ No newline at end of file
diff --git a/Source/QuanTAlib.csproj b/Source/QuanTAlib.csproj
index 3a18b409..be71640e 100644
--- a/Source/QuanTAlib.csproj
+++ b/Source/QuanTAlib.csproj
@@ -2,7 +2,7 @@
QuanTAlib
- 0.1.21
+ 0.1.22
Library of Technical Indicators for .NET
Quantitative Technical Analysis library for both real-time (streaming) and historical data analysis
git
@@ -11,7 +11,7 @@
Miha Kralj
Miha Kralj
readme.md
- net7.0;
+ net7.0;net6.0;netstandard2.1
disable
preview
disable
@@ -66,6 +66,7 @@
False
+
\ No newline at end of file
diff --git a/Source/Trends/MAMA_Series.cs b/Source/Trends/MAMA_Series.cs
index 20102431..ae26f66c 100644
--- a/Source/Trends/MAMA_Series.cs
+++ b/Source/Trends/MAMA_Series.cs
@@ -3,8 +3,8 @@ using System;
/*
MAMA: MESA Adaptive Moving Average
- Created by John Ehlers, the MAMA indicator is a 5-period adaptive moving average of
- high/low price that uses classic electrical radio-frequency signal processing algorithms
+ Created by John Ehlers, the MAMA indicator is a 5-period adaptive moving average of
+ high/low price that uses classic electrical radio-frequency signal processing algorithms
to reduce noise.
KAMAi = KAMAi - 1 + SC * ( price - KAMAi-1 )
@@ -22,84 +22,87 @@ public class MAMA_Series : Single_TSeries_Indicator
fastl = fastlimit;
slowl = slowlimit;
i = 0;
+ Fama = new();
if (base._data.Count > 0) { base.Add(base._data); }
}
-
+
private int i;
private double sumPr, jI, jQ, fastl, slowl;
private (double i, double i1, double i2, double i3, double i4, double i5, double i6, double io) pr, i1, q1, sm, dt;
private (double i, double i1, double io) i2, q2, re, im, pd, ph, mama, fama;
-
+ public TSeries Fama { get; }
+
public override void Add((System.DateTime t, double v) TValue, bool update)
{
- if (update) {
- i--;
- pr.i = pr.i1; pr.i1 = pr.i2; pr.i2 = pr.i3; pr.i3 = pr.i4; pr.i4 = pr.i5; pr.i5 = pr.i6; pr.i6 = pr.io;
- i1.i = i1.i1; i1.i1 = i1.i2; i1.i2 = i1.i3; i1.i3 = i1.i4; i1.i4 = i1.i5; i1.i5 = i1.i6; i1.i6 = i1.io;
- q1.i = q1.i1; q1.i1 = q1.i2; q1.i2 = q1.i3; q1.i3 = q1.i4; q1.i4 = q1.i5; q1.i5 = q1.i6; q1.i6 = q1.io;
- dt.i = dt.i1; dt.i1 = dt.i2; dt.i2 = dt.i3; dt.i3 = dt.i4; dt.i4 = dt.i5; dt.i5 = dt.i6; dt.i6 = dt.io;
- sm.i = sm.i1; sm.i1 = sm.i2; sm.i2 = sm.i3; sm.i3 = sm.i4; dt.i4 = sm.i5; sm.i5 = sm.i6; sm.i6 = sm.io;
- i2.i = i2.i1; i2.i1 = i2.io;
- q2.i = q2.i1; q2.i1 = q2.io;
- re.i = re.i1; re.i1 = re.io;
- im.i = im.i1; im.i1 = im.io;
- pd.i = pd.i1; pd.i1 = pd.io;
- ph.i = ph.i1; ph.i1 = ph.io;
- mama.i = mama.i1; mama.i1 = mama.io;
- fama.i = fama.i1; fama.i1 = fama.io;
- }
+
+ if (!update) {
+ // roll forward (oldx = x)
+ pr.io = pr.i6; pr.i6 = pr.i5; pr.i5 = pr.i4; pr.i4 = pr.i3; pr.i3 = pr.i2; pr.i2 = pr.i1; pr.i1 = pr.i;
+ i1.io = i1.i6; i1.i6 = i1.i5; i1.i5 = i1.i4; i1.i4 = i1.i3; i1.i3 = i1.i2; i1.i2 = i1.i1; i1.i1 = i1.i;
+ q1.io = q1.i6; q1.i6 = q1.i5; q1.i5 = q1.i4; q1.i4 = q1.i3; q1.i3 = q1.i2; q1.i2 = q1.i1; q1.i1 = q1.i;
+ dt.io = dt.i6; dt.i6 = dt.i5; dt.i5 = dt.i4; dt.i4 = dt.i3; dt.i3 = dt.i2; dt.i2 = dt.i1; dt.i1 = dt.i;
+ sm.io = sm.i6; sm.i6 = sm.i5; sm.i5 = sm.i4; sm.i4 = sm.i3; sm.i3 = sm.i2; sm.i2 = sm.i1; sm.i1 = sm.i;
+ i2.io = i2.i1; i2.i1 = i2.i;
+ q2.io = q2.i1; q2.i1 = q2.i;
+ re.io = re.i1; re.i1 = re.i;
+ im.io = im.i1; im.i1 = im.i;
+ pd.io = pd.i1; pd.i1 = pd.i;
+ ph.io = ph.i1; ph.i1 = ph.i;
+ mama.io = mama.i1; mama.i1 = mama.i;
+ fama.io = fama.i1; fama.i1 = fama.i;
+ }
pr.i = TValue.v;
if (i > 5) {
double adj = (0.075 * pd.i1) + 0.54;
-
+
// smooth and detrender
sm.i = ((4 * pr.i) + (3 * pr.i1) + (2 * pr.i2) + pr.i3) / 10;
dt.i = ((0.0962 * sm.i) + (0.5769 * sm.i2) - (0.5769 * sm.i4) - (0.0962 * sm.i6)) * adj;
-
+
// in-phase and quadrature
q1.i = ((0.0962 * dt.i) + (0.5769 * dt.i2) - (0.5769 * dt.i4) - (0.0962 * dt.i6)) * adj;
i1.i = dt.i3;
-
+
// advance the phases by 90 degrees
jI = ((0.0962 * i1.i) + (0.5769 * i1.i2) - (0.5769 * i1.i4) - (0.0962 * i1.i6)) * adj;
jQ = ((0.0962 * q1.i) + (0.5769 * q1.i2) - (0.5769 * q1.i4) - (0.0962 * q1.i6)) * adj;
-
+
// phasor addition for 3-bar averaging
i2.i = i1.i - jQ;
q2.i = q1.i + jI;
-
+
i2.i = (0.2 * i2.i) + (0.8 * i2.i1); // smoothing it
q2.i = (0.2 * q2.i) + (0.8 * q2.i1);
-
+
// homodyne discriminator
re.i = (i2.i * i2.i1) + (q2.i * q2.i1);
im.i = (i2.i * q2.i1) - (q2.i * i2.i1);
-
+
re.i = (0.2 * re.i) + (0.8 * re.i1); // smoothing it
im.i = (0.2 * im.i) + (0.8 * im.i1);
-
+
// calculate period
pd.i = (im.i != 0 && re.i != 0) ? (6.283185307179586 / Math.Atan(im.i / re.i)) : 0d;
-
+
// adjust period to thresholds
pd.i = (pd.i > 1.5 * pd.i1) ? 1.5 * pd.i1 : pd.i;
pd.i = (pd.i < 0.67 * pd.i1) ? 0.67 * pd.i1 : pd.i;
pd.i = (pd.i < 6d) ? 6d : pd.i;
pd.i = (pd.i > 50d) ? 50d : pd.i;
-
+
// smooth the period
pd.i = (0.2 * pd.i) + (0.8 * pd.i1);
-
+
// determine phase position
ph.i = (i1.i != 0) ? Math.Atan(q1.i / i1.i) * 57.29577951308232 : 0;
-
+
// change in phase
double delta = Math.Max(ph.i1 - ph.i, 1d);
-
+
// adaptive alpha value
double alpha = Math.Max(fastl / delta, slowl);
-
+
// final indicators
mama.i = ((alpha * pr.i) + ((1d - alpha) * mama.i1));
fama.i = ((0.5d * alpha * mama.i) + ((1d - (0.5d * alpha)) * fama.i1));
@@ -107,25 +110,12 @@ public class MAMA_Series : Single_TSeries_Indicator
else {
sumPr += pr.i;
pd.i = sm.i = dt.i = i1.i = q1.i = i2.i = q2.i = re.i = im.i = ph.i = 0;
- mama.i = fama.i = sumPr / (i+1);
+ mama.i = fama.i = sumPr / (i+1);
}
- i++;
- pr.io = pr.i6; pr.i6 = pr.i5; pr.i5 = pr.i4; pr.i4 = pr.i3; pr.i3 = pr.i2; pr.i2 = pr.i1; pr.i1 = pr.i;
- i1.io = i1.i6; i1.i6 = i1.i5; i1.i5 = i1.i4; i1.i4 = i1.i3; i1.i3 = i1.i2; i1.i2 = i1.i1; i1.i1 = i1.i;
- q1.io = q1.i6; q1.i6 = q1.i5; q1.i5 = q1.i4; q1.i4 = q1.i3; q1.i3 = q1.i2; q1.i2 = q1.i1; q1.i1 = q1.i;
- dt.io = dt.i6; dt.i6 = dt.i5; dt.i5 = dt.i4; dt.i4 = dt.i3; dt.i3 = dt.i2; dt.i2 = dt.i1; dt.i1 = dt.i;
- sm.io = sm.i6; sm.i6 = sm.i5; sm.i5 = sm.i4; sm.i4 = sm.i3; sm.i3 = sm.i2; sm.i2 = sm.i1; sm.i1 = sm.i;
-
- i2.io = i2.i1; i2.i1 = i2.i;
- q2.io = q2.i1; q2.i1 = q2.i;
- re.io = re.i1; re.i1 = re.i;
- im.io = im.i1; im.i1 = im.i;
- pd.io = pd.i1; pd.i1 = pd.i;
- ph.io = ph.i1; ph.i1 = ph.i;
-
- mama.io = mama.i1; mama.i1 = mama.i;
- fama.io = fama.i1; fama.i1 = fama.i;
+ if (!update) { i++; }
base.Add((TValue.t, mama.i), update, _NaN);
+ var result = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : fama.i);
+ Fama.Add(result, update);
}
}
diff --git a/Source/Trends/T3_Series.cs b/Source/Trends/T3_Series.cs
new file mode 100644
index 00000000..46e4217a
--- /dev/null
+++ b/Source/Trends/T3_Series.cs
@@ -0,0 +1,117 @@
+namespace QuanTAlib;
+using System;
+using System.Linq;
+using System.Numerics;
+
+/*
+T3: Triple Exponential Moving Average
+ TEMA uses EMA(EMA(EMA())) to calculate less laggy Exponential moving average.
+
+Sources:
+ https://www.tradingtechnologies.com/help/x-study/technical-indicator-definitions/triple-exponential-moving-average-tema/
+
+
+ */
+
+public class T3_Series : Single_TSeries_Indicator
+{
+ private int i;
+ private double k, a;
+ private double c1, c2, c3, c4;
+ private double o_c1, o_c2, o_c3, o_c4;
+
+ private double e1, e2, e3, e4, e5, e6;
+ private double o_e1, o_e2, o_e3, o_e4, o_e5, o_e6;
+
+ private double sum1, sum2, sum3, sum4, sum5, sum6;
+ private double o_sum1, o_sum2, o_sum3, o_sum4, o_sum5, o_sum6;
+
+ public T3_Series(TSeries source, int period, double vfactor, bool useNaN = false) : base(source, period, useNaN)
+ {
+ i = 0;
+ k = 2.0 / (_p + 1);
+ a = vfactor;
+ c1 = -a * a * a;
+ c2 = (3 * a * a) + (3 * a * a * a);
+ c3 = (-6 * a * a) - (3 * a) - (3 * a * a * a);
+ c4 = 1 + (3 * a) + (3 * a * a) + (a * a * a) ;
+ e1 = e2 = e3 = e4 = e5 = e6 = 0;
+ sum1 = sum2 = sum3 = sum4 = sum5 = sum6 = 0;
+
+ if (_data.Count > 0) { base.Add(data: _data); }
+ }
+
+ public override void Add((DateTime t, double v) TValue, bool update)
+ {
+ if (update) {
+ // roll back (x = oldx)
+ c1 = o_c1; c2 = o_c2; c3 = o_c3; c4 = o_c4;
+ e1 = o_e1; e2 = o_e2; e3 = o_e3; e4 = o_e4; e5 = o_e5; e6 = o_e6;
+ sum1 = o_sum1; sum2 = o_sum2; sum3 = o_sum3; sum4 = o_sum4; sum5 = o_sum5; sum6 = o_sum6;
+ } else {
+ // roll forward (oldx = x)
+ o_c1 = c1; o_c2 = c2; o_c3 = c3; o_c4 = c4;
+ o_e1 = e1; o_e2 = e2; o_e3 = e3; o_e4 = e4; o_e5 = e5; o_e6 = e6;
+ o_sum1 = sum1; o_sum2 = sum2; o_sum3 = sum3; o_sum4 = sum4; o_sum5 = sum5; o_sum6 = sum6;
+ }
+ double v = TValue.v;
+ if (i > _p - 1) {
+ e1 += k * (v - e1);
+ if (i > 2 * (_p - 1)) {
+ e2 += k * (e1 - e2);
+ if (i > 3 * (_p - 1)) {
+ e3 += k * (e2 - e3);
+ if (i > 4 * (_p - 1)) {
+ e4 += k * (e3 - e4);
+ if (i > 5 * (_p - 1)) {
+ e5 += k * (e4 - e5);
+ if (i > 6 * (_p - 1)) {
+ e6 += k * (e5 - e6);
+ }
+ else {
+ sum6 += e5;
+ if (i == 6 * (_p - 1)) {
+ e6 = sum6 / _p;
+ }
+ }
+ }
+ else {
+ sum5 += e4;
+ if (i == 5 * (_p - 1)) {
+ sum6 = e5 = sum5 / _p;
+ }
+ }
+ }
+ else {
+ sum4 += e3;
+ if (i == 4 * (_p - 1)) {
+ sum5 = e4 = sum4 / _p;
+ }
+ }
+ }
+ else {
+ sum3 += e2;
+ if (i == 3 * (_p - 1)) {
+ sum4 = e3 = sum3 / _p;
+ }
+ }
+ }
+ else {
+ sum2 += e1;
+ if (i == 2 * (_p - 1)) {
+ sum3 = e2 = sum2 / _p;
+ }
+ }
+ }
+ else {
+ sum1 += v;
+ if (i == _p - 1) {
+ sum2 = e1 = sum1 / _p;
+ }
+ }
+ if (!update) { i++; }
+
+ double t3 = (c1 * e6) + (c2 * e5) + (c3 * e4) + (c4 * e3);
+ base.Add(TValue: (TValue.t, t3), update: update, useNaN: _NaN);
+ }
+}
\ No newline at end of file
diff --git a/Source/Trends/ZLEMA_Series.cs b/Source/Trends/ZLEMA_Series.cs
index 9855a550..14f6605b 100644
--- a/Source/Trends/ZLEMA_Series.cs
+++ b/Source/Trends/ZLEMA_Series.cs
@@ -24,38 +24,36 @@ public class ZLEMA_Series : Single_TSeries_Indicator
{
private readonly System.Collections.Generic.List _buffer = new();
private readonly double _k, _k1m;
- private double _lastema, _lastlastema;
+ private double _lastema, _lastema_o;
+ private int _llag;
public ZLEMA_Series(TSeries source, int period, bool useNaN = false) : base(source, period, useNaN)
{
this._k = 2.0 / (this._p + 1);
this._k1m = 1.0 - this._k;
- this._lastema = this._lastlastema = double.NaN;
- if (base._data.Count > 0)
- { base.Add(base._data); }
+ this._lastema = this._lastema_o = double.NaN;
+ _llag = (int)((_p-1) * 0.5);
+ if (_data.Count > 0) { base.Add(_data); }
}
public override void Add((System.DateTime t, double v) TValue, bool update)
{
- int _lag = (int)((_p-1) * 0.5);
- _lag = (this.Count-_lag < 0) ? 0 : this.Count-_lag;
+ int _lag = Math.Max(this.Count-_llag, 0);
+ if (update) {
+ _lastema = _lastema_o; _lag--;
+ } else {
+ _lastema_o = _lastema;
+ }
double _zl = TValue.v + (TValue.v - _data[_lag].v);
-
double _ema = 0;
- if (update)
- { this._lastema = this._lastlastema; }
- if (this.Count < this._p)
- {
- Add_Replace_Trim(_buffer, _zl, _p, update);
- _ema = _buffer.Average();
- }
- else
- {
- _ema = (_zl * this._k) + (this._lastema * this._k1m);
- }
- this._lastlastema = this._lastema;
- this._lastema = _ema;
+ if (this.Count < this._p) {
+ Add_Replace_Trim(_buffer, _zl, _p, update);
+ _ema = _buffer.Average();
+ } else {
+ _ema = (_zl * _k) + (_lastema * _k1m);
+ }
+ _lastema = _ema;
base.Add((TValue.t, _ema), update, _NaN);
}
diff --git a/Source/Volatility/RSI_Series.cs b/Source/Volatility/RSI_Series.cs
index f5717f73..e4f6a350 100644
--- a/Source/Volatility/RSI_Series.cs
+++ b/Source/Volatility/RSI_Series.cs
@@ -16,30 +16,34 @@ public class RSI_Series : Single_TSeries_Indicator
{
private readonly System.Collections.Generic.List _gain = new();
private readonly System.Collections.Generic.List _loss = new();
- private double _avgGain;
- private double _avgLoss;
- private double _lastValue;
- private double _lastlastValue;
+ private double _avgGain, _avgLoss, _lastValue;
+ private double _avgGain_o, _avgLoss_o, _lastValue_o;
+ private int i;
- public RSI_Series(TSeries source, int period = 10, bool useNaN = false) : base(source, period: period, useNaN: useNaN)
- { if (source.Count > 0) { base.Add(source); } }
+ public RSI_Series(TSeries source, int period = 10, bool useNaN = false) : base(source, period: period, useNaN: useNaN) {
+ i = 0;
+ if (source.Count > 0) { base.Add(source); }
+ }
- public override void Add((System.DateTime t, double v) TValue, bool update)
- {
- int i = this.Count;
+ public override void Add((System.DateTime t, double v) TValue, bool update) {
double _rsi = 0;
- if (update) { _lastValue = _lastlastValue; }
+ if (update) {
+ _lastValue = _lastValue_o;
+ _avgGain = _avgGain_o;
+ _avgLoss = _avgLoss_o;
+ }
+ else {
+ _lastValue_o = _lastValue;
+ _avgGain_o = _avgGain;
+ _avgLoss_o = _avgLoss;
+ }
+
if (i == 0) { _lastValue = TValue.v; }
double _gainval = (TValue.v > _lastValue) ? TValue.v - _lastValue : 0;
- if (update) { _gain[_gain.Count - 1] = _gainval; } else { _gain.Add(_gainval); }
- if (_gain.Count > this._p) { _gain.RemoveAt(0); }
-
+ Add_Replace_Trim(_gain, _gainval, _p, update);
double _lossval = (TValue.v < _lastValue) ? _lastValue - TValue.v : 0;
- if (update) { _loss[_loss.Count - 1] = _lossval; } else { _loss.Add(_lossval); }
- if (_loss.Count > this._p) { _loss.RemoveAt(0); }
-
- _lastlastValue = _lastValue;
+ Add_Replace_Trim(_loss, _lossval, _p, update);
_lastValue = TValue.v;
// calculate RSI
@@ -67,6 +71,7 @@ public class RSI_Series : Single_TSeries_Indicator
_rsi = (_avgLoss > 0) ? 100 - (100 / (1 + (_avgGain / _avgLoss))) : 100;
}
+ if (!update) { i++; }
var result = (TValue.t, (this.Count < this._p && this._NaN) ? double.NaN : _rsi);
base.Add(result, update);
}
diff --git a/Tests/MovingAvg/ALMA_Test.cs b/Tests/MovingAvg/ALMA_Test.cs
index b0b2c297..589ab75e 100644
--- a/Tests/MovingAvg/ALMA_Test.cs
+++ b/Tests/MovingAvg/ALMA_Test.cs
@@ -3,7 +3,7 @@ using System;
using QuanTAlib;
namespace MovingAvg;
-public class ALMA_Test
+public class Update
{
[Fact]
public void Add_Test()
diff --git a/Tests/Series/Update.cs b/Tests/Series/Update.cs
new file mode 100644
index 00000000..37d3f9a7
--- /dev/null
+++ b/Tests/Series/Update.cs
@@ -0,0 +1,501 @@
+using Xunit;
+using System;
+using QuanTAlib;
+using Skender.Stock.Indicators;
+
+namespace Series;
+public class Update {
+ private readonly GBM_Feed bars;
+ private readonly Random rnd = new();
+ private readonly int period;
+
+ public Update() {
+ bars = new(Bars: 5000, Volatility: 0.8, Drift: 0.0);
+ period = rnd.Next(28) + 3;
+ }
+
+ [Fact] public void ADL() {
+ ADL_Series QL = new(bars);
+ var lastData = bars.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0, 0, 0, 0, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void ADOSC() {
+ ADOSC_Series QL = new(bars);
+ var lastData = bars.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0, 0, 0, 0, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void ALMA() {
+ ALMA_Series QL = new(source: bars.Close, period: period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void ATR() {
+ ATR_Series QL = new(bars, period: period);
+ var lastData = bars.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0, 0, 0, 0, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void ATRP() {
+ ATRP_Series QL = new(bars, period: period);
+ var lastData = bars.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0, 0, 0, 0, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void BBANDS() {
+ BBANDS_Series QL = new(source: bars.Close, period: period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void BIAS() {
+ BIAS_Series QL = new(source: bars.Close, period: period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void CCI() {
+ CCI_Series QL = new(bars, period: period);
+ var lastData = bars.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0, 0, 0, 0, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void CORR() {
+ CORR_Series QL = new(d1: bars.High, d2: bars.Low, period: period);
+ var lastData = bars.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), (DateTime.Today, 0), update: true);
+ QL.Add((lastData.t, lastData.h), (lastData.t, lastData.l), update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void COVAR() {
+ COVAR_Series QL = new(d1: bars.High, d2: bars.Low, period: period);
+ var lastData = bars.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), (DateTime.Today, 0), update: true);
+ QL.Add((lastData.t, lastData.h), (lastData.t, lastData.l), update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void DEMA() {
+ DEMA_Series QL = new(source: bars.Close, period: period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void ENTROPY() {
+ ENTROPY_Series QL = new(source: bars.Close, period: period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void EMA() {
+ EMA_Series QL = new(source: bars.Close, period: period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void HEMA() {
+ HEMA_Series QL = new(source: bars.Close, period: period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void HMA() {
+ HMA_Series QL = new(source: bars.Close, period: period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void JMA() {
+ JMA_Series QL = new(source: bars.Close, period: period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void KAMA() {
+ KAMA_Series QL = new(source: bars.Close, period: period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void KURTOSIS() {
+ KURTOSIS_Series QL = new(source: bars.Close, period: period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void LINREG() {
+ LINREG_Series QL = new(source: bars.Close, period: period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void MACD() {
+ MACD_Series QL = new(source: bars.Close);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ var lastC1 = QL.Signal.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ Assert.Equal(lastC1, QL.Signal.Last()); // same data
+ }
+ [Fact] public void MAD() {
+ MAD_Series QL = new(source: bars.Close, period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void MAMA() {
+ MAMA_Series QL = new(source: bars.Close);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ var lastC1 = QL.Fama.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ Assert.Equal(lastC1, QL.Fama.Last()); // same data
+ }
+ [Fact] public void MAPE() {
+ MAPE_Series QL = new(source: bars.Close, period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void MAX() {
+ MAX_Series QL = new(source: bars.Close, period: period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void MEDIAN() {
+ MEDIAN_Series QL = new(source: bars.Close, period: period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void MIDPOINT() {
+ MIDPOINT_Series QL = new(source: bars.Close, period: period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void MIDPRICE() {
+ MIDPRICE_Series QL = new(bars, period: period);
+ var lastData = bars.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0, 0, 0, 0, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void MIN() {
+ MAX_Series QL = new(source: bars.Close, period: period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void MSE() {
+ MSE_Series QL = new(source: bars.Close, period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void OBV() {
+ OBV_Series QL = new(bars, period: period);
+ var lastData = bars.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0, 0, 0, 0, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void RSI() {
+ RSI_Series QL = new(source: bars.Close, period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void RMA() {
+ RMA_Series QL = new(source: bars.Close, period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void SDEV() {
+ SDEV_Series QL = new(source: bars.Close, period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void SMA() {
+ SMA_Series QL = new(source: bars.Close, period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void SMAPE() {
+ SMAPE_Series QL = new(source: bars.Close, period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void SMMA() {
+ SMMA_Series QL = new(source: bars.Close, period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void SSDEV() {
+ SSDEV_Series QL = new(source: bars.Close, period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void SUM() {
+ SUM_Series QL = new(source: bars.Close, period: period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void SVAR() {
+ SVAR_Series QL = new(source: bars.Close, period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void T3() {
+ SMA_Series QL = new(source: bars.Close, period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void TEMA() {
+ TEMA_Series QL = new(source: bars.Close, period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void TR() {
+ TR_Series QL = new(bars);
+ var lastData = bars.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0, 0, 0, 0, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void TRIMA() {
+ TRIMA_Series QL = new(source: bars.Close, period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void VAR() {
+ VAR_Series QL = new(source: bars.Close, period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void WMA() {
+ WMA_Series QL = new(source: bars.Close, period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void WMAPE() {
+ WMAPE_Series QL = new(source: bars.Close, period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void ZLEMA() {
+ ZLEMA_Series QL = new(source: bars.Close, period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void ZSCORE() {
+ ZSCORE_Series QL = new(source: bars.Close, period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+}
diff --git a/Tests/Validations/Pandas_TA.cs b/Tests/Validations/Pandas_TA.cs
index fb589b18..2a971df5 100644
--- a/Tests/Validations/Pandas_TA.cs
+++ b/Tests/Validations/Pandas_TA.cs
@@ -7,287 +7,197 @@ using Python.Included;
namespace Validations;
public class PandasTA : IDisposable
{
- private readonly GBM_Feed bars;
- private readonly Random rnd = new();
- private readonly int period;
- private readonly string OStype;
- private readonly dynamic np;
- private readonly dynamic ta;
- private readonly dynamic df;
+ private readonly GBM_Feed bars;
+ private readonly Random rnd = new();
+ private readonly int period;
+ private int digits;
+ private readonly string OStype;
+ private readonly dynamic np;
+ private readonly dynamic ta;
+ private readonly dynamic df;
+
+ public PandasTA() {
+ bars = new(Bars: 5000, Volatility: 0.8, Drift: 0.0);
+ period = rnd.Next(maxValue: 28) + 3;
+ digits = 4; //minimizing rounding errors in type conversions
- public PandasTA()
- {
- bars = new(5000);
- period = rnd.Next(28) + 3;
+ // Checking the host OS and setting PythonDLL accordingly
+ OStype = Path.GetFullPath(path: ".") + @"\python-3.10.0-embed-amd64\python310.dll";
- // Checking the host OS and setting PythonDLL accordingly
- OStype = Environment.OSVersion.ToString();
- if (OStype == "Unix 13.1.0")
- {
- OStype = @"/usr/local/Cellar/python@3.10/3.10.8/Frameworks/Python.framework/Versions/3.10/lib/libpython3.10.dylib";
- }
- else
- {
- OStype = Path.GetFullPath(".") + @"\python-3.10.0-embed-amd64\python310.dll";
- }
+ Installer.InstallPath = Path.GetFullPath(path: ".");
+ Installer.SetupPython().Wait();
+ Installer.TryInstallPip();
+ Installer.PipInstallModule(module_name: "pandas-ta");
+ Runtime.PythonDLL = OStype;
+ PythonEngine.Initialize();
+ np = Py.Import(name: "numpy");
+ ta = Py.Import(name: "pandas_ta");
- Installer.InstallPath = Path.GetFullPath(".");
- Installer.SetupPython().Wait();
- Installer.TryInstallPip();
- Installer.PipInstallModule("pandas-ta");
- //alternative: git+https://github.com/twopirllc/pandas-ta
-
- Runtime.PythonDLL = OStype;
- PythonEngine.Initialize();
- np = Py.Import("numpy");
- ta = Py.Import("pandas_ta");
-
- string[] cols = { "open", "high", "low", "close", "volume" };
- double[,] ary = new double[bars.Count, 5];
- for (int i = 0; i < bars.Count; i++)
- {
- ary[i, 0] = bars.Open[i].v;
- ary[i, 1] = bars.High[i].v;
- ary[i, 2] = bars.Low[i].v;
- ary[i, 3] = bars.Close[i].v;
- ary[i, 4] = bars.Volume[i].v;
- }
- df = ta.DataFrame(data: np.array(ary), index: np.array(bars.Close.t), columns: np.array(cols));
- }
-
- public void Dispose()
- {
+ string[] cols = { "open", "high", "low", "close", "volume" };
+ double[,] ary = new double[bars.Count, 5];
+ for (int i = 0; i < bars.Count; i++) {
+ ary[i, 0] = bars.Open[i].v;
+ ary[i, 1] = bars.High[i].v;
+ ary[i, 2] = bars.Low[i].v;
+ ary[i, 3] = bars.Close[i].v;
+ ary[i, 4] = bars.Volume[i].v;
+ }
+ df = ta.DataFrame(data: np.array(ary), index: np.array(bars.Close.t), columns: np.array(cols));
+ }
+ public void Dispose()
+ {
PythonEngine.Shutdown();
- GC.SuppressFinalize(this);
+ GC.SuppressFinalize(this);
}
- [Fact]
- void HL2()
- {
- var pta = df.ta.hl2(high: df.high, low: df.low);
- Assert.Equal(Math.Round((double)pta.tail(1), 4), Math.Round(bars.HL2.Last().v, 4));
- }
-
- [Fact]
- void HLC3()
- {
- var pta = df.ta.hlc3(high: df.high, low: df.low, close: df.close);
- Assert.Equal(Math.Round((double)pta.tail(1), 4), Math.Round(bars.HLC3.Last().v, 4));
- }
-
- [Fact]
- void OHLC4()
- {
- var pta = df.ta.ohlc4(open: df.open, high: df.high, low: df.low, close: df.close);
- Assert.Equal(Math.Round((double)pta.tail(1), 4), Math.Round(bars.OHLC4.Last().v, 4));
- }
-
- [Fact]
- void MEDIAN()
- {
- MEDIAN_Series QL = new(bars.Close, period);
- var pta = df.ta.median(close: df.close, length: period);
- Assert.Equal(Math.Round((double)pta.tail(1), 4), Math.Round(QL.Last().v, 4));
- }
-
- [Fact]
- void VARIANCE()
- {
- VAR_Series QL = new(bars.Close, period);
- var pta = df.ta.variance(close: df.close, length: period, ddof:0);
- Assert.Equal(Math.Round((double)pta.tail(1), 5), Math.Round(QL.Last().v, 5));
- }
-
- [Fact]
- void SVARIANCE()
- {
- SVAR_Series QL = new(bars.Close, period);
- var pta = df.ta.variance(close: df.close, length: period, ddof: 1);
- Assert.Equal(Math.Round((double)pta.tail(1), 5), Math.Round(QL.Last().v, 5));
- }
-
- [Fact]
- void ADL()
- {
+ [Fact] void ADL() {
ADL_Series QL = new(bars);
var pta = df.ta.ad(high: df.high, low: df.low, close:df.close, volume:df.volume);
- Assert.Equal(Math.Round((double)pta.tail(1), 4), Math.Round(QL.Last().v, 4));
+ Assert.Equal(Math.Round((double)pta.tail(1), digits: digits), Math.Round(QL.Last().v, digits: digits));
}
-
- [Fact]
- void ADOSC()
- {
+ [Fact] void ADOSC() {
ADOSC_Series QL = new(bars);
var pta = df.ta.adosc(high: df.high, low: df.low, close: df.close, volume: df.volume);
- Assert.Equal(Math.Round((double)pta.tail(1), 4), Math.Round(QL.Last().v, 4));
+ Assert.Equal(Math.Round((double)pta.tail(1), digits: digits), Math.Round(QL.Last().v, digits: digits));
}
-
- [Fact]
- void TR()
- {
- TR_Series QL = new(bars);
- var pta = df.ta.true_range(high: df.high, low: df.low, close: df.close);
- Assert.Equal(Math.Round((double)pta.tail(1), 4), Math.Round(QL.Last().v, 4));
- }
-
- [Fact]
- void OBV()
- {
- OBV_Series QL = new(bars);
- var pta = df.ta.obv(close: df.close, volume: df.volume);
- Assert.Equal(Math.Round((double)pta.tail(1), 4), Math.Round(QL.Last().v, 4));
- }
-
- [Fact]
- void ATR()
- {
+ [Fact] void ATR() {
ATR_Series QL = new(bars, period);
var pta = df.ta.atr(high: df.high, low: df.low, close: df.close, length: period);
- Assert.Equal(Math.Round((double)pta.tail(1), 4), Math.Round(QL.Last().v, 4));
+ Assert.Equal(Math.Round((double)pta.tail(1), digits: digits), Math.Round(QL.Last().v, digits: digits));
}
-
- [Fact]
- void RSI()
- {
- RSI_Series QL = new(bars.Close, period);
- var pta = df.ta.rsi(close: df.close, length: period);
- Assert.Equal(Math.Round((double)pta.tail(1), 4), Math.Round(QL.Last().v, 4));
+ [Fact] void BIAS() {
+ BIAS_Series QL = new(bars.Close, period, false);
+ var pta = df.ta.bias(close: df.close, length: period);
+ Assert.Equal(Math.Round((double)pta.tail(1), digits: digits), Math.Round(QL.Last().v, digits: digits));
}
-
- [Fact]
- void TRIMA()
- {
- // TODO: return length to variable length (period) when Pandas-TA fixes trima
- TRIMA_Series QL = new(bars.Close, 11);
- var pta = df.ta.trima(close: df.close, length: 11);
- Assert.Equal(Math.Round((double)pta.tail(1), 4), Math.Round(QL.Last().v, 4));
+ [Fact] void DEMA() {
+ DEMA_Series QL = new(bars.Close, period, false);
+ var pta = df.ta.dema(close: df.close, length: period);
+ Assert.Equal(Math.Round((double)pta.tail(1), digits: digits), Math.Round(QL.Last().v, digits: digits));
}
-
- [Fact]
- void KAMA()
- {
+ [Fact] void EMA() {
+ EMA_Series QL = new(bars.Close, period, false);
+ var pta = df.ta.ema(close: df.close, length: period);
+ Assert.Equal(Math.Round((double)pta.tail(1), digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] void ENTROPY() {
+ ENTROPY_Series QL = new(bars.Close, period, useNaN: false);
+ var pta = df.ta.entropy(close: df.close, length: period);
+ Assert.Equal(Math.Round((double)pta.tail(1), digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] void HL2() {
+ var pta = df.ta.hl2(high: df.high, low: df.low);
+ Assert.Equal(Math.Round((double)pta.tail(1), digits: digits), Math.Round(bars.HL2.Last().v, digits: digits));
+ }
+ [Fact] void HLC3() {
+ var pta = df.ta.hlc3(high: df.high, low: df.low, close: df.close);
+ Assert.Equal(Math.Round((double)pta.tail(1), digits: digits), Math.Round(bars.HLC3.Last().v, digits: digits));
+ }
+ [Fact] void HMA() {
+ HMA_Series QL = new(bars.Close, period, false);
+ var pta = df.ta.hma(close: df.close, length: period);
+ Assert.Equal(Math.Round((double)pta.tail(1), digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] void KAMA() {
KAMA_Series QL = new(bars.Close, period);
var pta = df.ta.kama(close: df.close, length: period);
- Assert.Equal(Math.Round((double)pta.tail(1), 4), Math.Round(QL.Last().v, 4));
+ Assert.Equal(Math.Round((double)pta.tail(1), digits: digits), Math.Round(QL.Last().v, digits: digits));
}
-
- [Fact]
- void HMA()
- {
- HMA_Series QL = new(bars.Close, period, false);
- var pta = df.ta.hma(close: df.close, length: period);
- Assert.Equal(Math.Round((double)pta.tail(1), 4), Math.Round(QL.Last().v, 4));
- }
-
- [Fact]
- void SMA()
- {
- SMA_Series QL = new(bars.Close, period, false);
- var pta = df.ta.sma(close: df.close, length: period);
- Assert.Equal(Math.Round((double)pta.tail(1), 4), Math.Round(QL.Last().v, 4));
- }
-
- [Fact]
- void EMA()
- {
- EMA_Series QL = new(bars.Close, period, false);
- var pta = df.ta.ema(close: df.close, length: period);
- Assert.Equal(Math.Round((double)pta.tail(1), 4), Math.Round(QL.Last().v, 4));
- }
-
- [Fact]
- void TEMA()
- {
- TEMA_Series QL = new(bars.Close, period, false);
- var pta = df.ta.tema(close: df.close, length: period);
- Assert.Equal(Math.Round((double)pta.tail(1), 7), Math.Round(QL.Last().v, 7));
- }
-
- [Fact]
- void SDEV()
- {
- SDEV_Series QL = new(bars.Close, period, useNaN: false);
- var pta = df.ta.stdev(close: df.close, length: period, ddof: 0);
- Assert.Equal(Math.Round((double)pta.tail(1), 4), Math.Round(QL.Last().v, 4));
+ [Fact] void KURTOSIS() {
+ KURTOSIS_Series QL = new(bars.Close, period, useNaN: false);
+ var pta = df.ta.kurtosis(close: df.close, length: period);
+ Assert.Equal(Math.Round((double)pta.tail(1), digits: digits), Math.Round(QL.Last().v, digits: digits));
}
-
- [Fact]
- void SSDEV()
+ [Fact] void MAD()
{
- SSDEV_Series QL = new(bars.Close, period, useNaN: false);
- var pta = df.ta.stdev(close: df.close, length: period, ddof: 1);
- Assert.Equal(Math.Round((double)pta.tail(1), 4), Math.Round(QL.Last().v, 4));
+ MAD_Series QL = new(bars.Close, period, useNaN: false);
+ var pta = df.ta.mad(close: df.close, length: period);
+ Assert.Equal(Math.Round((double)pta.tail(1), digits: digits), Math.Round(QL.Last().v, digits: digits));
}
-
- [Fact]
- void ZSCORE()
- {
- ZSCORE_Series QL = new(bars.Close, period, useNaN: false);
- var pta = df.ta.zscore(close: df.close, length: period, ddof: 0);
- Assert.Equal(Math.Round((double)pta.tail(1), 4), Math.Round(QL.Last().v, 4));
+ [Fact] void MEDIAN() {
+ MEDIAN_Series QL = new(bars.Close, period);
+ var pta = df.ta.median(close: df.close, length: period);
+ Assert.Equal(Math.Round((double)pta.tail(1), digits: digits), Math.Round(QL.Last().v, digits: digits));
}
-
- [Fact]
- void ENTROPY()
- {
- ENTROPY_Series QL = new(bars.Close, period, useNaN: false);
- var pta = df.ta.entropy(close: df.close, length: period);
- Assert.Equal(Math.Round((double)pta.tail(1), 4), Math.Round(QL.Last().v, 4));
- }
-
- [Fact]
- void WMA()
- {
- WMA_Series QL = new(bars.Close, period, false);
- var pta = df.ta.wma(close: df.close, length: period);
- Assert.Equal(Math.Round((double)pta.tail(1), 4), Math.Round(QL.Last().v, 4));
- }
-
- [Fact]
- void RMA()
- {
+ [Fact] void OBV() {
+ OBV_Series QL = new(bars);
+ var pta = df.ta.obv(close: df.close, volume: df.volume);
+ Assert.Equal(Math.Round((double)pta.tail(1), digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] void OHLC4() {
+ var pta = df.ta.ohlc4(open: df.open, high: df.high, low: df.low, close: df.close);
+ Assert.Equal(Math.Round((double)pta.tail(1), digits: digits), Math.Round(bars.OHLC4.Last().v, digits: digits));
+ }
+ [Fact] void RMA() {
RMA_Series QL = new(bars.Close, period, false);
var pta = df.ta.rma(close: df.close, length: period);
- Assert.Equal(Math.Round((double)pta.tail(1), 4), Math.Round(QL.Last().v, 4));
+ Assert.Equal(Math.Round((double)pta.tail(1), digits: digits), Math.Round(QL.Last().v, digits: digits));
}
-
- [Fact]
- void ZLEMA()
- {
+ [Fact] void RSI() {
+ RSI_Series QL = new(bars.Close, period);
+ var pta = df.ta.rsi(close: df.close, length: period);
+ Assert.Equal(Math.Round((double)pta.tail(1), digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] void SDEV() {
+ SDEV_Series QL = new(bars.Close, period, useNaN: false);
+ var pta = df.ta.stdev(close: df.close, length: period, ddof: 0);
+ Assert.Equal(Math.Round((double)pta.tail(1), digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] void SMA() {
+ SMA_Series QL = new(bars.Close, period, false);
+ var pta = df.ta.sma(close: df.close, length: period);
+ Assert.Equal(Math.Round((double)pta.tail(1), digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] void SSDEV() {
+ SSDEV_Series QL = new(bars.Close, period, useNaN: false);
+ var pta = df.ta.stdev(close: df.close, length: period, ddof: 1);
+ Assert.Equal(Math.Round((double)pta.tail(1), digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] void SVARIANCE() {
+ SVAR_Series QL = new(bars.Close, period);
+ var pta = df.ta.variance(close: df.close, length: period, ddof: 1);
+ Assert.Equal(Math.Round((double)pta.tail(1), digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] void T3() {
+ T3_Series QL = new(source: bars.Close, period: period, vfactor: 0.7, useNaN: false);
+ var pta = df.ta.t3(close: df.close, length: period, a: 0.7);
+ Assert.Equal(Math.Round((double)pta.tail(1), digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] void TEMA() {
+ TEMA_Series QL = new(bars.Close, period, false);
+ var pta = df.ta.tema(close: df.close, length: period);
+ Assert.Equal(Math.Round((double)pta.tail(1), digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] void TR() {
+ TR_Series QL = new(bars);
+ var pta = df.ta.true_range(high: df.high, low: df.low, close: df.close);
+ Assert.Equal(Math.Round((double)pta.tail(1), digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] void TRIMA() {
+ // TODO: return length to variable length (period) when Pandas-TA fixes trima to calculate even periods right
+ TRIMA_Series QL = new(bars.Close, 11);
+ var pta = df.ta.trima(close: df.close, length: 11);
+ Assert.Equal(Math.Round((double)pta.tail(1), digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] void VARIANCE() {
+ VAR_Series QL = new(bars.Close, period);
+ var pta = df.ta.variance(close: df.close, length: period, ddof:0);
+ Assert.Equal(Math.Round((double)pta.tail(1), digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] void WMA() {
+ WMA_Series QL = new(bars.Close, period, false);
+ var pta = df.ta.wma(close: df.close, length: period);
+ Assert.Equal(Math.Round((double)pta.tail(1), digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] void ZLEMA() {
ZLEMA_Series QL = new(bars.Close, period, false);
var pta = df.ta.zlma(close: df.close, length: period);
- Assert.Equal(Math.Round((double)pta.tail(1), 4), Math.Round(QL.Last().v, 4));
+ Assert.Equal(Math.Round((double)pta.tail(1), digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] void ZSCORE() {
+ ZSCORE_Series QL = new(bars.Close, period, useNaN: false);
+ var pta = df.ta.zscore(close: df.close, length: period, ddof: 0);
+ Assert.Equal(Math.Round((double)pta.tail(1), digits: digits), Math.Round(QL.Last().v, digits: digits));
}
- [Fact]
- void DEMA()
- {
- DEMA_Series QL = new(bars.Close, period, false);
- var pta = df.ta.dema(close: df.close, length: period);
- Assert.Equal(Math.Round((double)pta.tail(1), 4), Math.Round(QL.Last().v, 4));
- }
-
- [Fact]
- void BIAS()
- {
- BIAS_Series QL = new(bars.Close, period, false);
- var pta = df.ta.bias(close: df.close, length: period);
- Assert.Equal(Math.Round((double)pta.tail(1), 4), Math.Round(QL.Last().v, 4));
- }
-
- [Fact]
- void KURTOSIS()
- {
- KURTOSIS_Series QL = new(bars.Close, period, useNaN: false);
- var pta = df.ta.kurtosis(close: df.close, length: period);
- Assert.Equal(Math.Round((double)pta.tail(1), 4), Math.Round(QL.Last().v, 4));
- }
-
- [Fact]
- void MAD()
- {
- MAD_Series QL = new(bars.Close, period, useNaN: false);
- var pta = df.ta.mad(close: df.close, length: period);
- Assert.Equal(Math.Round((double)pta.tail(1), 4), Math.Round(QL.Last().v, 4));
- }
}
\ No newline at end of file
diff --git a/Tests/Validations/Skender_Stock.cs b/Tests/Validations/Skender_Stock.cs
index 3e173138..418f9611 100644
--- a/Tests/Validations/Skender_Stock.cs
+++ b/Tests/Validations/Skender_Stock.cs
@@ -4,324 +4,201 @@ using Skender.Stock.Indicators;
using Xunit;
namespace Validations;
-public class Skender_Stock
-{
- private readonly GBM_Feed bars;
- private readonly Random rnd = new();
- private readonly int period;
- private readonly IEnumerable quotes;
+public class Skender_Stock {
+ private readonly GBM_Feed bars;
+ private readonly Random rnd = new();
+ private readonly int period, digits;
+ private readonly IEnumerable quotes;
- public Skender_Stock()
- {
- bars = new(Bars: 5000, Volatility: 0.7, Drift: 0.0);
- period = rnd.Next(28) + 3;
- quotes = bars.Select(
- q => new Quote
- {
- Date = q.t,
- Open = (decimal)q.o,
- High = (decimal)q.h,
- Low = (decimal)q.l,
- Close = (decimal)q.c,
- Volume = (decimal)q.v
+ public Skender_Stock() {
+ bars = new(Bars: 5000, Volatility: 0.8, Drift: 0.0);
+ period = rnd.Next(28) + 3;
+ digits = 4; //minimizing rounding errors in type conversions
+
+ quotes = bars.Select(q => new Quote {
+ Date = q.t,
+ Open = (decimal)q.o,
+ High = (decimal)q.h,
+ Low = (decimal)q.l,
+ Close = (decimal)q.c,
+ Volume = (decimal)q.v
});
- }
-
- [Fact]
- public void SMA()
- {
- SMA_Series QL = new(bars.Close, period, false);
- var SK = quotes.GetSma(period);
-
- Assert.Equal(Math.Round((double)SK.Last().Sma!, 6), Math.Round(QL.Last().v, 6));
- }
-
- [Fact]
- public void EMA()
- {
- EMA_Series QL = new(bars.Close, period, false);
- var SK = quotes.GetEma(period);
-
- Assert.Equal(Math.Round((double)SK.Last().Ema!, 6), Math.Round(QL.Last().v, 6));
- }
- [Fact]
- public void WMA()
- {
- WMA_Series QL = new(bars.Close, period, false);
- var SK = quotes.GetWma(period);
-
- Assert.Equal(Math.Round((double)SK.Last().Wma!, 6), Math.Round(QL.Last().v, 6));
- }
-
- [Fact]
- public void DEMA()
- {
- DEMA_Series QL = new(bars.Close, period, false);
- var SK = quotes.GetDema(period);
-
- Assert.Equal(Math.Round((double)SK.Last().Dema!, 6), Math.Round(QL.Last().v, 6));
- }
-
- [Fact]
- public void TEMA()
- {
- TEMA_Series QL = new(bars.Close, period, false);
- var SK = quotes.GetTema(period);
-
- Assert.Equal(Math.Round((double)SK.Last().Tema!, 6), Math.Round(QL.Last().v, 6));
- }
-
-
- [Fact]
- public void MAMA() {
+ }
+ [Fact] public void ADL() {
+ ADL_Series QL = new(bars, false);
+ var SK = quotes.GetAdl();
+ Assert.Equal(Math.Round(SK.Last().Adl!, digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void ALMA() {
+ ALMA_Series QL = new(bars.Close, period, useNaN: false);
+ var SK = quotes.GetAlma(period);
+ Assert.Equal(Math.Round((double)SK.Last().Alma!, digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void ATR() {
+ ATR_Series QL = new(bars, period, false);
+ var SK = quotes.GetAtr(period);
+ Assert.Equal(Math.Round((double)SK.Last().Atr!, digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void ATRP() {
+ ATRP_Series QL = new(bars, period, false);
+ var SK = quotes.GetAtr(period);
+ Assert.Equal(Math.Round((double)SK.Last().Atrp!, digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void BBANDS() {
+ BBANDS_Series QL = new(bars.Close, period, 2.0, useNaN: false);
+ var SK = quotes.GetBollingerBands(period, 2.0);
+ Assert.Equal(Math.Round((double)SK.Last().Sma!, digits: digits), Math.Round(QL.Mid.Last().v, digits: digits));
+ Assert.Equal(Math.Round((double)SK.Last().UpperBand!, digits: digits), Math.Round(QL.Upper.Last().v, digits: digits));
+ Assert.Equal(Math.Round((double)SK.Last().LowerBand!, digits: digits), Math.Round(QL.Lower.Last().v, digits: digits));
+ Assert.Equal(Math.Round((double)SK.Last().Width!, digits: digits), Math.Round(QL.Bandwidth.Last().v, digits: digits));
+ Assert.Equal(Math.Round((double)SK.Last().PercentB!, digits: digits), Math.Round(QL.PercentB.Last().v, digits: digits));
+ Assert.Equal(Math.Round((double)SK.Last().ZScore!, digits: digits), Math.Round(QL.Zscore.Last().v, digits: digits));
+ }
+ [Fact] public void CCI() {
+ CCI_Series QL = new(bars, period, false);
+ var SK = quotes.GetCci(period);
+ Assert.Equal(Math.Round((double)SK.Last().Cci!, digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void CORR() {
+ CORR_Series QL = new(bars.High, bars.Low, period, false);
+ var SK = quotes.Use(CandlePart.High).GetCorrelation(quotes.Use(CandlePart.Low), period);
+ Assert.Equal(Math.Round((double)SK.Last().Correlation!, digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void COVAR() {
+ COVAR_Series QL = new(bars.High, bars.Low, period, false);
+ var SK = quotes.Use(CandlePart.High).GetCorrelation(quotes.Use(CandlePart.Low), period);
+ Assert.Equal(Math.Round((double)SK.Last().Covariance!, digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void DEMA() {
+ DEMA_Series QL = new(bars.Close, period, false);
+ var SK = quotes.GetDema(period);
+ Assert.Equal(Math.Round((double)SK.Last().Dema!, digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void EMA() {
+ EMA_Series QL = new(bars.Close, period, false);
+ var SK = quotes.GetEma(period);
+ Assert.Equal(Math.Round((double)SK.Last().Ema!, digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void HL2() {
+ TSeries QL = bars.HL2;
+ var SK = quotes.GetBaseQuote(CandlePart.HL2);
+ Assert.Equal(Math.Round(SK.Last().Value!, digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void HLC3() {
+ TSeries QL = bars.HLC3;
+ var SK = quotes.GetBaseQuote(CandlePart.HLC3);
+ Assert.Equal(Math.Round(SK.Last().Value!, digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void HMA() {
+ HMA_Series QL = new(bars.Close, period, useNaN: false);
+ var SK = quotes.GetHma(period);
+ Assert.Equal(Math.Round((double)SK.Last().Hma!, digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void KAMA() {
+ KAMA_Series QL = new(bars.Close, period, useNaN: false);
+ var SK = quotes.GetKama(period);
+ Assert.Equal(Math.Round((double)SK.Last().Kama!, digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void LINREG() {
+ LINREG_Series QL = new(bars.Close, period, useNaN: false);
+ var SK = quotes.GetSlope(period);
+ Assert.Equal(Math.Round((double)SK.Last().Slope!, digits: digits), Math.Round(QL.Last().v, digits: digits));
+ Assert.Equal(Math.Round((double)SK.Last().Intercept!, digits: digits), Math.Round(QL.Intercept.Last().v, digits: digits));
+ Assert.Equal(Math.Round((double)SK.Last().RSquared!, digits: digits), Math.Round(QL.RSquared.Last().v, digits: digits));
+ Assert.Equal(Math.Round((double)SK.Last().StdDev!, digits: digits), Math.Round(QL.StdDev.Last().v, digits: digits));
+ }
+ [Fact] public void MACD() {
+ MACD_Series QL = new(bars.Close, 26, 12, 9, useNaN: false);
+ var SK = quotes.GetMacd(12, 26, 9);
+ Assert.Equal(Math.Round((double)SK.Last().Macd!, digits: digits), Math.Round(QL.Last().v, digits: digits));
+ Assert.Equal(Math.Round((double)SK.Last().Signal!, digits: digits), Math.Round(QL.Signal.Last().v, digits: digits));
+ }
+ [Fact] public void MAD() {
+ MAD_Series QL = new(bars.Close, period, false);
+ var SK = quotes.GetSmaAnalysis(period);
+ Assert.Equal(Math.Round((double)SK.Last().Mad!, digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void MAMA() {
MAMA_Series QL = new(bars.HL2, fastlimit: 0.5, slowlimit: 0.05);
var SK = quotes.GetMama(fastLimit: 0.5, slowLimit: 0.05);
+ Assert.Equal(Math.Round((double)SK.Last().Mama!, digits: digits), Math.Round(QL.Last().v, digits: digits));
+ Assert.Equal(Math.Round((double)SK.Last().Fama!, digits: digits), Math.Round(QL.Fama.Last().v, digits: digits));
+ }
+ [Fact] public void MAPE() {
+ MAPE_Series QL = new(bars.Close, period, false);
+ var SK = quotes.GetSmaAnalysis(period);
+ Assert.Equal(Math.Round((double)SK.Last().Mape!, digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void MSE() {
+ MSE_Series QL = new(bars.Close, period, false);
+ var SK = quotes.GetSmaAnalysis(period);
+ Assert.Equal(Math.Round((double)SK.Last().Mse!, digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void OBV() {
+ OBV_Series QL = new(bars, period, false);
+ var SK = quotes.GetObv(period);
+ // adding volume[0] to OBV to pass the test and keep compatibility with TA-LIB
+ Assert.Equal(Math.Round(SK.Last().Obv! + (double)quotes.First().Volume!, digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void OC2() {
+ TSeries QL = bars.OC2;
+ var SK = quotes.GetBaseQuote(CandlePart.OC2);
+ Assert.Equal(Math.Round(SK.Last().Value!, digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void OHL3() {
+ TSeries QL = bars.OHL3;
+ var SK = quotes.GetBaseQuote(CandlePart.OHL3);
+ Assert.Equal(Math.Round(SK.Last().Value!, digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void OHLC4() {
+ TSeries QL = bars.OHLC4;
+ var SK = quotes.GetBaseQuote(CandlePart.OHLC4);
+ Assert.Equal(Math.Round(SK.Last().Value!, digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void RSI() {
+ RSI_Series QL = new(bars.Close, period, useNaN: false);
+ var SK = quotes.GetRsi(period);
+ Assert.Equal(Math.Round((double)SK.Last().Rsi!, digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void SDEV() {
+ SDEV_Series QL = new(bars.Close, period, useNaN: false);
+ var SK = quotes.GetStdDev(period);
+ Assert.Equal(Math.Round((double)SK.Last().StdDev!, digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void SMA() {
+ SMA_Series QL = new(bars.Close, period, false);
+ var SK = quotes.GetSma(period);
+ Assert.Equal(Math.Round((double)SK.Last().Sma!, digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void SMMA() {
+ SMMA_Series QL = new(bars.Close, period, useNaN: false);
+ var SK = quotes.GetSmma(period);
+ Assert.Equal(Math.Round((double)SK.Last().Smma!, digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void T3() {
+ T3_Series QL = new(source: bars.Close, period, vfactor: 0.7, false);
+ var SK = quotes.GetT3(lookbackPeriods: period, volumeFactor: 0.7);
+ Assert.Equal(Math.Round((double)SK.Last().T3!, digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void TEMA() {
+ TEMA_Series QL = new(bars.Close, period, false);
+ var SK = quotes.GetTema(period);
+ Assert.Equal(Math.Round((double)SK.Last().Tema!, digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void TR() {
+ TR_Series QL = new(bars, useNaN: false);
+ var SK = quotes.GetTr();
+ Assert.Equal(Math.Round((double)SK.Last().Tr!, digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void WMA() {
+ WMA_Series QL = new(bars.Close, period, false);
+ var SK = quotes.GetWma(period);
+ Assert.Equal(Math.Round((double)SK.Last().Wma!, digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void ZSCORE() {
+ ZSCORE_Series QL = new(bars.Close, period, useNaN: false);
+ var SK = quotes.GetStdDev(period);
+ Assert.Equal(Math.Round((double)SK.Last().ZScore!, digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
- Assert.Equal(Math.Round((double)SK.Last().Mama!, 6), Math.Round(QL.Last().v, 6));
- }
-
- [Fact]
- public void MAD()
- {
- MAD_Series QL = new(bars.Close, period, false);
- var SK = quotes.GetSmaAnalysis(period);
-
- Assert.Equal(Math.Round((double)SK.Last().Mad!, 6), Math.Round(QL.Last().v, 6));
- }
-
- [Fact]
- public void MSE()
- {
- MSE_Series QL = new(bars.Close, period, false);
- var SK = quotes.GetSmaAnalysis(period);
-
- Assert.Equal(Math.Round((double)SK.Last().Mse!, 6), Math.Round(QL.Last().v, 6));
- }
-
- [Fact]
- public void MAPE()
- {
- MAPE_Series QL = new(bars.Close, period, false);
- var SK = quotes.GetSmaAnalysis(period);
-
- Assert.Equal(Math.Round((double)SK.Last().Mape!, 6), Math.Round(QL.Last().v, 6));
- }
-
- [Fact]
- public void COVAR()
- {
- COVAR_Series QL = new(bars.High, bars.Low, period, false);
- var SK = quotes.Use(CandlePart.High).GetCorrelation(quotes.Use(CandlePart.Low), period);
-
- Assert.Equal(Math.Round((double)SK.Last().Covariance!, 6), Math.Round(QL.Last().v, 6));
- }
-
- [Fact]
- public void CORR()
- {
- CORR_Series QL = new(bars.High, bars.Low, period, false);
- var SK = quotes.Use(CandlePart.High).GetCorrelation(quotes.Use(CandlePart.Low), period);
-
- Assert.Equal(Math.Round((double)SK.Last().Correlation!, 6), Math.Round(QL.Last().v, 6));
- }
-
- [Fact]
- public void ATR()
- {
- ATR_Series QL = new(bars, period, false);
- var SK = quotes.GetAtr(period);
-
- Assert.Equal(Math.Round((double)SK.Last().Atr!, 6), Math.Round(QL.Last().v, 6));
- }
-
- [Fact]
- public void OBV()
- {
- OBV_Series QL = new(bars, period, false);
- var SK = quotes.GetObv(period);
-
- // adding volume[0] to OBV to pass the test and keep compatibility with TA-LIB
- Assert.Equal(Math.Round(SK.Last().Obv! + (double)quotes.First().Volume!, 5),
- Math.Round(QL.Last().v, 5));
- }
-
- [Fact]
- public void ADL()
- {
- ADL_Series QL = new(bars, false);
- var SK = quotes.GetAdl();
-
- Assert.Equal(Math.Round(SK.Last().Adl!, 5), Math.Round(QL.Last().v, 5));
- }
-
- [Fact]
- public void CCI()
- {
- CCI_Series QL = new(bars, period, false);
- var SK = quotes.GetCci(period);
-
- Assert.Equal(Math.Round((double)SK.Last().Cci!, 6), Math.Round(QL.Last().v, 6));
- }
-
- [Fact]
- public void ATRP()
- {
- ATRP_Series QL = new(bars, period, false);
- var SK = quotes.GetAtr(period);
-
- Assert.Equal(Math.Round((double)SK.Last().Atrp!, 6), Math.Round(QL.Last().v, 6));
- }
-
- [Fact]
- public void KAMA()
- {
- KAMA_Series QL = new(bars.Close, period, useNaN: false);
- var SK = quotes.GetKama(period);
-
- Assert.Equal(Math.Round((double)SK.Last().Kama!, 6), Math.Round(QL.Last().v, 6));
- }
-
- [Fact]
- public void HMA()
- {
- HMA_Series QL = new(bars.Close, period, useNaN: false);
- var SK = quotes.GetHma(period);
-
- Assert.Equal(Math.Round((double)SK.Last().Hma!, 6), Math.Round(QL.Last().v, 6));
- }
-
- [Fact]
- public void SMMA()
- {
- SMMA_Series QL = new(bars.Close, period, useNaN: false);
- var SK = quotes.GetSmma(period);
-
- Assert.Equal(Math.Round((double)SK.Last().Smma!, 6), Math.Round(QL.Last().v, 6));
- }
-
- [Fact]
- public void MACD()
- {
- MACD_Series QL = new(bars.Close, 26, 12, 9, useNaN: false);
- var SK = quotes.GetMacd(12, 26, 9);
-
- Assert.Equal(Math.Round((double)SK.Last().Macd!, 6), Math.Round(QL.Last().v, 6));
- Assert.Equal(Math.Round((double)SK.Last().Signal!, 6), Math.Round(QL.Signal.Last().v, 6));
- }
-
- [Fact]
- public void BBANDS()
- {
- BBANDS_Series QL = new(bars.Close, period, 2.0, useNaN: false);
- var SK = quotes.GetBollingerBands(period, 2.0);
-
- Assert.Equal(Math.Round((double)SK.Last().Sma!, 6), Math.Round(QL.Mid.Last().v, 6));
- Assert.Equal(Math.Round((double)SK.Last().UpperBand!, 6), Math.Round(QL.Upper.Last().v, 6));
- Assert.Equal(Math.Round((double)SK.Last().LowerBand!, 6), Math.Round(QL.Lower.Last().v, 6));
- Assert.Equal(Math.Round((double)SK.Last().Width!, 6), Math.Round(QL.Bandwidth.Last().v, 6));
- Assert.Equal(Math.Round((double)SK.Last().PercentB!, 6), Math.Round(QL.PercentB.Last().v, 6));
- Assert.Equal(Math.Round((double)SK.Last().ZScore!, 6), Math.Round(QL.Zscore.Last().v, 6));
- }
-
- [Fact]
- public void RSI()
- {
- RSI_Series QL = new(bars.Close, period, useNaN: false);
- var SK = quotes.GetRsi(period);
-
- Assert.Equal(Math.Round((double)SK.Last().Rsi!, 6), Math.Round(QL.Last().v, 6));
- }
-
- [Fact]
- public void ALMA()
- {
- ALMA_Series QL = new(bars.Close, period, useNaN: false);
- var SK = quotes.GetAlma(period);
-
- Assert.Equal(Math.Round((double)SK.Last().Alma!, 6), Math.Round(QL.Last().v, 6));
- }
-
- [Fact]
- public void SDEV()
- {
- SDEV_Series QL = new(bars.Close, period, useNaN: false);
- var SK = quotes.GetStdDev(period);
-
- Assert.Equal(Math.Round((double)SK.Last().StdDev!, 6), Math.Round(QL.Last().v, 6));
- }
-
- [Fact]
- public void ZSCORE()
- {
- ZSCORE_Series QL = new(bars.Close, period, useNaN: false);
- var SK = quotes.GetStdDev(period);
-
- Assert.Equal(Math.Round((double)SK.Last().ZScore!, 6), Math.Round(QL.Last().v, 6));
- }
-
- [Fact]
- public void LINREG()
- {
- LINREG_Series QL = new(bars.Close, period, useNaN: false);
- var SK = quotes.GetSlope(period);
-
- Assert.Equal(Math.Round((double)SK.Last().Slope!, 6), Math.Round(QL.Last().v, 6));
- Assert.Equal(Math.Round((double)SK.Last().Intercept!, 6), Math.Round(QL.Intercept.Last().v, 6));
- Assert.Equal(Math.Round((double)SK.Last().RSquared!, 6), Math.Round(QL.RSquared.Last().v, 6));
- Assert.Equal(Math.Round((double)SK.Last().StdDev!, 6), Math.Round(QL.StdDev.Last().v, 6));
- }
-
- [Fact]
- public void TR()
- {
- TR_Series QL = new(bars, useNaN: false);
- var SK = quotes.GetTr();
-
- Assert.Equal(Math.Round((double)SK.Last().Tr!, 6), Math.Round(QL.Last().v, 6));
- }
-
- [Fact]
- public void HL2()
- {
- TSeries QL = bars.HL2;
- var SK = quotes.GetBaseQuote(CandlePart.HL2);
-
- Assert.Equal(Math.Round(SK.Last().Value!, 6), Math.Round(QL.Last().v, 6));
- }
-
- [Fact]
- public void OC2()
- {
- TSeries QL = bars.OC2;
- var SK = quotes.GetBaseQuote(CandlePart.OC2);
-
- Assert.Equal(Math.Round(SK.Last().Value!, 6), Math.Round(QL.Last().v, 6));
- }
-
- [Fact]
- public void HLC3()
- {
- TSeries QL = bars.HLC3;
- var SK = quotes.GetBaseQuote(CandlePart.HLC3);
-
- Assert.Equal(Math.Round(SK.Last().Value!, 6), Math.Round(QL.Last().v, 6));
- }
-
- [Fact]
- public void OHL3()
- {
- TSeries QL = bars.OHL3;
- var SK = quotes.GetBaseQuote(CandlePart.OHL3);
-
- Assert.Equal(Math.Round(SK.Last().Value!, 6), Math.Round(QL.Last().v, 6));
- }
-
- [Fact]
- public void OHLC4()
- {
- TSeries QL = bars.OHLC4;
- var SK = quotes.GetBaseQuote(CandlePart.OHLC4);
-
- Assert.Equal(Math.Round((double)SK.Last().Value!, 6), Math.Round(QL.Last().v, 6));
- }
}
diff --git a/Tests/Validations/TA_LIB.cs b/Tests/Validations/TA_LIB.cs
index 3e803230..e6e87b71 100644
--- a/Tests/Validations/TA_LIB.cs
+++ b/Tests/Validations/TA_LIB.cs
@@ -1,330 +1,208 @@
-using Xunit;
-using System;
-using TALib;
-using QuanTAlib;
-
-namespace Validations;
-public class TA_LIB
-{
- private readonly GBM_Feed bars;
- private readonly Random rnd = new();
- private readonly int period;
- private readonly double[] TALIB;
- private readonly double[] TALIB2;
- private readonly double[] inopen;
- private readonly double[] inhigh;
- private readonly double[] inlow;
- private readonly double[] inclose;
- private readonly double[] involume;
-
- public TA_LIB()
- {
- bars = new(5000);
- period = rnd.Next(28) + 3;
- TALIB = new double[bars.Count];
- TALIB2 = new double[bars.Count];
- inopen = bars.Open.v.ToArray();
- inhigh = bars.High.v.ToArray();
- inlow = bars.Low.v.ToArray();
- inclose = bars.Close.v.ToArray();
- involume = bars.Volume.v.ToArray();
- }
-
- /////////////////////////////////////////
-
- [Fact]
- public void ADD()
- {
- ADD_Series QL = new(bars.Open, bars.Close);
- Core.Add(inopen, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
-
- Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
- }
-
- [Fact]
- public void SUB()
- {
- SUB_Series QL = new(bars.Open, bars.Close);
- Core.Sub(inopen, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
-
- Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
- }
-
- [Fact]
- public void MUL()
- {
- MUL_Series QL = new(bars.Open, bars.Close);
- Core.Mult(inopen, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
-
- Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
- }
-
- [Fact]
- public void DIV()
- {
- DIV_Series QL = new(bars.Open, bars.Close);
- Core.Div(inopen, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
-
- Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
- }
-
- [Fact]
- public void CORR()
- {
- CORR_Series QL = new(bars.Open, bars.Close, period);
- Core.Correl(inopen, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, optInTimePeriod: period);
-
- Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
- }
-
- [Fact]
- public void SDEV()
- {
- SDEV_Series QL = new(bars.Close, period, false);
- Core.StdDev(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
-
- Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
- }
-
- [Fact]
- public void SMA()
- {
- SMA_Series QL = new(bars.Close, period, false);
- Core.Sma(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
-
- Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
- }
-
- [Fact]
- public void SUM()
- {
- SUM_Series QL = new(bars.Close, period, false);
- Core.Sum(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
-
- Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
- }
-
- [Fact]
- public void MIDPRICE()
- {
- MIDPRICE_Series QL = new(bars, period, false);
- Core.MidPrice(inhigh, inlow, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
-
- Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
- }
-
-
- [Fact]
- public void VAR()
- {
- VAR_Series QL = new(bars.Close, period, false);
- Core.Var(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
-
- Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 4, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 4));
- }
-
- [Fact]
- public void MIDPOINT()
- {
- MIDPOINT_Series QL = new(bars.Close, period, false);
- Core.MidPoint(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
-
- Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
- }
-
-
- [Fact]
- public void MAMA() {
- MAMA_Series QL = new(bars.Close, fastlimit: 0.5, slowlimit: 0.05);
- Core.Mama(inReal: inclose, startIdx: 0, endIdx: bars.Count - 1, outMama: TALIB, outFama: TALIB2, outBegIdx: out int outBegIdx, outNbElement: out _, optInFastLimit: 0.5, optInSlowLimit: 0.05);
-
- Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
- }
-
- [Fact]
- public void TRIMA()
- {
- TRIMA_Series QL = new(bars.Close, period, false);
- Core.Trima(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
-
- Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
- }
-
- [Fact]
- public void EMA()
- {
- EMA_Series QL = new(bars.Close, period, false);
- Core.Ema(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
-
- Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
- }
-
- [Fact]
- public void WMA()
- {
- WMA_Series QL = new(bars.Close, period, false);
- Core.Wma(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
-
- Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
- }
-
- [Fact]
- public void DEMA()
- {
- DEMA_Series QL = new(bars.Close, period, false);
- Core.Dema(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
-
- Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
- }
-
- [Fact]
- public void TEMA()
- {
- TEMA_Series QL = new(bars.Close, period, false);
- Core.Tema(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
-
- Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
- }
-
- [Fact]
- public void MAX()
- {
- MAX_Series QL = new(bars.Close, period, false);
- Core.Max(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
-
- Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
- }
-
- [Fact]
- public void MIN()
- {
- MIN_Series QL = new(bars.Close, period, false);
- Core.Min(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
-
- Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
- }
-
- [Fact]
- public void ADL()
- {
- ADL_Series QL = new(bars, false);
- Core.Ad(inhigh, inlow, inclose, involume, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
-
- Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
- }
-
- [Fact]
- public void OBV()
- {
- OBV_Series QL = new(bars, period, false);
- Core.Obv(inclose, involume, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
-
- Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
- }
-
- [Fact]
- public void ADOSC()
- {
- ADOSC_Series QL = new(bars, false);
- Core.AdOsc(inhigh, inlow, inclose, involume, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
-
- Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
- }
-
- [Fact]
- public void ATR()
- {
- ATR_Series QL = new(bars, period, false);
- Core.Atr(inhigh, inlow, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
-
- Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
- }
-
- [Fact]
- public void CCI()
- {
- CCI_Series QL = new(bars, period, false);
- Core.Cci(inhigh, inlow, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
-
- Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
- }
-
- [Fact]
- public void RSI()
- {
- RSI_Series QL = new(bars.Close, period, false);
- Core.Rsi(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
-
- Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
- }
-
- [Fact]
- public void TR()
- {
- TR_Series QL = new(bars, false);
- Core.TRange(inhigh, inlow, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
-
- Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
- }
-
- [Fact]
- public void MACD()
- {
- double[] macdSignal = new double[bars.Count];
- double[] macdHist = new double[bars.Count];
- MACD_Series QL = new(bars.Close, slow: 26, fast: 12, signal: 9, false);
- Core.Macd(inclose, 0, bars.Count - 1, outMacd: TALIB, outMacdSignal: macdSignal, outMacdHist: macdHist, out int outBegIdx, out _);
- Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
- Assert.Equal(Math.Round(macdSignal[macdSignal.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Signal.Last().v, 6, MidpointRounding.AwayFromZero));
- }
-
- [Fact]
- public void BBANDS()
- {
- double[] outMiddle = new double[bars.Count];
- double[] outUpper = new double[bars.Count];
- double[] outLower = new double[bars.Count];
- BBANDS_Series QL = new(bars.Close, period: 26, multiplier: 2.0, false);
- Core.Bbands(inclose, 0, 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], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Upper.Last().v, 6, MidpointRounding.AwayFromZero));
- Assert.Equal(Math.Round(outMiddle[outMiddle.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Mid.Last().v, 6, MidpointRounding.AwayFromZero));
- Assert.Equal(Math.Round(outLower[outLower.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Lower.Last().v, 6, MidpointRounding.AwayFromZero));
- }
-
- [Fact]
- public void HL2()
- {
- TSeries QL = bars.HL2;
- Core.MedPrice(inhigh, inlow, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
-
- Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
- }
-
- [Fact]
- public void HLC3()
- {
- TSeries QL = bars.HLC3;
- Core.TypPrice(inhigh, inlow, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
-
- Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
- }
-
- [Fact]
- public void OHLC4()
- {
- TSeries QL = bars.OHLC4;
- Core.AvgPrice(inopen, inhigh, inlow, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
-
- Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
- }
-
- [Fact]
- public void HLCC4()
- {
- TSeries QL = bars.HLCC4;
- Core.WclPrice(inhigh, inlow, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
-
- Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
- }
-
-}
+using Xunit;
+using System;
+using TALib;
+using QuanTAlib;
+
+namespace Validations;
+public class Ta_Lib
+{
+ private readonly GBM_Feed bars;
+ private readonly Random rnd = new();
+ private readonly int period, digits;
+ private readonly double[] TALIB;
+ private readonly double[] TALIB2;
+ private readonly double[] inopen;
+ private readonly double[] inhigh;
+ private readonly double[] inlow;
+ private readonly double[] inclose;
+ private readonly double[] involume;
+
+ public Ta_Lib() {
+ bars = new(Bars: 5000, Volatility: 0.8, Drift: 0.0);
+ period = rnd.Next(28) + 3;
+ digits = 6;
+
+ TALIB = new double[bars.Count];
+ TALIB2 = new double[bars.Count];
+ inopen = bars.Open.v.ToArray();
+ inhigh = bars.High.v.ToArray();
+ inlow = bars.Low.v.ToArray();
+ inclose = bars.Close.v.ToArray();
+ involume = bars.Volume.v.ToArray();
+ }
+
+ [Fact] public void ADD() {
+ ADD_Series QL = new(bars.Open, bars.Close);
+ Core.Add(inopen, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
+ Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void ADL() {
+ ADL_Series QL = new(bars, false);
+ Core.Ad(inhigh, inlow, inclose, involume, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
+ Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void ADOSC() {
+ ADOSC_Series QL = new(bars, false);
+ Core.AdOsc(inhigh, inlow, inclose, involume, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
+ Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void ATR() {
+ ATR_Series QL = new(bars, period, false);
+ Core.Atr(inhigh, inlow, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
+ Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void BBANDS() {
+ double[] outMiddle = new double[bars.Count];
+ double[] outUpper = new double[bars.Count];
+ double[] outLower = new double[bars.Count];
+ BBANDS_Series QL = new(bars.Close, period: 26, multiplier: 2.0, false);
+ Core.Bbands(inclose, 0, 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], digits: digits), Math.Round(QL.Upper.Last().v, digits: digits));
+ Assert.Equal(Math.Round(outMiddle[outMiddle.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Mid.Last().v, digits: digits));
+ Assert.Equal(Math.Round(outLower[outLower.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Lower.Last().v, digits: digits));
+ }
+ [Fact] public void CCI() {
+ CCI_Series QL = new(bars, period, false);
+ Core.Cci(inhigh, inlow, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
+ Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void CORR() {
+ CORR_Series QL = new(bars.Open, bars.Close, period);
+ Core.Correl(inopen, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, optInTimePeriod: period);
+ Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void DEMA() {
+ DEMA_Series QL = new(bars.Close, period, false);
+ Core.Dema(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
+ Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void DIV() {
+ DIV_Series QL = new(bars.Open, bars.Close);
+ Core.Div(inopen, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
+ Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void EMA() {
+ EMA_Series QL = new(bars.Close, period, false);
+ Core.Ema(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
+ Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void HL2() {
+ TSeries QL = bars.HL2;
+ Core.MedPrice(inhigh, inlow, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
+ Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void HLC3() {
+ TSeries QL = bars.HLC3;
+ Core.TypPrice(inhigh, inlow, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
+ Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void HLCC4() {
+ TSeries QL = bars.HLCC4;
+ Core.WclPrice(inhigh, inlow, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
+ Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void MACD() {
+ double[] macdSignal = new double[bars.Count];
+ double[] macdHist = new double[bars.Count];
+ MACD_Series QL = new(bars.Close, slow: 26, fast: 12, signal: 9, false);
+ Core.Macd(inclose, 0, bars.Count - 1, outMacd: TALIB, outMacdSignal: macdSignal, outMacdHist: macdHist, out int outBegIdx, out _);
+ Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Last().v, digits: digits));
+ Assert.Equal(Math.Round(macdSignal[macdSignal.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Signal.Last().v, digits: digits));
+ }
+ [Fact] public void MAMA() {
+ MAMA_Series QL = new(bars.Close, fastlimit: 0.5, slowlimit: 0.05);
+ Core.Mama(inReal: inclose, startIdx: 0, endIdx: bars.Count - 1, outMama: TALIB, outFama: TALIB2, outBegIdx: out int outBegIdx, outNbElement: out _, optInFastLimit: 0.5, optInSlowLimit: 0.05);
+ Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void MAX() {
+ MAX_Series QL = new(bars.Close, period, false);
+ Core.Max(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
+ Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void MIDPOINT() {
+ MIDPOINT_Series QL = new(bars.Close, period, false);
+ Core.MidPoint(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
+ Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void MIDPRICE() {
+ MIDPRICE_Series QL = new(bars, period, false);
+ Core.MidPrice(inhigh, inlow, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
+ Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void MIN() {
+ MIN_Series QL = new(bars.Close, period, false);
+ Core.Min(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
+ Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void MUL() {
+ MUL_Series QL = new(bars.Open, bars.Close);
+ Core.Mult(inopen, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
+ Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void OBV() {
+ OBV_Series QL = new(bars, period, false);
+ Core.Obv(inclose, involume, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
+ Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void OHLC4() {
+ TSeries QL = bars.OHLC4;
+ Core.AvgPrice(inopen, inhigh, inlow, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
+ Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void RSI() {
+ RSI_Series QL = new(bars.Close, period, false);
+ Core.Rsi(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
+ Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void SDEV() {
+ SDEV_Series QL = new(bars.Close, period, false);
+ Core.StdDev(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
+ Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void SMA() {
+ SMA_Series QL = new(bars.Close, period, false);
+ Core.Sma(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
+ Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void SUB() {
+ SUB_Series QL = new(bars.Open, bars.Close);
+ Core.Sub(inopen, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
+ Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void SUM() {
+ SUM_Series QL = new(bars.Close, period, false);
+ Core.Sum(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
+ Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void T3() {
+ T3_Series QL = new(source: bars.Close, period: period, vfactor:0.7, useNaN: false);
+ Core.T3(inReal: inclose, startIdx: 0, endIdx: bars.Count - 1, outReal: TALIB, outBegIdx: out int outBegIdx, outNbElement: out _, optInTimePeriod: period, optInVFactor: 0.7);
+ Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void TEMA() {
+ TEMA_Series QL = new(bars.Close, period, false);
+ Core.Tema(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
+ Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void TR() {
+ TR_Series QL = new(bars, false);
+ Core.TRange(inhigh, inlow, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
+ Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void TRIMA() {
+ TRIMA_Series QL = new(bars.Close, period, false);
+ Core.Trima(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
+ Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void VAR() {
+ VAR_Series QL = new(bars.Close, period, false);
+ Core.Var(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
+ Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+ [Fact] public void WMA() {
+ WMA_Series QL = new(bars.Close, period, false);
+ Core.Wma(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
+ Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Last().v, digits: digits));
+ }
+
+}
diff --git a/docs/readme.md b/docs/readme.md
index 4ff10d2f..224e2f64 100644
--- a/docs/readme.md
+++ b/docs/readme.md
@@ -92,7 +92,7 @@ See [Getting Started](https://github.com/mihakralj/QuanTAlib/blob/main/Docs/gett
| ⛔ KDJ - KDJ Indicator (trend reversal) |||| kdj |
| ⛔ LSMA - Least Squares Moving Average |||||
| ⭐ MACD - Moving Average Convergence/Divergence | `MACD_Series` | MACD | GetMacd | macd |
-| ⛔ MAMA - MESA Adaptive Moving Average || MAMA | GetMama ||
+| ⭐ MAMA - MESA Adaptive Moving Average | `MAMA_Series` | MAMA | GetMama ||
| ⛔ MCGD - McGinley Dynamic |||| mcgd |
| ⛔ MMA - Modified Moving Average |||||
| ⛔ PPMA - Pivot Point Moving Average |||||
@@ -104,7 +104,7 @@ See [Getting Started](https://github.com/mihakralj/QuanTAlib/blob/main/Docs/gett
| ⛔ SSF - Ehler's Super Smoother Filter |||| ssf |
| ⛔ SUPERTREND - Supertrend |||| supertrend |
| ⛔ SWMA - Symmetric Weighted Moving Average |||| swma |
-| ⛔ T3 - Tillson T3 Moving Average || T3 | GetT3 | t3 |
+| ⭐ T3 - Tillson T3 Moving Average | `T3_Series` | T3 | GetT3 | t3 |
| ⭐ TEMA - Triple EMA Average | `TEMA_Series` | TEMA | GetTema | tema |
| ⭐ TRIMA - Triangular Moving Average | `TRIMA_Series` | TRIMA || trima |
| ⛔ TSF - Time Series Forecast || TSF |||