This commit is contained in:
Miha Kralj
2022-11-18 22:02:48 -08:00
13 changed files with 1278 additions and 999 deletions
+4 -2
View File
@@ -19,14 +19,16 @@ Sources:
public class TR_Series : Single_TBars_Indicator 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) { 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); } 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) 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 d1 = Math.Abs(TBar.h - TBar.l);
double d2 = Math.Abs(_cm1 - TBar.h); double d2 = Math.Abs(_cm1 - TBar.h);
+7 -7
View File
@@ -11,18 +11,18 @@ Random Bars generator - used for testing, validation and fun
public class RND_Feed : TBars 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(); Random rnd = new();
double c = startvalue; double c = Startvalue;
for (int i = 0; i < bars; i++) for (int i = 0; i < Bars; i++)
{ {
double o = Math.Round(c + (c * (((volatility * 0.1) * rnd.NextDouble()) - 0.005)), 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 h = Math.Round(o + (c * Volatility * rnd.NextDouble()), 2);
double l = 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); c = Math.Round(l + ((h - l) * rnd.NextDouble()), 2);
double v = Math.Round(1000 * 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);
} }
} }
} }
+3 -2
View File
@@ -2,7 +2,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<Title>QuanTAlib</Title> <Title>QuanTAlib</Title>
<Version>0.1.21</Version> <Version>0.1.22</Version>
<Product>Library of Technical Indicators for .NET</Product> <Product>Library of Technical Indicators for .NET</Product>
<Description>Quantitative Technical Analysis library for both real-time (streaming) and historical data analysis</Description> <Description>Quantitative Technical Analysis library for both real-time (streaming) and historical data analysis</Description>
<RepositoryType>git</RepositoryType> <RepositoryType>git</RepositoryType>
@@ -11,7 +11,7 @@
<Authors>Miha Kralj</Authors> <Authors>Miha Kralj</Authors>
<Copyright>Miha Kralj</Copyright> <Copyright>Miha Kralj</Copyright>
<PackageReadmeFile>readme.md</PackageReadmeFile> <PackageReadmeFile>readme.md</PackageReadmeFile>
<TargetFrameworks>net7.0;</TargetFrameworks> <TargetFrameworks>net7.0;net6.0;netstandard2.1</TargetFrameworks>
<ImplicitUsings>disable</ImplicitUsings> <ImplicitUsings>disable</ImplicitUsings>
<LangVersion>preview</LangVersion> <LangVersion>preview</LangVersion>
<Nullable>disable</Nullable> <Nullable>disable</Nullable>
@@ -66,6 +66,7 @@
<Visible>False</Visible> <Visible>False</Visible>
<PackagePath></PackagePath> <PackagePath></PackagePath>
</None> </None>
<PackageReference Include="System.Collections" Version="4.3.0" />
<PackageReference Include="System.Text.Json" Version="7.0.0" /> <PackageReference Include="System.Text.Json" Version="7.0.0" />
</ItemGroup> </ItemGroup>
</Project> </Project>
+41 -51
View File
@@ -3,8 +3,8 @@ using System;
/* <summary> /* <summary>
MAMA: MESA Adaptive Moving Average MAMA: MESA Adaptive Moving Average
Created by John Ehlers, the MAMA indicator is a 5-period adaptive moving average of 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 high/low price that uses classic electrical radio-frequency signal processing algorithms
to reduce noise. to reduce noise.
KAMAi = KAMAi - 1 + SC * ( price - KAMAi-1 ) KAMAi = KAMAi - 1 + SC * ( price - KAMAi-1 )
@@ -22,84 +22,87 @@ public class MAMA_Series : Single_TSeries_Indicator
fastl = fastlimit; fastl = fastlimit;
slowl = slowlimit; slowl = slowlimit;
i = 0; i = 0;
Fama = new();
if (base._data.Count > 0) { base.Add(base._data); } if (base._data.Count > 0) { base.Add(base._data); }
} }
private int i; private int i;
private double sumPr, jI, jQ, fastl, slowl; 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 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; 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) public override void Add((System.DateTime t, double v) TValue, bool update)
{ {
if (update) {
i--; if (!update) {
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; // roll forward (oldx = x)
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; 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;
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; 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;
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; 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;
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; 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;
i2.i = i2.i1; i2.i1 = i2.io; 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;
q2.i = q2.i1; q2.i1 = q2.io; i2.io = i2.i1; i2.i1 = i2.i;
re.i = re.i1; re.i1 = re.io; q2.io = q2.i1; q2.i1 = q2.i;
im.i = im.i1; im.i1 = im.io; re.io = re.i1; re.i1 = re.i;
pd.i = pd.i1; pd.i1 = pd.io; im.io = im.i1; im.i1 = im.i;
ph.i = ph.i1; ph.i1 = ph.io; pd.io = pd.i1; pd.i1 = pd.i;
mama.i = mama.i1; mama.i1 = mama.io; ph.io = ph.i1; ph.i1 = ph.i;
fama.i = fama.i1; fama.i1 = fama.io; mama.io = mama.i1; mama.i1 = mama.i;
} fama.io = fama.i1; fama.i1 = fama.i;
}
pr.i = TValue.v; pr.i = TValue.v;
if (i > 5) { if (i > 5) {
double adj = (0.075 * pd.i1) + 0.54; double adj = (0.075 * pd.i1) + 0.54;
// smooth and detrender // smooth and detrender
sm.i = ((4 * pr.i) + (3 * pr.i1) + (2 * pr.i2) + pr.i3) / 10; 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; dt.i = ((0.0962 * sm.i) + (0.5769 * sm.i2) - (0.5769 * sm.i4) - (0.0962 * sm.i6)) * adj;
// in-phase and quadrature // in-phase and quadrature
q1.i = ((0.0962 * dt.i) + (0.5769 * dt.i2) - (0.5769 * dt.i4) - (0.0962 * dt.i6)) * adj; q1.i = ((0.0962 * dt.i) + (0.5769 * dt.i2) - (0.5769 * dt.i4) - (0.0962 * dt.i6)) * adj;
i1.i = dt.i3; i1.i = dt.i3;
// advance the phases by 90 degrees // advance the phases by 90 degrees
jI = ((0.0962 * i1.i) + (0.5769 * i1.i2) - (0.5769 * i1.i4) - (0.0962 * i1.i6)) * adj; 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; jQ = ((0.0962 * q1.i) + (0.5769 * q1.i2) - (0.5769 * q1.i4) - (0.0962 * q1.i6)) * adj;
// phasor addition for 3-bar averaging // phasor addition for 3-bar averaging
i2.i = i1.i - jQ; i2.i = i1.i - jQ;
q2.i = q1.i + jI; q2.i = q1.i + jI;
i2.i = (0.2 * i2.i) + (0.8 * i2.i1); // smoothing it i2.i = (0.2 * i2.i) + (0.8 * i2.i1); // smoothing it
q2.i = (0.2 * q2.i) + (0.8 * q2.i1); q2.i = (0.2 * q2.i) + (0.8 * q2.i1);
// homodyne discriminator // homodyne discriminator
re.i = (i2.i * i2.i1) + (q2.i * q2.i1); re.i = (i2.i * i2.i1) + (q2.i * q2.i1);
im.i = (i2.i * q2.i1) - (q2.i * i2.i1); im.i = (i2.i * q2.i1) - (q2.i * i2.i1);
re.i = (0.2 * re.i) + (0.8 * re.i1); // smoothing it re.i = (0.2 * re.i) + (0.8 * re.i1); // smoothing it
im.i = (0.2 * im.i) + (0.8 * im.i1); im.i = (0.2 * im.i) + (0.8 * im.i1);
// calculate period // calculate period
pd.i = (im.i != 0 && re.i != 0) ? (6.283185307179586 / Math.Atan(im.i / re.i)) : 0d; pd.i = (im.i != 0 && re.i != 0) ? (6.283185307179586 / Math.Atan(im.i / re.i)) : 0d;
// adjust period to thresholds // adjust period to thresholds
pd.i = (pd.i > 1.5 * pd.i1) ? 1.5 * pd.i1 : pd.i; 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 < 0.67 * pd.i1) ? 0.67 * pd.i1 : pd.i;
pd.i = (pd.i < 6d) ? 6d : pd.i; pd.i = (pd.i < 6d) ? 6d : pd.i;
pd.i = (pd.i > 50d) ? 50d : pd.i; pd.i = (pd.i > 50d) ? 50d : pd.i;
// smooth the period // smooth the period
pd.i = (0.2 * pd.i) + (0.8 * pd.i1); pd.i = (0.2 * pd.i) + (0.8 * pd.i1);
// determine phase position // determine phase position
ph.i = (i1.i != 0) ? Math.Atan(q1.i / i1.i) * 57.29577951308232 : 0; ph.i = (i1.i != 0) ? Math.Atan(q1.i / i1.i) * 57.29577951308232 : 0;
// change in phase // change in phase
double delta = Math.Max(ph.i1 - ph.i, 1d); double delta = Math.Max(ph.i1 - ph.i, 1d);
// adaptive alpha value // adaptive alpha value
double alpha = Math.Max(fastl / delta, slowl); double alpha = Math.Max(fastl / delta, slowl);
// final indicators // final indicators
mama.i = ((alpha * pr.i) + ((1d - alpha) * mama.i1)); mama.i = ((alpha * pr.i) + ((1d - alpha) * mama.i1));
fama.i = ((0.5d * alpha * mama.i) + ((1d - (0.5d * alpha)) * fama.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 { else {
sumPr += pr.i; sumPr += pr.i;
pd.i = sm.i = dt.i = i1.i = q1.i = i2.i = q2.i = re.i = im.i = ph.i = 0; 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); 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);
} }
} }
+117
View File
@@ -0,0 +1,117 @@
namespace QuanTAlib;
using System;
using System.Linq;
using System.Numerics;
/* <summary>
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/
</summary> */
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);
}
}
+18 -20
View File
@@ -24,38 +24,36 @@ public class ZLEMA_Series : Single_TSeries_Indicator
{ {
private readonly System.Collections.Generic.List<double> _buffer = new(); private readonly System.Collections.Generic.List<double> _buffer = new();
private readonly double _k, _k1m; 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) public ZLEMA_Series(TSeries source, int period, bool useNaN = false) : base(source, period, useNaN)
{ {
this._k = 2.0 / (this._p + 1); this._k = 2.0 / (this._p + 1);
this._k1m = 1.0 - this._k; this._k1m = 1.0 - this._k;
this._lastema = this._lastlastema = double.NaN; this._lastema = this._lastema_o = double.NaN;
if (base._data.Count > 0) _llag = (int)((_p-1) * 0.5);
{ base.Add(base._data); } if (_data.Count > 0) { base.Add(_data); }
} }
public override void Add((System.DateTime t, double v) TValue, bool update) public override void Add((System.DateTime t, double v) TValue, bool update)
{ {
int _lag = (int)((_p-1) * 0.5); int _lag = Math.Max(this.Count-_llag, 0);
_lag = (this.Count-_lag < 0) ? 0 : this.Count-_lag; if (update) {
_lastema = _lastema_o; _lag--;
} else {
_lastema_o = _lastema;
}
double _zl = TValue.v + (TValue.v - _data[_lag].v); double _zl = TValue.v + (TValue.v - _data[_lag].v);
double _ema = 0; 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; if (this.Count < this._p) {
this._lastema = _ema; 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); base.Add((TValue.t, _ema), update, _NaN);
} }
+22 -17
View File
@@ -16,30 +16,34 @@ public class RSI_Series : Single_TSeries_Indicator
{ {
private readonly System.Collections.Generic.List<double> _gain = new(); private readonly System.Collections.Generic.List<double> _gain = new();
private readonly System.Collections.Generic.List<double> _loss = new(); private readonly System.Collections.Generic.List<double> _loss = new();
private double _avgGain; private double _avgGain, _avgLoss, _lastValue;
private double _avgLoss; private double _avgGain_o, _avgLoss_o, _lastValue_o;
private double _lastValue; private int i;
private double _lastlastValue;
public RSI_Series(TSeries source, int period = 10, bool useNaN = false) : base(source, period: period, useNaN: useNaN) public RSI_Series(TSeries source, int period = 10, bool useNaN = false) : base(source, period: period, useNaN: useNaN) {
{ if (source.Count > 0) { base.Add(source); } } i = 0;
if (source.Count > 0) { base.Add(source); }
}
public override void Add((System.DateTime t, double v) TValue, bool update) public override void Add((System.DateTime t, double v) TValue, bool update) {
{
int i = this.Count;
double _rsi = 0; 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; } if (i == 0) { _lastValue = TValue.v; }
double _gainval = (TValue.v > _lastValue) ? TValue.v - _lastValue : 0; double _gainval = (TValue.v > _lastValue) ? TValue.v - _lastValue : 0;
if (update) { _gain[_gain.Count - 1] = _gainval; } else { _gain.Add(_gainval); } Add_Replace_Trim(_gain, _gainval, _p, update);
if (_gain.Count > this._p) { _gain.RemoveAt(0); }
double _lossval = (TValue.v < _lastValue) ? _lastValue - TValue.v : 0; double _lossval = (TValue.v < _lastValue) ? _lastValue - TValue.v : 0;
if (update) { _loss[_loss.Count - 1] = _lossval; } else { _loss.Add(_lossval); } Add_Replace_Trim(_loss, _lossval, _p, update);
if (_loss.Count > this._p) { _loss.RemoveAt(0); }
_lastlastValue = _lastValue;
_lastValue = TValue.v; _lastValue = TValue.v;
// calculate RSI // calculate RSI
@@ -67,6 +71,7 @@ public class RSI_Series : Single_TSeries_Indicator
_rsi = (_avgLoss > 0) ? 100 - (100 / (1 + (_avgGain / _avgLoss))) : 100; _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); var result = (TValue.t, (this.Count < this._p && this._NaN) ? double.NaN : _rsi);
base.Add(result, update); base.Add(result, update);
} }
+1 -1
View File
@@ -3,7 +3,7 @@ using System;
using QuanTAlib; using QuanTAlib;
namespace MovingAvg; namespace MovingAvg;
public class ALMA_Test public class Update
{ {
[Fact] [Fact]
public void Add_Test() public void Add_Test()
+501
View File
@@ -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
}
}
+162 -252
View File
@@ -7,287 +7,197 @@ using Python.Included;
namespace Validations; namespace Validations;
public class PandasTA : IDisposable public class PandasTA : IDisposable
{ {
private readonly GBM_Feed bars; private readonly GBM_Feed bars;
private readonly Random rnd = new(); private readonly Random rnd = new();
private readonly int period; private readonly int period;
private readonly string OStype; private int digits;
private readonly dynamic np; private readonly string OStype;
private readonly dynamic ta; private readonly dynamic np;
private readonly dynamic df; 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() // Checking the host OS and setting PythonDLL accordingly
{ OStype = Path.GetFullPath(path: ".") + @"\python-3.10.0-embed-amd64\python310.dll";
bars = new(5000);
period = rnd.Next(28) + 3;
// Checking the host OS and setting PythonDLL accordingly Installer.InstallPath = Path.GetFullPath(path: ".");
OStype = Environment.OSVersion.ToString(); Installer.SetupPython().Wait();
if (OStype == "Unix 13.1.0") Installer.TryInstallPip();
{ Installer.PipInstallModule(module_name: "pandas-ta");
OStype = @"/usr/local/Cellar/python@3.10/3.10.8/Frameworks/Python.framework/Versions/3.10/lib/libpython3.10.dylib"; Runtime.PythonDLL = OStype;
} PythonEngine.Initialize();
else np = Py.Import(name: "numpy");
{ ta = Py.Import(name: "pandas_ta");
OStype = Path.GetFullPath(".") + @"\python-3.10.0-embed-amd64\python310.dll";
}
Installer.InstallPath = Path.GetFullPath("."); string[] cols = { "open", "high", "low", "close", "volume" };
Installer.SetupPython().Wait(); double[,] ary = new double[bars.Count, 5];
Installer.TryInstallPip(); for (int i = 0; i < bars.Count; i++) {
Installer.PipInstallModule("pandas-ta"); ary[i, 0] = bars.Open[i].v;
//alternative: git+https://github.com/twopirllc/pandas-ta ary[i, 1] = bars.High[i].v;
ary[i, 2] = bars.Low[i].v;
Runtime.PythonDLL = OStype; ary[i, 3] = bars.Close[i].v;
PythonEngine.Initialize(); ary[i, 4] = bars.Volume[i].v;
np = Py.Import("numpy"); }
ta = Py.Import("pandas_ta"); df = ta.DataFrame(data: np.array(ary), index: np.array(bars.Close.t), columns: np.array(cols));
}
string[] cols = { "open", "high", "low", "close", "volume" }; public void Dispose()
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(); PythonEngine.Shutdown();
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
} }
[Fact] [Fact] void ADL() {
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()
{
ADL_Series QL = new(bars); ADL_Series QL = new(bars);
var pta = df.ta.ad(high: df.high, low: df.low, close:df.close, volume:df.volume); 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); ADOSC_Series QL = new(bars);
var pta = df.ta.adosc(high: df.high, low: df.low, close: df.close, volume: df.volume); 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 ATR() {
[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()
{
ATR_Series QL = new(bars, period); ATR_Series QL = new(bars, period);
var pta = df.ta.atr(high: df.high, low: df.low, close: df.close, length: 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 BIAS() {
[Fact] BIAS_Series QL = new(bars.Close, period, false);
void RSI() 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));
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 DEMA() {
[Fact] DEMA_Series QL = new(bars.Close, period, false);
void TRIMA() 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));
// 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 EMA() {
[Fact] EMA_Series QL = new(bars.Close, period, false);
void KAMA() 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); KAMA_Series QL = new(bars.Close, period);
var pta = df.ta.kama(close: df.close, length: 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 KURTOSIS() {
[Fact] KURTOSIS_Series QL = new(bars.Close, period, useNaN: false);
void HMA() 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));
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 MAD()
[Fact]
void SSDEV()
{ {
SSDEV_Series QL = new(bars.Close, period, useNaN: false); MAD_Series QL = new(bars.Close, period, useNaN: false);
var pta = df.ta.stdev(close: df.close, length: period, ddof: 1); 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)); Assert.Equal(Math.Round((double)pta.tail(1), digits: digits), Math.Round(QL.Last().v, digits: digits));
} }
[Fact] void MEDIAN() {
[Fact] MEDIAN_Series QL = new(bars.Close, period);
void ZSCORE() 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));
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 OBV() {
[Fact] OBV_Series QL = new(bars);
void ENTROPY() 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));
ENTROPY_Series QL = new(bars.Close, period, useNaN: false); }
var pta = df.ta.entropy(close: df.close, length: period); [Fact] void OHLC4() {
Assert.Equal(Math.Round((double)pta.tail(1), 4), Math.Round(QL.Last().v, 4)); 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] [Fact] void RMA() {
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()
{
RMA_Series QL = new(bars.Close, period, false); RMA_Series QL = new(bars.Close, period, false);
var pta = df.ta.rma(close: df.close, length: period); 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 RSI() {
[Fact] RSI_Series QL = new(bars.Close, period);
void ZLEMA() 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); ZLEMA_Series QL = new(bars.Close, period, false);
var pta = df.ta.zlma(close: df.close, length: period); 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));
}
} }
+192 -315
View File
@@ -4,324 +4,201 @@ using Skender.Stock.Indicators;
using Xunit; using Xunit;
namespace Validations; namespace Validations;
public class Skender_Stock public class Skender_Stock {
{ private readonly GBM_Feed bars;
private readonly GBM_Feed bars; private readonly Random rnd = new();
private readonly Random rnd = new(); private readonly int period, digits;
private readonly int period; private readonly IEnumerable<Quote> quotes;
private readonly IEnumerable<Quote> quotes;
public Skender_Stock() public Skender_Stock() {
{ bars = new(Bars: 5000, Volatility: 0.8, Drift: 0.0);
bars = new(Bars: 5000, Volatility: 0.7, Drift: 0.0); period = rnd.Next(28) + 3;
period = rnd.Next(28) + 3; digits = 4; //minimizing rounding errors in type conversions
quotes = bars.Select(
q => new Quote quotes = bars.Select(q => new Quote {
{ Date = q.t,
Date = q.t, Open = (decimal)q.o,
Open = (decimal)q.o, High = (decimal)q.h,
High = (decimal)q.h, Low = (decimal)q.l,
Low = (decimal)q.l, Close = (decimal)q.c,
Close = (decimal)q.c, Volume = (decimal)q.v
Volume = (decimal)q.v
}); });
} }
[Fact] public void ADL() {
[Fact] ADL_Series QL = new(bars, false);
public void SMA() var SK = quotes.GetAdl();
{ Assert.Equal(Math.Round(SK.Last().Adl!, digits: digits), Math.Round(QL.Last().v, digits: digits));
SMA_Series QL = new(bars.Close, period, false); }
var SK = quotes.GetSma(period); [Fact] public void ALMA() {
ALMA_Series QL = new(bars.Close, period, useNaN: false);
Assert.Equal(Math.Round((double)SK.Last().Sma!, 6), Math.Round(QL.Last().v, 6)); var SK = quotes.GetAlma(period);
} Assert.Equal(Math.Round((double)SK.Last().Alma!, digits: digits), Math.Round(QL.Last().v, digits: digits));
}
[Fact] [Fact] public void ATR() {
public void EMA() ATR_Series QL = new(bars, period, false);
{ var SK = quotes.GetAtr(period);
EMA_Series QL = new(bars.Close, period, false); Assert.Equal(Math.Round((double)SK.Last().Atr!, digits: digits), Math.Round(QL.Last().v, digits: digits));
var SK = quotes.GetEma(period); }
[Fact] public void ATRP() {
Assert.Equal(Math.Round((double)SK.Last().Ema!, 6), Math.Round(QL.Last().v, 6)); ATRP_Series QL = new(bars, period, false);
} var SK = quotes.GetAtr(period);
[Fact] Assert.Equal(Math.Round((double)SK.Last().Atrp!, digits: digits), Math.Round(QL.Last().v, digits: digits));
public void WMA() }
{ [Fact] public void BBANDS() {
WMA_Series QL = new(bars.Close, period, false); BBANDS_Series QL = new(bars.Close, period, 2.0, useNaN: false);
var SK = quotes.GetWma(period); 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().Wma!, 6), Math.Round(QL.Last().v, 6)); 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));
[Fact] Assert.Equal(Math.Round((double)SK.Last().PercentB!, digits: digits), Math.Round(QL.PercentB.Last().v, digits: digits));
public void DEMA() Assert.Equal(Math.Round((double)SK.Last().ZScore!, digits: digits), Math.Round(QL.Zscore.Last().v, digits: digits));
{ }
DEMA_Series QL = new(bars.Close, period, false); [Fact] public void CCI() {
var SK = quotes.GetDema(period); CCI_Series QL = new(bars, period, false);
var SK = quotes.GetCci(period);
Assert.Equal(Math.Round((double)SK.Last().Dema!, 6), Math.Round(QL.Last().v, 6)); Assert.Equal(Math.Round((double)SK.Last().Cci!, digits: digits), Math.Round(QL.Last().v, digits: digits));
} }
[Fact] public void CORR() {
[Fact] CORR_Series QL = new(bars.High, bars.Low, period, false);
public void TEMA() 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));
TEMA_Series QL = new(bars.Close, period, false); }
var SK = quotes.GetTema(period); [Fact] public void COVAR() {
COVAR_Series QL = new(bars.High, bars.Low, period, false);
Assert.Equal(Math.Round((double)SK.Last().Tema!, 6), Math.Round(QL.Last().v, 6)); 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() {
[Fact] DEMA_Series QL = new(bars.Close, period, false);
public void MAMA() { 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); MAMA_Series QL = new(bars.HL2, fastlimit: 0.5, slowlimit: 0.05);
var SK = quotes.GetMama(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));
}
} }
+208 -330
View File
@@ -1,330 +1,208 @@
using Xunit; using Xunit;
using System; using System;
using TALib; using TALib;
using QuanTAlib; using QuanTAlib;
namespace Validations; namespace Validations;
public class TA_LIB public class Ta_Lib
{ {
private readonly GBM_Feed bars; private readonly GBM_Feed bars;
private readonly Random rnd = new(); private readonly Random rnd = new();
private readonly int period; private readonly int period, digits;
private readonly double[] TALIB; private readonly double[] TALIB;
private readonly double[] TALIB2; private readonly double[] TALIB2;
private readonly double[] inopen; private readonly double[] inopen;
private readonly double[] inhigh; private readonly double[] inhigh;
private readonly double[] inlow; private readonly double[] inlow;
private readonly double[] inclose; private readonly double[] inclose;
private readonly double[] involume; private readonly double[] involume;
public TA_LIB() public Ta_Lib() {
{ bars = new(Bars: 5000, Volatility: 0.8, Drift: 0.0);
bars = new(5000); period = rnd.Next(28) + 3;
period = rnd.Next(28) + 3; digits = 6;
TALIB = new double[bars.Count];
TALIB2 = new double[bars.Count]; TALIB = new double[bars.Count];
inopen = bars.Open.v.ToArray(); TALIB2 = new double[bars.Count];
inhigh = bars.High.v.ToArray(); inopen = bars.Open.v.ToArray();
inlow = bars.Low.v.ToArray(); inhigh = bars.High.v.ToArray();
inclose = bars.Close.v.ToArray(); inlow = bars.Low.v.ToArray();
involume = bars.Volume.v.ToArray(); inclose = bars.Close.v.ToArray();
} involume = bars.Volume.v.ToArray();
}
/////////////////////////////////////////
[Fact] public void ADD() {
[Fact] ADD_Series QL = new(bars.Open, bars.Close);
public void ADD() 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));
ADD_Series QL = new(bars.Open, bars.Close); }
Core.Add(inopen, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _); [Fact] public void ADL() {
ADL_Series QL = new(bars, false);
Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); 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] [Fact] public void ADOSC() {
public void SUB() ADOSC_Series QL = new(bars, false);
{ Core.AdOsc(inhigh, inlow, inclose, involume, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
SUB_Series QL = new(bars.Open, bars.Close); Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Last().v, digits: digits));
Core.Sub(inopen, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _); }
[Fact] public void ATR() {
Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); 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 MUL() [Fact] public void BBANDS() {
{ double[] outMiddle = new double[bars.Count];
MUL_Series QL = new(bars.Open, bars.Close); double[] outUpper = new double[bars.Count];
Core.Mult(inopen, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _); double[] outLower = new double[bars.Count];
BBANDS_Series QL = new(bars.Close, period: 26, multiplier: 2.0, false);
Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); 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));
[Fact] Assert.Equal(Math.Round(outLower[outLower.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Lower.Last().v, digits: digits));
public void DIV() }
{ [Fact] public void CCI() {
DIV_Series QL = new(bars.Open, bars.Close); CCI_Series QL = new(bars, period, false);
Core.Div(inopen, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _); 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));
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);
[Fact] Core.Correl(inopen, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, optInTimePeriod: period);
public void CORR() Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Last().v, digits: digits));
{ }
CORR_Series QL = new(bars.Open, bars.Close, period); [Fact] public void DEMA() {
Core.Correl(inopen, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, optInTimePeriod: period); 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)); Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Last().v, digits: digits));
} }
[Fact] public void DIV() {
[Fact] DIV_Series QL = new(bars.Open, bars.Close);
public void SDEV() 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));
SDEV_Series QL = new(bars.Close, period, false); }
Core.StdDev(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period); [Fact] public void EMA() {
EMA_Series QL = new(bars.Close, period, false);
Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); 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] [Fact] public void HL2() {
public void SMA() TSeries QL = bars.HL2;
{ Core.MedPrice(inhigh, inlow, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
SMA_Series QL = new(bars.Close, period, false); Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Last().v, digits: digits));
Core.Sma(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period); }
[Fact] public void HLC3() {
Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); 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 SUM() [Fact] public void HLCC4() {
{ TSeries QL = bars.HLCC4;
SUM_Series QL = new(bars.Close, period, false); Core.WclPrice(inhigh, inlow, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
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));
}
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];
[Fact] MACD_Series QL = new(bars.Close, slow: 26, fast: 12, signal: 9, false);
public void MIDPRICE() 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));
MIDPRICE_Series QL = new(bars, period, false); Assert.Equal(Math.Round(macdSignal[macdSignal.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Signal.Last().v, digits: digits));
Core.MidPrice(inhigh, inlow, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period); }
[Fact] public void MAMA() {
Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); 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] [Fact] public void MAX() {
public void VAR() MAX_Series QL = new(bars.Close, period, false);
{ Core.Max(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
VAR_Series QL = new(bars.Close, period, false); Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Last().v, digits: digits));
Core.Var(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period); }
[Fact] public void MIDPOINT() {
Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 4, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 4)); 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 MIDPOINT() [Fact] public void MIDPRICE() {
{ MIDPRICE_Series QL = new(bars, period, false);
MIDPOINT_Series QL = new(bars.Close, period, false); Core.MidPrice(inhigh, inlow, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
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));
}
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], digits: digits), Math.Round(QL.Last().v, digits: digits));
[Fact] }
public void MAMA() { [Fact] public void MUL() {
MAMA_Series QL = new(bars.Close, fastlimit: 0.5, slowlimit: 0.05); MUL_Series QL = new(bars.Open, bars.Close);
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); 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));
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);
[Fact] Core.Obv(inclose, involume, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
public void TRIMA() Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Last().v, digits: digits));
{ }
TRIMA_Series QL = new(bars.Close, period, false); [Fact] public void OHLC4() {
Core.Trima(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period); 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)); Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Last().v, digits: digits));
} }
[Fact] public void RSI() {
[Fact] RSI_Series QL = new(bars.Close, period, false);
public void EMA() 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));
EMA_Series QL = new(bars.Close, period, false); }
Core.Ema(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period); [Fact] public void SDEV() {
SDEV_Series QL = new(bars.Close, period, false);
Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); 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] [Fact] public void SMA() {
public void WMA() SMA_Series QL = new(bars.Close, period, false);
{ Core.Sma(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
WMA_Series QL = new(bars.Close, period, false); Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Last().v, digits: digits));
Core.Wma(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period); }
[Fact] public void SUB() {
Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); 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 DEMA() [Fact] public void SUM() {
{ SUM_Series QL = new(bars.Close, period, false);
DEMA_Series QL = new(bars.Close, period, false); Core.Sum(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
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));
}
Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); [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);
[Fact] Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Last().v, digits: digits));
public void TEMA() }
{ [Fact] public void TEMA() {
TEMA_Series QL = new(bars.Close, period, false); TEMA_Series QL = new(bars.Close, period, false);
Core.Tema(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period); 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));
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);
[Fact] Core.TRange(inhigh, inlow, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
public void MAX() Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Last().v, digits: digits));
{ }
MAX_Series QL = new(bars.Close, period, false); [Fact] public void TRIMA() {
Core.Max(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period); 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)); Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Last().v, digits: digits));
} }
[Fact] public void VAR() {
[Fact] VAR_Series QL = new(bars.Close, period, false);
public void MIN() 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));
MIN_Series QL = new(bars.Close, period, false); }
Core.Min(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period); [Fact] public void WMA() {
WMA_Series QL = new(bars.Close, period, false);
Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); 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));
}
[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));
}
}
+2 -2
View File
@@ -92,7 +92,7 @@ See [Getting Started](https://github.com/mihakralj/QuanTAlib/blob/main/Docs/gett
| ⛔ KDJ - KDJ Indicator (trend reversal) |||| kdj | | ⛔ KDJ - KDJ Indicator (trend reversal) |||| kdj |
| ⛔ LSMA - Least Squares Moving Average ||||| | ⛔ LSMA - Least Squares Moving Average |||||
| ⭐ MACD - Moving Average Convergence/Divergence | `MACD_Series` | MACD | GetMacd | macd | | ⭐ 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 | | ⛔ MCGD - McGinley Dynamic |||| mcgd |
| ⛔ MMA - Modified Moving Average ||||| | ⛔ MMA - Modified Moving Average |||||
| ⛔ PPMA - Pivot Point 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 | | ⛔ SSF - Ehler's Super Smoother Filter |||| ssf |
| ⛔ SUPERTREND - Supertrend |||| supertrend | | ⛔ SUPERTREND - Supertrend |||| supertrend |
| ⛔ SWMA - Symmetric Weighted Moving Average |||| swma | | ⛔ 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 | | ⭐ TEMA - Triple EMA Average | `TEMA_Series` | TEMA | GetTema | tema |
| ⭐ TRIMA - Triangular Moving Average | `TRIMA_Series` | TRIMA || trima | | ⭐ TRIMA - Triangular Moving Average | `TRIMA_Series` | TRIMA || trima |
| ⛔ TSF - Time Series Forecast || TSF ||| | ⛔ TSF - Time Series Forecast || TSF |||