mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-08-22 04:28:04 +00:00
Merge branch 'dev' into main
This commit is contained in:
@@ -87,6 +87,20 @@ jobs:
|
|||||||
title: "Latest Build"
|
title: "Latest Build"
|
||||||
files: /Quantower/Settings/Scripts/Indicators/QuanTAlib/*.dll
|
files: /Quantower/Settings/Scripts/Indicators/QuanTAlib/*.dll
|
||||||
|
|
||||||
|
- name: Authenticate to Github packages source
|
||||||
|
run: dotnet nuget add source
|
||||||
|
--username mihakralj
|
||||||
|
--password ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
--store-password-in-clear-text
|
||||||
|
--name github "https://nuget.pkg.github.com/mihakralj/index.json"
|
||||||
|
|
||||||
|
- name: Push package to github
|
||||||
|
if: ${{ github.ref == 'refs/heads/dev' }}
|
||||||
|
run: dotnet nuget push '.\Source\bin\Release\QuanTAlib.*.nupkg'
|
||||||
|
--source https://nuget.pkg.github.com/mihakralj/index.json
|
||||||
|
--skip-duplicate
|
||||||
|
--no-symbols
|
||||||
|
|
||||||
- name: Push package to nuget.org
|
- name: Push package to nuget.org
|
||||||
if: ${{ github.ref == 'refs/heads/main' }}
|
if: ${{ github.ref == 'refs/heads/main' }}
|
||||||
run: dotnet nuget push '.\Source\bin\Release\QuanTAlib.*.nupkg'
|
run: dotnet nuget push '.\Source\bin\Release\QuanTAlib.*.nupkg'
|
||||||
|
|||||||
@@ -30,8 +30,8 @@ public class ATR_chart : Indicator
|
|||||||
this.ShortName = "ATR (" + this.Period + ")";
|
this.ShortName = "ATR (" + this.Period + ")";
|
||||||
this.bars = new();
|
this.bars = new();
|
||||||
this.indicator = new(source: bars, period: this.Period, useNaN: false);
|
this.indicator = new(source: bars, period: this.Period, useNaN: false);
|
||||||
}␍
|
}
|
||||||
␍
|
|
||||||
protected override void OnUpdate(UpdateArgs args)
|
protected override void OnUpdate(UpdateArgs args)
|
||||||
{
|
{
|
||||||
bool update = !(args.Reason == UpdateReason.NewBar ||
|
bool update = !(args.Reason == UpdateReason.NewBar ||
|
||||||
|
|||||||
@@ -51,11 +51,6 @@ public class WMAPE_chart : Indicator
|
|||||||
this.bars.Add(this.Time(), this.GetPrice(PriceType.Open), this.GetPrice(PriceType.High), this.GetPrice(PriceType.Low), this.GetPrice(PriceType.Close), this.GetPrice(PriceType.Volume), update);
|
this.bars.Add(this.Time(), this.GetPrice(PriceType.Open), this.GetPrice(PriceType.High), this.GetPrice(PriceType.Low), this.GetPrice(PriceType.Close), this.GetPrice(PriceType.Volume), update);
|
||||||
double result = this.indicator[this.indicator.Count - 1].v;
|
double result = this.indicator[this.indicator.Count - 1].v;
|
||||||
|
|
||||||
|
|
||||||
this.SetValue(result, 0);
|
this.SetValue(result, 0);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,93 +0,0 @@
|
|||||||
using System.Collections;
|
|
||||||
using System.Drawing;
|
|
||||||
using System.Drawing.Text;
|
|
||||||
using TradingPlatform.BusinessLayer;
|
|
||||||
namespace QuanTAlib;
|
|
||||||
|
|
||||||
public class ZLMA_chart : Indicator
|
|
||||||
{
|
|
||||||
#region Parameters
|
|
||||||
|
|
||||||
[InputParameter("Smoothing period", 0, 1, 999, 1, 1)]
|
|
||||||
private readonly int Period = 10;
|
|
||||||
|
|
||||||
[InputParameter("Data source", 1, variants: new object[]
|
|
||||||
{ "Open", 0, "High", 1, "Low", 2, "Close", 3, "HL2", 4, "OC2", 5,
|
|
||||||
"OHL3", 6, "HLC3", 7, "OHLC4", 8, "Weighted (HLCC4)", 9 })]
|
|
||||||
private readonly int DataSource = 3;
|
|
||||||
|
|
||||||
[InputParameter("MA algorithm", 2, variants: new object[]
|
|
||||||
{ "SMA", 0,
|
|
||||||
"WMA", 1,
|
|
||||||
"EMA", 2,
|
|
||||||
"DEMA", 3,
|
|
||||||
"TEMA", 4,
|
|
||||||
"HMA", 5,
|
|
||||||
"KAMA", 6,
|
|
||||||
"JMA", 7,
|
|
||||||
"SMMA", 8
|
|
||||||
})]
|
|
||||||
private readonly int matype = 2;
|
|
||||||
|
|
||||||
#endregion Parameters
|
|
||||||
|
|
||||||
private TBars bars;
|
|
||||||
///////
|
|
||||||
private TSeries indicator;
|
|
||||||
///////
|
|
||||||
|
|
||||||
public ZLMA_chart()
|
|
||||||
{
|
|
||||||
this.SeparateWindow = false;
|
|
||||||
this.Name = "ZLMA - Zero-lag Moving Average";
|
|
||||||
this.Description = "Zero-Lag Moving Average description";
|
|
||||||
this.AddLineSeries("ZLMA", Color.RoyalBlue, 3, LineStyle.Solid);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnInit()
|
|
||||||
{
|
|
||||||
this.bars = new();
|
|
||||||
string maname = matype switch
|
|
||||||
{
|
|
||||||
0 => "SMA",
|
|
||||||
1 => "WMA",
|
|
||||||
2 => "EMA",
|
|
||||||
3 => "DEMA",
|
|
||||||
4 => "TEMA",
|
|
||||||
5 => "HMA",
|
|
||||||
6 => "KAMA",
|
|
||||||
7 => "JMA",
|
|
||||||
8 => "SMMA",
|
|
||||||
_ => "???"
|
|
||||||
};
|
|
||||||
|
|
||||||
this.ShortName = "ZLMA (" + maname + ", " + TBars.SelectStr(this.DataSource) + ", " + this.Period + ")";
|
|
||||||
ZL_Series zerolag = new(source: bars.Select(this.DataSource), period: this.Period, useNaN: false);
|
|
||||||
this.indicator = matype switch
|
|
||||||
{
|
|
||||||
0 => new SMA_Series(source: zerolag, period: this.Period, useNaN: false),
|
|
||||||
1 => new WMA_Series(source: zerolag, period: this.Period, useNaN: false),
|
|
||||||
2 => new EMA_Series(source: zerolag, period: this.Period, useNaN: false),
|
|
||||||
3 => new DEMA_Series(source: zerolag, period: this.Period, useNaN: false),
|
|
||||||
4 => new TEMA_Series(source: zerolag, period: this.Period, useNaN: false),
|
|
||||||
5 => new HMA_Series(source: zerolag, period: this.Period, useNaN: false),
|
|
||||||
6 => new KAMA_Series(source: zerolag, period: this.Period, useNaN: false),
|
|
||||||
7 => new JMA_Series(source: zerolag, period: this.Period, useNaN: false),
|
|
||||||
8 => new SMMA_Series(source: zerolag, period: this.Period, useNaN: false),
|
|
||||||
_ => new EMA_Series(source: zerolag, period: this.Period, useNaN: false)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnUpdate(UpdateArgs args)
|
|
||||||
{
|
|
||||||
bool update = !(args.Reason == UpdateReason.NewBar ||
|
|
||||||
args.Reason == UpdateReason.HistoricalBar);
|
|
||||||
this.bars.Add(this.Time(), this.GetPrice(PriceType.Open),
|
|
||||||
this.GetPrice(PriceType.High), this.GetPrice(PriceType.Low),
|
|
||||||
this.GetPrice(PriceType.Close),
|
|
||||||
this.GetPrice(PriceType.Volume), update);
|
|
||||||
|
|
||||||
double result = this.indicator[this.indicator.Count-1].v;
|
|
||||||
this.SetValue(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+17
-51
@@ -32,23 +32,14 @@ public abstract class Single_TSeries_Indicator : TSeries
|
|||||||
public new virtual void Add((System.DateTime t, double v) TValue, bool update) => base.Add(TValue, update);
|
public new virtual void Add((System.DateTime t, double v) TValue, bool update) => base.Add(TValue, update);
|
||||||
|
|
||||||
// potentially overridable Add() method for the whole series (could be replaced with faster bulk algo)
|
// potentially overridable Add() method for the whole series (could be replaced with faster bulk algo)
|
||||||
public virtual void Add(TSeries data)
|
public virtual void Add(TSeries data) { for (int i = 0; i < data.Count; i++) { this.Add(TValue: data[i], update: false); }}
|
||||||
{
|
|
||||||
for (int i = 0; i < data.Count; i++) { this.Add(TValue: data[i], update: false); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public new void Add((System.DateTime t, double v) TValue)
|
public new void Add((System.DateTime t, double v) TValue) => this.Add(TValue: TValue, update: false);
|
||||||
=> this.Add(TValue: TValue, update: false);
|
public void Add(bool update) => this.Add(TValue: this._data[this._data.Count - 1], update: update);
|
||||||
public void Add(bool update)
|
public void Add() => this.Add(TValue: this._data[this._data.Count - 1], update: false);
|
||||||
=> this.Add(TValue: this._data[this._data.Count - 1], update: update);
|
public new void Sub(object source, TSeriesEventArgs e) => this.Add(TValue: this._data[this._data.Count - 1], update: e.update);
|
||||||
public void Add()
|
|
||||||
=> this.Add(TValue: this._data[this._data.Count - 1], update: false);
|
|
||||||
public new void Sub(object source, TSeriesEventArgs e)
|
|
||||||
=> this.Add(TValue: this._data[this._data.Count - 1], update: e.update);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public abstract class Pair_TSeries_Indicator : TSeries
|
public abstract class Pair_TSeries_Indicator : TSeries
|
||||||
{
|
{
|
||||||
protected readonly TSeries _d1;
|
protected readonly TSeries _d1;
|
||||||
@@ -83,24 +74,14 @@ public abstract class Pair_TSeries_Indicator : TSeries
|
|||||||
}
|
}
|
||||||
|
|
||||||
// overridable Add(Tvalue, Tvalue) method to add/update a single value at the end of the list
|
// overridable Add(Tvalue, Tvalue) method to add/update a single value at the end of the list
|
||||||
public virtual void Add((System.DateTime t, double v)TValue1, (System.DateTime t, double v)TValue2, bool update)
|
public virtual void Add((System.DateTime t, double v)TValue1, (System.DateTime t, double v)TValue2, bool update) => base.Add(TValue: (TValue1.t, 0), update: update); // default inserts zeros
|
||||||
=> base.Add(TValue: (TValue1.t, 0), update: update); // default inserts zeros
|
|
||||||
|
|
||||||
|
|
||||||
// potentially overridable Add() bulk variations (could be replaced with faster bulk algos)
|
// potentially overridable Add() bulk variations (could be replaced with faster bulk algos)
|
||||||
public virtual void Add(TSeries d1, TSeries d2) {
|
public virtual void Add(TSeries d1, TSeries d2) { for (int i = 0; i < d1.Count; i++) { this.Add(d1[i], d2[i], update: false); }}
|
||||||
for (int i = 0; i < d1.Count; i++) { this.Add(d1[i], d2[i], update: false); }
|
public virtual void Add(TSeries d1, double dd2) { for (int i = 0; i < d1.Count; i++) { this.Add(d1[i], (d1[i].t, dd2), update: false); }}
|
||||||
}
|
public virtual void Add(double dd1, TSeries d2) { for (int i = 0; i < d2.Count; i++) { this.Add((d2[i].t, dd1), d2[i], update: false); }}
|
||||||
public virtual void Add(TSeries d1, double dd2) {
|
|
||||||
for (int i = 0; i < d1.Count; i++) { this.Add(d1[i], (d1[i].t, dd2), update: false); }
|
|
||||||
}
|
|
||||||
public virtual void Add(double dd1, TSeries d2) {
|
|
||||||
for (int i = 0; i < d2.Count; i++) { this.Add((d2[i].t, dd1), d2[i], update: false); }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public void Add((System.DateTime t, double v)TValue1, (System.DateTime t, double v)TValue2) => this.Add(TValue1, TValue2, update: false);
|
||||||
public void Add((System.DateTime t, double v)TValue1, (System.DateTime t, double v)TValue2)
|
|
||||||
=> this.Add(TValue1, TValue2, update: false);
|
|
||||||
|
|
||||||
public void Add(bool update)
|
public void Add(bool update)
|
||||||
{
|
{
|
||||||
@@ -123,12 +104,9 @@ public abstract class Pair_TSeries_Indicator : TSeries
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void Add() => this.Add(update: false);
|
public void Add() => this.Add(update: false);
|
||||||
|
public new void Sub(object source, TSeriesEventArgs e) => this.Add(e.update);
|
||||||
public new void Sub(object source, TSeriesEventArgs e)
|
|
||||||
=> this.Add(e.update);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public abstract class Single_TBars_Indicator : TSeries
|
public abstract class Single_TBars_Indicator : TSeries
|
||||||
{
|
{
|
||||||
protected readonly int _p;
|
protected readonly int _p;
|
||||||
@@ -148,22 +126,10 @@ public abstract class Single_TBars_Indicator : TSeries
|
|||||||
public virtual void Add((System.DateTime t, double o, double h, double l, double c, double v) TBar, bool update) => base.Add((TBar.t, 0.0), update);
|
public virtual void Add((System.DateTime t, double o, double h, double l, double c, double v) TBar, bool update) => base.Add((TBar.t, 0.0), update);
|
||||||
|
|
||||||
// potentially overridable Add() method for the whole bars or series (could be replaced with faster bulk algo)
|
// potentially overridable Add() method for the whole bars or series (could be replaced with faster bulk algo)
|
||||||
public virtual void Add(TBars bars)
|
public virtual void Add(TBars bars) { for (int i = 0; i < bars.Count; i++) { this.Add(TBar: bars[i], update: false); }}
|
||||||
{
|
public virtual void Add(TSeries data) { for (int i = 0; i < data.Count; i++) { base.Add(TValue: data[i], update: false); }}
|
||||||
for (int i = 0; i < bars.Count; i++) { this.Add(TBar: bars[i], update: false); }
|
public void Add((System.DateTime t, double o, double h, double l, double c, double v) TBar) => this.Add(TBar: TBar, update: false);
|
||||||
}
|
public void Add(bool update) => this.Add(TBar: this._bars[this._bars.Count - 1], update: update);
|
||||||
|
public void Add() => this.Add(TBar: this._bars[this._bars.Count - 1], update: false);
|
||||||
public virtual void Add(TSeries data)
|
public new void Sub(object source, TSeriesEventArgs e) => this.Add(TBar: this._bars[this._bars.Count - 1], update: e.update);
|
||||||
{
|
|
||||||
for (int i = 0; i < data.Count; i++) { base.Add(TValue: data[i], update: false); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Add((System.DateTime t, double o, double h, double l, double c, double v) TBar)
|
|
||||||
=> this.Add(TBar: TBar, update: false);
|
|
||||||
public void Add(bool update)
|
|
||||||
=> this.Add(TBar: this._bars[this._bars.Count - 1], update: update);
|
|
||||||
public void Add()
|
|
||||||
=> this.Add(TBar: this._bars[this._bars.Count - 1], update: false);
|
|
||||||
public new void Sub(object source, TSeriesEventArgs e)
|
|
||||||
=> this.Add(TBar: this._bars[this._bars.Count - 1], update: e.update);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,10 @@ public class MAX_Series : Single_TSeries_Indicator
|
|||||||
|
|
||||||
double _max = TValue.v;
|
double _max = TValue.v;
|
||||||
for (int i = 0; i < this._buffer.Count; i++)
|
for (int i = 0; i < this._buffer.Count; i++)
|
||||||
{ _max = (this._buffer[i] > _max) ? this._buffer[i] : _max; }
|
{
|
||||||
|
//_max = (this._buffer[i] > _max) ? this._buffer[i] : _max;
|
||||||
|
_max = Math.Max(this._buffer[i], _max);
|
||||||
|
}
|
||||||
|
|
||||||
var result = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _max);
|
var result = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _max);
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,10 @@ public class MIN_Series : Single_TSeries_Indicator
|
|||||||
|
|
||||||
double _min = TValue.v;
|
double _min = TValue.v;
|
||||||
for (int i = 0; i < this._buffer.Count; i++)
|
for (int i = 0; i < this._buffer.Count; i++)
|
||||||
{ _min = (this._buffer[i] < _min) ? this._buffer[i] : _min; }
|
{
|
||||||
|
//_min = (this._buffer[i] < _min) ? this._buffer[i] : _min;
|
||||||
|
_min = Math.Min(this._buffer[i], _min);
|
||||||
|
}
|
||||||
|
|
||||||
var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _min);
|
var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _min);
|
||||||
|
|
||||||
|
|||||||
@@ -75,7 +75,6 @@ public class TBars : System.Collections.Generic.List<(DateTime t, double o, doub
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void Add((DateTime t, double o, double h, double l, double c, double v) i, bool update = false)
|
public void Add((DateTime t, double o, double h, double l, double c, double v) i, bool update = false)
|
||||||
=> Add(i.t, i.o, i.h, i.l, i.c, i.v, update);
|
=> Add(i.t, i.o, i.h, i.l, i.c, i.v, update);
|
||||||
|
|
||||||
@@ -130,6 +129,4 @@ public class TBars : System.Collections.Generic.List<(DateTime t, double o, doub
|
|||||||
Pub(this, new TSeriesEventArgs { update = update });
|
Pub(this, new TSeriesEventArgs { update = update });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,5 @@ public class ZL_Series : Single_TSeries_Indicator
|
|||||||
|
|
||||||
var ret = (TValue.t, (base.Count==0 && base._NaN) ? double.NaN : _zl );
|
var ret = (TValue.t, (base.Count==0 && base._NaN) ? double.NaN : _zl );
|
||||||
base.Add(ret, update);
|
base.Add(ret, update);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -55,4 +55,3 @@ public class Alphavantage_Feed : TBars
|
|||||||
return (date, o, h, l, c, v);
|
return (date, o, h, l, c, v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,11 +38,11 @@ public class GBM_Feed : TBars
|
|||||||
|
|
||||||
double OCMax = Math.Max(Open,Close);
|
double OCMax = Math.Max(Open,Close);
|
||||||
double High = (GBM_value(seed, volatility*0.5, 0));
|
double High = (GBM_value(seed, volatility*0.5, 0));
|
||||||
High = (High<OCMax)? 2*OCMax-High : High;
|
High = (High<OCMax)? (2 * OCMax) - High : High;
|
||||||
|
|
||||||
double OCMin = Math.Min(Open,Close);
|
double OCMin = Math.Min(Open,Close);
|
||||||
double Low = (GBM_value(seed, volatility*0.5, 0));
|
double Low = (GBM_value(seed, volatility*0.5, 0));
|
||||||
Low = (Low>OCMin)? 2*OCMin-Low : Low;
|
Low = (Low>OCMin)? (2 * OCMin) - Low : Low;
|
||||||
|
|
||||||
double Volume = GBM_value(seed*10, volatility*2, Drift:0);
|
double Volume = GBM_value(seed*10, volatility*2, Drift:0);
|
||||||
|
|
||||||
@@ -55,6 +55,6 @@ public class GBM_Feed : TBars
|
|||||||
double U1 = 1.0-rnd.NextDouble();
|
double U1 = 1.0-rnd.NextDouble();
|
||||||
double U2 = 1.0-rnd.NextDouble();
|
double U2 = 1.0-rnd.NextDouble();
|
||||||
double Z = Math.Sqrt(-2.0 * Math.Log(U1)) * Math.Sin(2.0 * Math.PI * U2);
|
double Z = Math.Sqrt(-2.0 * Math.Log(U1)) * Math.Sin(2.0 * Math.PI * U2);
|
||||||
return Seed * Math.Exp( Drift - (Volatility*Volatility*0.5) + Volatility * Z);
|
return Seed * Math.Exp( Drift - (Volatility*Volatility*0.5) + (Volatility * Z));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -17,10 +17,10 @@ public class RND_Feed : TBars
|
|||||||
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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,14 +20,13 @@ public class CCI_Series : Single_TBars_Indicator
|
|||||||
{
|
{
|
||||||
private readonly System.Collections.Generic.List<double> _tp = new();
|
private readonly System.Collections.Generic.List<double> _tp = new();
|
||||||
|
|
||||||
public CCI_Series(TBars source, int period = 10, bool useNaN = false)
|
public CCI_Series(TBars source, int period = 10, bool useNaN = false) : base(source, period: period, useNaN: useNaN)
|
||||||
: base(source, period: period, useNaN: useNaN) {
|
{
|
||||||
|
|
||||||
if (_bars.Count > 0) { base.Add(_bars); }
|
if (_bars.Count > 0) { base.Add(_bars); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Add((DateTime t, double o, double h, double l, double c, double v) TBar, bool update) {
|
public override void Add((DateTime t, double o, double h, double l, double c, double v) TBar, bool update)
|
||||||
|
{
|
||||||
double _tpItem = (TBar.h + TBar.l + TBar.c) / 3.0;
|
double _tpItem = (TBar.h + TBar.l + TBar.c) / 3.0;
|
||||||
if (update) { this._tp[this._tp.Count - 1] = _tpItem; } else { this._tp.Add(_tpItem); }
|
if (update) { this._tp[this._tp.Count - 1] = _tpItem; } else { this._tp.Add(_tpItem); }
|
||||||
if (this._tp.Count > this._p) { this._tp.RemoveAt(0); }
|
if (this._tp.Count > this._p) { this._tp.RemoveAt(0); }
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Version>0.1.17</Version>
|
<Version>0.1.18</Version>
|
||||||
<releaseNotes>
|
<releaseNotes>
|
||||||
</releaseNotes>
|
</releaseNotes>
|
||||||
<Title>QuanTAlib</Title>
|
<Title>QuanTAlib</Title>
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ public class KURT_Series : Single_TSeries_Indicator
|
|||||||
}
|
}
|
||||||
|
|
||||||
double _Vx = _s2 / (_n - 1);
|
double _Vx = _s2 / (_n - 1);
|
||||||
double _kurt = (_n > 3) ? (((_n * (_n + 1)) / ((_n - 1) * (_n - 2) * (_n - 3))) * (_s4 / (_Vx * _Vx)) - (3 * ((_n - 1) * (_n - 1) / ((_n - 2) * (_n - 3))))) : Double.NaN;
|
double _kurt = (_n > 3) ? ((((_n * (_n + 1)) / (((_n - 1) * (_n - 2)) * (_n - 3))) * (_s4 / (_Vx * _Vx))) - (3 * (((_n - 1) * (_n - 1)) / ((_n - 2) * (_n - 3))))) : Double.NaN;
|
||||||
|
|
||||||
var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? Double.NaN : _kurt);
|
var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? Double.NaN : _kurt);
|
||||||
base.Add(result, update);
|
base.Add(result, update);
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ public class MED_Series : Single_TSeries_Indicator
|
|||||||
System.Collections.Generic.List<double> _s = new(this._buffer);
|
System.Collections.Generic.List<double> _s = new(this._buffer);
|
||||||
_s.Sort();
|
_s.Sort();
|
||||||
int _p1 = _s.Count / 2;
|
int _p1 = _s.Count / 2;
|
||||||
int _p2 = Math.Max(0, _s.Count / 2 - 1);
|
int _p2 = Math.Max(0, (_s.Count / 2) - 1);
|
||||||
double _med = (_s.Count % 2 != 0) ? _s[_p1] : (_s[_p1] + _s[_p2]) / 2;
|
double _med = (_s.Count % 2 != 0) ? _s[_p1] : (_s[_p1] + _s[_p2]) / 2;
|
||||||
|
|
||||||
var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _med);
|
var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _med);
|
||||||
|
|||||||
@@ -1,68 +1,65 @@
|
|||||||
namespace QuanTAlib;
|
namespace QuanTAlib;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
/* <summary>
|
/* <summary>
|
||||||
ALMA: Arnaud Legoux Moving Average
|
ALMA: Arnaud Legoux Moving Average
|
||||||
The ALMA moving average uses the curve of the Normal (Gauss) distribution, which
|
The ALMA moving average uses the curve of the Normal (Gauss) distribution, which
|
||||||
can be shifted from 0 to 1. This allows regulating the smoothness and high
|
can be shifted from 0 to 1. This allows regulating the smoothness and high
|
||||||
sensitivity of the indicator. Sigma is another parameter that is responsible for
|
sensitivity of the indicator. Sigma is another parameter that is responsible for
|
||||||
the shape of the curve coefficients. This moving average reduces lag of the data
|
the shape of the curve coefficients. This moving average reduces lag of the data
|
||||||
in conjunction with smoothing to reduce noise.
|
in conjunction with smoothing to reduce noise.
|
||||||
|
|
||||||
|
|
||||||
Sources:
|
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/
|
||||||
|
|
||||||
</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;
|
_offset = offset;
|
||||||
_sigma = sigma;
|
_sigma = sigma;
|
||||||
_weight = new double[period];
|
_weight = new double[period];
|
||||||
|
|
||||||
if (this._data.Count > 0) { base.Add(this._data); }
|
if (this._data.Count > 0) { base.Add(this._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)
|
||||||
{
|
{
|
||||||
if (update) { this._buffer[this._buffer.Count - 1] = TValue.v; }
|
if (update) { this._buffer[this._buffer.Count - 1] = TValue.v; }
|
||||||
else { this._buffer.Add(TValue.v); }
|
else { this._buffer.Add(TValue.v); }
|
||||||
if (this._buffer.Count > this._p) { this._buffer.RemoveAt(0); }
|
if (this._buffer.Count > this._p) { this._buffer.RemoveAt(0); }
|
||||||
|
|
||||||
if (this._buffer.Count <= _p) { calc_weights(); }
|
if (this._buffer.Count <= _p) { calc_weights(); }
|
||||||
|
|
||||||
double _weightedSum = 0;
|
double _weightedSum = 0;
|
||||||
for (int i = 0; i < this._buffer.Count; i++) { _weightedSum += _weight[i] * _buffer[i]; }
|
for (int i = 0; i < this._buffer.Count; i++) { _weightedSum += _weight[i] * _buffer[i]; }
|
||||||
double _alma = _weightedSum / _norm;
|
double _alma = _weightedSum / _norm;
|
||||||
|
|
||||||
var ret = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _alma);
|
var ret = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _alma);
|
||||||
base.Add(ret, update);
|
base.Add(ret, update);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void calc_weights()
|
private void calc_weights()
|
||||||
{
|
{
|
||||||
int _len = this._buffer.Count;
|
int _len = this._buffer.Count;
|
||||||
_norm = 0;
|
_norm = 0;
|
||||||
double _m = _offset * (_len - 1);
|
double _m = _offset * (_len - 1);
|
||||||
double _s = _len / _sigma;
|
double _s = _len / _sigma;
|
||||||
for (int i = 0; i < _len; i++)
|
for (int i = 0; i < _len; i++)
|
||||||
{
|
{
|
||||||
double _wt = Math.Exp(-((i - _m) * (i - _m)) / (2 * _s * _s));
|
double _wt = Math.Exp(-((i - _m) * (i - _m)) / (2 * _s * _s));
|
||||||
_weight[i] = _wt;
|
_weight[i] = _wt;
|
||||||
_norm += _wt;
|
_norm += _wt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@@ -31,7 +31,6 @@ public class DEMA_Series : Single_TSeries_Indicator
|
|||||||
|
|
||||||
public override void Add((DateTime t, double v) TValue, bool update)
|
public override void Add((DateTime t, double v) TValue, bool update)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (update)
|
if (update)
|
||||||
{
|
{
|
||||||
this._lastema1 = this._lastlastema1;
|
this._lastema1 = this._lastlastema1;
|
||||||
@@ -53,15 +52,14 @@ public class DEMA_Series : Single_TSeries_Indicator
|
|||||||
for (int i = 0; i < _buffer.Count; i++) { _sma += _buffer[i]; }
|
for (int i = 0; i < _buffer.Count; i++) { _sma += _buffer[i]; }
|
||||||
_sma /= this._buffer.Count;
|
_sma /= this._buffer.Count;
|
||||||
_ema1 = _ema2 = _sma;
|
_ema1 = _ema2 = _sma;
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_ema1 = TValue.v * this._k + this._lastema1 * this._k1m;
|
_ema1 = (TValue.v * this._k) + (this._lastema1 * this._k1m);
|
||||||
_ema2 = _ema1 * this._k + this._lastema2 * this._k1m;
|
_ema2 = (_ema1 * this._k) + (this._lastema2 * this._k1m);
|
||||||
}
|
}
|
||||||
|
|
||||||
double _dema = 2 * _ema1 - _ema2;
|
double _dema = (2 * _ema1) - _ema2;
|
||||||
this._lastlastema1 = this._lastema1;
|
this._lastlastema1 = this._lastema1;
|
||||||
this._lastlastema2 = this._lastema2;
|
this._lastlastema2 = this._lastema2;
|
||||||
this._lastema1 = _ema1;
|
this._lastema1 = _ema1;
|
||||||
@@ -52,7 +52,7 @@ public class EMA_Series : Single_TSeries_Indicator
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_ema = TValue.v * this._k + this._lastema * this._k1m;
|
_ema = (TValue.v * this._k) + (this._lastema * this._k1m);
|
||||||
}
|
}
|
||||||
|
|
||||||
this._lastlastema = this._lastema;
|
this._lastlastema = this._lastema;
|
||||||
@@ -1,65 +1,65 @@
|
|||||||
namespace QuanTAlib;
|
namespace QuanTAlib;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
/* <summary>
|
/* <summary>
|
||||||
KAMA: Kaufman's Adaptive Moving Average
|
KAMA: Kaufman's Adaptive Moving Average
|
||||||
Created in 1988 by American quantitative finance theorist Perry J. Kaufman and is known as
|
Created in 1988 by American quantitative finance theorist Perry J. Kaufman and is known as
|
||||||
Kaufman's Adaptive Moving Average (KAMA). Even though the method was developed as early as 1972,
|
Kaufman's Adaptive Moving Average (KAMA). Even though the method was developed as early as 1972,
|
||||||
it was not until the popular book titled "Trading Systems and Methods" that it was made widely
|
it was not until the popular book titled "Trading Systems and Methods" that it was made widely
|
||||||
available to the public. Unlike other conventional moving averages systems, the Kaufman's Adaptive
|
available to the public. Unlike other conventional moving averages systems, the Kaufman's Adaptive
|
||||||
Moving Average, considers market volatility apart from price fluctuations.
|
Moving Average, considers market volatility apart from price fluctuations.
|
||||||
|
|
||||||
KAMAi = KAMAi - 1 + SC * ( price - KAMAi-1 )
|
KAMAi = KAMAi - 1 + SC * ( price - KAMAi-1 )
|
||||||
|
|
||||||
Sources:
|
Sources:
|
||||||
https://www.tutorialspoint.com/kaufman-s-adaptive-moving-average-kama-formula-and-how-does-it-work
|
https://www.tutorialspoint.com/kaufman-s-adaptive-moving-average-kama-formula-and-how-does-it-work
|
||||||
https://corporatefinanceinstitute.com/resources/knowledge/trading-investing/kaufmans-adaptive-moving-average-kama/
|
https://corporatefinanceinstitute.com/resources/knowledge/trading-investing/kaufmans-adaptive-moving-average-kama/
|
||||||
https://www.technicalindicators.net/indicators-technical-analysis/152-kama-kaufman-adaptive-moving-average
|
https://www.technicalindicators.net/indicators-technical-analysis/152-kama-kaufman-adaptive-moving-average
|
||||||
|
|
||||||
Remark:
|
Remark:
|
||||||
If useNaN:true argument is provided, KAMA starts calculating values from [period] bar onwards.
|
If useNaN:true argument is provided, KAMA starts calculating values from [period] bar onwards.
|
||||||
Without useNaN argument (default setting), KAMA starts calculating values from bar 1 - and yields
|
Without useNaN argument (default setting), KAMA starts calculating values from bar 1 - and yields
|
||||||
slightly different results for the first 50 bars - and then converges with the other one.
|
slightly different results for the first 50 bars - and then converges with the other one.
|
||||||
|
|
||||||
</summary> */
|
</summary> */
|
||||||
|
|
||||||
public class KAMA_Series : Single_TSeries_Indicator
|
public class KAMA_Series : Single_TSeries_Indicator
|
||||||
{
|
{
|
||||||
private readonly double _scFast, _scSlow;
|
private readonly double _scFast, _scSlow;
|
||||||
private readonly System.Collections.Generic.List<double> _buffer = new();
|
private readonly System.Collections.Generic.List<double> _buffer = new();
|
||||||
private double _lastkama = double.NaN;
|
private double _lastkama = double.NaN;
|
||||||
private double _lastlastkama;
|
private double _lastlastkama;
|
||||||
|
|
||||||
public KAMA_Series(TSeries source, int period, int fast = 2, int slow= 30, bool useNaN = false) : base(source, period, useNaN) {
|
public KAMA_Series(TSeries source, int period, int fast = 2, int slow= 30, bool useNaN = false) : base(source, period, useNaN) {
|
||||||
_scFast = 2.0 / (fast+1);
|
_scFast = 2.0 / (fast+1);
|
||||||
_scSlow = 2.0 / (slow+1);
|
_scSlow = 2.0 / (slow+1);
|
||||||
if (base._data.Count > 0) { base.Add(base._data); }
|
if (base._data.Count > 0) { base.Add(base._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)
|
||||||
{
|
{
|
||||||
if (update){
|
if (update){
|
||||||
_buffer[_buffer.Count - 1] = TValue.v;
|
_buffer[_buffer.Count - 1] = TValue.v;
|
||||||
this._lastkama = this._lastlastkama;
|
this._lastkama = this._lastlastkama;
|
||||||
} else {
|
} else {
|
||||||
_buffer.Add(TValue.v);
|
_buffer.Add(TValue.v);
|
||||||
}
|
}
|
||||||
if (_buffer.Count > _p + 1) { _buffer.RemoveAt(0); }
|
if (_buffer.Count > _p + 1) { _buffer.RemoveAt(0); }
|
||||||
double _kama = 0;
|
double _kama = 0;
|
||||||
if (this.Count < this._p) {
|
if (this.Count < this._p) {
|
||||||
for (int i = 0; i < this._buffer.Count; i++) { _kama += this._buffer[i]; }
|
for (int i = 0; i < this._buffer.Count; i++) { _kama += this._buffer[i]; }
|
||||||
_kama /= this._buffer.Count;
|
_kama /= this._buffer.Count;
|
||||||
} else {
|
} else {
|
||||||
double _change = Math.Abs(_buffer[_buffer.Count - 1] - _buffer[(_buffer.Count > _p + 1) ? 1 : 0]);
|
double _change = Math.Abs(_buffer[_buffer.Count - 1] - _buffer[(_buffer.Count > _p + 1) ? 1 : 0]);
|
||||||
double _sumpv = 0;
|
double _sumpv = 0;
|
||||||
for (int i = 1; i < _buffer.Count; i++)
|
for (int i = 1; i < _buffer.Count; i++)
|
||||||
{ _sumpv += Math.Abs(_buffer[(_buffer.Count > 0) ? i : 0] - _buffer[i - 1]); }
|
{ _sumpv += Math.Abs(_buffer[(_buffer.Count > 0) ? i : 0] - _buffer[i - 1]); }
|
||||||
double _er = (_sumpv == 0) ? 0 : _change / _sumpv;
|
double _er = (_sumpv == 0) ? 0 : _change / _sumpv;
|
||||||
double _sc = (_er * (_scFast - _scSlow)) + _scSlow;
|
double _sc = (_er * (_scFast - _scSlow)) + _scSlow;
|
||||||
_kama = (_lastkama + (_sc * _sc * (TValue.v - _lastkama)));
|
_kama = (_lastkama + (_sc * _sc * (TValue.v - _lastkama)));
|
||||||
}
|
}
|
||||||
_lastlastkama = _lastkama;
|
_lastlastkama = _lastkama;
|
||||||
_lastkama = _kama;
|
_lastkama = _kama;
|
||||||
var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _kama);
|
var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _kama);
|
||||||
base.Add(result, update);
|
base.Add(result, update);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -51,7 +51,7 @@ public class RMA_Series : Single_TSeries_Indicator
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_ema = TValue.v * _k + _lastema * _k1m;
|
_ema = (TValue.v * _k) + (_lastema * _k1m);
|
||||||
}
|
}
|
||||||
|
|
||||||
this._lastlastema = this._lastema;
|
this._lastlastema = this._lastema;
|
||||||
@@ -33,7 +33,6 @@ public class TEMA_Series : Single_TSeries_Indicator
|
|||||||
|
|
||||||
public override void Add((DateTime t, double v) TValue, bool update)
|
public override void Add((DateTime t, double v) TValue, bool update)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (update)
|
if (update)
|
||||||
{
|
{
|
||||||
this._lastema1 = this._lastlastema1;
|
this._lastema1 = this._lastlastema1;
|
||||||
@@ -59,12 +58,12 @@ public class TEMA_Series : Single_TSeries_Indicator
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_ema1 = TValue.v * this._k + this._lastema1 * this._k1m;
|
_ema1 = (TValue.v * this._k) + (this._lastema1 * this._k1m);
|
||||||
_ema2 = _ema1 * this._k + this._lastema2 * this._k1m;
|
_ema2 = (_ema1 * this._k) + (this._lastema2 * this._k1m);
|
||||||
_ema3 = _ema2 * this._k + this._lastema3 * this._k1m;
|
_ema3 = (_ema2 * this._k) + (this._lastema3 * this._k1m);
|
||||||
}
|
}
|
||||||
|
|
||||||
double _tema = 3 * (_ema1 - _ema2) + _ema3;
|
double _tema = (3 * (_ema1 - _ema2)) + _ema3;
|
||||||
|
|
||||||
this._lastlastema1 = this._lastema1;
|
this._lastlastema1 = this._lastema1;
|
||||||
this._lastlastema2 = this._lastema2;
|
this._lastlastema2 = this._lastema2;
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
namespace QuanTAlib;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
/* <summary>
|
||||||
|
TRIMA: Triangular Moving Average
|
||||||
|
A weighted moving average where the shape of the weights are triangular and the greatest
|
||||||
|
weight is in the middle of the period,
|
||||||
|
|
||||||
|
Sources:
|
||||||
|
https://www.tradingtechnologies.com/help/x-study/technical-indicator-definitions/triangular-moving-average-trima/
|
||||||
|
|
||||||
|
Remark:
|
||||||
|
trima = sma(sma(signal, n/2), n/2)
|
||||||
|
|
||||||
|
</summary> */
|
||||||
|
|
||||||
|
public class TRIMA_Series : Single_TSeries_Indicator
|
||||||
|
{
|
||||||
|
private readonly System.Collections.Generic.List<double> _buffer1 = new();
|
||||||
|
private readonly System.Collections.Generic.List<double> _buffer2 = new();
|
||||||
|
private readonly int _p1a, _p1b;
|
||||||
|
|
||||||
|
public TRIMA_Series(TSeries source, int period, bool useNaN = false) : base(source, period, useNaN)
|
||||||
|
{
|
||||||
|
_p1a = (int) Math.Floor((period * 0.5) + 1);
|
||||||
|
_p1b = (int) Math.Ceiling(0.5 * period);
|
||||||
|
if (base._data.Count > 0) { base.Add(base._data); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Add((System.DateTime t, double v) TValue, bool update)
|
||||||
|
{
|
||||||
|
if (update) { _buffer1[_buffer1.Count - 1] = TValue.v; } else { _buffer1.Add(TValue.v); }
|
||||||
|
if (_buffer1.Count > this._p1b && this._p1b != 0) { _buffer1.RemoveAt(0); }
|
||||||
|
|
||||||
|
double _sma1 = 0;
|
||||||
|
for (int i = 0; i < _buffer1.Count; i++) { _sma1 += _buffer1[i]; }
|
||||||
|
_sma1 /= this._buffer1.Count;
|
||||||
|
|
||||||
|
if (update) { _buffer2[_buffer2.Count - 1] = _sma1; } else { _buffer2.Add(_sma1); }
|
||||||
|
if (_buffer2.Count > this._p1a && this._p1a != 0) { _buffer2.RemoveAt(0); }
|
||||||
|
|
||||||
|
double _trima = 0;
|
||||||
|
for (int i = 0; i < _buffer2.Count; i++) { _trima += _buffer2[i]; }
|
||||||
|
_trima /= this._buffer2.Count;
|
||||||
|
|
||||||
|
var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _trima);
|
||||||
|
base.Add(result, update);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,72 +1,72 @@
|
|||||||
namespace QuanTAlib;
|
namespace QuanTAlib;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
/* <summary>
|
/* <summary>
|
||||||
ZLEMA: Zero Lag Exponential Moving Average
|
ZLEMA: Zero Lag Exponential Moving Average
|
||||||
The Zero lag exponential moving average (ZLEMA) indicator was created by John
|
The Zero lag exponential moving average (ZLEMA) indicator was created by John
|
||||||
Ehlers and Ric Way.
|
Ehlers and Ric Way.
|
||||||
|
|
||||||
The formula for a given N-Day period and for a given Data series is:
|
The formula for a given N-Day period and for a given Data series is:
|
||||||
Lag = (Period-1)/2
|
Lag = (Period-1)/2
|
||||||
Ema Data = {Data+(Data-Data(Lag days ago))
|
Ema Data = {Data+(Data-Data(Lag days ago))
|
||||||
ZLEMA = EMA (EmaData,Period)
|
ZLEMA = EMA (EmaData,Period)
|
||||||
|
|
||||||
Remark:
|
Remark:
|
||||||
The idea is do a regular exponential moving average (EMA) calculation but on a
|
The idea is do a regular exponential moving average (EMA) calculation but on a
|
||||||
de-lagged data instead of doing it on the regular data. Data is de-lagged by
|
de-lagged data instead of doing it on the regular data. Data is de-lagged by
|
||||||
removing the data from "lag" days ago thus removing (or attempting to remove)
|
removing the data from "lag" days ago thus removing (or attempting to remove)
|
||||||
the cumulative lag effect of the moving average.
|
the cumulative lag effect of the moving average.
|
||||||
|
|
||||||
</summary> */
|
</summary> */
|
||||||
|
|
||||||
public class ZLEMA_Series : Single_TSeries_Indicator
|
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, _lastlastema;
|
||||||
|
|
||||||
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._lastlastema = double.NaN;
|
||||||
if (base._data.Count > 0)
|
if (base._data.Count > 0)
|
||||||
{ base.Add(base._data); }
|
{ base.Add(base._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 = (int)((_p-1) * 0.5);
|
||||||
_lag = (this.Count-_lag < 0) ? 0 : this.Count-_lag;
|
_lag = (this.Count-_lag < 0) ? 0 : this.Count-_lag;
|
||||||
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)
|
if (update)
|
||||||
{ this._lastema = this._lastlastema; }
|
{ this._lastema = this._lastlastema; }
|
||||||
if (this.Count < this._p)
|
if (this.Count < this._p)
|
||||||
{
|
{
|
||||||
if (update)
|
if (update)
|
||||||
{ this._buffer[this._buffer.Count - 1] = _zl; }
|
{ this._buffer[this._buffer.Count - 1] = _zl; }
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this._buffer.Add(_zl);
|
this._buffer.Add(_zl);
|
||||||
}
|
}
|
||||||
if (this._buffer.Count > this._p)
|
if (this._buffer.Count > this._p)
|
||||||
{ this._buffer.RemoveAt(0); }
|
{ this._buffer.RemoveAt(0); }
|
||||||
|
|
||||||
for (int i = 0; i < this._buffer.Count; i++)
|
for (int i = 0; i < this._buffer.Count; i++)
|
||||||
{ _ema += this._buffer[i]; }
|
{ _ema += this._buffer[i]; }
|
||||||
_ema /= this._buffer.Count;
|
_ema /= this._buffer.Count;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_ema = _zl * this._k + this._lastema * this._k1m;
|
_ema = (_zl * this._k) + (this._lastema * this._k1m);
|
||||||
}
|
}
|
||||||
|
|
||||||
this._lastlastema = this._lastema;
|
this._lastlastema = this._lastema;
|
||||||
this._lastema = _ema;
|
this._lastema = _ema;
|
||||||
|
|
||||||
var ret = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _ema);
|
var ret = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _ema);
|
||||||
base.Add(ret, update);
|
base.Add(ret, update);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -50,7 +50,7 @@ public class ATRP_Series : Single_TBars_Indicator
|
|||||||
for (int i = 0; i < _buffer.Count; i++) { _ema += _buffer[i]; }
|
for (int i = 0; i < _buffer.Count; i++) { _ema += _buffer[i]; }
|
||||||
_ema /= this._buffer.Count;
|
_ema /= this._buffer.Count;
|
||||||
}
|
}
|
||||||
else { _ema = d.v * _k + _lastema * _k1m; }
|
else { _ema = (d.v * _k) + (_lastema * _k1m); }
|
||||||
|
|
||||||
this._lastlastema = this._lastema;
|
this._lastlastema = this._lastema;
|
||||||
this._lastema = _ema;
|
this._lastema = _ema;
|
||||||
@@ -13,7 +13,6 @@ Sources:
|
|||||||
|
|
||||||
</summary> */
|
</summary> */
|
||||||
|
|
||||||
|
|
||||||
public class ATR_Series : Single_TBars_Indicator
|
public class ATR_Series : Single_TBars_Indicator
|
||||||
{
|
{
|
||||||
private readonly System.Collections.Generic.List<double> _buffer = new();
|
private readonly System.Collections.Generic.List<double> _buffer = new();
|
||||||
@@ -53,7 +52,7 @@ public class ATR_Series : Single_TBars_Indicator
|
|||||||
for (int i = 0; i < _buffer.Count; i++) { _ema += _buffer[i]; }
|
for (int i = 0; i < _buffer.Count; i++) { _ema += _buffer[i]; }
|
||||||
_ema /= this._buffer.Count;
|
_ema /= this._buffer.Count;
|
||||||
}
|
}
|
||||||
else { _ema = d.v * _k + _lastema * _k1m; }
|
else { _ema = (d.v * _k) + (_lastema * _k1m); }
|
||||||
|
|
||||||
this._lastlastema = this._lastema;
|
this._lastlastema = this._lastema;
|
||||||
this._lastema = _ema;
|
this._lastema = _ema;
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
namespace QuanTAlib;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
/* <summary>
|
||||||
|
OBV: On-Balance Volume
|
||||||
|
On-balance volume (OBV) is a technical trading momentum indicator that uses volume flow to predict
|
||||||
|
changes in stock price. Joseph Granville first developed the OBV metric in the 1963 book
|
||||||
|
Granville's New Key to Stock Market Profits.
|
||||||
|
|
||||||
|
| +volume; if close > close[previous]
|
||||||
|
OBV = OBV[previous] + | 0; if close = close[previous]
|
||||||
|
| -volume; if close < close[previous]
|
||||||
|
|
||||||
|
Sources:
|
||||||
|
https://www.investopedia.com/terms/o/onbalancevolume.asp
|
||||||
|
https://www.tradingview.com/wiki/On_Balance_Volume_(OBV)
|
||||||
|
https://www.tradingtechnologies.com/help/x-study/technical-indicator-definitions/on-balance-volume-obv/
|
||||||
|
https://www.motivewave.com/studies/on_balance_volume.htm
|
||||||
|
|
||||||
|
Note:
|
||||||
|
There is no consensus on what is the first OBV value in the series:
|
||||||
|
- TA-LIB uses the first volume: OBV[0] = volume[0]
|
||||||
|
- Skender stock library uses 0: OBV[0] = 0
|
||||||
|
|
||||||
|
</summary> */
|
||||||
|
|
||||||
|
public class OBV_Series : Single_TBars_Indicator
|
||||||
|
{
|
||||||
|
private double _lastobv, _lastlastobv;
|
||||||
|
private double _lastclose, _lastlastclose;
|
||||||
|
public OBV_Series(TBars source, int period = 10, bool useNaN = false) : base(source, period: period, useNaN: useNaN)
|
||||||
|
{
|
||||||
|
this._lastobv = this._lastlastobv = 0;
|
||||||
|
this._lastclose = this._lastlastclose = 0;
|
||||||
|
if (_bars.Count > 0) { base.Add(_bars); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Add((DateTime t, double o, double h, double l, double c, double v) TBar, bool update)
|
||||||
|
{
|
||||||
|
if (update)
|
||||||
|
{
|
||||||
|
this._lastobv = this._lastlastobv;
|
||||||
|
this._lastclose = this._lastlastclose;
|
||||||
|
}
|
||||||
|
|
||||||
|
double _obv = this._lastobv;
|
||||||
|
if (TBar.c > this._lastclose) { _obv += TBar.v; }
|
||||||
|
if (TBar.c < this._lastclose) { _obv -= TBar.v; }
|
||||||
|
|
||||||
|
// Unclear what the first value in OBV series is - currently set to volume[0]
|
||||||
|
// if (this.Count == 0) { _obv = 0; }
|
||||||
|
|
||||||
|
this._lastlastobv = this._lastobv;
|
||||||
|
this._lastobv = _obv;
|
||||||
|
|
||||||
|
this._lastlastclose = this._lastclose;
|
||||||
|
this._lastclose = TBar.c;
|
||||||
|
|
||||||
|
var result = (TBar.t, (this.Count < this._p && this._NaN) ? double.NaN : _obv);
|
||||||
|
base.Add(result, update);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -108,6 +108,5 @@ public class TBars_Test
|
|||||||
s.Add(DateTime.Today, 0.1, 1.1, 2.1, 3.1, 4.1, false);
|
s.Add(DateTime.Today, 0.1, 1.1, 2.1, 3.1, 4.1, false);
|
||||||
Assert.Equal(s.Close.v, t.v);
|
Assert.Equal(s.Close.v, t.v);
|
||||||
Assert.Equal(s.Close.Count, t.Count);
|
Assert.Equal(s.Close.Count, t.Count);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,6 @@ public class TSeries_Test
|
|||||||
TSeries t = s;
|
TSeries t = s;
|
||||||
Assert.Equal(5, (double)t);
|
Assert.Equal(5, (double)t);
|
||||||
Assert.Equal(5, t.Count);
|
Assert.Equal(5, t.Count);
|
||||||
|
|
||||||
}
|
}
|
||||||
[Fact]
|
[Fact]
|
||||||
public void BroadcastingEvents()
|
public void BroadcastingEvents()
|
||||||
@@ -58,6 +57,5 @@ public class TSeries_Test
|
|||||||
s.Pub += t.Sub;
|
s.Pub += t.Sub;
|
||||||
s.Add(0.0, update: true);
|
s.Add(0.0, update: true);
|
||||||
Assert.Equal(0.0, (double)t);
|
Assert.Equal(0.0, (double)t);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,5 @@ public class ALMA_Test
|
|||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
a.Add(double.PositiveInfinity);
|
a.Add(double.PositiveInfinity);
|
||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,7 +52,5 @@ public class BBANDS_Test
|
|||||||
Assert.Equal(a.Count, c.PercentB.Count);
|
Assert.Equal(a.Count, c.PercentB.Count);
|
||||||
Assert.Equal(a.Count, c.Zscore.Count);
|
Assert.Equal(a.Count, c.Zscore.Count);
|
||||||
Assert.Equal(a.Count, c.Bandwidth.Count);
|
Assert.Equal(a.Count, c.Bandwidth.Count);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,5 @@ public class DEMA_Test
|
|||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
a.Add(double.PositiveInfinity);
|
a.Add(double.PositiveInfinity);
|
||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,5 @@ public class EMA_Test
|
|||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
a.Add(double.PositiveInfinity);
|
a.Add(double.PositiveInfinity);
|
||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,5 @@ public class HEMA_Test
|
|||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
a.Add(double.PositiveInfinity);
|
a.Add(double.PositiveInfinity);
|
||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,5 @@ public class HMA_Test
|
|||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
a.Add(double.PositiveInfinity);
|
a.Add(double.PositiveInfinity);
|
||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,5 @@ public class JMA_Test
|
|||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
a.Add(double.PositiveInfinity);
|
a.Add(double.PositiveInfinity);
|
||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,5 @@ public class KAMA_Test
|
|||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
a.Add(double.PositiveInfinity);
|
a.Add(double.PositiveInfinity);
|
||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,5 @@ public class MACD_Test
|
|||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
a.Add(double.PositiveInfinity);
|
a.Add(double.PositiveInfinity);
|
||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,5 @@ public class RMA_Test
|
|||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
a.Add(double.PositiveInfinity);
|
a.Add(double.PositiveInfinity);
|
||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,5 @@ public class RSI_Test
|
|||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
a.Add(double.PositiveInfinity);
|
a.Add(double.PositiveInfinity);
|
||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,5 @@ public class SMA_Test
|
|||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
a.Add(double.PositiveInfinity);
|
a.Add(double.PositiveInfinity);
|
||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,5 @@ public class SMMA_Test
|
|||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
a.Add(double.PositiveInfinity);
|
a.Add(double.PositiveInfinity);
|
||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,5 @@ public class TEMA_Test
|
|||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
a.Add(double.PositiveInfinity);
|
a.Add(double.PositiveInfinity);
|
||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,5 @@ public class WMA_Test
|
|||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
a.Add(double.PositiveInfinity);
|
a.Add(double.PositiveInfinity);
|
||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,5 @@ public class ZLEMA_Test
|
|||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
a.Add(double.PositiveInfinity);
|
a.Add(double.PositiveInfinity);
|
||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,5 @@ public class BIAS_Test
|
|||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
a.Add(double.PositiveInfinity);
|
a.Add(double.PositiveInfinity);
|
||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,5 @@ public class KURT_Test
|
|||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
a.Add(double.PositiveInfinity);
|
a.Add(double.PositiveInfinity);
|
||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,5 @@ public class ENTP_Test
|
|||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
a.Add(double.PositiveInfinity);
|
a.Add(double.PositiveInfinity);
|
||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,5 @@ public class LINREG_Test
|
|||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
a.Add(double.PositiveInfinity);
|
a.Add(double.PositiveInfinity);
|
||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,5 @@ public class MAD_Test
|
|||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
a.Add(double.PositiveInfinity);
|
a.Add(double.PositiveInfinity);
|
||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,5 @@ public class MAPE_Test
|
|||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
a.Add(double.PositiveInfinity);
|
a.Add(double.PositiveInfinity);
|
||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,5 @@ public class MAX_Test
|
|||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
a.Add(double.PositiveInfinity);
|
a.Add(double.PositiveInfinity);
|
||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,5 @@ public class MED_Test
|
|||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
a.Add(double.PositiveInfinity);
|
a.Add(double.PositiveInfinity);
|
||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,5 @@ public class MIN_Test
|
|||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
a.Add(double.PositiveInfinity);
|
a.Add(double.PositiveInfinity);
|
||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,5 @@ public class MSE_Test
|
|||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
a.Add(double.PositiveInfinity);
|
a.Add(double.PositiveInfinity);
|
||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,5 @@ public class PSDEV_Test
|
|||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
a.Add(double.PositiveInfinity);
|
a.Add(double.PositiveInfinity);
|
||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,5 @@ public class PVAR_Test
|
|||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
a.Add(double.PositiveInfinity);
|
a.Add(double.PositiveInfinity);
|
||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,5 @@ public class SDEV_Test
|
|||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
a.Add(double.PositiveInfinity);
|
a.Add(double.PositiveInfinity);
|
||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,5 @@ public class SMAPE_Test
|
|||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
a.Add(double.PositiveInfinity);
|
a.Add(double.PositiveInfinity);
|
||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,5 @@ public class VAR_Test
|
|||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
a.Add(double.PositiveInfinity);
|
a.Add(double.PositiveInfinity);
|
||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,5 @@ public class WMAPE_Test
|
|||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
a.Add(double.PositiveInfinity);
|
a.Add(double.PositiveInfinity);
|
||||||
Assert.Equal(a.Count, c.Count);
|
Assert.Equal(a.Count, c.Count);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
|
|
||||||
|
|
||||||
using Xunit;
|
using Xunit;
|
||||||
using System;
|
using System;
|
||||||
using QuanTAlib;
|
using QuanTAlib;
|
||||||
@@ -120,5 +118,4 @@ public class PandasTA
|
|||||||
Assert.Equal(System.Math.Round((double)pta.tail(1), 7), Math.Round(QL.Last().v, 7));
|
Assert.Equal(System.Math.Round((double)pta.tail(1), 7), Math.Round(QL.Last().v, 7));
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -3,7 +3,6 @@ using QuanTAlib;
|
|||||||
using Skender.Stock.Indicators;
|
using Skender.Stock.Indicators;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
|
||||||
namespace Validation;
|
namespace Validation;
|
||||||
public class Skender_Stock
|
public class Skender_Stock
|
||||||
{
|
{
|
||||||
@@ -14,7 +13,7 @@ public class Skender_Stock
|
|||||||
|
|
||||||
public Skender_Stock()
|
public Skender_Stock()
|
||||||
{
|
{
|
||||||
this.bars = new(1000);
|
this.bars = new(Bars: 1, Volatility:0.7, Drift:0.0);
|
||||||
this.period = this.rnd.Next(28) + 3;
|
this.period = this.rnd.Next(28) + 3;
|
||||||
this.quotes = this.bars.Select(
|
this.quotes = this.bars.Select(
|
||||||
q => new Quote
|
q => new Quote
|
||||||
@@ -34,7 +33,7 @@ public class Skender_Stock
|
|||||||
SMA_Series QL = new(this.bars.Close, this.period, false);
|
SMA_Series QL = new(this.bars.Close, this.period, false);
|
||||||
var SK = this.quotes.GetSma(this.period);
|
var SK = this.quotes.GetSma(this.period);
|
||||||
|
|
||||||
Assert.Equal(Math.Round((double)SK.Last().Sma!, 8), Math.Round(QL.Last().v, 8));
|
Assert.Equal(Math.Round((double)SK.Last().Sma!, 6), Math.Round(QL.Last().v, 6));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -43,7 +42,7 @@ public class Skender_Stock
|
|||||||
EMA_Series QL = new(this.bars.Close, this.period, false);
|
EMA_Series QL = new(this.bars.Close, this.period, false);
|
||||||
var SK = this.quotes.GetEma(this.period);
|
var SK = this.quotes.GetEma(this.period);
|
||||||
|
|
||||||
Assert.Equal(Math.Round((double)SK.Last().Ema!, 8), Math.Round(QL.Last().v, 8));
|
Assert.Equal(Math.Round((double)SK.Last().Ema!, 6), Math.Round(QL.Last().v, 6));
|
||||||
}
|
}
|
||||||
[Fact]
|
[Fact]
|
||||||
public void WMA()
|
public void WMA()
|
||||||
@@ -51,7 +50,7 @@ public class Skender_Stock
|
|||||||
WMA_Series QL = new(this.bars.Close, this.period, false);
|
WMA_Series QL = new(this.bars.Close, this.period, false);
|
||||||
var SK = this.quotes.GetWma(this.period);
|
var SK = this.quotes.GetWma(this.period);
|
||||||
|
|
||||||
Assert.Equal(Math.Round((double)SK.Last().Wma!, 8), Math.Round(QL.Last().v, 8));
|
Assert.Equal(Math.Round((double)SK.Last().Wma!, 6), Math.Round(QL.Last().v, 6));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -60,7 +59,7 @@ public class Skender_Stock
|
|||||||
DEMA_Series QL = new(this.bars.Close, this.period, false);
|
DEMA_Series QL = new(this.bars.Close, this.period, false);
|
||||||
var SK = this.quotes.GetDema(this.period);
|
var SK = this.quotes.GetDema(this.period);
|
||||||
|
|
||||||
Assert.Equal(Math.Round((double)SK.Last().Dema!, 8), Math.Round(QL.Last().v, 8));
|
Assert.Equal(Math.Round((double)SK.Last().Dema!, 6), Math.Round(QL.Last().v, 6));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -69,7 +68,7 @@ public class Skender_Stock
|
|||||||
TEMA_Series QL = new(this.bars.Close, this.period, false);
|
TEMA_Series QL = new(this.bars.Close, this.period, false);
|
||||||
var SK = this.quotes.GetTema(this.period);
|
var SK = this.quotes.GetTema(this.period);
|
||||||
|
|
||||||
Assert.Equal(Math.Round((double)SK.Last().Tema!, 8), Math.Round(QL.Last().v, 8));
|
Assert.Equal(Math.Round((double)SK.Last().Tema!, 6), Math.Round(QL.Last().v, 6));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -78,7 +77,7 @@ public class Skender_Stock
|
|||||||
MAD_Series QL = new(this.bars.Close, this.period, false);
|
MAD_Series QL = new(this.bars.Close, this.period, false);
|
||||||
var SK = this.quotes.GetSmaAnalysis(this.period);
|
var SK = this.quotes.GetSmaAnalysis(this.period);
|
||||||
|
|
||||||
Assert.Equal(Math.Round((double)SK.Last().Mad!, 8), Math.Round(QL.Last().v, 8));
|
Assert.Equal(Math.Round((double)SK.Last().Mad!, 6), Math.Round(QL.Last().v, 6));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -87,7 +86,7 @@ public class Skender_Stock
|
|||||||
MAPE_Series QL = new(this.bars.Close, this.period, false);
|
MAPE_Series QL = new(this.bars.Close, this.period, false);
|
||||||
var SK = this.quotes.GetSmaAnalysis(this.period);
|
var SK = this.quotes.GetSmaAnalysis(this.period);
|
||||||
|
|
||||||
Assert.Equal(Math.Round((double)SK.Last().Mape!, 8), Math.Round(QL.Last().v, 8));
|
Assert.Equal(Math.Round((double)SK.Last().Mape!, 6), Math.Round(QL.Last().v, 6));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -96,7 +95,18 @@ public class Skender_Stock
|
|||||||
ATR_Series QL = new(this.bars, this.period, false);
|
ATR_Series QL = new(this.bars, this.period, false);
|
||||||
var SK = this.quotes.GetAtr(this.period);
|
var SK = this.quotes.GetAtr(this.period);
|
||||||
|
|
||||||
Assert.Equal(Math.Round((double)SK.Last().Atr!, 8), Math.Round(QL.Last().v, 8));
|
Assert.Equal(Math.Round((double)SK.Last().Atr!, 6), Math.Round(QL.Last().v, 6));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void OBV()
|
||||||
|
{
|
||||||
|
OBV_Series QL = new(this.bars, this.period, false);
|
||||||
|
var SK = this.quotes.GetObv(this.period);
|
||||||
|
|
||||||
|
// adding volume[0] to OBV to pass the test and keep compatibility with TA-LIB
|
||||||
|
Assert.Equal(Math.Round((double)SK.Last().Obv!, 6) + Math.Round((double)this.quotes.First().Volume!, 6),
|
||||||
|
Math.Round(QL.Last().v, 6));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -105,7 +115,7 @@ public class Skender_Stock
|
|||||||
ADL_Series QL = new(this.bars, false);
|
ADL_Series QL = new(this.bars, false);
|
||||||
var SK = this.quotes.GetAdl();
|
var SK = this.quotes.GetAdl();
|
||||||
|
|
||||||
Assert.Equal(Math.Round((double)SK.Last().Adl!, 6), Math.Round(QL.Last().v, 6));
|
Assert.Equal(Math.Round((double)SK.Last().Adl!, 5), Math.Round(QL.Last().v, 5));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -114,7 +124,7 @@ public class Skender_Stock
|
|||||||
CCI_Series QL = new(this.bars, this.period, false);
|
CCI_Series QL = new(this.bars, this.period, false);
|
||||||
var SK = this.quotes.GetCci(this.period);
|
var SK = this.quotes.GetCci(this.period);
|
||||||
|
|
||||||
Assert.Equal(Math.Round((double)SK.Last().Cci!, 8), Math.Round(QL.Last().v, 8));
|
Assert.Equal(Math.Round((double)SK.Last().Cci!, 6), Math.Round(QL.Last().v, 6));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -123,7 +133,7 @@ public class Skender_Stock
|
|||||||
ATRP_Series QL = new(this.bars, this.period, false);
|
ATRP_Series QL = new(this.bars, this.period, false);
|
||||||
var SK = this.quotes.GetAtr(this.period);
|
var SK = this.quotes.GetAtr(this.period);
|
||||||
|
|
||||||
Assert.Equal(Math.Round((double)SK.Last().Atrp!, 8), Math.Round(QL.Last().v, 8));
|
Assert.Equal(Math.Round((double)SK.Last().Atrp!, 6), Math.Round(QL.Last().v, 6));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -132,7 +142,7 @@ public class Skender_Stock
|
|||||||
KAMA_Series QL = new(this.bars.Close, this.period, useNaN: false);
|
KAMA_Series QL = new(this.bars.Close, this.period, useNaN: false);
|
||||||
var SK = this.quotes.GetKama(this.period);
|
var SK = this.quotes.GetKama(this.period);
|
||||||
|
|
||||||
Assert.Equal(Math.Round((double)SK.Last().Kama!, 8), Math.Round(QL.Last().v, 8));
|
Assert.Equal(Math.Round((double)SK.Last().Kama!, 6), Math.Round(QL.Last().v, 6));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -141,7 +151,7 @@ public class Skender_Stock
|
|||||||
HMA_Series QL = new(this.bars.Close, this.period, useNaN: false);
|
HMA_Series QL = new(this.bars.Close, this.period, useNaN: false);
|
||||||
var SK = this.quotes.GetHma(this.period);
|
var SK = this.quotes.GetHma(this.period);
|
||||||
|
|
||||||
Assert.Equal(Math.Round((double)SK.Last().Hma!, 8), Math.Round(QL.Last().v, 8));
|
Assert.Equal(Math.Round((double)SK.Last().Hma!, 6), Math.Round(QL.Last().v, 6));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -150,7 +160,7 @@ public class Skender_Stock
|
|||||||
SMMA_Series QL = new(this.bars.Close, this.period, useNaN: false);
|
SMMA_Series QL = new(this.bars.Close, this.period, useNaN: false);
|
||||||
var SK = this.quotes.GetSmma(this.period);
|
var SK = this.quotes.GetSmma(this.period);
|
||||||
|
|
||||||
Assert.Equal(Math.Round((double)SK.Last().Smma!, 8), Math.Round(QL.Last().v, 8));
|
Assert.Equal(Math.Round((double)SK.Last().Smma!, 6), Math.Round(QL.Last().v, 6));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -159,8 +169,8 @@ public class Skender_Stock
|
|||||||
MACD_Series QL = new(this.bars.Close, 26,12,9, useNaN: false);
|
MACD_Series QL = new(this.bars.Close, 26,12,9, useNaN: false);
|
||||||
var SK = this.quotes.GetMacd(12,26,9);
|
var SK = this.quotes.GetMacd(12,26,9);
|
||||||
|
|
||||||
Assert.Equal(Math.Round((double)SK.Last().Macd!, 8), Math.Round(QL.Last().v, 8));
|
Assert.Equal(Math.Round((double)SK.Last().Macd!, 6), Math.Round(QL.Last().v, 6));
|
||||||
Assert.Equal(Math.Round((double)SK.Last().Signal!, 8), Math.Round(QL.Signal.Last().v, 8));
|
Assert.Equal(Math.Round((double)SK.Last().Signal!, 6), Math.Round(QL.Signal.Last().v, 6));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -169,22 +179,21 @@ public class Skender_Stock
|
|||||||
BBANDS_Series QL = new(this.bars.Close, this.period, 2.0, useNaN: false);
|
BBANDS_Series QL = new(this.bars.Close, this.period, 2.0, useNaN: false);
|
||||||
var SK = this.quotes.GetBollingerBands(this.period, 2.0);
|
var SK = this.quotes.GetBollingerBands(this.period, 2.0);
|
||||||
|
|
||||||
Assert.Equal(Math.Round((double)SK.Last().Sma!, 8), Math.Round(QL.Mid.Last().v, 8));
|
Assert.Equal(Math.Round((double)SK.Last().Sma!, 6), Math.Round(QL.Mid.Last().v, 6));
|
||||||
Assert.Equal(Math.Round((double)SK.Last().UpperBand!, 8), Math.Round(QL.Upper.Last().v, 8));
|
Assert.Equal(Math.Round((double)SK.Last().UpperBand!, 6), Math.Round(QL.Upper.Last().v, 6));
|
||||||
Assert.Equal(Math.Round((double)SK.Last().LowerBand!, 8), Math.Round(QL.Lower.Last().v, 8));
|
Assert.Equal(Math.Round((double)SK.Last().LowerBand!, 6), Math.Round(QL.Lower.Last().v, 6));
|
||||||
Assert.Equal(Math.Round((double)SK.Last().Width!, 8), Math.Round(QL.Bandwidth.Last().v, 8));
|
Assert.Equal(Math.Round((double)SK.Last().Width!, 6), Math.Round(QL.Bandwidth.Last().v, 6));
|
||||||
Assert.Equal(Math.Round((double)SK.Last().PercentB!, 8), Math.Round(QL.PercentB.Last().v, 8));
|
Assert.Equal(Math.Round((double)SK.Last().PercentB!, 6), Math.Round(QL.PercentB.Last().v, 6));
|
||||||
Assert.Equal(Math.Round((double)SK.Last().ZScore!, 8), Math.Round(QL.Zscore.Last().v, 8));
|
Assert.Equal(Math.Round((double)SK.Last().ZScore!, 6), Math.Round(QL.Zscore.Last().v, 6));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void RSI()
|
public void RSI()
|
||||||
{
|
{
|
||||||
RSI_Series QL = new(this.bars.Close, this.period, useNaN: false);
|
RSI_Series QL = new(this.bars.Close, this.period, useNaN: false);
|
||||||
var SK = this.quotes.GetRsi(this.period);
|
var SK = this.quotes.GetRsi(this.period);
|
||||||
|
|
||||||
Assert.Equal(Math.Round((double)SK.Last().Rsi!, 8), Math.Round(QL.Last().v, 8));
|
Assert.Equal(Math.Round((double)SK.Last().Rsi!, 6), Math.Round(QL.Last().v, 6));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -193,7 +202,7 @@ public class Skender_Stock
|
|||||||
ALMA_Series QL = new(this.bars.Close, this.period, useNaN: false);
|
ALMA_Series QL = new(this.bars.Close, this.period, useNaN: false);
|
||||||
var SK = this.quotes.GetAlma(this.period);
|
var SK = this.quotes.GetAlma(this.period);
|
||||||
|
|
||||||
Assert.Equal(Math.Round((double)SK.Last().Alma!, 8), Math.Round(QL.Last().v, 8));
|
Assert.Equal(Math.Round((double)SK.Last().Alma!, 6), Math.Round(QL.Last().v, 6));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -202,7 +211,7 @@ public class Skender_Stock
|
|||||||
SDEV_Series QL = new(this.bars.Close, this.period, useNaN: false);
|
SDEV_Series QL = new(this.bars.Close, this.period, useNaN: false);
|
||||||
var SK = this.quotes.GetStdDev(this.period);
|
var SK = this.quotes.GetStdDev(this.period);
|
||||||
|
|
||||||
Assert.Equal(Math.Round((double)SK.Last().StdDev!, 8), Math.Round(QL.Last().v, 8));
|
Assert.Equal(Math.Round((double)SK.Last().StdDev!, 6), Math.Round(QL.Last().v, 6));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -211,10 +220,10 @@ public class Skender_Stock
|
|||||||
LINREG_Series QL = new(this.bars.Close, this.period, useNaN: false);
|
LINREG_Series QL = new(this.bars.Close, this.period, useNaN: false);
|
||||||
var SK = this.quotes.GetSlope(this.period);
|
var SK = this.quotes.GetSlope(this.period);
|
||||||
|
|
||||||
Assert.Equal(Math.Round((double)SK.Last().Slope!, 8), Math.Round(QL.Last().v, 8));
|
Assert.Equal(Math.Round((double)SK.Last().Slope!, 6), Math.Round(QL.Last().v, 6));
|
||||||
Assert.Equal(Math.Round((double)SK.Last().Intercept!, 8), Math.Round(QL.Intercept.Last().v, 8));
|
Assert.Equal(Math.Round((double)SK.Last().Intercept!, 6), Math.Round(QL.Intercept.Last().v, 6));
|
||||||
Assert.Equal(Math.Round((double)SK.Last().RSquared!, 8), Math.Round(QL.RSquared.Last().v, 8));
|
Assert.Equal(Math.Round((double)SK.Last().RSquared!, 6), Math.Round(QL.RSquared.Last().v, 6));
|
||||||
Assert.Equal(Math.Round((double)SK.Last().StdDev!, 8), Math.Round(QL.StdDev.Last().v, 8));
|
Assert.Equal(Math.Round((double)SK.Last().StdDev!, 6), Math.Round(QL.StdDev.Last().v, 6));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -223,7 +232,7 @@ public class Skender_Stock
|
|||||||
TR_Series QL = new(this.bars, useNaN: false);
|
TR_Series QL = new(this.bars, useNaN: false);
|
||||||
var SK = this.quotes.GetTr();
|
var SK = this.quotes.GetTr();
|
||||||
|
|
||||||
Assert.Equal(Math.Round((double)SK.Last().Tr!, 8), Math.Round(QL.Last().v, 8));
|
Assert.Equal(Math.Round((double)SK.Last().Tr!, 6), Math.Round(QL.Last().v, 6));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -232,7 +241,7 @@ public class Skender_Stock
|
|||||||
TSeries QL = this.bars.HL2;
|
TSeries QL = this.bars.HL2;
|
||||||
var SK = this.quotes.GetBaseQuote(CandlePart.HL2);
|
var SK = this.quotes.GetBaseQuote(CandlePart.HL2);
|
||||||
|
|
||||||
Assert.Equal(Math.Round((double)SK.Last().Value!, 8), Math.Round(QL.Last().v, 8));
|
Assert.Equal(Math.Round((double)SK.Last().Value!, 6), Math.Round(QL.Last().v, 6));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -241,7 +250,7 @@ public class Skender_Stock
|
|||||||
TSeries QL = this.bars.OC2;
|
TSeries QL = this.bars.OC2;
|
||||||
var SK = this.quotes.GetBaseQuote(CandlePart.OC2);
|
var SK = this.quotes.GetBaseQuote(CandlePart.OC2);
|
||||||
|
|
||||||
Assert.Equal(Math.Round((double)SK.Last().Value!, 8), Math.Round(QL.Last().v, 8));
|
Assert.Equal(Math.Round((double)SK.Last().Value!, 6), Math.Round(QL.Last().v, 6));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -250,7 +259,7 @@ public class Skender_Stock
|
|||||||
TSeries QL = this.bars.HLC3;
|
TSeries QL = this.bars.HLC3;
|
||||||
var SK = this.quotes.GetBaseQuote(CandlePart.HLC3);
|
var SK = this.quotes.GetBaseQuote(CandlePart.HLC3);
|
||||||
|
|
||||||
Assert.Equal(Math.Round((double)SK.Last().Value!, 8), Math.Round(QL.Last().v, 8));
|
Assert.Equal(Math.Round((double)SK.Last().Value!, 6), Math.Round(QL.Last().v, 6));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -259,7 +268,7 @@ public class Skender_Stock
|
|||||||
TSeries QL = this.bars.OHL3;
|
TSeries QL = this.bars.OHL3;
|
||||||
var SK = this.quotes.GetBaseQuote(CandlePart.OHL3);
|
var SK = this.quotes.GetBaseQuote(CandlePart.OHL3);
|
||||||
|
|
||||||
Assert.Equal(Math.Round((double)SK.Last().Value!, 8), Math.Round(QL.Last().v, 8));
|
Assert.Equal(Math.Round((double)SK.Last().Value!, 6), Math.Round(QL.Last().v, 6));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -268,6 +277,6 @@ public class Skender_Stock
|
|||||||
TSeries QL = this.bars.OHLC4;
|
TSeries QL = this.bars.OHLC4;
|
||||||
var SK = this.quotes.GetBaseQuote(CandlePart.OHLC4);
|
var SK = this.quotes.GetBaseQuote(CandlePart.OHLC4);
|
||||||
|
|
||||||
Assert.Equal(Math.Round((double)SK.Last().Value!, 8), Math.Round(QL.Last().v, 8));
|
Assert.Equal(Math.Round((double)SK.Last().Value!, 6), Math.Round(QL.Last().v, 6));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+47
-34
@@ -18,7 +18,7 @@ public class TA_LIB
|
|||||||
|
|
||||||
public TA_LIB()
|
public TA_LIB()
|
||||||
{
|
{
|
||||||
this.bars = new(1000);
|
this.bars = new(5000);
|
||||||
this.period = this.rnd.Next(28) + 3;
|
this.period = this.rnd.Next(28) + 3;
|
||||||
this.TALIB = new double[this.bars.Count];
|
this.TALIB = new double[this.bars.Count];
|
||||||
this.inopen = this.bars.Open.v.ToArray();
|
this.inopen = this.bars.Open.v.ToArray();
|
||||||
@@ -36,7 +36,7 @@ public class TA_LIB
|
|||||||
ADD_Series QL = new(this.bars.Open, this.bars.Close);
|
ADD_Series QL = new(this.bars.Open, this.bars.Close);
|
||||||
Core.Add(this.inopen, this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _);
|
Core.Add(this.inopen, this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _);
|
||||||
|
|
||||||
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8));
|
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -45,7 +45,7 @@ public class TA_LIB
|
|||||||
SUB_Series QL = new(this.bars.Open, this.bars.Close);
|
SUB_Series QL = new(this.bars.Open, this.bars.Close);
|
||||||
Core.Sub(this.inopen, this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _);
|
Core.Sub(this.inopen, this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _);
|
||||||
|
|
||||||
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8));
|
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -54,7 +54,7 @@ public class TA_LIB
|
|||||||
MUL_Series QL = new(this.bars.Open, this.bars.Close);
|
MUL_Series QL = new(this.bars.Open, this.bars.Close);
|
||||||
Core.Mult(this.inopen, this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _);
|
Core.Mult(this.inopen, this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _);
|
||||||
|
|
||||||
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8));
|
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -63,7 +63,7 @@ public class TA_LIB
|
|||||||
DIV_Series QL = new(this.bars.Open, this.bars.Close);
|
DIV_Series QL = new(this.bars.Open, this.bars.Close);
|
||||||
Core.Div(this.inopen, this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _);
|
Core.Div(this.inopen, this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _);
|
||||||
|
|
||||||
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8));
|
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -72,17 +72,25 @@ public class TA_LIB
|
|||||||
SDEV_Series QL = new(this.bars.Close, this.period, false);
|
SDEV_Series QL = new(this.bars.Close, this.period, false);
|
||||||
Core.StdDev(this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _, this.period);
|
Core.StdDev(this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _, this.period);
|
||||||
|
|
||||||
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8));
|
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void SMA()
|
public void SMA()
|
||||||
{
|
{
|
||||||
SMA_Series QL = new(this.bars.Close, this.period, false);
|
SMA_Series QL = new(this.bars.Close, this.period, false);
|
||||||
Core.Sma(this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _, this.period);
|
Core.Sma(this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _, this.period);
|
||||||
|
|
||||||
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8));
|
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void TRIMA()
|
||||||
|
{
|
||||||
|
TRIMA_Series QL = new(this.bars.Close, this.period, false);
|
||||||
|
Core.Trima(this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _, this.period);
|
||||||
|
|
||||||
|
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -91,7 +99,7 @@ public class TA_LIB
|
|||||||
EMA_Series QL = new(this.bars.Close, this.period, false);
|
EMA_Series QL = new(this.bars.Close, this.period, false);
|
||||||
Core.Ema(this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _, this.period);
|
Core.Ema(this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _, this.period);
|
||||||
|
|
||||||
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8));
|
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -99,8 +107,8 @@ public class TA_LIB
|
|||||||
{
|
{
|
||||||
WMA_Series QL = new(this.bars.Close, this.period, false);
|
WMA_Series QL = new(this.bars.Close, this.period, false);
|
||||||
Core.Wma(this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _, this.period);
|
Core.Wma(this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _, this.period);
|
||||||
|
|
||||||
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8));
|
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -109,7 +117,7 @@ public class TA_LIB
|
|||||||
DEMA_Series QL = new(this.bars.Close, this.period, false);
|
DEMA_Series QL = new(this.bars.Close, this.period, false);
|
||||||
Core.Dema(this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _, this.period);
|
Core.Dema(this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _, this.period);
|
||||||
|
|
||||||
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8));
|
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -118,7 +126,7 @@ public class TA_LIB
|
|||||||
TEMA_Series QL = new(this.bars.Close, this.period, false);
|
TEMA_Series QL = new(this.bars.Close, this.period, false);
|
||||||
Core.Tema(this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _, this.period);
|
Core.Tema(this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _, this.period);
|
||||||
|
|
||||||
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8));
|
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -127,7 +135,7 @@ public class TA_LIB
|
|||||||
MAX_Series QL = new(this.bars.Close, this.period, false);
|
MAX_Series QL = new(this.bars.Close, this.period, false);
|
||||||
Core.Max(this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _, this.period);
|
Core.Max(this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _, this.period);
|
||||||
|
|
||||||
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8));
|
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -136,7 +144,7 @@ public class TA_LIB
|
|||||||
MIN_Series QL = new(this.bars.Close, this.period, false);
|
MIN_Series QL = new(this.bars.Close, this.period, false);
|
||||||
Core.Min(this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _, this.period);
|
Core.Min(this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _, this.period);
|
||||||
|
|
||||||
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8));
|
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -145,7 +153,16 @@ public class TA_LIB
|
|||||||
ADL_Series QL = new(this.bars, false);
|
ADL_Series QL = new(this.bars, false);
|
||||||
Core.Ad(this.inhigh, this.inlow, this.inclose, this.involume, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _);
|
Core.Ad(this.inhigh, this.inlow, this.inclose, this.involume, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _);
|
||||||
|
|
||||||
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8));
|
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void OBV()
|
||||||
|
{
|
||||||
|
OBV_Series QL = new(this.bars, this.period, false);
|
||||||
|
Core.Obv(this.inclose, this.involume, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _);
|
||||||
|
|
||||||
|
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -154,7 +171,7 @@ public class TA_LIB
|
|||||||
ADOSC_Series QL = new(this.bars, false);
|
ADOSC_Series QL = new(this.bars, false);
|
||||||
Core.AdOsc(this.inhigh, this.inlow, this.inclose, this.involume, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _);
|
Core.AdOsc(this.inhigh, this.inlow, this.inclose, this.involume, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _);
|
||||||
|
|
||||||
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8));
|
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -163,7 +180,7 @@ public class TA_LIB
|
|||||||
ATR_Series QL = new(this.bars, this.period, false);
|
ATR_Series QL = new(this.bars, this.period, false);
|
||||||
Core.Atr(this.inhigh, this.inlow, this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _, this.period);
|
Core.Atr(this.inhigh, this.inlow, this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _, this.period);
|
||||||
|
|
||||||
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8));
|
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -172,7 +189,7 @@ public class TA_LIB
|
|||||||
CCI_Series QL = new(this.bars, this.period, false);
|
CCI_Series QL = new(this.bars, this.period, false);
|
||||||
Core.Cci(this.inhigh, this.inlow, this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _, this.period);
|
Core.Cci(this.inhigh, this.inlow, this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _, this.period);
|
||||||
|
|
||||||
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8));
|
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -181,7 +198,7 @@ public class TA_LIB
|
|||||||
RSI_Series QL = new(this.bars.Close, this.period, false);
|
RSI_Series QL = new(this.bars.Close, this.period, false);
|
||||||
Core.Rsi(this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _, this.period);
|
Core.Rsi(this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _, this.period);
|
||||||
|
|
||||||
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8));
|
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -190,7 +207,7 @@ public class TA_LIB
|
|||||||
TR_Series QL = new(this.bars, false);
|
TR_Series QL = new(this.bars, false);
|
||||||
Core.TRange(this.inhigh, this.inlow, this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _);
|
Core.TRange(this.inhigh, this.inlow, this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _);
|
||||||
|
|
||||||
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8));
|
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -200,8 +217,8 @@ public class TA_LIB
|
|||||||
double[] macdHist = new double[this.bars.Count];
|
double[] macdHist = new double[this.bars.Count];
|
||||||
MACD_Series QL = new(this.bars.Close, slow: 26, fast: 12, signal: 9, false);
|
MACD_Series QL = new(this.bars.Close, slow: 26, fast: 12, signal: 9, false);
|
||||||
Core.Macd(this.inclose, 0, this.bars.Count - 1, outMacd: this.TALIB, outMacdSignal: macdSignal, outMacdHist: macdHist, out int outBegIdx, out _);
|
Core.Macd(this.inclose, 0, this.bars.Count - 1, outMacd: this.TALIB, outMacdSignal: macdSignal, outMacdHist: macdHist, out int outBegIdx, out _);
|
||||||
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8));
|
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
|
||||||
Assert.Equal(Math.Round(macdSignal[macdSignal.Length - outBegIdx - 1], 8), Math.Round(QL.Signal.Last().v, 8));
|
Assert.Equal(Math.Round(macdSignal[macdSignal.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Signal.Last().v, 6, MidpointRounding.AwayFromZero));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -212,21 +229,18 @@ public class TA_LIB
|
|||||||
double[] outLower = new double[this.bars.Count];
|
double[] outLower = new double[this.bars.Count];
|
||||||
BBANDS_Series QL = new(this.bars.Close, period:26, multiplier:2.0, false);
|
BBANDS_Series QL = new(this.bars.Close, period:26, multiplier:2.0, false);
|
||||||
Core.Bbands(this.inclose, 0, this.bars.Count - 1, outRealUpperBand: outUpper, outRealMiddleBand: outMiddle, outRealLowerBand: outLower, out int outBegIdx, out _, optInTimePeriod:26, optInNbDevUp:2.0, optInNbDevDn:2.0);
|
Core.Bbands(this.inclose, 0, this.bars.Count - 1, outRealUpperBand: outUpper, outRealMiddleBand: outMiddle, outRealLowerBand: outLower, out int outBegIdx, out _, optInTimePeriod:26, optInNbDevUp:2.0, optInNbDevDn:2.0);
|
||||||
Assert.Equal(Math.Round(outUpper[outUpper.Length - outBegIdx - 1], 7), Math.Round(QL.Upper.Last().v, 7));
|
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], 7), Math.Round(QL.Mid.Last().v, 7));
|
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], 7), Math.Round(QL.Lower.Last().v, 7));
|
Assert.Equal(Math.Round(outLower[outLower.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Lower.Last().v, 6, MidpointRounding.AwayFromZero));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void HL2()
|
public void HL2()
|
||||||
{
|
{
|
||||||
TSeries QL = this.bars.HL2;
|
TSeries QL = this.bars.HL2;
|
||||||
Core.MedPrice(this.inhigh, this.inlow, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _);
|
Core.MedPrice(this.inhigh, this.inlow, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _);
|
||||||
|
|
||||||
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8));
|
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -235,7 +249,7 @@ public class TA_LIB
|
|||||||
TSeries QL = this.bars.HLC3;
|
TSeries QL = this.bars.HLC3;
|
||||||
Core.TypPrice(this.inhigh, this.inlow, this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _);
|
Core.TypPrice(this.inhigh, this.inlow, this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _);
|
||||||
|
|
||||||
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8));
|
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -244,7 +258,7 @@ public class TA_LIB
|
|||||||
TSeries QL = this.bars.OHLC4;
|
TSeries QL = this.bars.OHLC4;
|
||||||
Core.AvgPrice(this.inopen, this.inhigh, this.inlow, this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _);
|
Core.AvgPrice(this.inopen, this.inhigh, this.inlow, this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _);
|
||||||
|
|
||||||
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8));
|
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -253,7 +267,6 @@ public class TA_LIB
|
|||||||
TSeries QL = this.bars.HLCC4;
|
TSeries QL = this.bars.HLCC4;
|
||||||
Core.WclPrice( this.inhigh, this.inlow, this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _);
|
Core.WclPrice( this.inhigh, this.inlow, this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _);
|
||||||
|
|
||||||
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8));
|
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-21
File diff suppressed because one or more lines are too long
+73
-74
@@ -37,84 +37,91 @@ See [Getting Started](https://github.com/mihakralj/QuanTAlib/blob/main/Docs/gett
|
|||||||
|
|
||||||
| **BASIC TRANSFORMS** | **QuanTAlib** | **TA-LIB** | **Skender** |
|
| **BASIC TRANSFORMS** | **QuanTAlib** | **TA-LIB** | **Skender** |
|
||||||
|--|:--:|:--:|:--:|
|
|--|:--:|:--:|:--:|
|
||||||
| ✔️ OC2 - (Open+Close)/2 |️ `.OC2` || ️`GetBaseQuote` |
|
| ✔️ OC2 - (Open+Close)/2 |️ `.OC2` || ️GetBaseQuote |
|
||||||
| ⭐ HL2 - Median Price | `.HL2` | `MEDPRICE` | ️`GetBaseQuote` |
|
| ⭐ HL2 - Median Price | `.HL2` | MEDPRICE | ️GetBaseQuote |
|
||||||
| ⭐ HLC3 - Typical Price | `.HLC3` | `TYPPRICE` ||
|
| ⭐ HLC3 - Typical Price | `.HLC3` | TYPPRICE ||
|
||||||
| ✔️ 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 ||
|
||||||
| ✔️ ZL - De-lagged price (Zero-Lag) | `ZL_Series` |||
|
| ⭐ MAX - Max value | `MAX_Series` | MAX ||
|
||||||
| ⭐ MAX - Max value | `MAX_Series` | `MAX` ||
|
| ⭐ MIN - Min value | `MIN_Series` | MIN ||
|
||||||
| ⛔ MID - Midpoint value || `MIDPOINT` ||
|
| ⛔ MID - Midpoint value || MIDPOINT ||
|
||||||
| ⛔ MIDP - Midpoint price || `MIDPRICE` ||
|
| ⛔ MIDP - Midpoint price || MIDPRICE ||
|
||||||
| ⭐ MIN - Min value | `MIN_Series` | `MIN` ||
|
| ⛔ 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 ||
|
||||||
| ⭐ DIV - Division | `DIV_Series` | `DIV` ||
|
| ⭐ DIV - Division | `DIV_Series` | DIV ||
|
||||||
|||||
|
|||||
|
||||||
| **STATISTICS & NUMERICAL ANALYSIS** | **QuanTAlib** | **TA-LIB** | **Skender** |
|
| **STATISTICS & NUMERICAL ANALYSIS** | **QuanTAlib** | **TA-LIB** | **Skender** |
|
||||||
| ✔️ BIAS - Bias | BIAS_Series |||
|
| ✔️ BIAS - Bias | `BIAS_Series` |||
|
||||||
| ⛔ CORREL - Pearson's Correlation Coefficient || CORREL | GetCorrelation |
|
| ⛔ CORREL - Pearson's Correlation Coefficient || CORREL | GetCorrelation |
|
||||||
| ⛔ COVAR - Covariance ||| GetCorrelation |
|
| ⛔ COVAR - Covariance ||| GetCorrelation |
|
||||||
| ✔️ ENTP - Entropy | ENTP_Series |||
|
| ✔️ ENTP - Entropy | `ENTP_Series` |||
|
||||||
| ✔️ KURT - Kurtosis | KURT_Series |||
|
| ✔️ KURT - Kurtosis | `KURT_Series` |||
|
||||||
| ⭐ LINREG - Linear Regression | LINREG_Series || GetSlope |
|
| ⭐ LINREG - Linear Regression | `LINREG_Series` || GetSlope |
|
||||||
| ⭐ MAD - Mean Absolute Deviation | MAD_Series || GetSma |
|
| ⭐ MAD - Mean Absolute Deviation | `MAD_Series` || GetSma |
|
||||||
| ⭐ MAPE - Mean Absolute Percent Error | MAPE_Series || GetSma |
|
| ⭐ MAPE - Mean Absolute Percent Error | `MAPE_Series` || GetSma |
|
||||||
| ✔️ MED - Median value | MED_Series |||
|
| ✔️ MED - Median value | `MED_Series` |||
|
||||||
| ✔️ MSE - Mean Squared Error | MSE_Series || GetSma |
|
| ✔️ MSE - Mean Squared Error | `MSE_Series` || GetSma |
|
||||||
| ⛔ SKEW - Skewness ||||
|
| ⛔ SKEW - Skewness ||||
|
||||||
| ⭐ SDEV - Standard Deviation (Volatility) | SDEV_Series |||
|
| ⭐ SDEV - Standard Deviation (Volatility) | `SDEV_Series` | STDDEV ||
|
||||||
| ✔️ SSDEV - Sample Standard Deviation | SSDEV_Series |||
|
| ✔️ SSDEV - Sample Standard Deviation | `SSDEV_Series` |||
|
||||||
| ✔️ SMAPE - Symmetric Mean Absolute Percent Error | SMAPE_Series |||
|
| ✔️ SMAPE - Symmetric Mean Absolute Percent Error | `SMAPE_Series` |||
|
||||||
| ✔️ VAR - Population Variance | VAR_Series |||
|
| ✔️ VAR - Population Variance | `VAR_Series` | VAR ||
|
||||||
| ✔️ SVAR - Sample Variance | SVAR_Series |||
|
| ✔️ SVAR - Sample Variance | `SVAR_Series` |||
|
||||||
| ⛔ QUANT - Quantile ||||
|
| ⛔ QUANT - Quantile ||||
|
||||||
| ✔️ WMAPE - Weighted Mean Absolute Percent Error | WMAPE_Series |||
|
| ✔️ WMAPE - Weighted Mean Absolute Percent Error | `WMAPE_Series` |||
|
||||||
| ⛔ ZSCORE - Number of standard deviations from mean ||||
|
| ⛔ ZSCORE - Number of standard deviations from mean ||||
|
||||||
|||||
|
|||||
|
||||||
| **TREND INDICATORS & AVERAGES** | **QuanTAlib** | **TA-LIB** | **Skender** |
|
| **TREND INDICATORS & AVERAGES** | **QuanTAlib** | **TA-LIB** | **Skender** |
|
||||||
| ⛔ AFIRMA - Autoregressive Finite Impulse Response Moving Average ||||
|
| ⛔ AFIRMA - Autoregressive Finite Impulse Response Moving Average ||||
|
||||||
| ⭐ ALMA - Arnaud Legoux Moving Average | ALMA_Series || GetAlma |
|
| ⭐ ALMA - Arnaud Legoux Moving Average | `ALMA_Series` || GetAlma |
|
||||||
| ⛔ ARIMA - Autoregressive Integrated Moving Average ||||
|
| ⛔ ARIMA - Autoregressive Integrated Moving Average ||||
|
||||||
| ⭐ DEMA - Double EMA Average | DEMA_Series | DEMA | GetDema |
|
| ⭐ DEMA - Double EMA Average | `DEMA_Series` | DEMA | GetDema |
|
||||||
| ⭐ EMA - Exponential Moving Average | EMA_Series || GetEma |
|
| ⭐ EMA - Exponential Moving Average | `EMA_Series` || GetEma |
|
||||||
| ⛔ EPMA - Endpoint Moving Average ||| GetEpma |
|
| ⛔ EPMA - Endpoint Moving Average ||| GetEpma |
|
||||||
|
| ⛔ FRAMA - Fractal Adaptive Moving Average ||||
|
||||||
| ⛔ FWMA - Fibonacci's Weighted Moving Average ||||
|
| ⛔ FWMA - Fibonacci's Weighted Moving Average ||||
|
||||||
| ✔️ HEMA - Hull/EMA Average | HEMA_Series |||
|
| ⛔ HILO - Gann High-Low Activator ||||
|
||||||
|
| ✔️ HEMA - Hull/EMA Average | `HEMA_Series` |||
|
||||||
| ⛔ Hilbert Transform Instantaneous Trendline || HT_TRENDLINE | GetHtTrendline |
|
| ⛔ Hilbert Transform Instantaneous Trendline || HT_TRENDLINE | GetHtTrendline |
|
||||||
| ⭐ HMA - Hull Moving Average | HMA_Series || GetHma |
|
| ⭐ HMA - Hull Moving Average | `HMA_Series` || GetHma |
|
||||||
| ⛔ HWMA - Holt-Winter Moving Average ||||
|
| ⛔ HWMA - Holt-Winter Moving Average ||||
|
||||||
| ✔️ JMA - Jurik Moving Average | JMA_Series |||
|
| ✔️ JMA - Jurik Moving Average | `JMA_Series` |||
|
||||||
| ⭐ KAMA - Kaufman's Adaptive Moving Average | KAMA_Series | KAMA | GetKama |
|
| ⭐ KAMA - Kaufman's Adaptive Moving Average | `KAMA_Series` | KAMA | GetKama |
|
||||||
|
| ⛔ KDJ - KDJ Indicator (trend reversal) ||||
|
||||||
| ⛔ LSMA - Least Squares Moving Average ||||
|
| ⛔ LSMA - Least Squares Moving Average ||||
|
||||||
| ⭐ MACD - Moving Average Convergence/Divergence | MACD_Series | MACD | GetMacd |
|
| ⭐ MACD - Moving Average Convergence/Divergence | `MACD_Series` | MACD | GetMacd |
|
||||||
| ⛔ MAMA - MESA Adaptive Moving Average || MAMA | GetMama |
|
| ⛔ MAMA - MESA Adaptive Moving Average || MAMA | GetMama |
|
||||||
|
| ⛔ MCGD - McGinley Dynamic ||||
|
||||||
| ⛔ MMA - Modified Moving Average ||||
|
| ⛔ MMA - Modified Moving Average ||||
|
||||||
| ⛔ PPMA - Pivot Point Moving Average ||||
|
| ⛔ PPMA - Pivot Point Moving Average ||||
|
||||||
| ⛔ PWMA - Pascal's Weighted Moving Average ||||
|
| ⛔ PWMA - Pascal's Weighted Moving Average ||||
|
||||||
| ✔️ RMA - WildeR's Moving Average | RMA__Series |||
|
| ✔️ RMA - WildeR's Moving Average | `RMA_Series` |||
|
||||||
| ⛔ SINWMA - Sine Weighted Moving Average ||||
|
| ⛔ SINWMA - Sine Weighted Moving Average ||||
|
||||||
| ⭐ SMA - Simple Moving Average | SMA_Series |||
|
| ⭐ SMA - Simple Moving Average | `SMA_Series` | SMA | GetSma |
|
||||||
| ⭐ SMMA - Smoothed Moving Average | SMMA_Series |||
|
| ⭐ SMMA - Smoothed Moving Average | `SMMA_Series` |||
|
||||||
| ⛔ SSF - Ehler's Super Smoother Filter ||||
|
| ⛔ SSF - Ehler's Super Smoother Filter ||||
|
||||||
| ⛔ SUP - Supertrend ||||
|
| ⛔ SUP - Supertrend ||||
|
||||||
| ⛔ SWMA - Symmetric Weighted Moving Average ||||
|
| ⛔ SWMA - Symmetric Weighted Moving Average ||||
|
||||||
| ⛔ T3 - Tillson T3 Moving Average ||||
|
| ⛔ T3 - Tillson T3 Moving Average || T3 | GetT3 |
|
||||||
| ⭐ TEMA - Triple EMA Average | TEMA_Series |||
|
| ⭐ TEMA - Triple EMA Average | `TEMA_Series` | TEMA | GetTema |
|
||||||
| ⛔ TRIMA - Triangular Moving Average ||||
|
| ⭐ TRIMA - Triangular Moving Average | `TRIMA_Series` | TRIMA ||
|
||||||
|
| ⛔ TSF - Time Series Forecast || TSF ||
|
||||||
| ⛔ VIDYA - Variable Index Dynamic Average ||||
|
| ⛔ VIDYA - Variable Index Dynamic Average ||||
|
||||||
| ⭐ WMA - Weighted Moving Average | WMA_Series |||
|
| ⛔ VOR - Vortex Indicator ||||
|
||||||
| ✔️ ZLEMA - Zero Lag EMA Average | ZLEMA_Series |||
|
| ⭐ WMA - Weighted Moving Average | `WMA_Series` | WMA | GetWma |
|
||||||
|
| ✔️ ZLEMA - Zero Lag EMA Average | `ZLEMA_Series` |||
|
||||||
|||||
|
|||||
|
||||||
| **VOLATILITY INDICATORS** | **QuanTAlib** | **TA-LIB** | **Skender** |
|
| **VOLATILITY INDICATORS** | **QuanTAlib** | **TA-LIB** | **Skender** |
|
||||||
| ⭐ ADL - Chaikin Accumulation Distribution Line | ADL_Series | AD | GetAdl |
|
| ⭐ ADL - Chaikin Accumulation Distribution Line | `ADL_Series` | AD | GetAdl |
|
||||||
| ⭐ ADOSC - Chaikin Accumulation Distribution Oscillator | ADOSC_Series | ADOSC| GetAdl |
|
| ⭐ ADOSC - Chaikin Accumulation Distribution Oscillator | `ADOSC_Series` | ADOSC| GetAdl |
|
||||||
| ⭐ ATR - Average True Range | ATR_Series | ATR | GetAtr |
|
| ⭐ ATR - Average True Range | `ATR_Series` | ATR | GetAtr |
|
||||||
| ⭐ ATRP - Average True Range Percent | ATRP_Series || GetAtr |
|
| ⭐ ATRP - Average True Range Percent | `ATRP_Series` || GetAtr |
|
||||||
| ✔️ BETA - Beta coefficient || BETA | GetBeta |
|
| ⛔ BETA - Beta coefficient || BETA | GetBeta |
|
||||||
| ⭐ BBANDS - Bollinger Bands® | BBANDS_Series | BBANDS | GetBollingerBands |
|
| ⭐ BBANDS - Bollinger Bands® | `BBANDS_Series` | BBANDS | GetBollingerBands |
|
||||||
|
| ⛔ CHAND - Chandelier Exit ||| GetChandelier |
|
||||||
| ⛔ CRSI - Connor RSI ||| GetConnorsRsi |
|
| ⛔ CRSI - Connor RSI ||| GetConnorsRsi |
|
||||||
| ⛔ DON - Donchian Channels ||| GetDonchian |
|
| ⛔ DON - Donchian Channels ||| GetDonchian |
|
||||||
| ⛔ FCB - Fractal Chaos Bands ||| GetFcb |
|
| ⛔ FCB - Fractal Chaos Bands ||| GetFcb |
|
||||||
@@ -122,11 +129,12 @@ See [Getting Started](https://github.com/mihakralj/QuanTAlib/blob/main/Docs/gett
|
|||||||
| ⛔ ICH - Ichimoku ||| GetIchimoku |
|
| ⛔ ICH - Ichimoku ||| GetIchimoku |
|
||||||
| ⛔ KEL - Keltner Channels ||| GetKeltner |
|
| ⛔ KEL - Keltner Channels ||| GetKeltner |
|
||||||
| ⛔ NATR - Normalized Average True Range || NATR | GetAtr |
|
| ⛔ NATR - Normalized Average True Range || NATR | GetAtr |
|
||||||
| ⭐ RSI - Relative Strength Index | RSI_Series ||
|
| ⛔ CHN - Price Channel Indicator ||||
|
||||||
|
| ⭐ RSI - Relative Strength Index | `RSI_Series` | RSI | GetRsi |
|
||||||
| ⛔ SAR - Parabolic Stop and Reverse || SAR | GetParabolicSar |
|
| ⛔ SAR - Parabolic Stop and Reverse || SAR | GetParabolicSar |
|
||||||
| ⛔ SRSI - Stochastic RSI ||||
|
| ⛔ SRSI - Stochastic RSI || STOCHRSI | GetStochRsi |
|
||||||
| ⛔ STARC - Starc Bands ||||
|
| ⛔ STARC - Starc Bands ||||
|
||||||
| ⭐ TR - True Range | TR_Series |||
|
| ⭐ TR - True Range | `TR_Series` | TRANGE | GetTr |
|
||||||
| ⛔ UI - Ulcer Index ||||
|
| ⛔ UI - Ulcer Index ||||
|
||||||
| ⛔ VSTOP - Volatility Stop ||||
|
| ⛔ VSTOP - Volatility Stop ||||
|
||||||
|||||
|
|||||
|
||||||
@@ -138,11 +146,11 @@ See [Getting Started](https://github.com/mihakralj/QuanTAlib/blob/main/Docs/gett
|
|||||||
| ⛔ APO - Absolute Price Oscillator || APO ||
|
| ⛔ APO - Absolute Price Oscillator || APO ||
|
||||||
| ⛔ AROON - Aroon oscillator || AROON | GetAroon |
|
| ⛔ AROON - Aroon oscillator || AROON | GetAroon |
|
||||||
| ⛔ BOP - Balance of Power || BOP | GetBop |
|
| ⛔ BOP - Balance of Power || BOP | GetBop |
|
||||||
| ⭐ CCI - Commodity Channel Index | CCI_Series | CCI | GetCci |
|
| ⭐ CCI - Commodity Channel Index | `CCI_Series` | CCI | GetCci |
|
||||||
| ⛔ CFO - Chande Forcast Oscillator ||||
|
| ⛔ CFO - Chande Forcast Oscillator ||||
|
||||||
| ⛔ CMF - Chaikin Money Flow ||||
|
|
||||||
| ⛔ CMO - Chande Momentum Oscillator || CMO | GetCmo |
|
| ⛔ CMO - Chande Momentum Oscillator || CMO | GetCmo |
|
||||||
| ⛔ COG - Center of Gravity ||||
|
| ⛔ COG - Center of Gravity ||||
|
||||||
|
| ⛔ COPPOCK - Coppock Curve ||||
|
||||||
| ⛔ CTI - Ehler's Correlation Trend Indicator ||||
|
| ⛔ CTI - Ehler's Correlation Trend Indicator ||||
|
||||||
| ⛔ DPO - Detrended Price Oscillator ||| GetDpo |
|
| ⛔ DPO - Detrended Price Oscillator ||| GetDpo |
|
||||||
| ⛔ DMI - Directional Movement Index || DX | GetAdx |
|
| ⛔ DMI - Directional Movement Index || DX | GetAdx |
|
||||||
@@ -152,23 +160,28 @@ See [Getting Started](https://github.com/mihakralj/QuanTAlib/blob/main/Docs/gett
|
|||||||
| ⛔ KRI - Kairi Relative Index ||||
|
| ⛔ KRI - Kairi Relative Index ||||
|
||||||
| ⛔ KVO - Klinger Volume Oscillator ||||
|
| ⛔ KVO - Klinger Volume Oscillator ||||
|
||||||
| ⛔ MFI - Money Flow Index || MFI | GetMfi |
|
| ⛔ MFI - Money Flow Index || MFI | GetMfi |
|
||||||
| ⛔ ROC - Rate of Change (Momentum) || MOM | GetRoc |
|
| ⛔ MOM - Momentum || MOM ||
|
||||||
| ⛔ NVI - Negative Volume Index ||||
|
| ⛔ NVI - Negative Volume Index ||||
|
||||||
| ⛔ PO - Price Oscillator ||||
|
| ⛔ PO - Price Oscillator ||||
|
||||||
| ⛔ PPO - Percentage Price Oscillator || PPO ||
|
| ⛔ PPO - Percentage Price Oscillator || PPO ||
|
||||||
| ⛔ PMO - Price Momentum Oscillator ||||
|
| ⛔ PMO - Price Momentum Oscillator ||||
|
||||||
| ⛔ PVI - Positive Volume Index ||||
|
| ⛔ PVI - Positive Volume Index ||||
|
||||||
|
| ⛔ ROC - Rate of Change || MOM | GetRoc |
|
||||||
| ⛔ RVGI - Relative Vigor Index ||||
|
| ⛔ RVGI - Relative Vigor Index ||||
|
||||||
| ⛔ SMI - Stochastic Momentum Index ||||
|
| ⛔ SMI - Stochastic Momentum Index ||||
|
||||||
| ⛔ STOCH - Stochastic Oscillator ||||
|
| ⛔ STC - Schaff Trend Cycle ||||
|
||||||
| ⛔ TRIX - 1-day ROC of TEMA ||||
|
| ⛔ STOCH - Stochastic Oscillator || STOCH | GetStoch |
|
||||||
|
| ⛔ TRIX - 1-day ROC of TEMA || TRIX | GetTrix |
|
||||||
| ⛔ TSI - True Strength Index ||||
|
| ⛔ TSI - True Strength Index ||||
|
||||||
| ⛔ UO - Ultimate Oscillator ||||
|
| ⛔ UO - Ultimate Oscillator || ULTOSC | GetUltimate |
|
||||||
|
| ⛔ WILLR - Larry Williams' %R || WILLR | GetWilliamsR |
|
||||||
| ⛔ WGAT - Williams Alligator ||||
|
| ⛔ WGAT - Williams Alligator ||||
|
||||||
|||||
|
|||||
|
||||||
| **VOLUME INDICATORS** | **QuanTAlib** | **TA-LIB** | **Skender** |
|
| **VOLUME INDICATORS** | **QuanTAlib** | **TA-LIB** | **Skender** |
|
||||||
| ⛔ AOBV - Archer On-Balance Volume ||||
|
| ⛔ AOBV - Archer On-Balance Volume ||||
|
||||||
| ⛔ OBV - On-Balance Volume || OBV | GetObv |
|
| ⛔ CMF - Chaikin Money Flow ||||
|
||||||
|
| ⛔ EOM - Ease of Movement ||||
|
||||||
|
| ⭐ OBV - On-Balance Volume | `OBV_Series` | OBV | GetObv |
|
||||||
| ⛔ PRS - Price Relative Strength |||
|
| ⛔ PRS - Price Relative Strength |||
|
||||||
| ⛔ PVOL - Price-Volume ||||
|
| ⛔ PVOL - Price-Volume ||||
|
||||||
| ⛔ PVO - Percentage Volume Oscillator ||||
|
| ⛔ PVO - Percentage Volume Oscillator ||||
|
||||||
@@ -177,17 +190,3 @@ See [Getting Started](https://github.com/mihakralj/QuanTAlib/blob/main/Docs/gett
|
|||||||
| ⛔ VP - Volume Profile ||||
|
| ⛔ VP - Volume Profile ||||
|
||||||
| ⛔ VWAP - Volume Weighted Average Price ||||
|
| ⛔ VWAP - Volume Weighted Average Price ||||
|
||||||
| ⛔ VWMA - Volume Weighted Moving Average ||||
|
| ⛔ VWMA - Volume Weighted Moving Average ||||
|
||||||
|||||
|
|
||||||
|**Unsorted** | **QuanTAlib** | **TA-LIB** | **Skender** |
|
|
||||||
| ⛔ CHN - Price Channel ||||
|
|
||||||
| ⛔ COPPOCK - Coppock Curve ||||
|
|
||||||
| ⛔ EOM - Ease of Movement ||||
|
|
||||||
| ⛔ HILO - Gann High-Low Activator ||||
|
|
||||||
| ⛔ HT - HT Trendline ||||
|
|
||||||
| ⛔ MCGD - McGinley Dynamic ||||
|
|
||||||
| ⛔ STC - Schaff Trend Cycle ||||
|
|
||||||
| ⛔ WILLR - Larry Williams' %R ||||
|
|
||||||
| ⛔ VOR - Vortex Indicator ||||
|
|
||||||
| ⛔ PVT - Pivot Points ||||
|
|
||||||
| ⛔ KDJ - KDJ Index ||||
|
|
||||||
| ⛔ CHAND - Chandelier Exit ||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user