mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-08-23 13:08:04 +00:00
SUM, MIDPOINT, MIDPRICE
This commit is contained in:
@@ -0,0 +1,44 @@
|
|||||||
|
namespace QuanTAlib;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
/* <summary>
|
||||||
|
MIDPOINT: Midpoint value (max+min)/2 in the given period in the series.
|
||||||
|
If period = 0 => period = full length of the series
|
||||||
|
|
||||||
|
Sources:
|
||||||
|
https://thefaqblog.com/what-is-the-midpoint-in-statistics/
|
||||||
|
|
||||||
|
</summary> */
|
||||||
|
|
||||||
|
public class MIDPOINT_Series : Single_TSeries_Indicator
|
||||||
|
{
|
||||||
|
public MIDPOINT_Series(TSeries source, int period, bool useNaN = false) : base(source, period, useNaN)
|
||||||
|
{
|
||||||
|
if (base._data.Count > 0)
|
||||||
|
{ base.Add(base._data); }
|
||||||
|
}
|
||||||
|
private readonly System.Collections.Generic.List<double> _buffer = new();
|
||||||
|
|
||||||
|
public override void Add((DateTime t, double v) TValue, bool update)
|
||||||
|
{
|
||||||
|
if (update)
|
||||||
|
{ this._buffer[this._buffer.Count - 1] = TValue.v; }
|
||||||
|
else
|
||||||
|
{ this._buffer.Add(TValue.v); }
|
||||||
|
if (this._buffer.Count > this._p && this._p != 0)
|
||||||
|
{ this._buffer.RemoveAt(0); }
|
||||||
|
|
||||||
|
double _max = TValue.v;
|
||||||
|
double _min = TValue.v;
|
||||||
|
for (int i = 0; i < this._buffer.Count; i++)
|
||||||
|
{
|
||||||
|
_max = Math.Max(this._buffer[i], _max);
|
||||||
|
_min = Math.Min(this._buffer[i], _min);
|
||||||
|
}
|
||||||
|
double _mid = (_max + _min) * 0.5;
|
||||||
|
|
||||||
|
var result = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _mid);
|
||||||
|
|
||||||
|
base.Add(result, update);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
namespace QuanTAlib;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
/* <summary>
|
||||||
|
MIDPRICE: Midpoint price (highhest high + lowest low)/2 in the given period in the series.
|
||||||
|
If period = 0 => period = full length of the series
|
||||||
|
|
||||||
|
</summary> */
|
||||||
|
|
||||||
|
public class MIDPRICE_Series : Single_TBars_Indicator
|
||||||
|
{
|
||||||
|
public MIDPRICE_Series(TBars source, int period, bool useNaN = false) : base(source, period, useNaN)
|
||||||
|
{
|
||||||
|
if (base._bars.Count > 0)
|
||||||
|
{ base.Add(base._bars); }
|
||||||
|
}
|
||||||
|
private readonly System.Collections.Generic.List<double> _bufferhi = new();
|
||||||
|
private readonly System.Collections.Generic.List<double> _bufferlo = new();
|
||||||
|
|
||||||
|
public override void Add((DateTime t, double o, double h, double l, double c, double v) TBar, bool update)
|
||||||
|
{
|
||||||
|
if (update)
|
||||||
|
{
|
||||||
|
this._bufferhi[this._bufferhi.Count - 1] = TBar.h;
|
||||||
|
this._bufferlo[this._bufferlo.Count - 1] = TBar.l;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this._bufferhi.Add(TBar.h);
|
||||||
|
this._bufferlo.Add(TBar.l);
|
||||||
|
}
|
||||||
|
if (this._bufferhi.Count > this._p && this._p != 0)
|
||||||
|
{ this._bufferhi.RemoveAt(0); }
|
||||||
|
if (this._bufferlo.Count > this._p && this._p != 0)
|
||||||
|
{ this._bufferlo.RemoveAt(0); }
|
||||||
|
|
||||||
|
double _max = TBar.h;
|
||||||
|
double _min = TBar.l;
|
||||||
|
for (int i = 0; i < this._bufferhi.Count; i++)
|
||||||
|
{
|
||||||
|
_max = Math.Max(this._bufferhi[i], _max);
|
||||||
|
_min = Math.Min(this._bufferlo[i], _min);
|
||||||
|
}
|
||||||
|
double _mid = (_max + _min) * 0.5;
|
||||||
|
|
||||||
|
var result = (TBar.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _mid);
|
||||||
|
|
||||||
|
base.Add(result, update);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
namespace QuanTAlib;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
/* <summary>
|
||||||
|
SUM: Cumulative Sum (aka Running Total)
|
||||||
|
SUM across a period provides a rolling sum of all values across the period.
|
||||||
|
If SUM values would be divided with period, the output would be SMA()
|
||||||
|
|
||||||
|
Sources:
|
||||||
|
https://en.wikipedia.org/wiki/CUSUM
|
||||||
|
|
||||||
|
</summary> */
|
||||||
|
|
||||||
|
public class SUM_Series : Single_TSeries_Indicator
|
||||||
|
{
|
||||||
|
public SUM_Series(TSeries source, int period, bool useNaN = false) : base(source, period, useNaN)
|
||||||
|
{
|
||||||
|
if (base._data.Count > 0) { base.Add(base._data); }
|
||||||
|
}
|
||||||
|
private readonly System.Collections.Generic.List<double> _buffer = new();
|
||||||
|
|
||||||
|
public override void Add((System.DateTime t, double v) TValue, bool update)
|
||||||
|
{
|
||||||
|
if (update) { _buffer[_buffer.Count - 1] = TValue.v; }
|
||||||
|
else { _buffer.Add(TValue.v); }
|
||||||
|
if (_buffer.Count > this._p && this._p != 0) { _buffer.RemoveAt(0); }
|
||||||
|
|
||||||
|
double _sum = 0;
|
||||||
|
for (int i = 0; i < _buffer.Count; i++) { _sum += _buffer[i]; }
|
||||||
|
|
||||||
|
var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _sum);
|
||||||
|
|
||||||
|
base.Add(result, update);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,52 +14,54 @@ Sources:
|
|||||||
https://phemex.com/academy/what-is-arnaud-legoux-moving-averages
|
https://phemex.com/academy/what-is-arnaud-legoux-moving-averages
|
||||||
https://www.prorealcode.com/prorealtime-indicators/alma-arnaud-legoux-moving-average/
|
https://www.prorealcode.com/prorealtime-indicators/alma-arnaud-legoux-moving-average/
|
||||||
|
|
||||||
|
TODO: Discrepancy with Pandas-TA (but passes the validation with Skender.GetAlma)
|
||||||
|
|
||||||
</summary> */
|
</summary> */
|
||||||
|
|
||||||
public class ALMA_Series : Single_TSeries_Indicator
|
public class ALMA_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[] _weight;
|
private readonly double[] _weight;
|
||||||
private double _norm;
|
private double _norm;
|
||||||
private readonly double _offset, _sigma;
|
private readonly double _offset, _sigma;
|
||||||
|
|
||||||
public ALMA_Series(TSeries source, int period, double offset = 0.85, double sigma = 6.0, bool useNaN = false)
|
public ALMA_Series(TSeries source, int period, double offset = 0.85, double sigma = 6.0, bool useNaN = false)
|
||||||
: base(source, period, useNaN)
|
: base(source, period, useNaN)
|
||||||
|
{
|
||||||
|
_offset = offset;
|
||||||
|
_sigma = sigma;
|
||||||
|
_weight = new double[period];
|
||||||
|
|
||||||
|
if (this._data.Count > 0) { base.Add(this._data); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Add((System.DateTime t, double v) TValue, bool update)
|
||||||
|
{
|
||||||
|
if (update) { this._buffer[this._buffer.Count - 1] = TValue.v; }
|
||||||
|
else { this._buffer.Add(TValue.v); }
|
||||||
|
if (this._buffer.Count > this._p) { this._buffer.RemoveAt(0); }
|
||||||
|
|
||||||
|
if (this._buffer.Count <= _p) { calc_weights(); }
|
||||||
|
|
||||||
|
double _weightedSum = 0;
|
||||||
|
for (int i = 0; i < this._buffer.Count; i++) { _weightedSum += _weight[i] * _buffer[i]; }
|
||||||
|
double _alma = _weightedSum / _norm;
|
||||||
|
|
||||||
|
var ret = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _alma);
|
||||||
|
base.Add(ret, update);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void calc_weights()
|
||||||
|
{
|
||||||
|
int _len = this._buffer.Count;
|
||||||
|
_norm = 0;
|
||||||
|
double _m = _offset * (_len - 1);
|
||||||
|
double _s = _len / _sigma;
|
||||||
|
for (int i = 0; i < _len; i++)
|
||||||
{
|
{
|
||||||
_offset = offset;
|
double _wt = Math.Exp(-((i - _m) * (i - _m)) / (2 * _s * _s));
|
||||||
_sigma = sigma;
|
_weight[i] = _wt;
|
||||||
_weight = new double[period];
|
_norm += _wt;
|
||||||
|
|
||||||
if (this._data.Count > 0) { base.Add(this._data); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Add((System.DateTime t, double v) TValue, bool update)
|
|
||||||
{
|
|
||||||
if (update) { this._buffer[this._buffer.Count - 1] = TValue.v; }
|
|
||||||
else { this._buffer.Add(TValue.v); }
|
|
||||||
if (this._buffer.Count > this._p) { this._buffer.RemoveAt(0); }
|
|
||||||
|
|
||||||
if (this._buffer.Count <= _p) { calc_weights(); }
|
|
||||||
|
|
||||||
double _weightedSum = 0;
|
|
||||||
for (int i = 0; i < this._buffer.Count; i++) { _weightedSum += _weight[i] * _buffer[i]; }
|
|
||||||
double _alma = _weightedSum / _norm;
|
|
||||||
|
|
||||||
var ret = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _alma);
|
|
||||||
base.Add(ret, update);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void calc_weights()
|
|
||||||
{
|
|
||||||
int _len = this._buffer.Count;
|
|
||||||
_norm = 0;
|
|
||||||
double _m = _offset * (_len - 1);
|
|
||||||
double _s = _len / _sigma;
|
|
||||||
for (int i = 0; i < _len; i++)
|
|
||||||
{
|
|
||||||
double _wt = Math.Exp(-((i - _m) * (i - _m)) / (2 * _s * _s));
|
|
||||||
_weight[i] = _wt;
|
|
||||||
_norm += _wt;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+153
-105
@@ -7,122 +7,170 @@ using Python.Included;
|
|||||||
namespace Validations;
|
namespace Validations;
|
||||||
public class PandasTA : IDisposable
|
public class PandasTA : IDisposable
|
||||||
{
|
{
|
||||||
private GBM_Feed bars;
|
private GBM_Feed bars;
|
||||||
private Random rnd = new();
|
private Random rnd = new();
|
||||||
private int period;
|
private int period;
|
||||||
private string OStype;
|
private string OStype;
|
||||||
private dynamic np;
|
private dynamic np;
|
||||||
private dynamic ta;
|
private dynamic ta;
|
||||||
private dynamic df;
|
private dynamic df;
|
||||||
|
|
||||||
public PandasTA()
|
public PandasTA()
|
||||||
|
{
|
||||||
|
bars = new(5000);
|
||||||
|
period = rnd.Next(28) + 3;
|
||||||
|
|
||||||
|
// Checking the host OS and setting PythonDLL accordingly
|
||||||
|
OStype = Environment.OSVersion.ToString();
|
||||||
|
if (OStype == "Unix 13.1.0")
|
||||||
|
OStype = @"/usr/local/Cellar/python@3.10/3.10.8/Frameworks/Python.framework/Versions/3.10/lib/libpython3.10.dylib";
|
||||||
|
else OStype = Path.GetFullPath(".") + @"\python-3.10.0-embed-amd64\python310.dll";
|
||||||
|
|
||||||
|
Installer.InstallPath = Path.GetFullPath(".");
|
||||||
|
Installer.SetupPython().Wait();
|
||||||
|
Installer.TryInstallPip();
|
||||||
|
//Installer.PipInstallModule("pandas-ta");
|
||||||
|
Installer.PipInstallModule("git+https://github.com/twopirllc/pandas-ta@development");
|
||||||
|
|
||||||
|
Runtime.PythonDLL = OStype;
|
||||||
|
PythonEngine.Initialize();
|
||||||
|
np = Py.Import("numpy");
|
||||||
|
ta = Py.Import("pandas_ta");
|
||||||
|
|
||||||
|
string[] cols = { "open", "high", "low", "close", "volume" };
|
||||||
|
double[,] ary = new double[bars.Count, 5];
|
||||||
|
for (int i = 0; i < bars.Count; i++)
|
||||||
{
|
{
|
||||||
bars = new(5000);
|
ary[i, 0] = bars.Open[i].v;
|
||||||
period = rnd.Next(28) + 3;
|
ary[i, 1] = bars.High[i].v;
|
||||||
|
ary[i, 2] = bars.Low[i].v;
|
||||||
// Checking the host OS and setting PythonDLL accordingly
|
ary[i, 3] = bars.Close[i].v;
|
||||||
OStype = Environment.OSVersion.ToString();
|
ary[i, 4] = bars.Volume[i].v;
|
||||||
if (OStype == "Unix 13.1.0")
|
|
||||||
OStype = @"/usr/local/Cellar/python@3.10/3.10.8/Frameworks/Python.framework/Versions/3.10/lib/libpython3.10.dylib";
|
|
||||||
else OStype = Path.GetFullPath(".") + @"\python-3.10.0-embed-amd64\python310.dll";
|
|
||||||
|
|
||||||
Installer.InstallPath = Path.GetFullPath(".");
|
|
||||||
Installer.SetupPython().Wait();
|
|
||||||
Installer.TryInstallPip();
|
|
||||||
Installer.PipInstallModule("pandas-ta");
|
|
||||||
|
|
||||||
Runtime.PythonDLL = OStype;
|
|
||||||
PythonEngine.Initialize();
|
|
||||||
np = Py.Import("numpy");
|
|
||||||
ta = Py.Import("pandas_ta");
|
|
||||||
|
|
||||||
string[] cols = { "open", "high", "low", "close", "volume" };
|
|
||||||
double[,] ary = new double[bars.Count, 5];
|
|
||||||
for (int i = 0; i < bars.Count; i++)
|
|
||||||
{
|
|
||||||
ary[i, 0] = bars.Open[i].v;
|
|
||||||
ary[i, 1] = bars.High[i].v;
|
|
||||||
ary[i, 2] = bars.Low[i].v;
|
|
||||||
ary[i, 3] = bars.Close[i].v;
|
|
||||||
ary[i, 4] = bars.Volume[i].v;
|
|
||||||
}
|
|
||||||
df = ta.DataFrame(data: np.array(ary), index: np.array(bars.Close.t), columns: np.array(cols));
|
|
||||||
}
|
}
|
||||||
|
df = ta.DataFrame(data: np.array(ary), index: np.array(bars.Close.t), columns: np.array(cols));
|
||||||
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
PythonEngine.Shutdown();
|
PythonEngine.Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
void SMA()
|
void HL2()
|
||||||
{
|
{
|
||||||
SMA_Series QL = new(bars.Close, period, false);
|
var pta = df.ta.hl2(high: df.high, low: df.low);
|
||||||
var pta = df.ta.sma(close: df.close, length: period);
|
Assert.Equal(Math.Round((double)pta.tail(1), 7), Math.Round(bars.HL2.Last().v, 7));
|
||||||
Assert.Equal(Math.Round((double)pta.tail(1), 7), Math.Round(QL.Last().v, 7));
|
}
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
void EMA()
|
void HLC3()
|
||||||
{
|
{
|
||||||
EMA_Series QL = new(bars.Close, period, false);
|
var pta = df.ta.hlc3(high: df.high, low: df.low, close: df.close);
|
||||||
var pta = df.ta.ema(close: df.close, length: period);
|
Assert.Equal(Math.Round((double)pta.tail(1), 7), Math.Round(bars.HLC3.Last().v, 7));
|
||||||
Assert.Equal(Math.Round((double)pta.tail(1), 7), Math.Round(QL.Last().v, 7));
|
}
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
void TEMA()
|
void OHLC4()
|
||||||
{
|
{
|
||||||
TEMA_Series QL = new(bars.Close, period, false);
|
var pta = df.ta.ohlc4(open: df.open, high: df.high, low: df.low, close: df.close);
|
||||||
var pta = df.ta.tema(close: df.close, length: period);
|
Assert.Equal(Math.Round((double)pta.tail(1), 7), Math.Round(bars.OHLC4.Last().v, 7));
|
||||||
Assert.Equal(Math.Round((double)pta.tail(1), 7), Math.Round(QL.Last().v, 7));
|
}
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
void ENTP()
|
void KAMA()
|
||||||
{
|
{
|
||||||
ENTP_Series QL = new(bars.Close, period, useNaN: false);
|
KAMA_Series QL = new(bars.Close, period);
|
||||||
var pta = df.ta.entropy(close: df.close, length: period);
|
var pta = df.ta.kama(close: df.close, length: period);
|
||||||
Assert.Equal(Math.Round((double)pta.tail(1), 7), Math.Round(QL.Last().v, 7));
|
Assert.Equal(Math.Round((double)pta.tail(1), 7), Math.Round(QL.Last().v, 7));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
/*
|
||||||
void WMA()
|
[Fact]
|
||||||
{
|
void ALMA()
|
||||||
WMA_Series QL = new(bars.Close, period, false);
|
{
|
||||||
var pta = df.ta.wma(close: df.close, length: period);
|
ALMA_Series QL = new(bars.Close, period: period, offset: 0.85, sigma: 6.0, false);
|
||||||
Assert.Equal(Math.Round((double)pta.tail(1), 7), Math.Round(QL.Last().v, 7));
|
var pta = df.ta.alma(close: df.close, length: period, distribution_offset: 0.85, sigma: 6.0);
|
||||||
}
|
Assert.Equal(Math.Round((double)pta.tail(1), 7), Math.Round(QL.Last().v, 7));
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
void DEMA()
|
void HMA()
|
||||||
{
|
{
|
||||||
DEMA_Series QL = new(bars.Close, period, false);
|
HMA_Series QL = new(bars.Close, period, false);
|
||||||
var pta = df.ta.dema(close: df.close, length: period);
|
var pta = df.ta.hma(close: df.close, length: period);
|
||||||
Assert.Equal(Math.Round((double)pta.tail(1), 7), Math.Round(QL.Last().v, 7));
|
Assert.Equal(Math.Round((double)pta.tail(1), 7), Math.Round(QL.Last().v, 7));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
void BIAS()
|
void SMA()
|
||||||
{
|
{
|
||||||
BIAS_Series QL = new(bars.Close, period, false);
|
SMA_Series QL = new(bars.Close, period, false);
|
||||||
var pta = df.ta.bias(close: df.close, length: period);
|
var pta = df.ta.sma(close: df.close, length: period);
|
||||||
Assert.Equal(Math.Round((double)pta.tail(1), 7), Math.Round(QL.Last().v, 7));
|
Assert.Equal(Math.Round((double)pta.tail(1), 7), Math.Round(QL.Last().v, 7));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
void KURT()
|
void EMA()
|
||||||
{
|
{
|
||||||
KURT_Series QL = new(bars.Close, period, useNaN: false);
|
EMA_Series QL = new(bars.Close, period, false);
|
||||||
var pta = df.ta.kurtosis(close: df.close, length: period);
|
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));
|
Assert.Equal(Math.Round((double)pta.tail(1), 7), Math.Round(QL.Last().v, 7));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
void MAD()
|
void TEMA()
|
||||||
{
|
{
|
||||||
MAD_Series QL = new(bars.Close, period, useNaN: false);
|
TEMA_Series QL = new(bars.Close, period, false);
|
||||||
var pta = df.ta.mad(close: df.close, length: period);
|
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));
|
Assert.Equal(Math.Round((double)pta.tail(1), 7), Math.Round(QL.Last().v, 7));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
void ENTP()
|
||||||
|
{
|
||||||
|
ENTP_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), 7), Math.Round(QL.Last().v, 7));
|
||||||
|
}
|
||||||
|
|
||||||
|
[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), 7), Math.Round(QL.Last().v, 7));
|
||||||
|
}
|
||||||
|
|
||||||
|
[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), 7), Math.Round(QL.Last().v, 7));
|
||||||
|
}
|
||||||
|
|
||||||
|
[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), 7), Math.Round(QL.Last().v, 7));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
void KURT()
|
||||||
|
{
|
||||||
|
KURT_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), 7), Math.Round(QL.Last().v, 7));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -85,6 +85,33 @@ public class TA_LIB
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
public void SUM()
|
||||||
|
{
|
||||||
|
SUM_Series QL = new(bars.Close, period, false);
|
||||||
|
Core.Sum(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
|
||||||
|
|
||||||
|
Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void MIDPRICE()
|
||||||
|
{
|
||||||
|
MIDPRICE_Series QL = new(bars, period, false);
|
||||||
|
Core.MidPrice(inhigh, inlow, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
|
||||||
|
|
||||||
|
Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void MIDPOINT()
|
||||||
|
{
|
||||||
|
MIDPOINT_Series QL = new(bars.Close, period, false);
|
||||||
|
Core.MidPoint(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
|
||||||
|
|
||||||
|
Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
public void TRIMA()
|
public void TRIMA()
|
||||||
{
|
{
|
||||||
TRIMA_Series QL = new(bars.Close, period, false);
|
TRIMA_Series QL = new(bars.Close, period, false);
|
||||||
|
|||||||
+3
-3
@@ -43,11 +43,11 @@ See [Getting Started](https://github.com/mihakralj/QuanTAlib/blob/main/Docs/gett
|
|||||||
| ✔️ OHL3 - (Open+High+Low)/3 | `.OHL3` |||
|
| ✔️ OHL3 - (Open+High+Low)/3 | `.OHL3` |||
|
||||||
| ⭐ OHLC4 - Average Price | `.OHLC4` | AVGPRICE |️ GetBaseQuote |
|
| ⭐ OHLC4 - Average Price | `.OHLC4` | AVGPRICE |️ GetBaseQuote |
|
||||||
| ⭐ HLCC4 - Weighted Price | `.HLCC4` | WCLPRICE ||
|
| ⭐ HLCC4 - Weighted Price | `.HLCC4` | WCLPRICE ||
|
||||||
|
| ⭐ MIDPOINT - Midpoint value | `MIDPOINT_Series` | MIDPOINT ||
|
||||||
|
| ⭐ MIDPRICE - Midpoint price | `MIDPRICE_Series` | MIDPRICE ||
|
||||||
| ⭐ MAX - Max value | `MAX_Series` | MAX ||
|
| ⭐ MAX - Max value | `MAX_Series` | MAX ||
|
||||||
| ⭐ MIN - Min value | `MIN_Series` | MIN ||
|
| ⭐ MIN - Min value | `MIN_Series` | MIN ||
|
||||||
| ⛔ MID - Midpoint value || MIDPOINT ||
|
| ⭐ SUM - Summation | `SUM_Series` | SUM ||
|
||||||
| ⛔ MIDP - Midpoint price || MIDPRICE ||
|
|
||||||
| ⛔ SUM - Summation || SUM ||
|
|
||||||
| ⭐ ADD - Addition | `ADD_Series` | ADD ||
|
| ⭐ ADD - Addition | `ADD_Series` | ADD ||
|
||||||
| ⭐ SUB - Subtraction | `SUB_Series` | SUB ||
|
| ⭐ SUB - Subtraction | `SUB_Series` | SUB ||
|
||||||
| ⭐ MUL - Multiplication | `MUL_Series` | MUL ||
|
| ⭐ MUL - Multiplication | `MUL_Series` | MUL ||
|
||||||
|
|||||||
Reference in New Issue
Block a user