diff --git a/Quantower/Indicators/AAA_chart.cs b/Quantower/Indicators/AAA_chart.cs
new file mode 100644
index 00000000..11884745
--- /dev/null
+++ b/Quantower/Indicators/AAA_chart.cs
@@ -0,0 +1,59 @@
+using System.Diagnostics;
+using System.Drawing;
+using System.Linq;
+using TradingPlatform.BusinessLayer;
+namespace QuanTAlib;
+
+public class AAA_chart : Indicator {
+ #region Parameters
+
+ [InputParameter("Smoothing period", 0, 1, 999, 1, 1)]
+ private readonly int Period = 10;
+
+ #endregion Parameters
+
+ private TBars bars;
+ private TSeries series;
+ private JMA_Series jma;
+ private DWMA_Series dwma;
+
+ public AAA_chart() : base()
+ {
+ this.SeparateWindow = true;
+ this.Name = "AAA - Test indicator";
+ this.Description = "Test indicator";
+
+ this.AddLineSeries("JMA", Color.RoyalBlue, 3, LineStyle.Solid);
+ this.AddLineSeries("DWMA", Color.OrangeRed, 3, LineStyle.Solid);
+ this.SeparateWindow = false;
+ }
+
+ protected override void OnInit()
+ {
+ this.ShortName = "AAA (" + this.Period + ")";
+ this.bars = new();
+ this.series = new();
+
+ this.jma = new(source: bars.HLC3, period: this.Period, useNaN: false);
+ this.dwma = new(source: bars.HLC3, period: this.Period, useNaN: false);
+ }
+
+ protected override void OnUpdate(UpdateArgs args)
+ {
+ Debug.WriteLine($"{args.Reason}");
+ 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);
+
+ //this.series.Add(0.25*(this.GetPrice(PriceType.Open)+ this.GetPrice(PriceType.High)+ this.GetPrice(PriceType.Low)+ this.GetPrice(PriceType.Close)), update);
+
+ this.SetValue(this.jma.v.Last(), 0);
+ this.SetValue(this.dwma.v.Last(), 1);
+ }
+}
diff --git a/Quantower/Indicators/HMA_chart.cs b/Quantower/Indicators/HMA_chart.cs
index 26630247..ed0e3ea8 100644
--- a/Quantower/Indicators/HMA_chart.cs
+++ b/Quantower/Indicators/HMA_chart.cs
@@ -43,14 +43,11 @@ public class HMA_chart : Indicator
protected override void OnUpdate(UpdateArgs args)
{
- Debug.WriteLine("Send to debug output.");
+ bool update = !(args.Reason == UpdateReason.NewBar || args.Reason == UpdateReason.HistoricalBar);
- 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);
+ this.GetPrice(PriceType.Close),this.GetPrice(PriceType.Volume), update);
double result = this.indicator[this.indicator.Count - 1].v;
this.SetValue(result);
}
diff --git a/Quantower/Quantower.csproj b/Quantower/Quantower.csproj
index 0a13f65e..080b789a 100644
--- a/Quantower/Quantower.csproj
+++ b/Quantower/Quantower.csproj
@@ -1,50 +1,52 @@
-
-
-
- net48
- preview
- true
- AnyCPU
- Indicator
- Quantower_QTAlib
- QuanTAlib
- embedded
- preview
- AnyCPU
- disable
- False
- ..\.sonarlint\mihakralj_quantalibcsharp.ruleset
-
-
- True
- 3
- True
- anycpu
- full
-
-
- embedded
- True
- 3
- True
- anycpu
-
-
-
- QuanTAlib\%(RecursiveDir)%(Filename)%(Extension)
-
-
-
-
-
-
-
-
- C:\Quantower\TradingPlatform\v1.124.6\bin\TradingPlatform.BusinessLayer.dll
-
-
+ -->
+
+
+
+
+
+ C:\Quantower\TradingPlatform\v1.128.18\bin\TradingPlatform.BusinessLayer.dll
+
+
\ No newline at end of file
diff --git a/Source/Basics/Single_TBars_Abstract.cs b/Source/Basics/Single_TBars_Abstract.cs
index 9d24a889..4d5e3170 100644
--- a/Source/Basics/Single_TBars_Abstract.cs
+++ b/Source/Basics/Single_TBars_Abstract.cs
@@ -18,49 +18,50 @@ Abstract classes with all scaffolding required to build indicators.
public abstract class Single_TBars_Indicator : TSeries
{
- protected readonly int _p;
- protected readonly bool _NaN;
- protected readonly TBars _bars;
+ protected readonly int _p;
+ protected readonly bool _NaN;
+ protected readonly TBars _bars;
- // Chainable Constructor - add it at the end of primary constructor :base(source: source, period: period, useNaN: useNaN)
- protected Single_TBars_Indicator(TBars source, int period, bool useNaN)
- {
- this._p = period;
- this._bars = source;
- this._NaN = useNaN;
- this._bars.Pub += this.Sub;
- }
+ // Chainable Constructor - add it at the end of primary constructor :base(source: source, period: period, useNaN: useNaN)
+ protected Single_TBars_Indicator(TBars source, int period, bool useNaN)
+ {
+ this._p = period;
+ this._bars = source;
+ this._NaN = useNaN;
+ this._bars.Pub += this.Sub;
- // overridable Add() method to add/update a single item at the end of the list
+ }
+
+ // overridable Add() method to add/update a single item at the end of the list
- 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 v) TValue, bool update, bool useNaN)
- {
- var res = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : TValue.v);
- base.Add(res, 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);
+ public virtual void Add((System.DateTime t, double v) TValue, bool update, bool useNaN)
+ {
+ var res = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : TValue.v);
+ base.Add(res, update);
+ }
- // potentially overridable Add() method for the whole bars or series (could be replaced with faster bulk algo)
- 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); }}
- 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);
+ // potentially overridable Add() method for the whole bars or series (could be replaced with faster bulk algo)
+ 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); } }
+ 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);
- protected static void Add_Replace(List l, double v, bool update)
- {
- if (update)
- { l[l.Count - 1] = v; }
- else
- { l.Add(v); }
- }
- protected static void Add_Replace_Trim(List l, double v, int p, bool update)
- {
- Add_Replace(l, v, update);
- if (l.Count > p && p != 0)
- { l.RemoveAt(0); }
- }
+ protected static void Add_Replace(List l, double v, bool update)
+ {
+ if (update)
+ { l[l.Count - 1] = v; }
+ else
+ { l.Add(v); }
+ }
+ protected static void Add_Replace_Trim(List l, double v, int p, bool update)
+ {
+ Add_Replace(l, v, update);
+ if (l.Count > p && p != 0)
+ { l.RemoveAt(0); }
+ }
}
diff --git a/Source/Basics/Single_TSeries_Abstract.cs b/Source/Basics/Single_TSeries_Abstract.cs
index 1e96b5ca..24e5e5f4 100644
--- a/Source/Basics/Single_TSeries_Abstract.cs
+++ b/Source/Basics/Single_TSeries_Abstract.cs
@@ -1,71 +1,71 @@
-namespace QuanTAlib;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-/*
-Abstract classes with all scaffolding required to build indicators.
- All abstracts support period, NaN, and all permutations of Add() methods.
- Indicator classess need to implement:
- - Chaining constructor (Abstract's constructor executes first)
- - Default Add(value) class
- - optional Add(series) bulk insert class (for optimization of historical analysis)
-
- Single_TSeries_Indicator - one single-value TSeries in, one TSeries out.
- Pair_TSeries_Indicator - Two TSeries in, one TSeries out. (includes simple semaphoring)
- Single_TBars_Indicator - One OHLCV TBars in, one TSeries out.
-
- */
-public abstract class Single_TSeries_Indicator : TSeries
-{
- protected readonly int _period;
- protected readonly bool _NaN;
- protected readonly TSeries _data;
- protected int _p;
-
- // Chainable Constructor - add it at the end of primary constructor :base(source: source, period: period, useNaN: useNaN)
- protected Single_TSeries_Indicator(TSeries source, int period, bool useNaN)
- {
- this._data = source;
- this._period = period;
- this._p = _period;
- this._NaN = useNaN;
- this._data.Pub += this.Sub;
- }
-
- // overridable Add() method to add/update a single item at the end of the list
-
- public virtual void Add((System.DateTime t, double v) TValue, bool update, bool useNaN)
- {
- if (_period == 0) { _p = this.Length; }
- var res = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : TValue.v);
- base.Add(res, 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)
- public virtual void Add(TSeries data) { 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) => 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() => 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);
-
- protected static void Add_Replace(List l, double v, bool update)
- {
- if (update)
- { l[l.Count - 1] = v; }
- else
- { l.Add(v); }
- }
- protected static double Add_Replace_Trim(List l, double v, int p, bool update)
- {
- Add_Replace(l, v, update);
- double ret = (l.Count > 0) ? l.First() : 0;
- if (l.Count > p && p != 0)
- {
- l.RemoveAt(0);
- }
- return ret;
- }
-}
+namespace QuanTAlib;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+/*
+Abstract classes with all scaffolding required to build indicators.
+ All abstracts support period, NaN, and all permutations of Add() methods.
+ Indicator classess need to implement:
+ - Chaining constructor (Abstract's constructor executes first)
+ - Default Add(value) class
+ - optional Add(series) bulk insert class (for optimization of historical analysis)
+
+ Single_TSeries_Indicator - one single-value TSeries in, one TSeries out.
+ Pair_TSeries_Indicator - Two TSeries in, one TSeries out. (includes simple semaphoring)
+ Single_TBars_Indicator - One OHLCV TBars in, one TSeries out.
+
+ */
+public abstract class Single_TSeries_Indicator : TSeries
+{
+ protected readonly int _period;
+ protected readonly bool _NaN;
+ protected readonly TSeries _data;
+ protected int _p;
+
+ // Chainable Constructor - add it at the end of primary constructor :base(source: source, period: period, useNaN: useNaN)
+ protected Single_TSeries_Indicator(TSeries source, int period, bool useNaN)
+ {
+ this._data = source;
+ this._period = period;
+ this._p = _period;
+ this._NaN = useNaN;
+ this._data.Pub += this.Sub;
+ }
+
+ // overridable Add() method to add/update a single item at the end of the list
+
+ public virtual void Add((System.DateTime t, double v) TValue, bool update, bool useNaN)
+ {
+ if (_period == 0) { _p = this.Length; }
+ var res = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : TValue.v);
+ base.Add(res, 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)
+ public virtual void Add(TSeries data) { 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) => 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() => 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);
+
+ protected static void Add_Replace(List l, double v, bool update)
+ {
+ if (update)
+ { l[l.Count - 1] = v; }
+ else
+ { l.Add(v); }
+ }
+ protected static double Add_Replace_Trim(List l, double v, int p, bool update)
+ {
+ Add_Replace(l, v, update);
+ double ret = (l.Count > 0) ? l.First() : 0;
+ if (l.Count > p && p != 0)
+ {
+ l.RemoveAt(0);
+ }
+ return ret;
+ }
+}
diff --git a/Source/Basics/TBars.cs b/Source/Basics/TBars.cs
index 850a9db7..66cd5c4d 100644
--- a/Source/Basics/TBars.cs
+++ b/Source/Basics/TBars.cs
@@ -1,132 +1,136 @@
-namespace QuanTAlib;
-using System;
-
-/*
-TBars class - includes all series for common data used in indicators and other calculations.
- Has a bit limited overloading and casting (compared to TSeries)
- Includes Select(int) method to simplify choosing the most optimal data source for indicators
- Includes the most basic pricing calcs: HL2, OC2, OHL3, HLC3, OHLC4, HLCC4
- (it is 'cheaper' to calculate them once during data capture than each time during data analysis)
-
- */
-
-public class TBars : System.Collections.Generic.List<(DateTime t, double o, double h, double l, double c, double v)>
-{
- private readonly TSeries _open = new();
- private readonly TSeries _high = new();
- private readonly TSeries _low = new();
- private readonly TSeries _close = new();
- private readonly TSeries _volume = new();
- private readonly TSeries _hl2 = new();
- private readonly TSeries _oc2 = new();
- private readonly TSeries _ohl3 = new();
- private readonly TSeries _hlc3 = new();
- private readonly TSeries _ohlc4 = new();
- private readonly TSeries _hlcc4 = new();
-
- public TSeries Open => this._open;
- public TSeries High => this._high;
- public TSeries Low => this._low;
- public TSeries Close => this._close;
- public TSeries Volume => this._volume;
- public TSeries HL2 => this._hl2;
- public TSeries OC2 => this._oc2;
- public TSeries OHL3 => this._ohl3;
- public TSeries HLC3 => this._hlc3;
- public TSeries OHLC4 => this._ohlc4;
- public TSeries HLCC4 => this._hlcc4;
-
- public TBars Tail(int count=10) {
- TBars outBars = new();
- if (count > this.Count) { count = this.Count; }
- for (int i = this.Count-count; i _open,
- 1 => _high,
- 2 => _low,
- 3 => _close,
- 4 => _hl2,
- 5 => _oc2,
- 6 => _ohl3,
- 7 => _hlc3,
- 8 => _ohlc4,
- _ => _hlcc4,
- };
- }
- public static string SelectStr(int source)
- {
- return source switch
- {
- 0 => "Open",
- 1 => "High",
- 2 => "Low",
- 3 => "Close",
- 4 => "HL2",
- 5 => "OC2",
- 6 => "OHL3",
- 7 => "Typical",
- 8 => "Mean",
- _ => "Weighted",
- };
- }
-
- 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);
-
- public void Add(DateTime t, decimal o, decimal h, decimal l, decimal c, decimal v, bool update = false)
- => Add(t, (double)o, (double)h, (double)l, (double)c, (double)v, update);
-
- public void Add(DateTime t, double o, double h, double l, double c, double v, bool update = false)
- {
- if (update)
- {
- this[this.Count - 1] = (t, o, h, l, c, v);
- _open[_open.Count - 1] = (t, o);
- _high[_high.Count - 1] = (t, h);
- _low[_low.Count - 1] = (t, l);
- _close[_close.Count - 1] = (t, c);
- _volume[_volume.Count - 1] = (t, v);
- _hl2[_hl2.Count - 1] = (t, (h + l) * 0.5);
- _oc2[_oc2.Count - 1] = (t, (o + c) * 0.5);
- _ohl3[_ohl3.Count - 1] = (t, (o + h + l) * 0.333333333333333);
- _hlc3[_hlc3.Count - 1] = (t, (h + l + c) * 0.333333333333333);
- _ohlc4[_ohlc4.Count - 1] = (t, (o + h + l + c) * 0.25);
- _hlcc4[_hlcc4.Count - 1] = (t, (h + l + c + c) * 0.25);
- }
- else
- {
- base.Add((t, o, h, l, c, v));
- _open.Add((t, o));
- _high.Add((t, h));
- _low.Add((t, l));
- _close.Add((t, c));
- _volume.Add((t, v));
- _hl2.Add((t, (h + l) * 0.5));
- _oc2.Add((t, (o + c) * 0.5));
- _ohl3.Add((t, (o + h + l) * 0.333333333333333));
- _hlc3.Add((t, (h + l + c) * 0.333333333333333));
- _ohlc4.Add((t, (o + h + l + c) * 0.25));
- _hlcc4.Add((t, (h + l + c + c) * 0.25));
- }
- this.OnEvent(update);
- }
-
- // delegate used by event handler + event handler (Pub == publisher)
- public delegate
- void NewDataEventHandler(object source, TSeriesEventArgs args);
- public event NewDataEventHandler Pub;
-
- // Broadcast handler - only to valid targets
- protected virtual void OnEvent(bool update = false)
- {
- if (Pub != null && Pub.Target != this)
- {
- Pub(this, new TSeriesEventArgs { update = update });
- }
- }
-}
+namespace QuanTAlib;
+using System;
+
+/*
+TBars class - includes all series for common data used in indicators and other calculations.
+ Has a bit limited overloading and casting (compared to TSeries)
+ Includes Select(int) method to simplify choosing the most optimal data source for indicators
+ Includes the most basic pricing calcs: HL2, OC2, OHL3, HLC3, OHLC4, HLCC4
+ (it is 'cheaper' to calculate them once during data capture than each time during data analysis)
+
+ */
+
+public class TBars : System.Collections.Generic.List<(DateTime t, double o, double h, double l, double c, double v)>
+{
+ private readonly TSeries _open = new();
+ private readonly TSeries _high = new();
+ private readonly TSeries _low = new();
+ private readonly TSeries _close = new();
+ private readonly TSeries _volume = new();
+ private readonly TSeries _hl2 = new();
+ private readonly TSeries _oc2 = new();
+ private readonly TSeries _ohl3 = new();
+ private readonly TSeries _hlc3 = new();
+ private readonly TSeries _ohlc4 = new();
+ private readonly TSeries _hlcc4 = new();
+
+ public TSeries Open => this._open;
+ public TSeries High => this._high;
+ public TSeries Low => this._low;
+ public TSeries Close => this._close;
+ public TSeries Volume => this._volume;
+ public TSeries HL2 => this._hl2;
+ public TSeries OC2 => this._oc2;
+ public TSeries OHL3 => this._ohl3;
+ public TSeries HLC3 => this._hlc3;
+ public TSeries OHLC4 => this._ohlc4;
+ public TSeries HLCC4 => this._hlcc4;
+
+ public TBars Tail(int count = 10)
+ {
+ TBars outBars = new();
+ if (count > this.Count) { count = this.Count; }
+ for (int i = this.Count - count; i < this.Count; i++) { outBars.Add(this[i]); }
+ return outBars;
+ }
+ public TSeries Select(int source)
+ {
+ return source switch
+ {
+ 0 => _open,
+ 1 => _high,
+ 2 => _low,
+ 3 => _close,
+ 4 => _hl2,
+ 5 => _oc2,
+ 6 => _ohl3,
+ 7 => _hlc3,
+ 8 => _ohlc4,
+ _ => _hlcc4,
+ };
+ }
+ public static string SelectStr(int source)
+ {
+ return source switch
+ {
+ 0 => "Open",
+ 1 => "High",
+ 2 => "Low",
+ 3 => "Close",
+ 4 => "HL2",
+ 5 => "OC2",
+ 6 => "OHL3",
+ 7 => "Typical",
+ 8 => "Mean",
+ _ => "Weighted",
+ };
+ }
+
+ 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);
+
+ public void Add(DateTime t, decimal o, decimal h, decimal l, decimal c, decimal v, bool update = false)
+ => Add(t, (double)o, (double)h, (double)l, (double)c, (double)v, update);
+
+ public void Add(DateTime t, double o, double h, double l, double c, double v, bool update = false)
+ {
+ if (update) {
+ this[this.Count - 1] = (t, o, h, l, c, v);
+ }
+ else {
+ base.Add((t, o, h, l, c, v));
+ }
+ _open.Add((t, o),update);
+ _high.Add((t, h), update);
+ _low.Add((t, l), update);
+ _close.Add((t, c), update);
+ _volume.Add((t, v), update);
+ _hl2.Add((t, (h + l) * 0.5), update);
+ _oc2.Add((t, (o + c) * 0.5), update);
+ _ohl3.Add((t, (o + h + l) * 0.333333333333333), update);
+ _hlc3.Add((t, (h + l + c) * 0.333333333333333), update);
+ _ohlc4.Add((t, (o + h + l + c) * 0.25), update);
+ _hlcc4.Add((t, (h + l + c + c) * 0.25), update);
+
+ this.OnEvent(update);
+ }
+
+ // delegate used by event handler + event handler (Pub == publisher)
+ public delegate void NewDataEventHandler(object source, TSeriesEventArgs args);
+ public event NewDataEventHandler Pub;
+
+ // Broadcast handler - only to valid targets
+ protected virtual void OnEvent(bool update = false)
+ {
+ if (Pub != null && Pub.Target != this)
+ {
+ Pub(this, new TSeriesEventArgs { update = update });
+ }
+ }
+
+ public void Sub(object source, TSeriesEventArgs e)
+ {
+ TBars ss = (TBars)source;
+ if (ss.Count > 1)
+ {
+ for (int i = 0; i < ss.Count; i++)
+ {
+ this.Add(ss[i]);
+ }
+ }
+ else
+ {
+ this.Add(ss[ss.Count - 1], e.update);
+ }
+ }
+}
diff --git a/Source/Trends/DEMA_Series.cs b/Source/Trends/DEMA_Series.cs
index cb165726..ed1a0f92 100644
--- a/Source/Trends/DEMA_Series.cs
+++ b/Source/Trends/DEMA_Series.cs
@@ -22,13 +22,15 @@ public class DEMA_Series : Single_TSeries_Indicator
private readonly System.Collections.Generic.List _buffer1 = new();
private readonly System.Collections.Generic.List _buffer2 = new();
private readonly double _k;
- private double _lastema1, _lastlastema1;
+ private readonly bool _useSMA;
+ private double _lastema1, _lastlastema1;
private double _lastema2, _lastlastema2;
- public DEMA_Series(TSeries source, int period, bool useNaN = false) : base(source, period, useNaN)
+ public DEMA_Series(TSeries source, int period, bool useNaN = false, bool useSMA = true) : base(source, period, useNaN)
{
_k = 2.0 / (_p + 1);
- if (_data.Count > 0) { base.Add(_data); }
+ _useSMA = useSMA;
+ if (_data.Count > 0) { base.Add(_data); }
}
public override void Add((DateTime t, double v) TValue, bool update)
@@ -40,7 +42,7 @@ public class DEMA_Series : Single_TSeries_Indicator
}
double _ema1, _ema2, _dema;
- if (this.Count < _p)
+ if (this.Count < _p && _useSMA)
{
Add_Replace_Trim(_buffer1, TValue.v, _p, update);
_ema1 = 0;
@@ -52,7 +54,7 @@ public class DEMA_Series : Single_TSeries_Indicator
for (int i = 0; i < _buffer2.Count; i++) { _ema2 += _buffer2[i]; }
_ema2 /= _buffer2.Count;
}
- else if(this.Count < (2*_p - 1)) // second _p
+ else if(this.Count < (2*_p - 1) && _useSMA) // second _p
{
_ema1 = (TValue.v - _lastema1) * _k + _lastema1;
diff --git a/Source/Trends/DWMA_Series.cs b/Source/Trends/DWMA_Series.cs
index 0cff2aec..68eaf0bc 100644
--- a/Source/Trends/DWMA_Series.cs
+++ b/Source/Trends/DWMA_Series.cs
@@ -1,39 +1,39 @@
-namespace QuanTAlib;
-using System;
-
-/*
-DWMA: Double (linearly) Weighted Moving Average
- The weights are linearly decreasing over the period and the most recent data has
- the heaviest weight.
-
-Sources:
-
-
- */
-
-public class DWMA_Series : Single_TSeries_Indicator
-{
- public DWMA_Series(TSeries source, int period, bool useNaN = false) : base(source, period, useNaN)
- {
- for (int i = 0; i < this._p; i++) { this._weights.Add(i + 1); }
- if (base._data.Count > 0) { base.Add(base._data); }
- }
- private readonly System.Collections.Generic.List _buffer1 = new();
- private readonly System.Collections.Generic.List _buffer2 = new();
- private readonly System.Collections.Generic.List _weights = new();
-
- public override void Add((System.DateTime t, double v) TValue, bool update)
- {
- Add_Replace_Trim(_buffer1, TValue.v, _p, update);
- double _wma = 0;
- for (int i = 0; i < _buffer1.Count; i++) { _wma += _buffer1[i] * this._weights[i]; }
- _wma /= (this._buffer1.Count * (this._buffer1.Count + 1)) * 0.5;
-
- Add_Replace_Trim(_buffer2, TValue.v, _p, update);
- double _dwma = 0;
- for (int i = 0; i < _buffer2.Count; i++) { _dwma += _buffer2[i] * this._weights[i]; }
- _dwma /= (this._buffer2.Count * (this._buffer2.Count + 1)) * 0.5;
-
- base.Add((TValue.t, _dwma), update, _NaN);
- }
+namespace QuanTAlib;
+using System;
+
+/*
+DWMA: Double (linearly) Weighted Moving Average
+ The weights are linearly decreasing over the period and the most recent data has
+ the heaviest weight.
+
+Sources:
+
+
+ */
+
+public class DWMA_Series : Single_TSeries_Indicator
+{
+ public DWMA_Series(TSeries source, int period, bool useNaN = false) : base(source, period, useNaN)
+ {
+ for (int i = 0; i < this._p; i++) { this._weights.Add(i + 1); }
+ if (base._data.Count > 0) { base.Add(base._data); }
+ }
+ private readonly System.Collections.Generic.List _buffer1 = new();
+ private readonly System.Collections.Generic.List _buffer2 = new();
+ private readonly System.Collections.Generic.List _weights = new();
+
+ public override void Add((System.DateTime t, double v) TValue, bool update)
+ {
+ Add_Replace_Trim(_buffer1, TValue.v, _p, update);
+ double _wma = 0;
+ for (int i = 0; i < _buffer1.Count; i++) { _wma += _buffer1[i] * this._weights[i]; }
+ _wma /= (this._buffer1.Count * (this._buffer1.Count + 1)) * 0.5;
+
+ Add_Replace_Trim(_buffer2, TValue.v, _p, update);
+ double _dwma = 0;
+ for (int i = 0; i < _buffer2.Count; i++) { _dwma += _buffer2[i] * this._weights[i]; }
+ _dwma /= (this._buffer2.Count * (this._buffer2.Count + 1)) * 0.5;
+
+ base.Add((TValue.t, 2*_wma - _dwma), update, _NaN);
+ }
}
\ No newline at end of file
diff --git a/Source/Trends/EMA_Series.cs b/Source/Trends/EMA_Series.cs
index c3fdc19e..abb4bcfd 100644
--- a/Source/Trends/EMA_Series.cs
+++ b/Source/Trends/EMA_Series.cs
@@ -25,7 +25,7 @@ public class EMA_Series : Single_TSeries_Indicator
private readonly System.Collections.Generic.List _buffer = new();
private readonly double _k, _k1m;
private double _lastema, _lastlastema;
- private bool _useSMA;
+ private readonly bool _useSMA;
public EMA_Series(TSeries source, int period, bool useNaN = false, bool useSMA = true) : base(source, period, useNaN)
{
diff --git a/Source/Trends/JMA_Series.cs b/Source/Trends/JMA_Series.cs
index 94b17d56..6a3f79fa 100644
--- a/Source/Trends/JMA_Series.cs
+++ b/Source/Trends/JMA_Series.cs
@@ -23,9 +23,11 @@ Issues:
public class JMA_Series : Single_TSeries_Indicator {
private readonly System.Collections.Generic.List volty_10 = new();
private readonly System.Collections.Generic.List vsum_buff = new();
- private readonly double pr, beta;
+ private readonly double pr;
+ public TSeries mma1 { get; }
+ public TSeries mma2 { get; }
- private double upperBand, lowerBand, _phase, vsum, Kv, del1, del2, prev_del1, prev_del2;
+ private double upperBand, lowerBand, vsum, Kv, del1, del2;
private double prev_ma1, prev_det0, prev_det1, prev_vsum, prev_jma;
private double p_upperBand, p_lowerBand, p_Kv, p_prev_ma1, p_prev_det0, p_prev_det1, p_prev_vsum, p_prev_jma;
@@ -35,18 +37,34 @@ public class JMA_Series : Single_TSeries_Indicator {
pr = (phase * 0.01) + 1.5;
if (phase < -100) pr = 0.5;
if (phase > 100) pr = 2.5;
- beta = 0.45 * (_p - 1) / (0.45 * (_p - 1) + 2);
+
+ mma1 = new();
+ mma2 = new();
if (base._data.Count > 0) { base.Add(base._data); }
}
public override void Add((System.DateTime t, double v) TValue, bool update) {
+ if (this.Count == 0) { prev_ma1 = TValue.v; }
if (update) {
- upperBand = p_upperBand; lowerBand = p_lowerBand; Kv = p_Kv; prev_vsum = p_prev_vsum;
- prev_ma1 = p_prev_ma1; prev_det0 = p_prev_det0; prev_det1 = p_prev_det1; prev_jma = p_prev_jma;
- } else {
- p_upperBand = upperBand; p_lowerBand = lowerBand; p_Kv = Kv; p_prev_vsum = prev_vsum;
- p_prev_ma1 = prev_ma1; p_prev_det0 = prev_det0; p_prev_det1 = prev_det1; p_prev_jma = prev_jma;
+ upperBand = p_upperBand;
+ lowerBand = p_lowerBand;
+ Kv = p_Kv;
+ prev_vsum = p_prev_vsum;
+ prev_ma1 = p_prev_ma1;
+ prev_det0 = p_prev_det0;
+ prev_det1 = p_prev_det1;
+ prev_jma = p_prev_jma;
+ }
+ else {
+ p_upperBand = upperBand;
+ p_lowerBand = lowerBand;
+ p_Kv = Kv;
+ p_prev_vsum = prev_vsum;
+ p_prev_ma1 = prev_ma1;
+ p_prev_det0 = prev_det0;
+ p_prev_det1 = prev_det1;
+ p_prev_jma = prev_jma;
}
// from Tvalue to volty
@@ -59,41 +77,49 @@ public class JMA_Series : Single_TSeries_Indicator {
if (Math.Abs(del1) < Math.Abs(del2)) { volty = Math.Abs(del2); }
//// from volty to avolty
- if (update) { volty_10[volty_10.Count - 1] = volty; } else { volty_10.Add(volty); }
- if (volty_10.Count > 10) { volty_10.RemoveAt(0); }
+ if (update) { volty_10[volty_10.Count - 1] = volty; }
+ else { volty_10.Add(volty); }
+ if (volty_10.Count > _p) { volty_10.RemoveAt(0); }
vsum = prev_vsum + 0.1 * (volty - volty_10.First());
- if (update) { vsum_buff[vsum_buff.Count - 1] = vsum; } else { vsum_buff.Add(vsum); }
- if (vsum_buff.Count > 65) vsum_buff.RemoveAt(0);
+ if (update) { vsum_buff[vsum_buff.Count - 1] = vsum; }
+ else { vsum_buff.Add(vsum); }
+ if (vsum_buff.Count > (65))
+ vsum_buff.RemoveAt(0);
double avolty = 0;
for (int i = 0; i < vsum_buff.Count; i++) { avolty += vsum_buff[i]; }
avolty /= vsum_buff.Count;
/// from avolty to rolty
- double rvolty = (avolty > 0) ? volty / avolty : 0;
- double len1 = (Math.Log(Math.Sqrt(_p)) / Math.Log(2.0)) + 2;
- if (len1 < 0) len1 = 0;
+ double rvolty = (avolty != 0) ? volty / avolty : 0;
+ double len1 = (Math.Log(Math.Sqrt(0.5 * (_p - 1))) / Math.Log(2.0)) + 2;
+ if (len1 < 0)
+ len1 = 0;
double pow1 = Math.Max(len1 - 2.0, 0.5);
- if (rvolty > Math.Pow(len1, 1.0 / pow1)) rvolty = Math.Pow(len1, 1.0 / pow1);
- if (rvolty < 1) rvolty = 1;
+ if (rvolty > Math.Pow(len1, 1.0 / pow1))
+ rvolty = Math.Pow(len1, 1.0 / pow1);
+ if (rvolty < 1)
+ rvolty = 1;
//// from rvolty to second smoothing
double pow2 = Math.Pow(rvolty, pow1);
double len2 = Math.Sqrt(0.5 * (_p - 1)) * len1;
- Kv = Math.Pow(len2 / (len2 + 1), Math.Sqrt(pow2));
- double alpha = Math.Pow(beta, pow2);
- double ma1 = (1 - alpha) * TValue.v + alpha * prev_ma1;
+ Kv = Math.Pow(len2 / (len2 + 2), Math.Sqrt(pow2));
+ double beta = 0.45 * (_p - 1) / (0.45 * (_p - 1) + 2);
+ double alpha = Math.Pow(beta * 1.1, pow2);
+ double ma1 = (1 - alpha) * TValue.v + alpha * prev_ma1;
prev_ma1 = ma1;
- double det0 = (1 - beta) * (TValue.v - ma1) + beta * prev_det0;
- prev_det0 = det0;
+ mma1.Add(ma1);
- /// from second smoothing to jma
+ double det0 = (1 - beta) * (TValue.v - ma1) + beta * prev_det0;
+ prev_det0 = det0;
double ma2 = ma1 + pr * det0;
- double det1 = (1 - alpha) * (1 - alpha) * (ma2 - prev_jma) + alpha * alpha * prev_det1;
+ mma2.Add(ma2);
+
+ double det1 = ((1 - alpha) * (1 - alpha) * (ma2 - prev_jma)) + (alpha * alpha * prev_det1);
prev_det1 = det1;
double jma = prev_jma + det1;
prev_jma = jma;
- base.Add((TValue.t, jma), update, _NaN);
+ base.Add((TValue.t, ma1), update, _NaN);
}
-}
-
+}
\ No newline at end of file
diff --git a/Source/Trends/MAMA_Series.cs b/Source/Trends/MAMA_Series.cs
index ff85d784..0224dc98 100644
--- a/Source/Trends/MAMA_Series.cs
+++ b/Source/Trends/MAMA_Series.cs
@@ -1,118 +1,118 @@
-namespace QuanTAlib;
-using System;
-
-/*
-MAMA: MESA Adaptive Moving Average
- Created by John Ehlers, the MAMA indicator is a 5-period adaptive moving average of
- high/low price that uses classic electrical radio-frequency signal processing algorithms
- to reduce noise.
-
- KAMAi = KAMAi - 1 + SC * ( price - KAMAi-1 )
-
-Sources:
- https://mesasoftware.com/papers/MAMA.pdf
- https://www.tradingview.com/script/foQxLbU3-Ehlers-MESA-Adaptive-Moving-Average-LazyBear/
-
- */
-
-public class MAMA_Series : Single_TSeries_Indicator
-{
- public MAMA_Series(TSeries source, double fastlimit = 0.5, double slowlimit = 0.05, bool useNaN = false) : base(source, period: 5, useNaN)
- {
- fastl = fastlimit;
- slowl = slowlimit;
- Fama = new();
- if (base._data.Count > 0) { base.Add(base._data); }
- }
-
- private double sumPr, jI, jQ, fastl, slowl;
- private (double i, double i1, double i2, double i3, double i4, double i5, double i6, double io) pr, i1, q1, sm, dt;
- private (double i, double i1, double io) i2, q2, re, im, pd, ph, mama, fama;
- public TSeries Fama { get; }
-
- public override void Add((System.DateTime t, double v) TValue, bool update)
- {
-
- if (!update) {
- // roll forward (oldx = x)
- pr.io = pr.i6; pr.i6 = pr.i5; pr.i5 = pr.i4; pr.i4 = pr.i3; pr.i3 = pr.i2; pr.i2 = pr.i1; pr.i1 = pr.i;
- i1.io = i1.i6; i1.i6 = i1.i5; i1.i5 = i1.i4; i1.i4 = i1.i3; i1.i3 = i1.i2; i1.i2 = i1.i1; i1.i1 = i1.i;
- q1.io = q1.i6; q1.i6 = q1.i5; q1.i5 = q1.i4; q1.i4 = q1.i3; q1.i3 = q1.i2; q1.i2 = q1.i1; q1.i1 = q1.i;
- dt.io = dt.i6; dt.i6 = dt.i5; dt.i5 = dt.i4; dt.i4 = dt.i3; dt.i3 = dt.i2; dt.i2 = dt.i1; dt.i1 = dt.i;
- sm.io = sm.i6; sm.i6 = sm.i5; sm.i5 = sm.i4; sm.i4 = sm.i3; sm.i3 = sm.i2; sm.i2 = sm.i1; sm.i1 = sm.i;
- i2.io = i2.i1; i2.i1 = i2.i;
- q2.io = q2.i1; q2.i1 = q2.i;
- re.io = re.i1; re.i1 = re.i;
- im.io = im.i1; im.i1 = im.i;
- pd.io = pd.i1; pd.i1 = pd.i;
- ph.io = ph.i1; ph.i1 = ph.i;
- mama.io = mama.i1; mama.i1 = mama.i;
- fama.io = fama.i1; fama.i1 = fama.i;
- }
- int i = base.Count;
- pr.i = TValue.v;
- if (i > 5) {
- double adj = (0.075 * pd.i1) + 0.54;
-
- // smooth and detrender
- sm.i = ((4 * pr.i) + (3 * pr.i1) + (2 * pr.i2) + pr.i3) / 10;
- dt.i = ((0.0962 * sm.i) + (0.5769 * sm.i2) - (0.5769 * sm.i4) - (0.0962 * sm.i6)) * adj;
-
- // in-phase and quadrature
- q1.i = ((0.0962 * dt.i) + (0.5769 * dt.i2) - (0.5769 * dt.i4) - (0.0962 * dt.i6)) * adj;
- i1.i = dt.i3;
-
- // advance the phases by 90 degrees
- jI = ((0.0962 * i1.i) + (0.5769 * i1.i2) - (0.5769 * i1.i4) - (0.0962 * i1.i6)) * adj;
- jQ = ((0.0962 * q1.i) + (0.5769 * q1.i2) - (0.5769 * q1.i4) - (0.0962 * q1.i6)) * adj;
-
- // phasor addition for 3-bar averaging
- i2.i = i1.i - jQ;
- q2.i = q1.i + jI;
-
- i2.i = (0.2 * i2.i) + (0.8 * i2.i1); // smoothing it
- q2.i = (0.2 * q2.i) + (0.8 * q2.i1);
-
- // homodyne discriminator
- re.i = (i2.i * i2.i1) + (q2.i * q2.i1);
- im.i = (i2.i * q2.i1) - (q2.i * i2.i1);
-
- re.i = (0.2 * re.i) + (0.8 * re.i1); // smoothing it
- im.i = (0.2 * im.i) + (0.8 * im.i1);
-
- // calculate period
- pd.i = (im.i != 0 && re.i != 0) ? (6.283185307179586 / Math.Atan(im.i / re.i)) : 0d;
-
- // adjust period to thresholds
- pd.i = (pd.i > 1.5 * pd.i1) ? 1.5 * pd.i1 : pd.i;
- pd.i = (pd.i < 0.67 * pd.i1) ? 0.67 * pd.i1 : pd.i;
- pd.i = (pd.i < 6d) ? 6d : pd.i;
- pd.i = (pd.i > 50d) ? 50d : pd.i;
-
- // smooth the period
- pd.i = (0.2 * pd.i) + (0.8 * pd.i1);
-
- // determine phase position
- ph.i = (i1.i != 0) ? Math.Atan(q1.i / i1.i) * 57.29577951308232 : 0;
-
- // change in phase
- double delta = Math.Max(ph.i1 - ph.i, 1d);
-
- // adaptive alpha value
- double alpha = Math.Max(fastl / delta, slowl);
-
- // final indicators
- mama.i = ((alpha * pr.i) + ((1d - alpha) * mama.i1));
- fama.i = ((0.5d * alpha * mama.i) + ((1d - (0.5d * alpha)) * fama.i1));
- }
- else {
- sumPr += pr.i;
- pd.i = sm.i = dt.i = i1.i = q1.i = i2.i = q2.i = re.i = im.i = ph.i = 0;
- mama.i = fama.i = sumPr / (i+1);
- }
-
- base.Add((TValue.t, mama.i), update, _NaN);
- var result = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : fama.i);
- Fama.Add(result, update);
- }
-}
+namespace QuanTAlib;
+using System;
+
+/*
+MAMA: MESA Adaptive Moving Average
+ Created by John Ehlers, the MAMA indicator is a 5-period adaptive moving average of
+ high/low price that uses classic electrical radio-frequency signal processing algorithms
+ to reduce noise.
+
+ KAMAi = KAMAi - 1 + SC * ( price - KAMAi-1 )
+
+Sources:
+ https://mesasoftware.com/papers/MAMA.pdf
+ https://www.tradingview.com/script/foQxLbU3-Ehlers-MESA-Adaptive-Moving-Average-LazyBear/
+
+ */
+
+public class MAMA_Series : Single_TSeries_Indicator
+{
+ public MAMA_Series(TSeries source, double fastlimit = 0.5, double slowlimit = 0.05, bool useNaN = false) : base(source, period: 5, useNaN)
+ {
+ fastl = fastlimit;
+ slowl = slowlimit;
+ Fama = new();
+ if (base._data.Count > 0) { base.Add(base._data); }
+ }
+
+ private double sumPr, jI, jQ, fastl, slowl;
+ private (double i, double i1, double i2, double i3, double i4, double i5, double i6, double io) pr, i1, q1, sm, dt;
+ private (double i, double i1, double io) i2, q2, re, im, pd, ph, mama, fama;
+ public TSeries Fama { get; }
+
+ public override void Add((System.DateTime t, double v) TValue, bool update)
+ {
+
+ if (!update) {
+ // roll forward (oldx = x)
+ pr.io = pr.i6; pr.i6 = pr.i5; pr.i5 = pr.i4; pr.i4 = pr.i3; pr.i3 = pr.i2; pr.i2 = pr.i1; pr.i1 = pr.i;
+ i1.io = i1.i6; i1.i6 = i1.i5; i1.i5 = i1.i4; i1.i4 = i1.i3; i1.i3 = i1.i2; i1.i2 = i1.i1; i1.i1 = i1.i;
+ q1.io = q1.i6; q1.i6 = q1.i5; q1.i5 = q1.i4; q1.i4 = q1.i3; q1.i3 = q1.i2; q1.i2 = q1.i1; q1.i1 = q1.i;
+ dt.io = dt.i6; dt.i6 = dt.i5; dt.i5 = dt.i4; dt.i4 = dt.i3; dt.i3 = dt.i2; dt.i2 = dt.i1; dt.i1 = dt.i;
+ sm.io = sm.i6; sm.i6 = sm.i5; sm.i5 = sm.i4; sm.i4 = sm.i3; sm.i3 = sm.i2; sm.i2 = sm.i1; sm.i1 = sm.i;
+ i2.io = i2.i1; i2.i1 = i2.i;
+ q2.io = q2.i1; q2.i1 = q2.i;
+ re.io = re.i1; re.i1 = re.i;
+ im.io = im.i1; im.i1 = im.i;
+ pd.io = pd.i1; pd.i1 = pd.i;
+ ph.io = ph.i1; ph.i1 = ph.i;
+ mama.io = mama.i1; mama.i1 = mama.i;
+ fama.io = fama.i1; fama.i1 = fama.i;
+ }
+ int i = base.Count;
+ pr.i = TValue.v;
+ if (i > 5) {
+ double adj = (0.075 * pd.i1) + 0.54;
+
+ // smooth and detrender
+ sm.i = ((4 * pr.i) + (3 * pr.i1) + (2 * pr.i2) + pr.i3) / 10;
+ dt.i = ((0.0962 * sm.i) + (0.5769 * sm.i2) - (0.5769 * sm.i4) - (0.0962 * sm.i6)) * adj;
+
+ // in-phase and quadrature
+ q1.i = ((0.0962 * dt.i) + (0.5769 * dt.i2) - (0.5769 * dt.i4) - (0.0962 * dt.i6)) * adj;
+ i1.i = dt.i3;
+
+ // advance the phases by 90 degrees
+ jI = ((0.0962 * i1.i) + (0.5769 * i1.i2) - (0.5769 * i1.i4) - (0.0962 * i1.i6)) * adj;
+ jQ = ((0.0962 * q1.i) + (0.5769 * q1.i2) - (0.5769 * q1.i4) - (0.0962 * q1.i6)) * adj;
+
+ // phasor addition for 3-bar averaging
+ i2.i = i1.i - jQ;
+ q2.i = q1.i + jI;
+
+ i2.i = (0.2 * i2.i) + (0.8 * i2.i1); // smoothing it
+ q2.i = (0.2 * q2.i) + (0.8 * q2.i1);
+
+ // homodyne discriminator
+ re.i = (i2.i * i2.i1) + (q2.i * q2.i1);
+ im.i = (i2.i * q2.i1) - (q2.i * i2.i1);
+
+ re.i = (0.2 * re.i) + (0.8 * re.i1); // smoothing it
+ im.i = (0.2 * im.i) + (0.8 * im.i1);
+
+ // calculate period
+ pd.i = (im.i != 0 && re.i != 0) ? (6.283185307179586 / Math.Atan(im.i / re.i)) : 0d;
+
+ // adjust period to thresholds
+ pd.i = (pd.i > 1.5 * pd.i1) ? 1.5 * pd.i1 : pd.i;
+ pd.i = (pd.i < 0.67 * pd.i1) ? 0.67 * pd.i1 : pd.i;
+ pd.i = (pd.i < 6d) ? 6d : pd.i;
+ pd.i = (pd.i > 50d) ? 50d : pd.i;
+
+ // smooth the period
+ pd.i = (0.2 * pd.i) + (0.8 * pd.i1);
+
+ // determine phase position
+ ph.i = (i1.i != 0) ? Math.Atan(q1.i / i1.i) * 57.29577951308232 : 0;
+
+ // change in phase
+ double delta = Math.Max(ph.i1 - ph.i, 1d);
+
+ // adaptive alpha value
+ double alpha = Math.Max(fastl / delta, slowl);
+
+ // final indicators
+ mama.i = ((alpha * pr.i) + ((1d - alpha) * mama.i1));
+ fama.i = ((0.5d * alpha * mama.i) + ((1d - (0.5d * alpha)) * fama.i1));
+ }
+ else {
+ sumPr += pr.i;
+ pd.i = sm.i = dt.i = i1.i = q1.i = i2.i = q2.i = re.i = im.i = ph.i = 0;
+ mama.i = fama.i = sumPr / (i+1);
+ }
+
+ base.Add((TValue.t, mama.i), update, _NaN);
+ var result = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : fama.i);
+ Fama.Add(result, update);
+ }
+}
diff --git a/Source/Trends/T3_Series.cs b/Source/Trends/T3_Series.cs
index 7e548962..12479ceb 100644
--- a/Source/Trends/T3_Series.cs
+++ b/Source/Trends/T3_Series.cs
@@ -1,127 +1,110 @@
-namespace QuanTAlib;
-using System;
-using System.Linq;
-using System.Numerics;
-
-/*
-T3: Tillson T3 Moving Average
- Tim Tillson described it in "Technical Analysis of Stocks and Commodities", January 1998 in the
- article "Better Moving Averages". Tillson’s moving average becomes a popular indicator of
- technical analysis as it gets less lag with the price chart and its curve is considerably smoother.
-
-Sources:
- https://technicalindicators.net/indicators-technical-analysis/150-t3-moving-average
- http://www.binarytribune.com/forex-trading-indicators/t3-moving-average-indicator/
-
-Calculation:
- a = 0.7 (but also 0.618);
- Ema1 = Ema (Close);
- Ema2 = Ema (Ema1);
- Ema3 = Ema (Ema2);
- Ema4 = Ema (Ema3);
- Ema5 = Ema (Ema4);
- Ema6 = Ema (Ema5);
- T3 = –(a*a*a) * Ema6 + (3*a*a + 3*a*a*a) * Ema5 + (–6*a*a – 3*a – 3*a*a*a) * Ema4 + (1 + 3*a + a*a*a + 3*a*a) * Ema3
-
- */
-
-public class T3_Series : Single_TSeries_Indicator
-{
- private double k, a;
- private double c1, c2, c3, c4;
- private double o_c1, o_c2, o_c3, o_c4;
-
- private double e1, e2, e3, e4, e5, e6;
- private double o_e1, o_e2, o_e3, o_e4, o_e5, o_e6;
-
- private double sum1, sum2, sum3, sum4, sum5, sum6;
- private double o_sum1, o_sum2, o_sum3, o_sum4, o_sum5, o_sum6;
-
- public T3_Series(TSeries source, int period, double vfactor = 0.7, bool useNaN = false) : base(source, period, useNaN)
- {
- k = 2.0 / (_p + 1);
- a = vfactor;
- c1 = -a * a * a;
- c2 = (3 * a * a) + (3 * a * a * a);
- c3 = (-6 * a * a) - (3 * a) - (3 * a * a * a);
- c4 = 1 + (3 * a) + (3 * a * a) + (a * a * a) ;
- e1 = e2 = e3 = e4 = e5 = e6 = 0;
- sum1 = sum2 = sum3 = sum4 = sum5 = sum6 = 0;
-
- if (_data.Count > 0) { base.Add(data: _data); }
- }
-
- public override void Add((DateTime t, double v) TValue, bool update)
- {
- if (update) {
- // roll back (x = oldx)
- c1 = o_c1; c2 = o_c2; c3 = o_c3; c4 = o_c4;
- e1 = o_e1; e2 = o_e2; e3 = o_e3; e4 = o_e4; e5 = o_e5; e6 = o_e6;
- sum1 = o_sum1; sum2 = o_sum2; sum3 = o_sum3; sum4 = o_sum4; sum5 = o_sum5; sum6 = o_sum6;
- } else {
- // roll forward (oldx = x)
- o_c1 = c1; o_c2 = c2; o_c3 = c3; o_c4 = c4;
- o_e1 = e1; o_e2 = e2; o_e3 = e3; o_e4 = e4; o_e5 = e5; o_e6 = e6;
- o_sum1 = sum1; o_sum2 = sum2; o_sum3 = sum3; o_sum4 = sum4; o_sum5 = sum5; o_sum6 = sum6;
- }
- double v = TValue.v;
- int i = base.Count;
- if (i > _p - 1) {
- e1 += k * (v - e1);
- if (i > 2 * (_p - 1)) {
- e2 += k * (e1 - e2);
- if (i > 3 * (_p - 1)) {
- e3 += k * (e2 - e3);
- if (i > 4 * (_p - 1)) {
- e4 += k * (e3 - e4);
- if (i > 5 * (_p - 1)) {
- e5 += k * (e4 - e5);
- if (i > 6 * (_p - 1)) {
- e6 += k * (e5 - e6);
- }
- else {
- sum6 += e5;
- if (i == 6 * (_p - 1)) {
- e6 = sum6 / Math.Max(_p, base.Count);
- }
- }
- }
- else {
- sum5 += e4;
- if (i == 5 * (_p - 1)) {
- sum6 = e5 = sum5 / Math.Max(_p, base.Count);
- }
- }
- }
- else {
- sum4 += e3;
- if (i == 4 * (_p - 1)) {
- sum5 = e4 = sum4 / Math.Max(_p, base.Count);
- }
- }
- }
- else {
- sum3 += e2;
- if (i == 3 * (_p - 1)) {
- sum4 = e3 = sum3 / Math.Max(_p, base.Count);
- }
- }
- }
- else {
- sum2 += e1;
- if (i == 2 * (_p - 1)) {
- sum3 = e2 = sum2 / Math.Max(_p, base.Count);
- }
- }
- }
- else {
- sum1 += v;
- if (i == _p - 1) {
- sum2 = e1 = sum1 / Math.Max(_p, base.Count);
- }
- }
-
- double t3 = (c1 * e6) + (c2 * e5) + (c3 * e4) + (c4 * e3);
- base.Add(TValue: (TValue.t, t3), update: update, useNaN: _NaN);
- }
+namespace QuanTAlib;
+using System;
+using System.Linq;
+using System.Numerics;
+
+/*
+T3: Tillson T3 Moving Average
+ Tim Tillson described it in "Technical Analysis of Stocks and Commodities", January 1998 in the
+ article "Better Moving Averages". Tillson’s moving average becomes a popular indicator of
+ technical analysis as it gets less lag with the price chart and its curve is considerably smoother.
+
+Sources:
+ https://technicalindicators.net/indicators-technical-analysis/150-t3-moving-average
+ http://www.binarytribune.com/forex-trading-indicators/t3-moving-average-indicator/
+
+Calculation:
+ Volume Factor is typically 0.7 (but also 0.618);
+ Ema1 = Ema (Close);
+ Ema2 = Ema (Ema1);
+ Ema3 = Ema (Ema2);
+ Ema4 = Ema (Ema3);
+ Ema5 = Ema (Ema4);
+ Ema6 = Ema (Ema5);
+ T3 = –(a*a*a) * Ema6 + (3*a*a + 3*a*a*a) * Ema5 + (–6*a*a – 3*a – 3*a*a*a) * Ema4 + (1 + 3*a + a*a*a + 3*a*a) * Ema3
+
+ */
+public class T3_Series : Single_TSeries_Indicator {
+ private readonly double _k, _k1m, _c1, _c2, _c3, _c4;
+ private readonly System.Collections.Generic.List _buffer1 = new();
+ private readonly System.Collections.Generic.List _buffer2 = new();
+ private readonly System.Collections.Generic.List _buffer3 = new();
+ private readonly System.Collections.Generic.List _buffer4 = new();
+ private readonly System.Collections.Generic.List _buffer5 = new();
+ private readonly System.Collections.Generic.List _buffer6 = new();
+
+ private double _lastema1, _lastema2, _lastema3, _lastema4, _lastema5, _lastema6;
+ private double _llastema1, _llastema2, _llastema3, _llastema4, _llastema5, _llastema6;
+ private bool _useSMA;
+
+ public T3_Series(TSeries source, int period, double vfactor = 0.7, bool useNaN = false, bool useSMA = true) : base(source, period, useNaN) {
+ double _a = vfactor; //0.7; //0.618
+ _c1 = -_a * _a * _a;
+ _c2 = 3 * _a * _a + 3 * _a * _a * _a;
+ _c3 = -6 * _a * _a - 3 * _a - 3 * _a * _a * _a;
+ _c4 = 1 + 3 * _a + _a * _a * _a + 3 * _a * _a;
+
+ _k = 2.0 / (_p + 1);
+ _k1m = 1.0 - _k;
+ _lastema1 = _llastema1 = _lastema2 = _llastema2 = _lastema3 = _llastema3 = _lastema4 = _llastema4 = _lastema5 = _llastema5 = _lastema5 = _llastema5 = 0;
+ _useSMA = useSMA;
+ if (this._data.Count > 0) { base.Add(this._data); }
+ }
+
+ public override void Add((DateTime t, double v) TValue, bool update) {
+ double _ema1, _ema2, _ema3, _ema4, _ema5, _ema6;
+ if (update) { _lastema1 = _llastema1; _lastema2 = _llastema2; _lastema3 = _llastema3; _lastema4 = _llastema4; _lastema5 = _llastema5; _lastema6 = _llastema6; }
+ else { _llastema1 = _lastema1; _llastema2 = _lastema2; _llastema3 = _lastema3; _llastema4 = _lastema4; _llastema5 = _lastema5; _llastema6 = _lastema6; }
+
+ if (this.Count == 0) { _lastema1 = _lastema2 = _lastema3 = _lastema4 = _lastema5 = _lastema6 = TValue.v; }
+
+ if ((this.Count < _p) && _useSMA) {
+ Add_Replace(_buffer1, TValue.v, update);
+ _ema1 = 0;
+ for (int i = 0; i < _buffer1.Count; i++) { _ema1 += _buffer1[i]; }
+ _ema1 /= _buffer1.Count;
+
+ Add_Replace(_buffer2, _ema1, update);
+ _ema2 = 0;
+ for (int i = 0; i < _buffer2.Count; i++) { _ema2 += _buffer2[i]; }
+ _ema2 /= _buffer2.Count;
+
+ Add_Replace(_buffer3, _ema2, update);
+ _ema3 = 0;
+ for (int i = 0; i < _buffer3.Count; i++) { _ema3 += _buffer3[i]; }
+ _ema3 /= _buffer3.Count;
+
+ Add_Replace(_buffer4, _ema3, update);
+ _ema4 = 0;
+ for (int i = 0; i < _buffer4.Count; i++) { _ema4 += _buffer4[i]; }
+ _ema4 /= _buffer4.Count;
+
+ Add_Replace(_buffer5, _ema4, update);
+ _ema5 = 0;
+ for (int i = 0; i < _buffer5.Count; i++) { _ema5 += _buffer5[i]; }
+ _ema5 /= _buffer5.Count;
+
+ Add_Replace(_buffer6, _ema5, update);
+ _ema6 = 0;
+ for (int i = 0; i < _buffer6.Count; i++) { _ema6 += _buffer6[i]; }
+ _ema6 /= _buffer6.Count;
+ }
+ else {
+ _ema1 = (TValue.v * this._k) + (this._lastema1 * this._k1m);
+ _ema2 = (_ema1 * this._k) + (this._lastema2 * this._k1m);
+ _ema3 = (_ema2 * this._k) + (this._lastema3 * this._k1m);
+ _ema4 = (_ema3 * this._k) + (this._lastema4 * this._k1m);
+ _ema5 = (_ema4 * this._k) + (this._lastema5 * this._k1m);
+ _ema6 = (_ema5 * this._k) + (this._lastema6 * this._k1m);
+ }
+ _lastema1 = _ema1;
+ _lastema2 = _ema2;
+ _lastema3 = _ema3;
+ _lastema4 = _ema4;
+ _lastema5 = _ema5;
+ _lastema6 = _ema6;
+
+ double _T3 = _c1 * _ema6 + _c2 * _ema5 + _c3 * _ema4 + _c4 * _ema3;
+ base.Add((TValue.t, _T3), update, _NaN);
+ }
}
\ No newline at end of file
diff --git a/Source/Trends/TRIX_Series.cs b/Source/Trends/TRIX_Series.cs
new file mode 100644
index 00000000..d557bc56
--- /dev/null
+++ b/Source/Trends/TRIX_Series.cs
@@ -0,0 +1,82 @@
+namespace QuanTAlib;
+using System;
+using System.Linq;
+using System.Numerics;
+
+/*
+TRIX: Triple Exponential Average
+ Developed by Jack Hutson in the early 1980s, the triple exponential average (TRIX)
+ has become a popular technical analysis tool to aid chartists in spotting diversions
+and directional cues in stock trading patterns.
+
+
+Calculation:
+ Ema1 = Ema (Close);
+ Ema2 = Ema (Ema1);
+ Ema3 = Ema (Ema2);
+ TRIX = (Ema3-Ema3[1]) / Ema3[1]
+
+Sources:
+ https://www.investopedia.com/terms/t/trix.asp
+
+ */
+public class TRIX_Series : Single_TSeries_Indicator
+{
+ private readonly double _k, _k1m;
+ private readonly System.Collections.Generic.List _buffer1 = new();
+ private readonly System.Collections.Generic.List _buffer2 = new();
+ private readonly System.Collections.Generic.List _buffer3 = new();
+
+ private double _lastema1, _lastema2, _lastema3;
+ private double _llastema1, _llastema2, _llastema3;
+ private bool _useSMA;
+
+ public TRIX_Series(TSeries source, int period, bool useNaN = false, bool useSMA = true) : base(source, period, useNaN)
+ {
+
+ _k = 2.0 / (_p + 1);
+ _k1m = 1.0 - _k;
+ _lastema1 = _llastema1 = _lastema2 = _llastema2 = _lastema3 = _llastema3 = 0;
+ _useSMA = useSMA;
+ if (this._data.Count > 0) { base.Add(this._data); }
+ }
+
+ public override void Add((DateTime t, double v) TValue, bool update)
+ {
+ double _ema1, _ema2, _ema3;
+ if (this.Count == 0) { _lastema1 = _lastema2 = _lastema3 = TValue.v; }
+
+ if (update) { _lastema1 = _llastema1; _lastema2 = _llastema2; _lastema3 = _llastema3; }
+ else { _llastema1 = _lastema1; _llastema2 = _lastema2; _llastema3 = _lastema3; }
+
+ if ((this.Count < _p) && _useSMA)
+ {
+ Add_Replace(_buffer1, TValue.v, update);
+ _ema1 = 0;
+ for (int i = 0; i < _buffer1.Count; i++) { _ema1 += _buffer1[i]; }
+ _ema1 /= _buffer1.Count;
+
+ Add_Replace(_buffer2, _ema1, update);
+ _ema2 = 0;
+ for (int i = 0; i < _buffer2.Count; i++) { _ema2 += _buffer2[i]; }
+ _ema2 /= _buffer2.Count;
+
+ Add_Replace(_buffer3, _ema2, update);
+ _ema3 = 0;
+ for (int i = 0; i < _buffer3.Count; i++) { _ema3 += _buffer3[i]; }
+ _ema3 /= _buffer3.Count;
+ }
+ else
+ {
+ _ema1 = (TValue.v * this._k) + (this._lastema1 * this._k1m);
+ _ema2 = (_ema1 * this._k) + (this._lastema2 * this._k1m);
+ _ema3 = (_ema2 * this._k) + (this._lastema3 * this._k1m);
+ }
+ double _trix = 100 * (_ema3 - _lastema3) / _lastema3;
+ _lastema1 = _ema1;
+ _lastema2 = _ema2;
+ _lastema3 = _ema3;
+
+ base.Add((TValue.t, _trix), update, _NaN);
+ }
+}
\ No newline at end of file
diff --git a/Source/Volatility/CMO_Series.cs b/Source/Volatility/CMO_Series.cs
new file mode 100644
index 00000000..9a47b469
--- /dev/null
+++ b/Source/Volatility/CMO_Series.cs
@@ -0,0 +1,47 @@
+namespace QuanTAlib;
+using System;
+
+/*
+CMO: Chande Momentum Oscillator
+ Chande Momentum Oscillator (also known as CMO indicator) was developed by Tushar S. Chande
+ CMO is similar to other momentum oscillators (e.g. RSI or Stochastics). Alike RSI oscillator,
+ the CMO values move in the range from -100 to +100 points and its aim is to detect the
+ overbought and oversold market conditions. CMO calculates the price momentum on both the up
+ days as well as the down days. The CMO calculation is based on non-smoothed price values
+ meaning that it can reach its extremes more frequently and the short-time swings are more visible.
+
+Sources:
+ https://www.technicalindicators.net/indicators-technical-analysis/144-cmo-chande-momentum-oscillator
+
+ */
+
+public class CMO_Series : Single_TSeries_Indicator {
+ private readonly System.Collections.Generic.List _buff_up = new();
+ private readonly System.Collections.Generic.List _buff_dn = new();
+ private double _plast_value, _last_value;
+
+ public CMO_Series(TSeries source, int period, bool useNaN = false) : base(source, period, useNaN) {
+ if (this._data.Count > 0) { base.Add(this._data); }
+ }
+
+ public override void Add((DateTime t, double v) TValue, bool update) {
+ if (this.Count == 0) { _plast_value = _last_value = TValue.v; }
+ if (update) _last_value = _plast_value; else _plast_value = _last_value;
+
+ Add_Replace_Trim(_buff_up, (TValue.v > _last_value) ? TValue.v-_last_value : 0, _p, update);
+ Add_Replace_Trim(_buff_dn, (TValue.v < _last_value) ? _last_value-TValue.v : 0, _p, update);
+ _last_value = TValue.v;
+
+ double _cmo_up = 0;
+ double _cmo_dn = 0;
+ for (int i = 0; i < Math.Min(_buff_up.Count, _buff_dn.Count); i++) {
+ _cmo_up += _buff_up[i];
+ _cmo_dn += _buff_dn[i];
+ }
+
+ double _cmo = 100 * (_cmo_up - _cmo_dn) / (_cmo_up + _cmo_dn);
+ if (_cmo_up + _cmo_dn == 0)
+ _cmo = 0;
+ base.Add((TValue.t, _cmo), update, _NaN);
+ }
+}
\ No newline at end of file
diff --git a/Tests/Series/Update.cs b/Tests/Series/Update.cs
index ad8260e1..80335697 100644
--- a/Tests/Series/Update.cs
+++ b/Tests/Series/Update.cs
@@ -1,512 +1,512 @@
-using Xunit;
-using System;
-using QuanTAlib;
-using Skender.Stock.Indicators;
-
-namespace Series;
-public class Update {
- private readonly GBM_Feed bars;
- private readonly Random rnd = new();
- private readonly int period;
-
- public Update() {
- bars = new(Bars: 5000, Volatility: 0.8, Drift: 0.0);
- period = rnd.Next(28) + 3;
- }
-
- [Fact] public void ADL() {
- ADL_Series QL = new(bars);
- var lastData = bars.Last();
- var lastCalc = QL.Last();
- int lastLen = QL.Count;
- QL.Add((DateTime.Today, 0, 0, 0, 0, 0), update: true);
- QL.Add(lastData, update: true);
- Assert.Equal(lastLen, QL.Count); // same size
- Assert.Equal(lastCalc, QL.Last()); // same data
- }
- [Fact] public void ADOSC() {
- ADOSC_Series QL = new(bars);
- var lastData = bars.Last();
- var lastCalc = QL.Last();
- int lastLen = QL.Count;
- QL.Add((DateTime.Today, 0, 0, 0, 0, 0), update: true);
- QL.Add(lastData, update: true);
- Assert.Equal(lastLen, QL.Count); // same size
- Assert.Equal(lastCalc, QL.Last()); // same data
- }
- [Fact] public void ALMA() {
- ALMA_Series QL = new(source: bars.Close, period: period);
- var lastData = bars.Close.Last();
- var lastCalc = QL.Last();
- int lastLen = QL.Count;
- QL.Add((DateTime.Today, 0), update: true);
- QL.Add(lastData, update: true);
- Assert.Equal(lastLen, QL.Count); // same size
- Assert.Equal(lastCalc, QL.Last()); // same data
- }
- [Fact] public void ATR() {
- ATR_Series QL = new(bars, period: period);
- var lastData = bars.Last();
- var lastCalc = QL.Last();
- int lastLen = QL.Count;
- QL.Add((DateTime.Today, 0, 0, 0, 0, 0), update: true);
- QL.Add(lastData, update: true);
- Assert.Equal(lastLen, QL.Count); // same size
- Assert.Equal(lastCalc, QL.Last()); // same data
- }
- [Fact] public void ATRP() {
- ATRP_Series QL = new(bars, period: period);
- var lastData = bars.Last();
- var lastCalc = QL.Last();
- int lastLen = QL.Count;
- QL.Add((DateTime.Today, 0, 0, 0, 0, 0), update: true);
- QL.Add(lastData, update: true);
- Assert.Equal(lastLen, QL.Count); // same size
- Assert.Equal(lastCalc, QL.Last()); // same data
- }
- [Fact] public void BBANDS() {
- BBANDS_Series QL = new(source: bars.Close, period: period);
- var lastData = bars.Close.Last();
- var lastCalc = QL.Last();
- int lastLen = QL.Count;
- QL.Add((DateTime.Today, 0), update: true);
- QL.Add(lastData, update: true);
- Assert.Equal(lastLen, QL.Count); // same size
- Assert.Equal(lastCalc, QL.Last()); // same data
- }
- [Fact] public void BIAS() {
- BIAS_Series QL = new(source: bars.Close, period: period);
- var lastData = bars.Close.Last();
- var lastCalc = QL.Last();
- int lastLen = QL.Count;
- QL.Add((DateTime.Today, 0), update: true);
- QL.Add(lastData, update: true);
- Assert.Equal(lastLen, QL.Count); // same size
- Assert.Equal(lastCalc, QL.Last()); // same data
- }
- [Fact] public void CCI() {
- CCI_Series QL = new(bars, period: period);
- var lastData = bars.Last();
- var lastCalc = QL.Last();
- int lastLen = QL.Count;
- QL.Add((DateTime.Today, 0, 0, 0, 0, 0), update: true);
- QL.Add(lastData, update: true);
- Assert.Equal(lastLen, QL.Count); // same size
- Assert.Equal(lastCalc, QL.Last()); // same data
- }
- [Fact] public void CORR() {
- CORR_Series QL = new(d1: bars.High, d2: bars.Low, period: period);
- var lastData = bars.Last();
- var lastCalc = QL.Last();
- int lastLen = QL.Count;
- QL.Add((DateTime.Today, 0), (DateTime.Today, 0), update: true);
- QL.Add((lastData.t, lastData.h), (lastData.t, lastData.l), update: true);
- Assert.Equal(lastLen, QL.Count); // same size
- Assert.Equal(lastCalc, QL.Last()); // same data
- }
- [Fact] public void COVAR() {
- COVAR_Series QL = new(d1: bars.High, d2: bars.Low, period);
- var lastData = bars.Last();
- var lastCalc = QL.Last();
- int lastLen = QL.Count;
- QL.Add((DateTime.Today, 0), (DateTime.Today, 0), update: true);
- QL.Add((lastData.t, lastData.h), (lastData.t, lastData.l), update: true);
- Assert.Equal(lastLen, QL.Count); // same size
- Assert.Equal(lastCalc, QL.Last()); // same data
- }
- [Fact] public void DEMA() {
- DEMA_Series QL = new(source: bars.Close, period: period);
- var lastData = bars.Close.Last();
- var lastCalc = QL.Last();
- int lastLen = QL.Count;
- QL.Add((DateTime.Today, 0), update: true);
- QL.Add(lastData, update: true);
- Assert.Equal(lastLen, QL.Count); // same size
- Assert.Equal(lastCalc, QL.Last()); // same data
- }
- [Fact]
- public void DWMA() {
- DWMA_Series QL = new(source: bars.Close, period);
- var lastData = bars.Close.Last();
- var lastCalc = QL.Last();
- int lastLen = QL.Count;
- QL.Add((DateTime.Today, 0), update: true);
- QL.Add(lastData, update: true);
- Assert.Equal(lastLen, QL.Count); // same size
- Assert.Equal(lastCalc, QL.Last()); // same data
- }
- [Fact] public void ENTROPY() {
- ENTROPY_Series QL = new(source: bars.Close, period: period);
- var lastData = bars.Close.Last();
- var lastCalc = QL.Last();
- int lastLen = QL.Count;
- QL.Add((DateTime.Today, 0), update: true);
- QL.Add(lastData, update: true);
- Assert.Equal(lastLen, QL.Count); // same size
- Assert.Equal(lastCalc, QL.Last()); // same data
- }
- [Fact] public void EMA() {
- EMA_Series QL = new(source: bars.Close, period: period);
- var lastData = bars.Close.Last();
- var lastCalc = QL.Last();
- int lastLen = QL.Count;
- QL.Add((DateTime.Today, 0), update: true);
- QL.Add(lastData, update: true);
- Assert.Equal(lastLen, QL.Count); // same size
- Assert.Equal(lastCalc, QL.Last()); // same data
- }
- [Fact] public void HEMA() {
- HEMA_Series QL = new(source: bars.Close, period: period);
- var lastData = bars.Close.Last();
- var lastCalc = QL.Last();
- int lastLen = QL.Count;
- QL.Add((DateTime.Today, 0), update: true);
- QL.Add(lastData, update: true);
- Assert.Equal(lastLen, QL.Count); // same size
- Assert.Equal(lastCalc, QL.Last()); // same data
- }
- [Fact] public void HMA() {
- HMA_Series QL = new(source: bars.Close, period: period);
- var lastData = bars.Close.Last();
- var lastCalc = QL.Last();
- int lastLen = QL.Count;
- QL.Add((DateTime.Today, 0), update: true);
- QL.Add(lastData, update: true);
- Assert.Equal(lastLen, QL.Count); // same size
- Assert.Equal(lastCalc, QL.Last()); // same data
- }
- [Fact] public void JMA() {
- JMA_Series QL = new(source: bars.Close, period: period);
- var lastData = bars.Close.Last();
- var lastCalc = QL.Last();
- int lastLen = QL.Count;
- QL.Add((DateTime.Today, 0), update: true);
- QL.Add(lastData, update: true);
- Assert.Equal(lastLen, QL.Count); // same size
- Assert.Equal(lastCalc, QL.Last()); // same data
- }
- [Fact] public void KAMA() {
- KAMA_Series QL = new(source: bars.Close, period: period);
- var lastData = bars.Close.Last();
- var lastCalc = QL.Last();
- int lastLen = QL.Count;
- QL.Add((DateTime.Today, 0), update: true);
- QL.Add(lastData, update: true);
- Assert.Equal(lastLen, QL.Count); // same size
- Assert.Equal(lastCalc, QL.Last()); // same data
- }
- [Fact] public void KURTOSIS() {
- KURTOSIS_Series QL = new(source: bars.Close, period: period);
- var lastData = bars.Close.Last();
- var lastCalc = QL.Last();
- int lastLen = QL.Count;
- QL.Add((DateTime.Today, 0), update: true);
- QL.Add(lastData, update: true);
- Assert.Equal(lastLen, QL.Count); // same size
- Assert.Equal(lastCalc, QL.Last()); // same data
- }
- [Fact] public void LINREG() {
- LINREG_Series QL = new(source: bars.Close, period: period);
- var lastData = bars.Close.Last();
- var lastCalc = QL.Last();
- int lastLen = QL.Count;
- QL.Add((DateTime.Today, 0), update: true);
- QL.Add(lastData, update: true);
- Assert.Equal(lastLen, QL.Count); // same size
- Assert.Equal(lastCalc, QL.Last()); // same data
- }
- [Fact] public void MACD() {
- MACD_Series QL = new(source: bars.Close);
- var lastData = bars.Close.Last();
- var lastCalc = QL.Last();
- var lastC1 = QL.Signal.Last();
- int lastLen = QL.Count;
- QL.Add((DateTime.Today, 0), update: true);
- QL.Add(lastData, update: true);
- Assert.Equal(lastLen, QL.Count); // same size
- Assert.Equal(lastCalc, QL.Last()); // same data
- Assert.Equal(lastC1, QL.Signal.Last()); // same data
- }
- [Fact] public void MAD() {
- MAD_Series QL = new(source: bars.Close, period);
- var lastData = bars.Close.Last();
- var lastCalc = QL.Last();
- int lastLen = QL.Count;
- QL.Add((DateTime.Today, 0), update: true);
- QL.Add(lastData, update: true);
- Assert.Equal(lastLen, QL.Count); // same size
- Assert.Equal(lastCalc, QL.Last()); // same data
- }
- [Fact] public void MAMA() {
- MAMA_Series QL = new(source: bars.Close);
- var lastData = bars.Close.Last();
- var lastCalc = QL.Last();
- var lastC1 = QL.Fama.Last();
- int lastLen = QL.Count;
- QL.Add((DateTime.Today, 0), update: true);
- QL.Add(lastData, update: true);
- Assert.Equal(lastLen, QL.Count); // same size
- Assert.Equal(lastCalc, QL.Last()); // same data
- Assert.Equal(lastC1, QL.Fama.Last()); // same data
- }
- [Fact] public void MAPE() {
- MAPE_Series QL = new(source: bars.Close, period);
- var lastData = bars.Close.Last();
- var lastCalc = QL.Last();
- int lastLen = QL.Count;
- QL.Add((DateTime.Today, 0), update: true);
- QL.Add(lastData, update: true);
- Assert.Equal(lastLen, QL.Count); // same size
- Assert.Equal(lastCalc, QL.Last()); // same data
- }
- [Fact] public void MAX() {
- MAX_Series QL = new(source: bars.Close, period: period);
- var lastData = bars.Close.Last();
- var lastCalc = QL.Last();
- int lastLen = QL.Count;
- QL.Add((DateTime.Today, 0), update: true);
- QL.Add(lastData, update: true);
- Assert.Equal(lastLen, QL.Count); // same size
- Assert.Equal(lastCalc, QL.Last()); // same data
- }
- [Fact] public void MEDIAN() {
- MEDIAN_Series QL = new(source: bars.Close, period: period);
- var lastData = bars.Close.Last();
- var lastCalc = QL.Last();
- int lastLen = QL.Count;
- QL.Add((DateTime.Today, 0), update: true);
- QL.Add(lastData, update: true);
- Assert.Equal(lastLen, QL.Count); // same size
- Assert.Equal(lastCalc, QL.Last()); // same data
- }
- [Fact] public void MIDPOINT() {
- MIDPOINT_Series QL = new(source: bars.Close, period: period);
- var lastData = bars.Close.Last();
- var lastCalc = QL.Last();
- int lastLen = QL.Count;
- QL.Add((DateTime.Today, 0), update: true);
- QL.Add(lastData, update: true);
- Assert.Equal(lastLen, QL.Count); // same size
- Assert.Equal(lastCalc, QL.Last()); // same data
- }
- [Fact] public void MIDPRICE() {
- MIDPRICE_Series QL = new(bars, period: period);
- var lastData = bars.Last();
- var lastCalc = QL.Last();
- int lastLen = QL.Count;
- QL.Add((DateTime.Today, 0, 0, 0, 0, 0), update: true);
- QL.Add(lastData, update: true);
- Assert.Equal(lastLen, QL.Count); // same size
- Assert.Equal(lastCalc, QL.Last()); // same data
- }
- [Fact] public void MIN() {
- MAX_Series QL = new(source: bars.Close, period: period);
- var lastData = bars.Close.Last();
- var lastCalc = QL.Last();
- int lastLen = QL.Count;
- QL.Add((DateTime.Today, 0), update: true);
- QL.Add(lastData, update: true);
- Assert.Equal(lastLen, QL.Count); // same size
- Assert.Equal(lastCalc, QL.Last()); // same data
- }
- [Fact] public void MSE() {
- MSE_Series QL = new(source: bars.Close, period);
- var lastData = bars.Close.Last();
- var lastCalc = QL.Last();
- int lastLen = QL.Count;
- QL.Add((DateTime.Today, 0), update: true);
- QL.Add(lastData, update: true);
- Assert.Equal(lastLen, QL.Count); // same size
- Assert.Equal(lastCalc, QL.Last()); // same data
- }
- [Fact] public void OBV() {
- OBV_Series QL = new(bars, period: period);
- var lastData = bars.Last();
- var lastCalc = QL.Last();
- int lastLen = QL.Count;
- QL.Add((DateTime.Today, 0, 0, 0, 0, 0), update: true);
- QL.Add(lastData, update: true);
- Assert.Equal(lastLen, QL.Count); // same size
- Assert.Equal(lastCalc, QL.Last()); // same data
- }
- [Fact] public void RSI() {
- RSI_Series QL = new(source: bars.Close, period);
- var lastData = bars.Close.Last();
- var lastCalc = QL.Last();
- int lastLen = QL.Count;
- QL.Add((DateTime.Today, 0), update: true);
- QL.Add(lastData, update: true);
- Assert.Equal(lastLen, QL.Count); // same size
- Assert.Equal(lastCalc, QL.Last()); // same data
- }
- [Fact] public void RMA() {
- RMA_Series QL = new(source: bars.Close, period);
- var lastData = bars.Close.Last();
- var lastCalc = QL.Last();
- int lastLen = QL.Count;
- QL.Add((DateTime.Today, 0), update: true);
- QL.Add(lastData, update: true);
- Assert.Equal(lastLen, QL.Count); // same size
- Assert.Equal(lastCalc, QL.Last()); // same data
- }
- [Fact] public void SDEV() {
- SDEV_Series QL = new(source: bars.Close, period);
- var lastData = bars.Close.Last();
- var lastCalc = QL.Last();
- int lastLen = QL.Count;
- QL.Add((DateTime.Today, 0), update: true);
- QL.Add(lastData, update: true);
- Assert.Equal(lastLen, QL.Count); // same size
- Assert.Equal(lastCalc, QL.Last()); // same data
- }
- [Fact] public void SMA() {
- SMA_Series QL = new(source: bars.Close, period);
- var lastData = bars.Close.Last();
- var lastCalc = QL.Last();
- int lastLen = QL.Count;
- QL.Add((DateTime.Today, 0), update: true);
- QL.Add(lastData, update: true);
- Assert.Equal(lastLen, QL.Count); // same size
- Assert.Equal(lastCalc, QL.Last()); // same data
- }
- [Fact] public void SMAPE() {
- SMAPE_Series QL = new(source: bars.Close, period);
- var lastData = bars.Close.Last();
- var lastCalc = QL.Last();
- int lastLen = QL.Count;
- QL.Add((DateTime.Today, 0), update: true);
- QL.Add(lastData, update: true);
- Assert.Equal(lastLen, QL.Count); // same size
- Assert.Equal(lastCalc, QL.Last()); // same data
- }
- [Fact] public void SMMA() {
- SMMA_Series QL = new(source: bars.Close, period);
- var lastData = bars.Close.Last();
- var lastCalc = QL.Last();
- int lastLen = QL.Count;
- QL.Add((DateTime.Today, 0), update: true);
- QL.Add(lastData, update: true);
- Assert.Equal(lastLen, QL.Count); // same size
- Assert.Equal(lastCalc, QL.Last()); // same data
- }
- [Fact] public void SSDEV() {
- SSDEV_Series QL = new(source: bars.Close, period);
- var lastData = bars.Close.Last();
- var lastCalc = QL.Last();
- int lastLen = QL.Count;
- QL.Add((DateTime.Today, 0), update: true);
- QL.Add(lastData, update: true);
- Assert.Equal(lastLen, QL.Count); // same size
- Assert.Equal(lastCalc, QL.Last()); // same data
- }
- [Fact] public void SUM() {
- SUM_Series QL = new(source: bars.Close, period: period);
- var lastData = bars.Close.Last();
- var lastCalc = QL.Last();
- int lastLen = QL.Count;
- QL.Add((DateTime.Today, 0), update: true);
- QL.Add(lastData, update: true);
- Assert.Equal(lastLen, QL.Count); // same size
- Assert.Equal(lastCalc, QL.Last()); // same data
- }
- [Fact] public void SVAR() {
- SVAR_Series QL = new(source: bars.Close, period);
- var lastData = bars.Close.Last();
- var lastCalc = QL.Last();
- int lastLen = QL.Count;
- QL.Add((DateTime.Today, 0), update: true);
- QL.Add(lastData, update: true);
- Assert.Equal(lastLen, QL.Count); // same size
- Assert.Equal(lastCalc, QL.Last()); // same data
- }
- [Fact] public void T3() {
- SMA_Series QL = new(source: bars.Close, period);
- var lastData = bars.Close.Last();
- var lastCalc = QL.Last();
- int lastLen = QL.Count;
- QL.Add((DateTime.Today, 0), update: true);
- QL.Add(lastData, update: true);
- Assert.Equal(lastLen, QL.Count); // same size
- Assert.Equal(lastCalc, QL.Last()); // same data
- }
- [Fact] public void TEMA() {
- TEMA_Series QL = new(source: bars.Close, period);
- var lastData = bars.Close.Last();
- var lastCalc = QL.Last();
- int lastLen = QL.Count;
- QL.Add((DateTime.Today, 0), update: true);
- QL.Add(lastData, update: true);
- Assert.Equal(lastLen, QL.Count); // same size
- Assert.Equal(lastCalc, QL.Last()); // same data
- }
- [Fact] public void TR() {
- TR_Series QL = new(bars);
- var lastData = bars.Last();
- var lastCalc = QL.Last();
- int lastLen = QL.Count;
- QL.Add((DateTime.Today, 0, 0, 0, 0, 0), update: true);
- QL.Add(lastData, update: true);
- Assert.Equal(lastLen, QL.Count); // same size
- Assert.Equal(lastCalc, QL.Last()); // same data
- }
- [Fact] public void TRIMA() {
- TRIMA_Series QL = new(source: bars.Close, period);
- var lastData = bars.Close.Last();
- var lastCalc = QL.Last();
- int lastLen = QL.Count;
- QL.Add((DateTime.Today, 0), update: true);
- QL.Add(lastData, update: true);
- Assert.Equal(lastLen, QL.Count); // same size
- Assert.Equal(lastCalc, QL.Last()); // same data
- }
- [Fact] public void VAR() {
- VAR_Series QL = new(source: bars.Close, period);
- var lastData = bars.Close.Last();
- var lastCalc = QL.Last();
- int lastLen = QL.Count;
- QL.Add((DateTime.Today, 0), update: true);
- QL.Add(lastData, update: true);
- Assert.Equal(lastLen, QL.Count); // same size
- Assert.Equal(lastCalc, QL.Last()); // same data
- }
- [Fact] public void WMA() {
- WMA_Series QL = new(source: bars.Close, period);
- var lastData = bars.Close.Last();
- var lastCalc = QL.Last();
- int lastLen = QL.Count;
- QL.Add((DateTime.Today, 0), update: true);
- QL.Add(lastData, update: true);
- Assert.Equal(lastLen, QL.Count); // same size
- Assert.Equal(lastCalc, QL.Last()); // same data
- }
- [Fact] public void WMAPE() {
- WMAPE_Series QL = new(source: bars.Close, period);
- var lastData = bars.Close.Last();
- var lastCalc = QL.Last();
- int lastLen = QL.Count;
- QL.Add((DateTime.Today, 0), update: true);
- QL.Add(lastData, update: true);
- Assert.Equal(lastLen, QL.Count); // same size
- Assert.Equal(lastCalc, QL.Last()); // same data
- }
- [Fact] public void ZLEMA() {
- ZLEMA_Series QL = new(source: bars.Close, period);
- var lastData = bars.Close.Last();
- var lastCalc = QL.Last();
- int lastLen = QL.Count;
- QL.Add((DateTime.Today, 0), update: true);
- QL.Add(lastData, update: true);
- Assert.Equal(lastLen, QL.Count); // same size
- Assert.Equal(lastCalc, QL.Last()); // same data
- }
- [Fact] public void ZSCORE() {
- ZSCORE_Series QL = new(source: bars.Close, period);
- var lastData = bars.Close.Last();
- var lastCalc = QL.Last();
- int lastLen = QL.Count;
- QL.Add((DateTime.Today, 0), update: true);
- QL.Add(lastData, update: true);
- Assert.Equal(lastLen, QL.Count); // same size
- Assert.Equal(lastCalc, QL.Last()); // same data
- }
-}
+using Xunit;
+using System;
+using QuanTAlib;
+using Skender.Stock.Indicators;
+
+namespace Series;
+public class Update {
+ private readonly GBM_Feed bars;
+ private readonly Random rnd = new();
+ private readonly int period;
+
+ public Update() {
+ bars = new(Bars: 5000, Volatility: 0.8, Drift: 0.0);
+ period = rnd.Next(28) + 3;
+ }
+
+ [Fact] public void ADL() {
+ ADL_Series QL = new(bars);
+ var lastData = bars.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0, 0, 0, 0, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void ADOSC() {
+ ADOSC_Series QL = new(bars);
+ var lastData = bars.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0, 0, 0, 0, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void ALMA() {
+ ALMA_Series QL = new(source: bars.Close, period: period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void ATR() {
+ ATR_Series QL = new(bars, period: period);
+ var lastData = bars.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0, 0, 0, 0, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void ATRP() {
+ ATRP_Series QL = new(bars, period: period);
+ var lastData = bars.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0, 0, 0, 0, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void BBANDS() {
+ BBANDS_Series QL = new(source: bars.Close, period: period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void BIAS() {
+ BIAS_Series QL = new(source: bars.Close, period: period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void CCI() {
+ CCI_Series QL = new(bars, period: period);
+ var lastData = bars.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0, 0, 0, 0, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void CORR() {
+ CORR_Series QL = new(d1: bars.High, d2: bars.Low, period: period);
+ var lastData = bars.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), (DateTime.Today, 0), update: true);
+ QL.Add((lastData.t, lastData.h), (lastData.t, lastData.l), update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void COVAR() {
+ COVAR_Series QL = new(d1: bars.High, d2: bars.Low, period);
+ var lastData = bars.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), (DateTime.Today, 0), update: true);
+ QL.Add((lastData.t, lastData.h), (lastData.t, lastData.l), update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void DEMA() {
+ DEMA_Series QL = new(source: bars.Close, period: period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact]
+ public void DWMA() {
+ DWMA_Series QL = new(source: bars.Close, period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void ENTROPY() {
+ ENTROPY_Series QL = new(source: bars.Close, period: period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void EMA() {
+ EMA_Series QL = new(source: bars.Close, period: period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void HEMA() {
+ HEMA_Series QL = new(source: bars.Close, period: period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void HMA() {
+ HMA_Series QL = new(source: bars.Close, period: period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void JMA() {
+ JMA_Series QL = new(source: bars.Close, period: period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void KAMA() {
+ KAMA_Series QL = new(source: bars.Close, period: period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void KURTOSIS() {
+ KURTOSIS_Series QL = new(source: bars.Close, period: period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void LINREG() {
+ LINREG_Series QL = new(source: bars.Close, period: period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void MACD() {
+ MACD_Series QL = new(source: bars.Close);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ var lastC1 = QL.Signal.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ Assert.Equal(lastC1, QL.Signal.Last()); // same data
+ }
+ [Fact] public void MAD() {
+ MAD_Series QL = new(source: bars.Close, period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void MAMA() {
+ MAMA_Series QL = new(source: bars.Close);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ var lastC1 = QL.Fama.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ Assert.Equal(lastC1, QL.Fama.Last()); // same data
+ }
+ [Fact] public void MAPE() {
+ MAPE_Series QL = new(source: bars.Close, period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void MAX() {
+ MAX_Series QL = new(source: bars.Close, period: period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void MEDIAN() {
+ MEDIAN_Series QL = new(source: bars.Close, period: period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void MIDPOINT() {
+ MIDPOINT_Series QL = new(source: bars.Close, period: period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void MIDPRICE() {
+ MIDPRICE_Series QL = new(bars, period: period);
+ var lastData = bars.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0, 0, 0, 0, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void MIN() {
+ MAX_Series QL = new(source: bars.Close, period: period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void MSE() {
+ MSE_Series QL = new(source: bars.Close, period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void OBV() {
+ OBV_Series QL = new(bars, period: period);
+ var lastData = bars.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0, 0, 0, 0, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void RSI() {
+ RSI_Series QL = new(source: bars.Close, period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void RMA() {
+ RMA_Series QL = new(source: bars.Close, period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void SDEV() {
+ SDEV_Series QL = new(source: bars.Close, period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void SMA() {
+ SMA_Series QL = new(source: bars.Close, period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void SMAPE() {
+ SMAPE_Series QL = new(source: bars.Close, period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void SMMA() {
+ SMMA_Series QL = new(source: bars.Close, period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void SSDEV() {
+ SSDEV_Series QL = new(source: bars.Close, period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void SUM() {
+ SUM_Series QL = new(source: bars.Close, period: period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void SVAR() {
+ SVAR_Series QL = new(source: bars.Close, period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void T3() {
+ SMA_Series QL = new(source: bars.Close, period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void TEMA() {
+ TEMA_Series QL = new(source: bars.Close, period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void TR() {
+ TR_Series QL = new(bars);
+ var lastData = bars.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0, 0, 0, 0, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void TRIMA() {
+ TRIMA_Series QL = new(source: bars.Close, period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void VAR() {
+ VAR_Series QL = new(source: bars.Close, period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void WMA() {
+ WMA_Series QL = new(source: bars.Close, period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void WMAPE() {
+ WMAPE_Series QL = new(source: bars.Close, period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void ZLEMA() {
+ ZLEMA_Series QL = new(source: bars.Close, period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+ [Fact] public void ZSCORE() {
+ ZSCORE_Series QL = new(source: bars.Close, period);
+ var lastData = bars.Close.Last();
+ var lastCalc = QL.Last();
+ int lastLen = QL.Count;
+ QL.Add((DateTime.Today, 0), update: true);
+ QL.Add(lastData, update: true);
+ Assert.Equal(lastLen, QL.Count); // same size
+ Assert.Equal(lastCalc, QL.Last()); // same data
+ }
+}
diff --git a/Tests/Tests.csproj b/Tests/Tests.csproj
index 19c1f9e1..7b17bb07 100644
--- a/Tests/Tests.csproj
+++ b/Tests/Tests.csproj
@@ -17,7 +17,7 @@
-
+
diff --git a/Tests/Validations/Trends/Pandas_TA.cs b/Tests/Validations/Trends/Pandas_TA.cs
index e38c82a9..a8cc5876 100644
--- a/Tests/Validations/Trends/Pandas_TA.cs
+++ b/Tests/Validations/Trends/Pandas_TA.cs
@@ -1,361 +1,382 @@
-using Xunit;
-using System;
-using QuanTAlib;
-using Python.Runtime;
-using Python.Included;
-
-namespace Validations;
-public class PandasTA : IDisposable
-{
- private readonly GBM_Feed bars;
- private readonly Random rnd = new();
- private readonly int period, sample;
- private int digits;
- private readonly string OStype;
- private readonly dynamic np;
- private readonly dynamic ta;
- private readonly dynamic df;
-
- public PandasTA() {
- bars = new(Bars: 5000, Volatility: 0.8, Drift: 0.0);
- period = rnd.Next(maxValue: 28) + 3;
- sample = 200;
- digits = 10;
-
- // Checking the host OS and setting PythonDLL accordingly
- OStype = Environment.OSVersion.ToString();
- if (OStype == "Unix 13.1.0")
- OStype = @"/usr/local/Cellar/python@3.10/3.10.8/Frameworks/Python.framework/Versions/3.10/lib/libpython3.10.dylib";
- else OStype = Path.GetFullPath(".") + @"\python-3.10.0-embed-amd64\python310.dll";
-
- Installer.InstallPath = Path.GetFullPath(path: ".");
- Installer.SetupPython().Wait();
- Installer.TryInstallPip();
- Installer.PipInstallModule(module_name: "pandas-ta");
- Runtime.PythonDLL = OStype;
- PythonEngine.Initialize();
- np = Py.Import(name: "numpy");
- ta = Py.Import(name: "pandas_ta");
-
- string[] cols = { "open", "high", "low", "close", "volume" };
- double[,] ary = new double[bars.Count, 5];
- for (int i = 0; i < bars.Count; i++) {
- ary[i, 0] = bars.Open[i].v;
- ary[i, 1] = bars.High[i].v;
- ary[i, 2] = bars.Low[i].v;
- ary[i, 3] = bars.Close[i].v;
- ary[i, 4] = bars.Volume[i].v;
- }
- df = ta.DataFrame(data: np.array(ary), index: np.array(bars.Close.t), columns: np.array(cols));
- }
- public void Dispose()
- {
- PythonEngine.Shutdown();
- GC.SuppressFinalize(this);
- }
-
- [Fact] void ADL() {
- ADL_Series QL = new(bars);
- var pta = df.ta.ad(high: df.high, low: df.low, close:df.close, volume:df.volume);
- for (int i = QL.Length; i > QL.Length-sample; i--)
- {
- double QL_item = Math.Round(QL[i-1].v, digits: digits);
- double PanTA_item = Math.Round((double)pta[i-1], digits: digits);
- Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
-
- }
- }
- [Fact] void ADOSC() {
- ADOSC_Series QL = new(bars);
- var pta = df.ta.adosc(high: df.high, low: df.low, close: df.close, volume: df.volume);
- for (int i = QL.Length; i > QL.Length-sample; i--)
- {
- double QL_item = Math.Round(QL[i - 1].v, digits: digits);
- double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
- Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact] void ATR() {
- ATR_Series QL = new(bars, period);
- var pta = df.ta.atr(high: df.high, low: df.low, close: df.close, length: period);
- for (int i = QL.Length; i > QL.Length-sample; i--)
- {
- double QL_item = Math.Round(QL[i - 1].v, digits: digits);
- double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
- Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact] void BIAS() {
- BIAS_Series QL = new(bars.Close, period, false);
- var pta = df.ta.bias(close: df.close, length: period);
- for (int i = QL.Length; i > QL.Length-sample; i--)
- {
- double QL_item = Math.Round(QL[i - 1].v, digits: digits);
- double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
- Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact] void DEMA() {
- DEMA_Series QL = new(bars.Close, period, false);
- var pta = df.ta.dema(close: df.close, length: period);
- for (int i = QL.Length; i > QL.Length-sample; i--)
- {
- double QL_item = Math.Round(QL[i - 1].v, digits: digits);
- double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
- Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact] void EMA() {
- EMA_Series QL = new(bars.Close, period, false);
- var pta = df.ta.ema(close: df.close, length: period);
- for (int i = QL.Length; i > QL.Length-sample; i--)
- {
- double QL_item = Math.Round(QL[i - 1].v, digits: digits);
- double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
- Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact] void ENTROPY() {
- ENTROPY_Series QL = new(bars.Close, period, useNaN: false);
- var pta = df.ta.entropy(close: df.close, length: period);
- for (int i = QL.Length; i > QL.Length-sample; i--)
- {
- double QL_item = Math.Round(QL[i - 1].v, digits: digits);
- double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
- Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact] void HL2() {
- var pta = df.ta.hl2(high: df.high, low: df.low);
- for (int i = bars.HL2.Length; i > bars.HL2.Length-sample; i--)
- {
- double QL_item = Math.Round(bars.HL2[i - 1].v, digits: digits);
- double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
- Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact] void HLC3() {
- var pta = df.ta.hlc3(high: df.high, low: df.low, close: df.close);
- for (int i = bars.HLC3.Length; i > bars.HLC3.Length-sample; i--)
- {
- double QL_item = Math.Round(bars.HLC3[i - 1].v, digits: digits);
- double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
- Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact] void HMA() {
- HMA_Series QL = new(bars.Close, period, false);
- var pta = df.ta.hma(close: df.close, length: period);
- for (int i = QL.Length; i > QL.Length-sample; i--)
- {
- double QL_item = Math.Round(QL[i - 1].v, digits: digits);
- double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
- Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
-
- }
- [Fact] void KAMA() {
- KAMA_Series QL = new(bars.Close, period);
- var pta = df.ta.kama(close: df.close, length: period);
- for (int i = QL.Length; i > QL.Length-sample; i--)
- {
- double QL_item = Math.Round(QL[i - 1].v, digits: digits);
- double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
- Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact] void KURTOSIS() {
- KURTOSIS_Series QL = new(bars.Close, period, useNaN: false);
- var pta = df.ta.kurtosis(close: df.close, length: period);
- for (int i = QL.Length; i > QL.Length-sample; i--)
- {
- double QL_item = Math.Round(QL[i - 1].v, digits: digits);
- double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
- Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact] void MAD()
- {
- MAD_Series QL = new(bars.Close, period, useNaN: false);
- var pta = df.ta.mad(close: df.close, length: period);
- for (int i = QL.Length; i > QL.Length-sample; i--)
- {
- double QL_item = Math.Round(QL[i - 1].v, digits: digits);
- double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
- Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact] void MEDIAN() {
- MEDIAN_Series QL = new(bars.Close, period);
- var pta = df.ta.median(close: df.close, length: period);
- for (int i = QL.Length; i > QL.Length-sample; i--)
- {
- double QL_item = Math.Round(QL[i - 1].v, digits: digits);
- double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
- Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact] void OBV() {
- OBV_Series QL = new(bars);
- var pta = df.ta.obv(close: df.close, volume: df.volume);
- for (int i = QL.Length; i > QL.Length-sample; i--)
- {
- double QL_item = Math.Round(QL[i - 1].v, digits: digits);
- double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
- Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact] void OHLC4() {
- var pta = df.ta.ohlc4(open: df.open, high: df.high, low: df.low, close: df.close);
- for (int i = bars.OHLC4.Length; i > bars.OHLC4.Length-sample; i--)
- {
- double QL_item = Math.Round(bars.OHLC4[i - 1].v, digits: digits);
- double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
- Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact] void RMA() {
- RMA_Series QL = new(bars.Close, period, false);
- var pta = df.ta.rma(close: df.close, length: period);
- for (int i = QL.Length; i > QL.Length-sample; i--)
- {
- double QL_item = Math.Round(QL[i - 1].v, digits: digits);
- double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
- Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact] void RSI() {
- RSI_Series QL = new(bars.Close, period);
- var pta = df.ta.rsi(close: df.close, length: period);
- for (int i = QL.Length; i > QL.Length-sample; i--)
- {
- double QL_item = Math.Round(QL[i - 1].v, digits: digits);
- double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
- Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact] void SDEV() {
- SDEV_Series QL = new(bars.Close, period, useNaN: false);
- var pta = df.ta.stdev(close: df.close, length: period, ddof: 0);
- for (int i = QL.Length; i > QL.Length-sample; i--)
- {
- double QL_item = Math.Round(QL[i - 1].v, digits: digits);
- double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
- Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact] void SMA() {
- SMA_Series QL = new(bars.Close, period, false);
- var pta = df.ta.sma(close: df.close, length: period);
- for (int i = QL.Length; i > QL.Length-sample; i--)
- {
- double QL_item = Math.Round(QL[i - 1].v, digits: digits);
- double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
- Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact] void SSDEV() {
- SSDEV_Series QL = new(bars.Close, period, useNaN: false);
- var pta = df.ta.stdev(close: df.close, length: period, ddof: 1);
- for (int i = QL.Length; i > QL.Length-sample; i--)
- {
- double QL_item = Math.Round(QL[i - 1].v, digits: digits);
- double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
- Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- /*
- [Fact] void SVARIANCE() {
- SVAR_Series QL = new(bars.Close, period);
- var pta = df.ta.variance(close: df.close, length: period, ddof: 1);
- for (int i = QL.Length; i > QL.Length-sample; i--)
- {
- double QL_item = Math.Round(QL[i - 1].v, digits: digits);
- double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
- Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
-*/
- [Fact] void T3() {
- T3_Series QL = new(source: bars.Close, period: period, vfactor: 0.7, useNaN: false);
- var pta = df.ta.t3(close: df.close, length: period, a: 0.7);
- for (int i = QL.Length; i > QL.Length-sample; i--)
- {
- double QL_item = Math.Round(QL[i - 1].v, digits: digits);
- double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
- Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact] void TEMA() {
- TEMA_Series QL = new(bars.Close, period, false);
- var pta = df.ta.tema(close: df.close, length: period);
- for (int i = QL.Length; i > QL.Length-sample; i--)
- {
- double QL_item = Math.Round(QL[i - 1].v, digits: digits);
- double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
- Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact] void TR() {
- TR_Series QL = new(bars);
- var pta = df.ta.true_range(high: df.high, low: df.low, close: df.close);
- for (int i = QL.Length; i > QL.Length-sample; i--)
- {
- double QL_item = Math.Round(QL[i - 1].v, digits: digits);
- double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
- Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact] void TRIMA() {
- // TODO: return length to variable length (period) when Pandas-TA fixes trima to calculate even periods right
- TRIMA_Series QL = new(bars.Close, 11);
- var pta = df.ta.trima(close: df.close, length: 11);
- for (int i = QL.Length; i > QL.Length-sample; i--)
- {
- double QL_item = Math.Round(QL[i - 1].v, digits: digits);
- double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
- Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact] void VARIANCE() {
- VAR_Series QL = new(bars.Close, period);
- var pta = df.ta.variance(close: df.close, length: period, ddof:0);
- for (int i = QL.Length; i > QL.Length-sample; i--)
- {
- double QL_item = Math.Round(QL[i - 1].v, digits: digits);
- double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
- Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact] void WMA() {
- WMA_Series QL = new(bars.Close, period, false);
- var pta = df.ta.wma(close: df.close, length: period);
- for (int i = QL.Length; i > QL.Length-sample; i--)
- {
- double QL_item = Math.Round(QL[i - 1].v, digits: digits);
- double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
- Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact] void ZLEMA() {
- ZLEMA_Series QL = new(bars.Close, period, false);
- var pta = df.ta.zlma(close: df.close, length: period);
- for (int i = QL.Length; i > QL.Length-sample; i--)
- {
- double QL_item = Math.Round(QL[i - 1].v, digits: digits);
- double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
- Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact] void ZSCORE() {
- ZSCORE_Series QL = new(bars.Close, period, useNaN: false);
- var pta = df.ta.zscore(close: df.close, length: period, ddof: 0);
- for (int i = QL.Length; i > QL.Length-sample; i--)
- {
- double QL_item = Math.Round(QL[i - 1].v, digits: digits);
- double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
- Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
-
+using Xunit;
+using System;
+using QuanTAlib;
+using Python.Runtime;
+using Python.Included;
+
+namespace Validations;
+public class PandasTA : IDisposable
+{
+ private readonly GBM_Feed bars;
+ private readonly Random rnd = new();
+ private readonly int period, sample;
+ private int digits;
+ private readonly string OStype;
+ private readonly dynamic np;
+ private readonly dynamic ta;
+ private readonly dynamic df;
+
+ public PandasTA() {
+ bars = new(Bars: 5000, Volatility: 0.8, Drift: 0.0);
+ period = rnd.Next(maxValue: 28) + 3;
+ sample = 200;
+ digits = 10;
+
+ // Checking the host OS and setting PythonDLL accordingly
+ OStype = Environment.OSVersion.ToString();
+ if (OStype == "Unix 13.1.0")
+ OStype = @"/usr/local/Cellar/python@3.10/3.10.8/Frameworks/Python.framework/Versions/3.10/lib/libpython3.10.dylib";
+ else OStype = Path.GetFullPath(".") + @"\python-3.10.0-embed-amd64\python310.dll";
+
+ Installer.InstallPath = Path.GetFullPath(path: ".");
+ Installer.SetupPython().Wait();
+ Installer.TryInstallPip();
+ Installer.PipInstallModule(module_name: "pandas-ta");
+ Runtime.PythonDLL = OStype;
+ PythonEngine.Initialize();
+ np = Py.Import(name: "numpy");
+ ta = Py.Import(name: "pandas_ta");
+
+ string[] cols = { "open", "high", "low", "close", "volume" };
+ double[,] ary = new double[bars.Count, 5];
+ for (int i = 0; i < bars.Count; i++) {
+ ary[i, 0] = bars.Open[i].v;
+ ary[i, 1] = bars.High[i].v;
+ ary[i, 2] = bars.Low[i].v;
+ ary[i, 3] = bars.Close[i].v;
+ ary[i, 4] = bars.Volume[i].v;
+ }
+ df = ta.DataFrame(data: np.array(ary), index: np.array(bars.Close.t), columns: np.array(cols));
+ }
+ public void Dispose()
+ {
+ PythonEngine.Shutdown();
+ GC.SuppressFinalize(this);
+ }
+
+ [Fact] void ADL() {
+ ADL_Series QL = new(bars);
+ var pta = df.ta.ad(high: df.high, low: df.low, close:df.close, volume:df.volume);
+ for (int i = QL.Length; i > QL.Length-sample; i--)
+ {
+ double QL_item = Math.Round(QL[i-1].v, digits: digits);
+ double PanTA_item = Math.Round((double)pta[i-1], digits: digits);
+ Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+
+ }
+ }
+ [Fact] void ADOSC() {
+ ADOSC_Series QL = new(bars);
+ var pta = df.ta.adosc(high: df.high, low: df.low, close: df.close, volume: df.volume);
+ for (int i = QL.Length; i > QL.Length-sample; i--)
+ {
+ double QL_item = Math.Round(QL[i - 1].v, digits: digits);
+ double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
+ Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact] void ATR() {
+ ATR_Series QL = new(bars, period);
+ var pta = df.ta.atr(high: df.high, low: df.low, close: df.close, length: period);
+ for (int i = QL.Length; i > QL.Length-sample; i--)
+ {
+ double QL_item = Math.Round(QL[i - 1].v, digits: digits);
+ double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
+ Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact] void BIAS() {
+ BIAS_Series QL = new(bars.Close, period, false);
+ var pta = df.ta.bias(close: df.close, length: period);
+ for (int i = QL.Length; i > QL.Length-sample; i--)
+ {
+ double QL_item = Math.Round(QL[i - 1].v, digits: digits);
+ double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
+ Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+/*
+ [Fact]
+ void CMO() {
+ CMO_Series QL = new(bars.Close, period, false);
+ var pta = df.ta.cmo(close: df.close, length: period);
+ for (int i = QL.Length; i > QL.Length - sample; i--) {
+ double QL_item = Math.Round(QL[i - 1].v, digits: digits);
+ double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
+ Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+*/
+ [Fact] void DEMA() {
+ DEMA_Series QL = new(bars.Close, period, false);
+ var pta = df.ta.dema(close: df.close, length: period);
+ for (int i = QL.Length; i > QL.Length-sample; i--)
+ {
+ double QL_item = Math.Round(QL[i - 1].v, digits: digits);
+ double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
+ Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact] void EMA() {
+ EMA_Series QL = new(bars.Close, period, false);
+ var pta = df.ta.ema(close: df.close, length: period);
+ for (int i = QL.Length; i > QL.Length-sample; i--)
+ {
+ double QL_item = Math.Round(QL[i - 1].v, digits: digits);
+ double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
+ Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact] void ENTROPY() {
+ ENTROPY_Series QL = new(bars.Close, period, useNaN: false);
+ var pta = df.ta.entropy(close: df.close, length: period);
+ for (int i = QL.Length; i > QL.Length-sample; i--)
+ {
+ double QL_item = Math.Round(QL[i - 1].v, digits: digits);
+ double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
+ Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact] void HL2() {
+ var pta = df.ta.hl2(high: df.high, low: df.low);
+ for (int i = bars.HL2.Length; i > bars.HL2.Length-sample; i--)
+ {
+ double QL_item = Math.Round(bars.HL2[i - 1].v, digits: digits);
+ double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
+ Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact] void HLC3() {
+ var pta = df.ta.hlc3(high: df.high, low: df.low, close: df.close);
+ for (int i = bars.HLC3.Length; i > bars.HLC3.Length-sample; i--)
+ {
+ double QL_item = Math.Round(bars.HLC3[i - 1].v, digits: digits);
+ double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
+ Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact] void HMA() {
+ HMA_Series QL = new(bars.Close, period, false);
+ var pta = df.ta.hma(close: df.close, length: period);
+ for (int i = QL.Length; i > QL.Length-sample; i--)
+ {
+ double QL_item = Math.Round(QL[i - 1].v, digits: digits);
+ double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
+ Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+
+ }
+ [Fact] void KAMA() {
+ KAMA_Series QL = new(bars.Close, period);
+ var pta = df.ta.kama(close: df.close, length: period);
+ for (int i = QL.Length; i > QL.Length-sample; i--)
+ {
+ double QL_item = Math.Round(QL[i - 1].v, digits: digits);
+ double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
+ Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact] void KURTOSIS() {
+ KURTOSIS_Series QL = new(bars.Close, period, useNaN: false);
+ var pta = df.ta.kurtosis(close: df.close, length: period);
+ for (int i = QL.Length; i > QL.Length-sample; i--)
+ {
+ double QL_item = Math.Round(QL[i - 1].v, digits: digits);
+ double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
+ Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact] void MAD()
+ {
+ MAD_Series QL = new(bars.Close, period, useNaN: false);
+ var pta = df.ta.mad(close: df.close, length: period);
+ for (int i = QL.Length; i > QL.Length-sample; i--)
+ {
+ double QL_item = Math.Round(QL[i - 1].v, digits: digits);
+ double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
+ Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact] void MEDIAN() {
+ MEDIAN_Series QL = new(bars.Close, period);
+ var pta = df.ta.median(close: df.close, length: period);
+ for (int i = QL.Length; i > QL.Length-sample; i--)
+ {
+ double QL_item = Math.Round(QL[i - 1].v, digits: digits);
+ double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
+ Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact] void OBV() {
+ OBV_Series QL = new(bars);
+ var pta = df.ta.obv(close: df.close, volume: df.volume);
+ for (int i = QL.Length; i > QL.Length-sample; i--)
+ {
+ double QL_item = Math.Round(QL[i - 1].v, digits: digits);
+ double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
+ Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact] void OHLC4() {
+ var pta = df.ta.ohlc4(open: df.open, high: df.high, low: df.low, close: df.close);
+ for (int i = bars.OHLC4.Length; i > bars.OHLC4.Length-sample; i--)
+ {
+ double QL_item = Math.Round(bars.OHLC4[i - 1].v, digits: digits);
+ double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
+ Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact] void RMA() {
+ RMA_Series QL = new(bars.Close, period, false);
+ var pta = df.ta.rma(close: df.close, length: period);
+ for (int i = QL.Length; i > QL.Length-sample; i--)
+ {
+ double QL_item = Math.Round(QL[i - 1].v, digits: digits);
+ double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
+ Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact] void RSI() {
+ RSI_Series QL = new(bars.Close, period);
+ var pta = df.ta.rsi(close: df.close, length: period);
+ for (int i = QL.Length; i > QL.Length-sample; i--)
+ {
+ double QL_item = Math.Round(QL[i - 1].v, digits: digits);
+ double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
+ Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact] void SDEV() {
+ SDEV_Series QL = new(bars.Close, period, useNaN: false);
+ var pta = df.ta.stdev(close: df.close, length: period, ddof: 0);
+ for (int i = QL.Length; i > QL.Length-sample; i--)
+ {
+ double QL_item = Math.Round(QL[i - 1].v, digits: digits);
+ double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
+ Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact] void SMA() {
+ SMA_Series QL = new(bars.Close, period, false);
+ var pta = df.ta.sma(close: df.close, length: period);
+ for (int i = QL.Length; i > QL.Length-sample; i--)
+ {
+ double QL_item = Math.Round(QL[i - 1].v, digits: digits);
+ double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
+ Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact] void SSDEV() {
+ SSDEV_Series QL = new(bars.Close, period, useNaN: false);
+ var pta = df.ta.stdev(close: df.close, length: period, ddof: 1);
+ for (int i = QL.Length; i > QL.Length-sample; i--)
+ {
+ double QL_item = Math.Round(QL[i - 1].v, digits: digits);
+ double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
+ Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ /*
+ [Fact] void SVARIANCE() {
+ SVAR_Series QL = new(bars.Close, period);
+ var pta = df.ta.variance(close: df.close, length: period, ddof: 1);
+ for (int i = QL.Length; i > QL.Length-sample; i--)
+ {
+ double QL_item = Math.Round(QL[i - 1].v, digits: digits);
+ double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
+ Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+*/
+ [Fact] void T3() {
+ T3_Series QL = new(source: bars.Close, period: period, vfactor: 0.7, useNaN: false);
+ var pta = df.ta.t3(close: df.close, length: period, a: 0.7);
+ for (int i = QL.Length; i > QL.Length-sample; i--)
+ {
+ double QL_item = Math.Round(QL[i - 1].v, digits: digits);
+ double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
+ Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact] void TEMA() {
+ TEMA_Series QL = new(bars.Close, period, false);
+ var pta = df.ta.tema(close: df.close, length: period);
+ for (int i = QL.Length; i > QL.Length-sample; i--)
+ {
+ double QL_item = Math.Round(QL[i - 1].v, digits: digits);
+ double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
+ Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact] void TR() {
+ TR_Series QL = new(bars);
+ var pta = df.ta.true_range(high: df.high, low: df.low, close: df.close);
+ for (int i = QL.Length; i > QL.Length-sample; i--)
+ {
+ double QL_item = Math.Round(QL[i - 1].v, digits: digits);
+ double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
+ Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact] void TRIMA() {
+ // TODO: return length to variable length (period) when Pandas-TA fixes trima to calculate even periods right
+ TRIMA_Series QL = new(bars.Close, 11);
+ var pta = df.ta.trima(close: df.close, length: 11);
+ for (int i = QL.Length; i > QL.Length-sample; i--)
+ {
+ double QL_item = Math.Round(QL[i - 1].v, digits: digits);
+ double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
+ Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact] void TRIX() {
+ TRIX_Series QL = new(bars.Close, period);
+ var pta = df.ta.trix(close: df.close, length: period).to_numpy();
+ for (int i = QL.Length; i > QL.Length - sample; i--) {
+ double QL_item = Math.Round(QL[i - 1].v, digits: digits);
+ double PanTA_item = Math.Round((double)pta[i - 1][0], digits: digits);
+ Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact] void VARIANCE() {
+ VAR_Series QL = new(bars.Close, period);
+ var pta = df.ta.variance(close: df.close, length: period, ddof:0);
+ for (int i = QL.Length; i > QL.Length-sample; i--)
+ {
+ double QL_item = Math.Round(QL[i - 1].v, digits: digits);
+ double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
+ Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact] void WMA() {
+ WMA_Series QL = new(bars.Close, period, false);
+ var pta = df.ta.wma(close: df.close, length: period);
+ for (int i = QL.Length; i > QL.Length-sample; i--)
+ {
+ double QL_item = Math.Round(QL[i - 1].v, digits: digits);
+ double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
+ Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact] void ZLEMA() {
+ ZLEMA_Series QL = new(bars.Close, period, false);
+ var pta = df.ta.zlma(close: df.close, length: period);
+ for (int i = QL.Length; i > QL.Length-sample; i--)
+ {
+ double QL_item = Math.Round(QL[i - 1].v, digits: digits);
+ double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
+ Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact] void ZSCORE() {
+ ZSCORE_Series QL = new(bars.Close, period, useNaN: false);
+ var pta = df.ta.zscore(close: df.close, length: period, ddof: 0);
+ for (int i = QL.Length; i > QL.Length-sample; i--)
+ {
+ double QL_item = Math.Round(QL[i - 1].v, digits: digits);
+ double PanTA_item = Math.Round((double)pta[i - 1], digits: digits);
+ Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+
}
\ No newline at end of file
diff --git a/Tests/Validations/Trends/Skender.cs b/Tests/Validations/Trends/Skender.cs
index 0efda3dd..8997d5bc 100644
--- a/Tests/Validations/Trends/Skender.cs
+++ b/Tests/Validations/Trends/Skender.cs
@@ -10,16 +10,16 @@ public class Skender
private readonly Random rnd = new();
private readonly int period, digits, skip;
private readonly IEnumerable quotes;
-
+
public Skender()
{
bars = new(Bars: 10000, Volatility: 0.5, Drift: 0.0, Precision: 2);
period = rnd.Next(30) + 5;
- skip = 200;
- digits = 10;
+ digits = 2; //minimizing rounding errors in type conversions
+ skip = 300;
- quotes = bars.Select(q => new Quote
+ quotes = bars.Select(q => new Quote
{
Date = q.t,
Open = (decimal)q.o,
@@ -33,14 +33,15 @@ public class Skender
[Fact]
public void ADL()
{
+ // TODO: check precision of ADL()
ADL_Series QL = new(bars, false);
var SK = quotes.GetAdl().Select(i => i.Adl);
for (int i = QL.Length; i > skip; i--)
{
double QL_item = Math.Round(QL[i - 1].v, digits: digits);
double SK_item = Math.Round(SK.ElementAt(i - 1)!, digits: digits);
- Assert.InRange(SK_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
+ Assert.Equal(SK_item!, QL_item);
+ }
}
[Fact]
public void ALMA()
@@ -51,7 +52,7 @@ public class Skender
{
double QL_item = Math.Round(QL[i - 1].v, digits: digits);
double SK_item = Math.Round((double)SK.ElementAt(i - 1), digits: digits);
- Assert.InRange(SK_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ Assert.Equal(SK_item!, QL_item);
}
}
[Fact]
@@ -63,7 +64,7 @@ public class Skender
{
double QL_item = Math.Round(QL[i - 1].v, digits: digits);
double SK_item = Math.Round((double)SK.ElementAt(i - 1), digits: digits);
- Assert.InRange(SK_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ Assert.Equal(SK_item!, QL_item);
}
}
[Fact]
@@ -75,7 +76,7 @@ public class Skender
{
double QL_item = Math.Round(QL[i - 1].v, digits: digits);
double SK_item = Math.Round((double)SK.ElementAt(i - 1), digits: digits);
- Assert.InRange(SK_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ Assert.Equal(SK_item!, QL_item);
}
}
[Fact]
@@ -87,22 +88,22 @@ public class Skender
{
double QL_item = Math.Round(QL.Mid[i - 1].v, digits: digits);
double SK_item = Math.Round((double)SK.ElementAt(i - 1).Sma!.Value, digits: digits);
- Assert.InRange(SK_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ Assert.Equal(SK_item!, QL_item);
QL_item = Math.Round(QL.Upper[i - 1].v, digits: digits);
SK_item = Math.Round((double)SK.ElementAt(i - 1).UpperBand!.Value, digits: digits);
- Assert.InRange(SK_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ Assert.Equal(SK_item!, QL_item);
QL_item = Math.Round(QL.Lower[i - 1].v, digits: digits);
SK_item = Math.Round((double)SK.ElementAt(i - 1).LowerBand!.Value, digits: digits);
- Assert.InRange(SK_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ Assert.Equal(SK_item!, QL_item);
QL_item = Math.Round(QL.Bandwidth[i - 1].v, digits: digits);
SK_item = Math.Round((double)SK.ElementAt(i - 1).Width!.Value, digits: digits);
- Assert.InRange(SK_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ Assert.Equal(SK_item!, QL_item);
QL_item = Math.Round(QL.PercentB[i - 1].v, digits: digits);
SK_item = Math.Round((double)SK.ElementAt(i - 1).PercentB!.Value, digits: digits);
- Assert.InRange(SK_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ Assert.Equal(SK_item!, QL_item);
QL_item = Math.Round(QL.Zscore[i - 1].v, digits: digits);
SK_item = Math.Round((double)SK.ElementAt(i - 1).ZScore!.Value, digits: digits);
- Assert.InRange(SK_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ Assert.Equal(SK_item!, QL_item);
}
}
[Fact]
@@ -114,7 +115,19 @@ public class Skender
{
double QL_item = Math.Round(QL[i - 1].v, digits: digits);
double SK_item = Math.Round((double)SK.ElementAt(i - 1), digits: digits);
- Assert.InRange(SK_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ Assert.Equal(SK_item!, QL_item);
+ }
+ }
+ [Fact]
+ public void CMO()
+ {
+ CMO_Series QL = new(bars.Close, period, false);
+ var SK = quotes.GetCmo(period).Select(i => i.Cmo.Null2NaN()!);
+ for (int i = QL.Length; i > skip; i--)
+ {
+ double QL_item = Math.Round(QL[i - 1].v, digits: digits);
+ double SK_item = Math.Round((double)SK.ElementAt(i - 1), digits: digits);
+ Assert.Equal(SK_item!, QL_item);
}
}
[Fact]
@@ -126,7 +139,7 @@ public class Skender
{
double QL_item = Math.Round(QL[i - 1].v, digits: digits);
double SK_item = Math.Round((double)SK.ElementAt(i - 1), digits: digits);
- Assert.InRange(SK_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ Assert.Equal(SK_item!, QL_item);
}
}
[Fact]
@@ -138,10 +151,9 @@ public class Skender
{
double QL_item = Math.Round(QL[i - 1].v, digits: digits);
double SK_item = Math.Round((double)SK.ElementAt(i - 1), digits: digits);
- Assert.InRange(SK_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ Assert.Equal(SK_item!, QL_item);
}
}
-/*
[Fact]
public void DEMA()
{
@@ -151,10 +163,9 @@ public class Skender
{
double QL_item = Math.Round(QL[i - 1].v, digits: digits);
double SK_item = Math.Round((double)SK.ElementAt(i - 1), digits: digits);
- Assert.InRange(SK_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ Assert.Equal(SK_item!, QL_item);
}
}
-*/
[Fact]
public void EMA()
{
@@ -164,7 +175,7 @@ public class Skender
{
double QL_item = Math.Round(QL[i - 1].v, digits: digits);
double SK_item = Math.Round((double)SK.ElementAt(i - 1), digits: digits);
- Assert.InRange(SK_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ Assert.Equal(SK_item!, QL_item);
}
}
/*
@@ -177,7 +188,7 @@ public class Skender
{
double QL_item = Math.Round(QL[i - 1].v, digits: digits);
double SK_item = Math.Round((double)SK.ElementAt(i - 1)!, digits: digits);
- Assert.InRange(SK_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ Assert.Equal(SK_item!, QL_item);
}
}
[Fact]
@@ -189,7 +200,7 @@ public class Skender
{
double QL_item = Math.Round(QL[i - 1].v, digits: digits);
double SK_item = Math.Round((double)SK.ElementAt(i - 1)!, digits: digits);
- Assert.InRange(SK_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ Assert.Equal(SK_item!, QL_item);
}
}
*/
@@ -202,10 +213,9 @@ public class Skender
{
double QL_item = Math.Round(QL[i - 1].v, digits: digits);
double SK_item = Math.Round(SK.ElementAt(i - 1), digits: digits);
- Assert.InRange(SK_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ Assert.Equal(SK_item!, QL_item);
}
}
-/*
[Fact]
public void KAMA()
{
@@ -216,10 +226,9 @@ public class Skender
{
double QL_item = Math.Round(QL[i - 1].v, digits: digits);
double SK_item = Math.Round(SK.ElementAt(i - 1), digits: digits);
- Assert.InRange(SK_item! - QL_item, -Math.Exp(-digits/2), Math.Exp(-digits/2));
+ Assert.Equal(SK_item!, QL_item);
}
}
-*/
[Fact]
public void LINREG()
{
@@ -229,16 +238,16 @@ public class Skender
{
double QL_item = Math.Round(QL[i - 1].v, digits: digits);
double SK_item = Math.Round((double)SK.ElementAt(i - 1).Slope!, digits: digits);
- Assert.InRange(SK_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ Assert.Equal(SK_item!, QL_item);
QL_item = Math.Round(QL.Intercept[i - 1].v, digits: digits);
SK_item = Math.Round((double)SK.ElementAt(i - 1).Intercept!, digits: digits);
- Assert.InRange(SK_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ Assert.Equal(SK_item!, QL_item);
QL_item = Math.Round(QL.RSquared[i - 1].v, digits: digits);
SK_item = Math.Round((double)SK.ElementAt(i - 1).RSquared!, digits: digits);
- Assert.InRange(SK_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ Assert.Equal(SK_item!, QL_item);
QL_item = Math.Round(QL.StdDev[i - 1].v, digits: digits);
SK_item = Math.Round((double)SK.ElementAt(i - 1).StdDev!, digits: digits);
- Assert.InRange(SK_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ Assert.Equal(SK_item!, QL_item);
}
}
[Fact]
@@ -250,10 +259,10 @@ public class Skender
{
double QL_item = Math.Round(QL[i - 1].v, digits: digits);
double SK_item = Math.Round(SK.ElementAt(i - 1).Macd.Null2NaN()!, digits: digits);
- Assert.InRange(SK_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ Assert.Equal(SK_item!, QL_item);
QL_item = Math.Round(QL.Signal[i - 1].v, digits: digits);
SK_item = Math.Round(SK.ElementAt(i - 1).Signal.Null2NaN()!, digits: digits);
- Assert.InRange(SK_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ Assert.Equal(SK_item!, QL_item);
}
}
[Fact]
@@ -265,7 +274,7 @@ public class Skender
{
double QL_item = Math.Round(QL[i - 1].v, digits: digits);
double SK_item = Math.Round(SK.ElementAt(i - 1), digits: digits);
- Assert.InRange(SK_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ Assert.Equal(SK_item!, QL_item);
}
}
[Fact]
@@ -277,10 +286,10 @@ public class Skender
{
double QL_item = Math.Round(QL[i - 1].v, digits: digits);
double SK_item = Math.Round(SK.ElementAt(i - 1).Mama.Null2NaN()!, digits: digits);
- Assert.InRange(SK_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ Assert.Equal(SK_item!, QL_item);
QL_item = Math.Round(QL.Fama[i - 1].v, digits: digits);
SK_item = Math.Round(SK.ElementAt(i - 1).Fama.Null2NaN()!, digits: digits);
- Assert.InRange(SK_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ Assert.Equal(SK_item!, QL_item);
}
}
[Fact]
@@ -292,7 +301,7 @@ public class Skender
{
double QL_item = Math.Round(QL[i - 1].v, digits: digits);
double SK_item = Math.Round(SK.ElementAt(i - 1), digits: digits);
- Assert.InRange(SK_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ Assert.Equal(SK_item!, QL_item);
}
}
[Fact]
@@ -304,7 +313,7 @@ public class Skender
{
double QL_item = Math.Round(QL[i - 1].v, digits: digits);
double SK_item = Math.Round(SK.ElementAt(i - 1), digits: digits);
- Assert.InRange(SK_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ Assert.Equal(SK_item!, QL_item);
}
}
[Fact]
@@ -317,7 +326,7 @@ public class Skender
{
double QL_item = Math.Round(QL.Last().v, digits: digits);
double SK_item = Math.Round(SK.Last()! + (double)quotes.First().Volume!, digits: digits);
- Assert.InRange(SK_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ Assert.Equal(SK_item!, QL_item);
}
}
/*
@@ -330,7 +339,7 @@ public class Skender
{
double QL_item = Math.Round(QL[i - 1].v, digits: digits);
double SK_item = Math.Round((double)SK.ElementAt(i - 1)!, digits: digits);
- Assert.InRange(SK_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ Assert.Equal(SK_item!, QL_item);
}
}
[Fact]
@@ -342,7 +351,7 @@ public class Skender
{
double QL_item = Math.Round(QL[i - 1].v, digits: digits);
double SK_item = Math.Round((double)SK.ElementAt(i - 1)!, digits: digits);
- Assert.InRange(SK_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ Assert.Equal(SK_item!, QL_item);
}
}
[Fact]
@@ -354,7 +363,7 @@ public class Skender
{
double QL_item = Math.Round(QL[i - 1].v, digits: digits);
double SK_item = Math.Round((double)SK.ElementAt(i - 1)!, digits: digits);
- Assert.InRange(SK_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ Assert.Equal(SK_item!, QL_item);
}
}
*/
@@ -367,7 +376,7 @@ public class Skender
{
double QL_item = Math.Round(QL[i - 1].v, digits: digits);
double SK_item = Math.Round(SK.ElementAt(i - 1), digits: digits);
- Assert.InRange(SK_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ Assert.Equal(SK_item!, QL_item);
}
}
[Fact]
@@ -379,7 +388,7 @@ public class Skender
{
double QL_item = Math.Round(QL[i - 1].v, digits: digits);
double SK_item = Math.Round(SK.ElementAt(i - 1), digits: digits);
- Assert.InRange(SK_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ Assert.Equal(SK_item!, QL_item);
}
}
[Fact]
@@ -391,7 +400,7 @@ public class Skender
{
double QL_item = Math.Round(QL[i - 1].v, digits: digits);
double SK_item = Math.Round(SK.ElementAt(i - 1), digits: digits);
- Assert.InRange(SK_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ Assert.Equal(SK_item!, QL_item);
}
}
[Fact]
@@ -403,10 +412,9 @@ public class Skender
{
double QL_item = Math.Round(QL[i - 1].v, digits: digits);
double SK_item = Math.Round(SK.ElementAt(i - 1), digits: digits);
- Assert.InRange(SK_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ Assert.Equal(SK_item!, QL_item);
}
}
-/*
[Fact]
public void T3()
{
@@ -416,10 +424,9 @@ public class Skender
{
double QL_item = Math.Round(QL[i - 1].v, digits: digits);
double SK_item = Math.Round(SK.ElementAt(i - 1), digits: digits);
- Assert.InRange(SK_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ Assert.Equal(SK_item!, QL_item);
}
}
-*/
[Fact]
public void TEMA()
{
@@ -429,7 +436,7 @@ public class Skender
{
double QL_item = Math.Round(QL[i - 1].v, digits: digits);
double SK_item = Math.Round(SK.ElementAt(i - 1), digits: digits);
- Assert.InRange(SK_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ Assert.Equal(SK_item!, QL_item);
}
}
[Fact]
@@ -441,7 +448,7 @@ public class Skender
{
double QL_item = Math.Round(QL[i - 1].v, digits: digits);
double SK_item = Math.Round(SK.ElementAt(i - 1), digits: digits);
- Assert.InRange(SK_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ Assert.Equal(SK_item!, QL_item);
}
}
[Fact]
@@ -453,7 +460,7 @@ public class Skender
{
double QL_item = Math.Round(QL[i - 1].v, digits: digits);
double SK_item = Math.Round(SK.ElementAt(i - 1), digits: digits);
- Assert.InRange(SK_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ Assert.Equal(SK_item!, QL_item);
}
}
[Fact]
@@ -465,7 +472,7 @@ public class Skender
{
double QL_item = Math.Round(QL[i - 1].v, digits: digits);
double SK_item = Math.Round(SK.ElementAt(i - 1), digits: digits);
- Assert.InRange(SK_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ Assert.Equal(SK_item!, QL_item);
}
}
diff --git a/Tests/Validations/Trends/TA_LIB.cs b/Tests/Validations/Trends/TA_LIB.cs
index d9d783be..2e8e6571 100644
--- a/Tests/Validations/Trends/TA_LIB.cs
+++ b/Tests/Validations/Trends/TA_LIB.cs
@@ -1,452 +1,474 @@
-using Xunit;
-using System;
-using TALib;
-using QuanTAlib;
-
-namespace Validations;
-public class Ta_Lib
-{
- private readonly GBM_Feed bars;
- private readonly Random rnd = new();
- private readonly int period, digits, skip;
- private readonly double[] TALIB;
- private readonly double[] TALIB2;
- private readonly double[] inopen;
- private readonly double[] inhigh;
- private readonly double[] inlow;
- private readonly double[] inclose;
- private readonly double[] involume;
-
- public Ta_Lib()
- {
- bars = new(Bars: 5000, Volatility: 0.8, Drift: 0.0, Precision: 3);
- period = rnd.Next(28) + 3;
- skip = 500;
- digits = 10;
-
- TALIB = new double[bars.Count];
- TALIB2 = new double[bars.Count];
- inopen = bars.Open.v.ToArray();
- inhigh = bars.High.v.ToArray();
- inlow = bars.Low.v.ToArray();
- inclose = bars.Close.v.ToArray();
- involume = bars.Volume.v.ToArray();
- }
-
- [Fact]
- public void ADD()
- {
- ADD_Series QL = new(bars.Open, bars.Close);
- Core.Add(inopen, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
- for (int i = QL.Length - 1; i > skip; i--)
- {
- double QL_item = Math.Round(QL[i].v, digits: digits);
- double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
- Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact]
- public void ADL()
- {
- ADL_Series QL = new(bars, false);
- Core.Ad(inhigh, inlow, inclose, involume, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
- for (int i = QL.Length - 1; i > 0; i--)
- {
- double QL_item = Math.Round(QL[i].v, digits: digits);
- double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
- Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact]
- public void ADOSC()
- {
- ADOSC_Series QL = new(bars, 3, 10, false);
- Core.AdOsc(inhigh, inlow, inclose, involume, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
- for (int i = QL.Length - 1; i > skip; i--)
- {
- double QL_item = Math.Round(QL[i].v, digits: digits);
- double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
- Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact]
- public void ATR()
- {
- ATR_Series QL = new(bars, period, false);
- Core.Atr(inhigh, inlow, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
- for (int i = QL.Length - 1; i > skip * 15; i--)
- {
- double QL_item = Math.Round(QL[i].v, digits: digits);
- double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
- Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
-/*
- [Fact]
- public void BBANDS()
- {
- double[] outMiddle = new double[bars.Count];
- double[] outUpper = new double[bars.Count];
- double[] outLower = new double[bars.Count];
- BBANDS_Series QL = new(bars.Close, period: 26, multiplier: 2.0, false);
- Core.Bbands(inclose, 0, bars.Count - 1, outRealUpperBand: outUpper, outRealMiddleBand: outMiddle, outRealLowerBand: outLower, out int outBegIdx, out _, optInTimePeriod: 26, optInNbDevUp: 2.0, optInNbDevDn: 2.0);
- for (int i = QL.Length - 1; i > skip; i--)
- {
- double QL_item = Math.Round(QL.Upper[i].v, digits: digits);
- double TA_item = Math.Round(outUpper[i - outBegIdx], digits: digits);
- Assert.Equal(TA_item!, QL_item);
- QL_item = Math.Round(QL.Mid[i].v, digits: digits);
- TA_item = Math.Round(outMiddle[i - outBegIdx], digits: digits);
- Assert.Equal(TA_item!, QL_item);
- QL_item = Math.Round(QL.Lower[i].v, digits: digits);
- TA_item = Math.Round(outLower[i - outBegIdx], digits: digits);
- Assert.Equal(TA_item!, QL_item);
- }
- Assert.Equal(Math.Round(outUpper[outUpper.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Upper.Last().v, digits: digits));
- Assert.Equal(Math.Round(outMiddle[outMiddle.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Mid.Last().v, digits: digits));
- Assert.Equal(Math.Round(outLower[outLower.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Lower.Last().v, digits: digits));
- }
-*/
- [Fact]
- public void CCI()
- {
- CCI_Series QL = new(bars, period, false);
- Core.Cci(inhigh, inlow, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
- for (int i = QL.Length - 1; i > skip; i--)
- {
- double QL_item = Math.Round(QL[i].v, digits: digits);
- double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
- Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact]
- public void CORR()
- {
- CORR_Series QL = new(bars.Open, bars.Close, period);
- Core.Correl(inopen, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, optInTimePeriod: period);
- for (int i = QL.Length - 1; i > skip; i--)
- {
- double QL_item = Math.Round(QL[i].v, digits: digits);
- double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
- Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact]
- public void DEMA()
- {
- DEMA_Series QL = new(bars.Close, period, false);
- Core.Dema(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
- for (int i = QL.Length - 1; i > skip; i--)
- {
- double QL_item = Math.Round(QL[i].v, digits: digits);
- double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
- Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact]
- public void DIV()
- {
- DIV_Series QL = new(bars.Open, bars.Close);
- Core.Div(inopen, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
- for (int i = QL.Length - 1; i > skip; i--)
- {
- double QL_item = Math.Round(QL[i].v, digits: digits);
- double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
- Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact]
- public void EMA()
- {
- EMA_Series QL = new(bars.Close, period, false);
- Core.Ema(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
- for (int i = QL.Length - 1; i > skip; i--)
- {
- double QL_item = Math.Round(QL[i].v, digits: digits);
- double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
- Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact]
- public void HL2()
- {
- TSeries QL = bars.HL2;
- Core.MedPrice(inhigh, inlow, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
- for (int i = QL.Length - 1; i > skip; i--)
- {
- double QL_item = Math.Round(QL[i].v, digits: digits);
- double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
- Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact]
- public void HLC3()
- {
- TSeries QL = bars.HLC3;
- Core.TypPrice(inhigh, inlow, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
- for (int i = QL.Length - 1; i > skip; i--)
- {
- double QL_item = Math.Round(QL[i].v, digits: digits);
- double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
- Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact]
- public void HLCC4()
- {
- TSeries QL = bars.HLCC4;
- Core.WclPrice(inhigh, inlow, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
- for (int i = QL.Length - 1; i > skip; i--)
- {
- double QL_item = Math.Round(QL[i].v, digits: digits);
- double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
- Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact]
- public void MACD()
- {
- double[] macdSignal = new double[bars.Count];
- double[] macdHist = new double[bars.Count];
- MACD_Series QL = new(bars.Close, slow: 26, fast: 12, signal: 9, false);
- Core.Macd(inclose, 0, bars.Count - 1, outMacd: TALIB, outMacdSignal: macdSignal, outMacdHist: macdHist, out int outBegIdx, out _);
- for (int i = QL.Length - 1; i > skip * 10; i--)
- {
- double QL_item = Math.Round(QL[i].v, digits: digits);
- double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
- Assert.Equal(TA_item!, QL_item);
- QL_item = Math.Round(QL.Signal[i].v, digits: digits);
- TA_item = Math.Round(macdSignal[i - outBegIdx], digits: digits);
- Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact]
- public void MAMA()
- {
- MAMA_Series QL = new(bars.Close, fastlimit: 0.5, slowlimit: 0.05);
- Core.Mama(inReal: inclose, startIdx: 0, endIdx: bars.Count - 1, outMama: TALIB, outFama: TALIB2, outBegIdx: out int outBegIdx, outNbElement: out _, optInFastLimit: 0.5, optInSlowLimit: 0.05);
- for (int i = QL.Length - 1; i > skip * 15; i--)
- {
- double QL_item = Math.Round(QL[i].v, digits: digits);
- double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
- Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact]
- public void MAX()
- {
- MAX_Series QL = new(bars.Close, period, false);
- Core.Max(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
- for (int i = QL.Length - 1; i > skip; i--)
- {
- double QL_item = Math.Round(QL[i].v, digits: digits);
- double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
- Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact]
- public void MIDPOINT()
- {
- MIDPOINT_Series QL = new(bars.Close, period, false);
- Core.MidPoint(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
- for (int i = QL.Length - 1; i > skip; i--)
- {
- double QL_item = Math.Round(QL[i].v, digits: digits);
- double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
- Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact]
- public void MIDPRICE()
- {
- MIDPRICE_Series QL = new(bars, period, false);
- Core.MidPrice(inhigh, inlow, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
- for (int i = QL.Length - 1; i > skip; i--)
- {
- double QL_item = Math.Round(QL[i].v, digits: digits);
- double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
- Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact]
- public void MIN()
- {
- MIN_Series QL = new(bars.Close, period, false);
- Core.Min(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
- for (int i = QL.Length - 1; i > skip; i--)
- {
- double QL_item = Math.Round(QL[i].v, digits: digits);
- double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
- Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact]
- public void MUL()
- {
- MUL_Series QL = new(bars.Open, bars.Close);
- Core.Mult(inopen, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
- for (int i = QL.Length - 1; i > skip; i--)
- {
- double QL_item = Math.Round(QL[i].v, digits: digits);
- double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
- Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact]
- public void OBV()
- {
- OBV_Series QL = new(bars, period, false);
- Core.Obv(inclose, involume, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
- for (int i = QL.Length - 1; i > skip; i--)
- {
- double QL_item = Math.Round(QL[i].v, digits: digits);
- double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
- Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact]
- public void OHLC4()
- {
- TSeries QL = bars.OHLC4;
- Core.AvgPrice(inopen, inhigh, inlow, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
- for (int i = QL.Length - 1; i > skip; i--)
- {
- double QL_item = Math.Round(QL[i].v, digits: digits);
- double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
- Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact]
- public void RSI()
- {
- RSI_Series QL = new(bars.Close, period, false);
- Core.Rsi(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
- for (int i = QL.Length - 1; i > skip; i--)
- {
- double QL_item = Math.Round(QL[i].v, digits: digits);
- double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
- Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact]
- public void SDEV()
- {
- SDEV_Series QL = new(bars.Close, period, false);
- Core.StdDev(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
- for (int i = QL.Length - 1; i > skip; i--)
- {
- double QL_item = Math.Round(QL[i].v, digits: digits);
- double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
- Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact]
- public void SMA()
- {
- SMA_Series QL = new(bars.Close, period, false);
- Core.Sma(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
- for (int i = QL.Length - 1; i > skip; i--)
- {
- double QL_item = Math.Round(QL[i].v, digits: digits);
- double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
- Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact]
- public void SUB()
- {
- SUB_Series QL = new(bars.Open, bars.Close);
- Core.Sub(inopen, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
- for (int i = QL.Length - 1; i > skip; i--)
- {
- double QL_item = Math.Round(QL[i].v, digits: digits);
- double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
- Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact]
- public void SUM()
- {
- SUM_Series QL = new(bars.Close, period, false);
- Core.Sum(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
- for (int i = QL.Length - 1; i > skip; i--)
- {
- double QL_item = Math.Round(QL[i].v, digits: digits);
- double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
- Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact]
- public void T3()
- {
- T3_Series QL = new(source: bars.Close, period: period, vfactor: 0.7, useNaN: false);
- Core.T3(inReal: inclose, startIdx: 0, endIdx: bars.Count - 1, outReal: TALIB, outBegIdx: out int outBegIdx, outNbElement: out _, optInTimePeriod: period, optInVFactor: 0.7);
- for (int i = QL.Length - 1; i > skip * 15; i--)
- {
- double QL_item = Math.Round(QL[i].v, digits: digits);
- double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
- Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact]
- public void TEMA()
- {
- TEMA_Series QL = new(bars.Close, period, false);
- Core.Tema(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
- for (int i = QL.Length - 1; i > skip * 15; i--)
- {
- double QL_item = Math.Round(QL[i].v, digits: digits);
- double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
- Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact]
- public void TR()
- {
- TR_Series QL = new(bars, false);
- Core.TRange(inhigh, inlow, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
- for (int i = QL.Length - 1; i > skip; i--)
- {
- double QL_item = Math.Round(QL[i].v, digits: digits);
- double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
- Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact]
- public void TRIMA()
- {
- TRIMA_Series QL = new(bars.Close, period, false);
- Core.Trima(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
- for (int i = QL.Length - 1; i > skip; i--)
- {
- double QL_item = Math.Round(QL[i].v, digits: digits);
- double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
- Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact]
- public void VAR()
- {
- VAR_Series QL = new(bars.Close, period, false);
- Core.Var(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
- for (int i = QL.Length - 1; i > skip * 15; i--)
- {
- double QL_item = Math.Round(QL[i].v, digits: digits);
- double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
- Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact]
- public void WMA()
- {
- WMA_Series QL = new(bars.Close, period, false);
- Core.Wma(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
- for (int i = QL.Length - 1; i > skip; i--)
- {
- double QL_item = Math.Round(QL[i].v, digits: digits);
- double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
- Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
-
-}
+using Xunit;
+using System;
+using TALib;
+using QuanTAlib;
+
+namespace Validations;
+public class Ta_Lib
+{
+ private readonly GBM_Feed bars;
+ private readonly Random rnd = new();
+ private readonly int period, digits, skip;
+ private readonly double[] TALIB;
+ private readonly double[] TALIB2;
+ private readonly double[] inopen;
+ private readonly double[] inhigh;
+ private readonly double[] inlow;
+ private readonly double[] inclose;
+ private readonly double[] involume;
+
+ public Ta_Lib()
+ {
+ bars = new(Bars: 5000, Volatility: 0.8, Drift: 0.0, Precision: 3);
+ period = rnd.Next(28) + 3;
+ skip = 500;
+ digits = 10;
+
+ TALIB = new double[bars.Count];
+ TALIB2 = new double[bars.Count];
+ inopen = bars.Open.v.ToArray();
+ inhigh = bars.High.v.ToArray();
+ inlow = bars.Low.v.ToArray();
+ inclose = bars.Close.v.ToArray();
+ involume = bars.Volume.v.ToArray();
+ }
+
+ [Fact]
+ public void ADD()
+ {
+ ADD_Series QL = new(bars.Open, bars.Close);
+ Core.Add(inopen, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
+ for (int i = QL.Length - 1; i > skip; i--)
+ {
+ double QL_item = Math.Round(QL[i].v, digits: digits);
+ double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
+ Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact]
+ public void ADL()
+ {
+ ADL_Series QL = new(bars, false);
+ Core.Ad(inhigh, inlow, inclose, involume, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
+ for (int i = QL.Length - 1; i > 0; i--)
+ {
+ double QL_item = Math.Round(QL[i].v, digits: digits);
+ double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
+ Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact]
+ public void ADOSC()
+ {
+ ADOSC_Series QL = new(bars, 3, 10, false);
+ Core.AdOsc(inhigh, inlow, inclose, involume, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
+ for (int i = QL.Length - 1; i > skip; i--)
+ {
+ double QL_item = Math.Round(QL[i].v, digits: digits);
+ double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
+ Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact]
+ public void ATR()
+ {
+ ATR_Series QL = new(bars, period, false);
+ Core.Atr(inhigh, inlow, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
+ for (int i = QL.Length - 1; i > skip * 15; i--)
+ {
+ double QL_item = Math.Round(QL[i].v, digits: digits);
+ double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
+ Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+/*
+ [Fact]
+ public void BBANDS()
+ {
+ double[] outMiddle = new double[bars.Count];
+ double[] outUpper = new double[bars.Count];
+ double[] outLower = new double[bars.Count];
+ BBANDS_Series QL = new(bars.Close, period: 26, multiplier: 2.0, false);
+ Core.Bbands(inclose, 0, bars.Count - 1, outRealUpperBand: outUpper, outRealMiddleBand: outMiddle, outRealLowerBand: outLower, out int outBegIdx, out _, optInTimePeriod: 26, optInNbDevUp: 2.0, optInNbDevDn: 2.0);
+ for (int i = QL.Length - 1; i > skip; i--)
+ {
+ double QL_item = Math.Round(QL.Upper[i].v, digits: digits);
+ double TA_item = Math.Round(outUpper[i - outBegIdx], digits: digits);
+ Assert.Equal(TA_item!, QL_item);
+ QL_item = Math.Round(QL.Mid[i].v, digits: digits);
+ TA_item = Math.Round(outMiddle[i - outBegIdx], digits: digits);
+ Assert.Equal(TA_item!, QL_item);
+ QL_item = Math.Round(QL.Lower[i].v, digits: digits);
+ TA_item = Math.Round(outLower[i - outBegIdx], digits: digits);
+ Assert.Equal(TA_item!, QL_item);
+ }
+ Assert.Equal(Math.Round(outUpper[outUpper.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Upper.Last().v, digits: digits));
+ Assert.Equal(Math.Round(outMiddle[outMiddle.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Mid.Last().v, digits: digits));
+ Assert.Equal(Math.Round(outLower[outLower.Length - outBegIdx - 1], digits: digits), Math.Round(QL.Lower.Last().v, digits: digits));
+ }
+*/
+ [Fact]
+ public void CCI()
+ {
+ CCI_Series QL = new(bars, period, false);
+ Core.Cci(inhigh, inlow, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
+ for (int i = QL.Length - 1; i > skip; i--)
+ {
+ double QL_item = Math.Round(QL[i].v, digits: digits);
+ double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
+ Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+/*
+ [Fact]
+ public void CMO() {
+ CMO_Series QL = new(bars.Close, period, false);
+ Core.Cmo(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
+ for (int i = QL.Length - 1; i > skip; i--) {
+ double QL_item = Math.Round(QL[i].v, digits: digits);
+ double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
+ Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+*/
+ [Fact]
+ public void CORR()
+ {
+ CORR_Series QL = new(bars.Open, bars.Close, period);
+ Core.Correl(inopen, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, optInTimePeriod: period);
+ for (int i = QL.Length - 1; i > skip; i--)
+ {
+ double QL_item = Math.Round(QL[i].v, digits: digits);
+ double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
+ Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact]
+ public void DEMA()
+ {
+ DEMA_Series QL = new(bars.Close, period, false);
+ Core.Dema(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
+ for (int i = QL.Length - 1; i > skip; i--)
+ {
+ double QL_item = Math.Round(QL[i].v, digits: digits);
+ double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
+ Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact]
+ public void DIV()
+ {
+ DIV_Series QL = new(bars.Open, bars.Close);
+ Core.Div(inopen, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
+ for (int i = QL.Length - 1; i > skip; i--)
+ {
+ double QL_item = Math.Round(QL[i].v, digits: digits);
+ double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
+ Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact]
+ public void EMA()
+ {
+ EMA_Series QL = new(bars.Close, period, false);
+ Core.Ema(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
+ for (int i = QL.Length - 1; i > skip; i--)
+ {
+ double QL_item = Math.Round(QL[i].v, digits: digits);
+ double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
+ Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact]
+ public void HL2()
+ {
+ TSeries QL = bars.HL2;
+ Core.MedPrice(inhigh, inlow, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
+ for (int i = QL.Length - 1; i > skip; i--)
+ {
+ double QL_item = Math.Round(QL[i].v, digits: digits);
+ double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
+ Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact]
+ public void HLC3()
+ {
+ TSeries QL = bars.HLC3;
+ Core.TypPrice(inhigh, inlow, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
+ for (int i = QL.Length - 1; i > skip; i--)
+ {
+ double QL_item = Math.Round(QL[i].v, digits: digits);
+ double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
+ Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact]
+ public void HLCC4()
+ {
+ TSeries QL = bars.HLCC4;
+ Core.WclPrice(inhigh, inlow, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
+ for (int i = QL.Length - 1; i > skip; i--)
+ {
+ double QL_item = Math.Round(QL[i].v, digits: digits);
+ double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
+ Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact]
+ public void MACD()
+ {
+ double[] macdSignal = new double[bars.Count];
+ double[] macdHist = new double[bars.Count];
+ MACD_Series QL = new(bars.Close, slow: 26, fast: 12, signal: 9, false);
+ Core.Macd(inclose, 0, bars.Count - 1, outMacd: TALIB, outMacdSignal: macdSignal, outMacdHist: macdHist, out int outBegIdx, out _);
+ for (int i = QL.Length - 1; i > skip * 10; i--)
+ {
+ double QL_item = Math.Round(QL[i].v, digits: digits);
+ double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
+ Assert.Equal(TA_item!, QL_item);
+ QL_item = Math.Round(QL.Signal[i].v, digits: digits);
+ TA_item = Math.Round(macdSignal[i - outBegIdx], digits: digits);
+ Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact]
+ public void MAMA()
+ {
+ MAMA_Series QL = new(bars.Close, fastlimit: 0.5, slowlimit: 0.05);
+ Core.Mama(inReal: inclose, startIdx: 0, endIdx: bars.Count - 1, outMama: TALIB, outFama: TALIB2, outBegIdx: out int outBegIdx, outNbElement: out _, optInFastLimit: 0.5, optInSlowLimit: 0.05);
+ for (int i = QL.Length - 1; i > skip * 15; i--)
+ {
+ double QL_item = Math.Round(QL[i].v, digits: digits);
+ double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
+ Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact]
+ public void MAX()
+ {
+ MAX_Series QL = new(bars.Close, period, false);
+ Core.Max(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
+ for (int i = QL.Length - 1; i > skip; i--)
+ {
+ double QL_item = Math.Round(QL[i].v, digits: digits);
+ double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
+ Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact]
+ public void MIDPOINT()
+ {
+ MIDPOINT_Series QL = new(bars.Close, period, false);
+ Core.MidPoint(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
+ for (int i = QL.Length - 1; i > skip; i--)
+ {
+ double QL_item = Math.Round(QL[i].v, digits: digits);
+ double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
+ Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact]
+ public void MIDPRICE()
+ {
+ MIDPRICE_Series QL = new(bars, period, false);
+ Core.MidPrice(inhigh, inlow, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
+ for (int i = QL.Length - 1; i > skip; i--)
+ {
+ double QL_item = Math.Round(QL[i].v, digits: digits);
+ double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
+ Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact]
+ public void MIN()
+ {
+ MIN_Series QL = new(bars.Close, period, false);
+ Core.Min(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
+ for (int i = QL.Length - 1; i > skip; i--)
+ {
+ double QL_item = Math.Round(QL[i].v, digits: digits);
+ double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
+ Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact]
+ public void MUL()
+ {
+ MUL_Series QL = new(bars.Open, bars.Close);
+ Core.Mult(inopen, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
+ for (int i = QL.Length - 1; i > skip; i--)
+ {
+ double QL_item = Math.Round(QL[i].v, digits: digits);
+ double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
+ Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact]
+ public void OBV()
+ {
+ OBV_Series QL = new(bars, period, false);
+ Core.Obv(inclose, involume, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
+ for (int i = QL.Length - 1; i > skip; i--)
+ {
+ double QL_item = Math.Round(QL[i].v, digits: digits);
+ double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
+ Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact]
+ public void OHLC4()
+ {
+ TSeries QL = bars.OHLC4;
+ Core.AvgPrice(inopen, inhigh, inlow, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
+ for (int i = QL.Length - 1; i > skip; i--)
+ {
+ double QL_item = Math.Round(QL[i].v, digits: digits);
+ double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
+ Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact]
+ public void RSI()
+ {
+ RSI_Series QL = new(bars.Close, period, false);
+ Core.Rsi(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
+ for (int i = QL.Length - 1; i > skip; i--)
+ {
+ double QL_item = Math.Round(QL[i].v, digits: digits);
+ double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
+ Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact]
+ public void SDEV()
+ {
+ SDEV_Series QL = new(bars.Close, period, false);
+ Core.StdDev(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
+ for (int i = QL.Length - 1; i > skip; i--)
+ {
+ double QL_item = Math.Round(QL[i].v, digits: digits);
+ double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
+ Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact]
+ public void SMA()
+ {
+ SMA_Series QL = new(bars.Close, period, false);
+ Core.Sma(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
+ for (int i = QL.Length - 1; i > skip; i--)
+ {
+ double QL_item = Math.Round(QL[i].v, digits: digits);
+ double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
+ Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact]
+ public void SUB()
+ {
+ SUB_Series QL = new(bars.Open, bars.Close);
+ Core.Sub(inopen, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
+ for (int i = QL.Length - 1; i > skip; i--)
+ {
+ double QL_item = Math.Round(QL[i].v, digits: digits);
+ double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
+ Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact]
+ public void SUM()
+ {
+ SUM_Series QL = new(bars.Close, period, false);
+ Core.Sum(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
+ for (int i = QL.Length - 1; i > skip; i--)
+ {
+ double QL_item = Math.Round(QL[i].v, digits: digits);
+ double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
+ Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact]
+ public void T3()
+ {
+ T3_Series QL = new(source: bars.Close, period: period, vfactor: 0.7, useNaN: false);
+ Core.T3(inReal: inclose, startIdx: 0, endIdx: bars.Count - 1, outReal: TALIB, outBegIdx: out int outBegIdx, outNbElement: out _, optInTimePeriod: period, optInVFactor: 0.7);
+ for (int i = QL.Length - 1; i > skip; i--)
+ {
+ double QL_item = Math.Round(QL[i].v, digits: digits);
+ double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
+ Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact]
+ public void TEMA()
+ {
+ TEMA_Series QL = new(bars.Close, period, false);
+ Core.Tema(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
+ for (int i = QL.Length - 1; i > skip * 15; i--)
+ {
+ double QL_item = Math.Round(QL[i].v, digits: digits);
+ double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
+ Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact]
+ public void TR()
+ {
+ TR_Series QL = new(bars, false);
+ Core.TRange(inhigh, inlow, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
+ for (int i = QL.Length - 1; i > skip; i--)
+ {
+ double QL_item = Math.Round(QL[i].v, digits: digits);
+ double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
+ Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact]
+ public void TRIMA()
+ {
+ TRIMA_Series QL = new(bars.Close, period, false);
+ Core.Trima(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
+ for (int i = QL.Length - 1; i > skip; i--)
+ {
+ double QL_item = Math.Round(QL[i].v, digits: digits);
+ double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
+ Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact]
+ public void TRIX() {
+ TRIX_Series QL = new(bars.Close, period, useNaN: false, useSMA: true);
+ Core.Trix(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
+ for (int i = QL.Length - 1; i > skip; i--) {
+ double QL_item = Math.Round(QL[i].v, digits: digits);
+ double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
+ Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact]
+ public void VAR()
+ {
+ VAR_Series QL = new(bars.Close, period, false);
+ Core.Var(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
+ for (int i = QL.Length - 1; i > skip * 15; i--)
+ {
+ double QL_item = Math.Round(QL[i].v, digits: digits);
+ double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
+ Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact]
+ public void WMA()
+ {
+ WMA_Series QL = new(bars.Close, period, false);
+ Core.Wma(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
+ for (int i = QL.Length - 1; i > skip; i--)
+ {
+ double QL_item = Math.Round(QL[i].v, digits: digits);
+ double TA_item = Math.Round(TALIB[i - outBegIdx], digits: digits);
+ Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+
+}
diff --git a/Tests/Validations/Trends/Tulip.cs b/Tests/Validations/Trends/Tulip.cs
index b7ddcc32..3157f81f 100644
--- a/Tests/Validations/Trends/Tulip.cs
+++ b/Tests/Validations/Trends/Tulip.cs
@@ -1,158 +1,194 @@
-using Xunit;
-using System;
-using Tulip;
-using QuanTAlib;
-
-namespace Validations;
-public class Tulip_Test
-{
- private readonly GBM_Feed bars;
- private readonly Random rnd = new();
- private readonly int period, digits, skip;
- private readonly double[] outdata;
- private readonly double[] inopen;
- private readonly double[] inhigh;
- private readonly double[] inlow;
- private readonly double[] inclose;
- private readonly double[] involume;
-
- public Tulip_Test()
- {
- bars = new(Bars: 5000, Volatility: 0.8, Drift: 0.0, Precision: 3);
- period = rnd.Next(28) + 3;
- skip = 200;
- digits = 10;
-
- outdata = new double[bars.Count];
- inopen = bars.Open.v.ToArray();
- inhigh = bars.High.v.ToArray();
- inlow = bars.Low.v.ToArray();
- inclose = bars.Close.v.ToArray()!;
- involume = bars.Volume.v.ToArray()!;
-
- }
- [Fact]
- public void AD()
- {
- double[][] arrin = {inhigh, inlow, inclose, involume };
- double[][] arrout = { outdata };
- ADL_Series QL = new(bars, false);
- Tulip.Indicators.ad.Run(inputs: arrin, options: new double[] { }, outputs: arrout);
- for (int i = QL.Length - 1; i > skip; i--)
- {
- double QL_item = Math.Round(QL[i].v, digits: digits);
- double TU_item = Math.Round(arrout[0][i], digits);
- Assert.InRange(TU_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact]
- public void ADD()
- {
- double[][] arrin = { inhigh, inlow };
- double[][] arrout = { outdata };
- ADD_Series QL = new(bars.High, bars.Low);
- Tulip.Indicators.add.Run(inputs: arrin, options: new double[] { period }, outputs: arrout);
- for (int i = QL.Length - 1; i > skip; i--)
- {
- double QL_item = Math.Round(QL[i].v, digits: digits);
- double TU_item = Math.Round(arrout[0][i], digits);
- Assert.InRange(TU_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact]
- public void ADOSC()
- {
- double[][] arrin = { inhigh, inlow, inclose, involume };
- double[][] arrout = { outdata };
- int s = 3;
- ADOSC_Series QL = new(bars, s, period, false);
- Tulip.Indicators.adosc.Run(inputs: arrin, options: new double[] { s, period }, outputs: arrout);
- for (int i = QL.Length - 1; i > skip; i--)
- {
- double QL_item = Math.Round(QL[i].v, digits: digits);
- double TU_item = Math.Round(arrout[0][i-period+1], digits);
- Assert.InRange(TU_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact]
- public void ATR()
- {
- double[][] arrin = { inhigh, inlow, inclose };
- double[][] arrout = { outdata };
-
- ATR_Series QL = new(bars, period, false);
- Tulip.Indicators.atr.Run(inputs: arrin, options: new double[] { period }, outputs: arrout);
- for (int i = QL.Length - 1; i > skip; i--)
- {
- double QL_item = Math.Round(QL[i].v, digits: digits);
- double TU_item = Math.Round(arrout[0][i - period + 1], digits);
- Assert.InRange(TU_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact]
- public void BBANDS()
- {
- double[][] arrin = { inclose };
- double[] outmid = new double[bars.Count];
- double[] outlower = new double[bars.Count];
- double[] outupper = new double[bars.Count];
- double[][] arrout = { outlower, outmid, outupper};
- BBANDS_Series QL = new(bars.Close, period, 2, false);
- Tulip.Indicators.bbands.Run(inputs: arrin, options: new double[] { period, 2 }, outputs: arrout);
- for (int i = QL.Length - 1; i > skip; i--)
- {
- double QL_item = Math.Round(QL.Lower[i].v, digits: digits);
- double TU_item = Math.Round(outlower[i - period + 1], digits);
- Assert.InRange(TU_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- QL_item = Math.Round(QL.Mid[i].v, digits: digits);
- TU_item = Math.Round(outmid[i - period + 1], digits);
- Assert.InRange(TU_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- QL_item = Math.Round(QL.Upper[i].v, digits: digits);
- TU_item = Math.Round(outupper[i - period + 1], digits);
- Assert.InRange(TU_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact]
- public void EMA()
- {
- double[][] arrin = { inclose };
- double[][] arrout = { outdata };
- EMA_Series QL = new(bars.Close, period, false);
- Tulip.Indicators.ema.Run(inputs: arrin, options: new double[] { period }, outputs: arrout);
- for (int i = QL.Length - 1; i > skip; i--)
- {
- double QL_item = Math.Round(QL[i].v, digits: digits);
- double TU_item = Math.Round(arrout[0][i], digits);
- Assert.InRange(TU_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact]
- public void AVGPRICE()
- {
- double[][] arrin = { inopen, inhigh, inlow, inclose };
- double[][] arrout = { outdata };
-
- TSeries QL = bars.OHLC4;
- Tulip.Indicators.avgprice.Run(inputs: arrin, options: new double[] { }, outputs: arrout);
- for (int i = QL.Length - 1; i > skip; i--)
- {
- double QL_item = Math.Round(QL[i].v, digits: digits);
- double TU_item = Math.Round(arrout[0][i], digits);
- Assert.InRange(TU_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
- [Fact]
- public void SMA()
- {
- double[][] arrin = { inclose };
- double[][] arrout = { outdata };
- SMA_Series QL = new(bars.Close, period, false);
- Tulip.Indicators.sma.Run(inputs: arrin, options: new double[] { period }, outputs: arrout);
- for (int i = QL.Length - 1; i > skip; i--)
- {
- double QL_item = Math.Round(QL[i].v, digits: digits);
- double TU_item = Math.Round(arrout[0][i-period+1], digits);
- Assert.InRange(TU_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
- }
- }
-}
+using Xunit;
+using System;
+using Tulip;
+using QuanTAlib;
+
+namespace Validations;
+public class Tulip_Test
+{
+ private readonly GBM_Feed bars;
+ private readonly Random rnd = new();
+ private readonly int period, digits, skip;
+ private readonly double[] outdata;
+ private readonly double[] inopen;
+ private readonly double[] inhigh;
+ private readonly double[] inlow;
+ private readonly double[] inclose;
+ private readonly double[] involume;
+
+ public Tulip_Test()
+ {
+ bars = new(Bars: 5000, Volatility: 0.8, Drift: 0.0, Precision: 3);
+ period = rnd.Next(28) + 3;
+ skip = 200;
+ digits = 10;
+
+ outdata = new double[bars.Count];
+ inopen = bars.Open.v.ToArray();
+ inhigh = bars.High.v.ToArray();
+ inlow = bars.Low.v.ToArray();
+ inclose = bars.Close.v.ToArray()!;
+ involume = bars.Volume.v.ToArray()!;
+
+ }
+ [Fact]
+ public void ADL()
+ {
+ double[][] arrin = {inhigh, inlow, inclose, involume };
+ double[][] arrout = { outdata };
+ ADL_Series QL = new(bars, false);
+ Tulip.Indicators.ad.Run(inputs: arrin, options: new double[] { }, outputs: arrout);
+ for (int i = QL.Length - 1; i > skip; i--)
+ {
+ double QL_item = Math.Round(QL[i].v, digits: digits);
+ double TU_item = Math.Round(arrout[0][i], digits);
+ Assert.InRange(TU_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact]
+ public void ADD()
+ {
+ double[][] arrin = { inhigh, inlow };
+ double[][] arrout = { outdata };
+ ADD_Series QL = new(bars.High, bars.Low);
+ Tulip.Indicators.add.Run(inputs: arrin, options: new double[] { period }, outputs: arrout);
+ for (int i = QL.Length - 1; i > skip; i--)
+ {
+ double QL_item = Math.Round(QL[i].v, digits: digits);
+ double TU_item = Math.Round(arrout[0][i], digits);
+ Assert.InRange(TU_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact]
+ public void ADOSC()
+ {
+ double[][] arrin = { inhigh, inlow, inclose, involume };
+ double[][] arrout = { outdata };
+ int s = 3;
+ ADOSC_Series QL = new(bars, s, period, false);
+ Tulip.Indicators.adosc.Run(inputs: arrin, options: new double[] { s, period }, outputs: arrout);
+ for (int i = QL.Length - 1; i > skip; i--)
+ {
+ double QL_item = Math.Round(QL[i].v, digits: digits);
+ double TU_item = Math.Round(arrout[0][i-period+1], digits);
+ Assert.InRange(TU_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact]
+ public void ATR()
+ {
+ double[][] arrin = { inhigh, inlow, inclose };
+ double[][] arrout = { outdata };
+
+ ATR_Series QL = new(bars, period, false);
+ Tulip.Indicators.atr.Run(inputs: arrin, options: new double[] { period }, outputs: arrout);
+ for (int i = QL.Length - 1; i > skip; i--)
+ {
+ double QL_item = Math.Round(QL[i].v, digits: digits);
+ double TU_item = Math.Round(arrout[0][i - period + 1], digits);
+ Assert.InRange(TU_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact]
+ public void BBANDS()
+ {
+ double[][] arrin = { inclose };
+ double[] outmid = new double[bars.Count];
+ double[] outlower = new double[bars.Count];
+ double[] outupper = new double[bars.Count];
+ double[][] arrout = { outlower, outmid, outupper};
+ BBANDS_Series QL = new(bars.Close, period, 2, false);
+ Tulip.Indicators.bbands.Run(inputs: arrin, options: new double[] { period, 2 }, outputs: arrout);
+ for (int i = QL.Length - 1; i > skip; i--)
+ {
+ double QL_item = Math.Round(QL.Lower[i].v, digits: digits);
+ double TU_item = Math.Round(outlower[i - period + 1], digits);
+ Assert.InRange(TU_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ QL_item = Math.Round(QL.Mid[i].v, digits: digits);
+ TU_item = Math.Round(outmid[i - period + 1], digits);
+ Assert.InRange(TU_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ QL_item = Math.Round(QL.Upper[i].v, digits: digits);
+ TU_item = Math.Round(outupper[i - period + 1], digits);
+ Assert.InRange(TU_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact]
+ public void DEMA() {
+ double[][] arrin = { inclose };
+ double[][] arrout = { outdata };
+ DEMA_Series QL = new(bars.Close, period, useNaN: false, useSMA: false);
+ Tulip.Indicators.dema.Run(inputs: arrin, options: new double[] { period }, outputs: arrout);
+ for (int i = QL.Length - 1; i > skip; i--) {
+ double QL_item = Math.Round(QL[i].v, digits: digits);
+ double TU_item = Math.Round(arrout[0][i-(period+period-2)], digits);
+ Assert.InRange(TU_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact]
+ public void EMA()
+ {
+ double[][] arrin = { inclose };
+ double[][] arrout = { outdata };
+ EMA_Series QL = new(bars.Close, period, false);
+ Tulip.Indicators.ema.Run(inputs: arrin, options: new double[] { period }, outputs: arrout);
+ for (int i = QL.Length - 1; i > skip; i--)
+ {
+ double QL_item = Math.Round(QL[i].v, digits: digits);
+ double TU_item = Math.Round(arrout[0][i], digits);
+ Assert.InRange(TU_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact]
+ public void AVGPRICE()
+ {
+ double[][] arrin = { inopen, inhigh, inlow, inclose };
+ double[][] arrout = { outdata };
+
+ TSeries QL = bars.OHLC4;
+ Tulip.Indicators.avgprice.Run(inputs: arrin, options: new double[] { }, outputs: arrout);
+ for (int i = QL.Length - 1; i > skip; i--)
+ {
+ double QL_item = Math.Round(QL[i].v, digits: digits);
+ double TU_item = Math.Round(arrout[0][i], digits);
+ Assert.InRange(TU_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact]
+ public void SMA()
+ {
+ double[][] arrin = { inclose };
+ double[][] arrout = { outdata };
+ SMA_Series QL = new(bars.Close, period, false);
+ Tulip.Indicators.sma.Run(inputs: arrin, options: new double[] { period }, outputs: arrout);
+ for (int i = QL.Length - 1; i > skip; i--)
+ {
+ double QL_item = Math.Round(QL[i].v, digits: digits);
+ double TU_item = Math.Round(arrout[0][i-period+1], digits);
+ Assert.InRange(TU_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact]
+ public void HMA() {
+ double[][] arrin = { inclose };
+ double[][] arrout = { outdata };
+ HMA_Series QL = new(bars.Close, period, false);
+ Tulip.Indicators.hma.Run(inputs: arrin, options: new double[] { period }, outputs: arrout);
+ for (int i = QL.Length - 1; i > skip; i--) {
+ double QL_item = Math.Round(QL[i].v, digits: digits);
+ double TU_item = Math.Round(arrout[0][i-period-1], digits);
+ Assert.InRange(TU_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+ [Fact]
+ public void CMO() {
+ double[][] arrin = { inclose };
+ double[][] arrout = { outdata };
+ CMO_Series QL = new(bars.Close, period, useNaN: false);
+ Tulip.Indicators.cmo.Run(inputs: arrin, options: new double[] { period }, outputs: arrout);
+ for (int i = QL.Length - 1; i > skip; i--) {
+ double QL_item = Math.Round(QL[i].v, digits: digits);
+ double TU_item = Math.Round(arrout[0][i-period], digits);
+ Assert.InRange(TU_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
+ }
+ }
+}
diff --git a/docs/EMA.md b/docs/EMA.md
index ac161421..e372995e 100644
--- a/docs/EMA.md
+++ b/docs/EMA.md
@@ -1,38 +1,38 @@
-# EMA: Exponential Moving Average
-
-EMA needs very short history buffer and calculates the EMA value using just the previous EMA value. The weight of the new datapoint (k) is k = 2 / (period-1)
-
-## Calculation
-
-There is an adopted practice to calculate $SMA$ when $n < period$.
-
-$$
-EMA_n = \left\{ \begin{array}{cl}
-\frac{1}{p}\left( data_{n}-data_{n-p}\right)+SMA_{n-1} & : \ n \leq period \\
-{k}\times ({data_{n}} - EMA_{n-1}) + EMA_{n-1} & : \ x > period
-\end{array} \right.
-$$
-
-
-## Implementation
-
-``` csharp
-EMA_Series mean = new(source: data, period: p, useNaN: false);
-```
-
-- `TSeries source` - List of value tuples (DateTime, double)
-- `int period` - Integer representing the period of SMA
-- `bool useNaN` - if true, initial values from 1 to period-1 will be replaced with NaN. If false, the initial calculation will return values for SMA(length) instead of SMA(period)
-
-## Comparison & Validation
-
-Validation tests
-Performance tests
-
-## Visual analysis
-
-
-
-
-
-## References
+# EMA: Exponential Moving Average
+
+EMA needs very short history buffer and calculates the EMA value using just the previous EMA value. The weight of the new datapoint (k) is k = 2 / (period-1)
+
+## Calculation
+
+There is an adopted practice to calculate $SMA$ when $n < period$.
+
+$$
+EMA_n = \left\{ \begin{array}{cl}
+\frac{1}{p}\left( data_{n}-data_{n-p}\right)+SMA_{n-1} & : \ n \leq period \\
+{k}\times ({data_{n}} - EMA_{n-1}) + EMA_{n-1} & : \ x > period
+\end{array} \right.
+$$
+
+
+## Implementation
+
+``` csharp
+EMA_Series mean = new(source: data, period: p, useNaN: false);
+```
+
+- `TSeries source` - List of value tuples (DateTime, double)
+- `int period` - Integer representing the period of SMA
+- `bool useNaN` - if true, initial values from 1 to period-1 will be replaced with NaN. If false, the initial calculation will return values for SMA(length) instead of SMA(period)
+
+## Comparison & Validation
+
+Validation tests
+Performance tests
+
+## Visual analysis
+
+
+
+
+
+## References
diff --git a/docs/SMA.md b/docs/SMA.md
index 557852bd..409e4c3e 100644
--- a/docs/SMA.md
+++ b/docs/SMA.md
@@ -1,39 +1,39 @@
-
-# SMA: Simple Moving Average
-SMA is one of the most basic trend-following indicators used in Technical Analysis. It is calculated as the *unweighted mean* of the previous $p$ (period) data-points.
-
-
-## Calculation
-
-SMA is a rolling calculation looking backwards from the position ${n}$ and is denoted as ${SMA}_{p}{(data)}$ where $p$ represents the period and $data$ represents the list of data points:
-$$
-SMA_p{(data)} = \frac{1}{p}\sum_{i=n-p+1}^{n} data_i
-$$
-When calculating the value of next $SMA_{p,next}$ while knowing all previous SMA values, SMA calculation can be reduced to:
-$$
-SMA_{p,next} = SMA_{p,prev}+\frac{1}{p}\left( data_{n+1}-data_{n+1-p}\right)
-$$
-
-## Implementation
-
-``` csharp
-SMA_Series mean = new(source: data, period: p, useNaN: false);
-```
-
-- `TSeries source` - List of value tuples (DateTime, double)
-- `int period` - Integer representing the period of SMA
-- `bool useNaN` - if true, initial values from 1 to period-1 will be replaced with NaN. If false, the initial calculation will return values for SMA(length) instead of SMA(period)
-
-## Comparison & Validation
-
-Validation tests
-Performance tests
-
-## Visual analysis
-
-
-
-
-
-## References
+
+# SMA: Simple Moving Average
+SMA is one of the most basic trend-following indicators used in Technical Analysis. It is calculated as the *unweighted mean* of the previous $p$ (period) data-points.
+
+
+## Calculation
+
+SMA is a rolling calculation looking backwards from the position ${n}$ and is denoted as ${SMA}_{p}{(data)}$ where $p$ represents the period and $data$ represents the list of data points:
+$$
+SMA_p{(data)} = \frac{1}{p}\sum_{i=n-p+1}^{n} data_i
+$$
+When calculating the value of next $SMA_{p,next}$ while knowing all previous SMA values, SMA calculation can be reduced to:
+$$
+SMA_{p,next} = SMA_{p,prev}+\frac{1}{p}\left( data_{n+1}-data_{n+1-p}\right)
+$$
+
+## Implementation
+
+``` csharp
+SMA_Series mean = new(source: data, period: p, useNaN: false);
+```
+
+- `TSeries source` - List of value tuples (DateTime, double)
+- `int period` - Integer representing the period of SMA
+- `bool useNaN` - if true, initial values from 1 to period-1 will be replaced with NaN. If false, the initial calculation will return values for SMA(length) instead of SMA(period)
+
+## Comparison & Validation
+
+Validation tests
+Performance tests
+
+## Visual analysis
+
+
+
+
+
+## References
- https://www.tradingtechnologies.com/help/x-study/technical-indicator-definitions/simple-moving-average-sma/
\ No newline at end of file
diff --git a/docs/_sidebar.md b/docs/_sidebar.md
index a61da47f..1b76dc91 100644
--- a/docs/_sidebar.md
+++ b/docs/_sidebar.md
@@ -1,13 +1,13 @@
-* [Home](/)
-
-* [Indicators](indicators.md "Indocators coverage")
-
- * [SMA - Simple Moving Average](SMA.md "SMA - Simple Moving Average")
- * [WMA - Weighted Moving Average](WMA.md "WMA - Weighted Moving Average")
- * [EMA - Exponential Moving Average](EMA.md "EMA - Exponential Moving Average")
- * [DEMA - Double Exponential Moving Average](DEMA.md "DEMA - Double Exponential Moving Average")
- * [TEMA - Triple Exponential Moving Average](TEMA.md "TEMA - Triple Exponential Moving Average")
- * [HMA - Hull Moving Average](HMA.md "HMA - Hull Moving Average")
- * [ZLEMA - Zero-Lag Exponential Moving Average](ZLEMA.md "ZLEMA - Zero-Lag Exponential Moving Average")
- * [KAMA - Kaufman Adaptive Moving Average](KAMA.md "KAMA - Kaufman Adaptive Moving Average")
+* [Home](/)
+
+* [Indicators](indicators.md "Indocators coverage")
+
+ * [SMA - Simple Moving Average](SMA.md "SMA - Simple Moving Average")
+ * [WMA - Weighted Moving Average](WMA.md "WMA - Weighted Moving Average")
+ * [EMA - Exponential Moving Average](EMA.md "EMA - Exponential Moving Average")
+ * [DEMA - Double Exponential Moving Average](DEMA.md "DEMA - Double Exponential Moving Average")
+ * [TEMA - Triple Exponential Moving Average](TEMA.md "TEMA - Triple Exponential Moving Average")
+ * [HMA - Hull Moving Average](HMA.md "HMA - Hull Moving Average")
+ * [ZLEMA - Zero-Lag Exponential Moving Average](ZLEMA.md "ZLEMA - Zero-Lag Exponential Moving Average")
+ * [KAMA - Kaufman Adaptive Moving Average](KAMA.md "KAMA - Kaufman Adaptive Moving Average")
* [MAMA - Mesa Adaptive Moving Average](MAMA.md "MAMA - Mesa Adaptive Moving Average")
\ No newline at end of file
diff --git a/docs/getting_started.ipynb b/docs/getting_started.ipynb
index bf8c469c..f8700ccb 100644
--- a/docs/getting_started.ipynb
+++ b/docs/getting_started.ipynb
@@ -1,272 +1,272 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {
- "dotnet_interactive": {
- "language": "csharp"
- },
- "polyglot_notebook": {
- "kernelName": "csharp"
- }
- },
- "source": [
- "# Quick Start\n",
- "\n",
- "In order to use this .NET Interactive Notebook and play along with QuanTAlib (outside of making your own app or plugging QuanTAlib into Quantower platform), you will need:\n",
- "\n",
- "- Installed Visual Studio Code\n",
- "- Installed .NET 6 SDK\n",
- "- Installed .NET Interactive Notebooks extension\n",
- "\n",
- "**For impatient**, here is a simple example of calculating three moving averages - SMA(data), EMA(SMA(data)) and WMA(EMA(SMA(data))) from 10 days of AAPL stock data using QuanTAlib:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "dotnet_interactive": {
- "language": "csharp"
- },
- "vscode": {
- "languageId": "polyglot-notebook"
- }
- },
- "outputs": [],
- "source": [
- "#r \"nuget:QuanTAlib;\"\n",
- "using QuanTAlib;\n",
- "\n",
- "Yahoo_Feed aapl = new(\"AAPL\", 10);\n",
- "TSeries data = aapl.Close;\n",
- "SMA_Series sma = new(source: data, period: 5, useNaN: false);\n",
- "EMA_Series ema = new(sma, period: 5); // by default, indicators expose all data, no NaN values\n",
- "WMA_Series wma = new(ema, 5, useNaN: true); // for the final calculation we can hide early data with NaNs\n",
- "\n",
- "Console.Write($\"index\\t data\\t\\t sma(data)\\t ema(sma(data))\\t wma(ema(sma(data)))\\n\");\n",
- "for (int i=0; iVisual Studio Code\n",
+ "- Installed .NET 6 SDK\n",
+ "- Installed .NET Interactive Notebooks extension\n",
+ "\n",
+ "**For impatient**, here is a simple example of calculating three moving averages - SMA(data), EMA(SMA(data)) and WMA(EMA(SMA(data))) from 10 days of AAPL stock data using QuanTAlib:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "dotnet_interactive": {
+ "language": "csharp"
+ },
+ "vscode": {
+ "languageId": "polyglot-notebook"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "#r \"nuget:QuanTAlib;\"\n",
+ "using QuanTAlib;\n",
+ "\n",
+ "Yahoo_Feed aapl = new(\"AAPL\", 10);\n",
+ "TSeries data = aapl.Close;\n",
+ "SMA_Series sma = new(source: data, period: 5, useNaN: false);\n",
+ "EMA_Series ema = new(sma, period: 5); // by default, indicators expose all data, no NaN values\n",
+ "WMA_Series wma = new(ema, 5, useNaN: true); // for the final calculation we can hide early data with NaNs\n",
+ "\n",
+ "Console.Write($\"index\\t data\\t\\t sma(data)\\t ema(sma(data))\\t wma(ema(sma(data)))\\n\");\n",
+ "for (int i=0; i"
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- },
- {
- "data": {
- "text/plain": [
- "Loading extensions from `C:\\Users\\miha\\.nuget\\packages\\plotly.net.interactive\\3.0.2\\interactive-extensions\\dotnet\\Plotly.NET.Interactive.dll`"
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- }
- ],
- "source": [
- "//#r \"nuget: QuanTAlib;\"\n",
- "\n",
- "#r \"nuget: Plotly.NET;\"\n",
- "#r \"nuget: Plotly.NET.Interactive;\"\n",
- "#r \"nuget: Plotly.NET.ImageExport;\"\n",
- "#r \"..\\..\\Source\\bin\\Debug\\net6.0\\QuanTAlib.dll\"\n",
- "\n",
- "using QuanTAlib;\n",
- "using Plotly.NET;\n",
- "using Plotly.NET.LayoutObjects;\n",
- "using Plotly.NET.ImageExport;"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "metadata": {
- "dotnet_interactive": {
- "language": "csharp"
- },
- "polyglot_notebook": {
- "kernelName": "csharp"
- }
- },
- "outputs": [],
- "source": [
- "TSeries d1a = new() {0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};\n",
- "TSeries d2a = new() {0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};\n",
- "TSeries d3a = new() {0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};\n",
- "TSeries d4a = new() {0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2};\n",
- "TSeries d5a = new() {0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0.32,0.56,0.72,0.84,0.93,0.99,1,0.97,0.91,0.81,0.68,0.52,0.33,0.14,-0.06,-0.26,-0.44,-0.61,-0.76,-0.87,-0.95,-0.99,-1,-0.96,-0.88,-0.77,-0.63,-0.46,-0.28,-0.08,0.12,0.31,0.49,0.66,0.79,0.9,0.97,1,0.99,0.94,0.85,0.73,0.58,0.41,0.22,0.02,-0.17,-0.37,-0.54,-0.7,-0.83,-0.92,-0.98,-1,-0.98,-0.92,-0.82,-0.69,-0.54,-0.36,-0.17,0.03,0.23,0.42,0.59,0.74};\n",
- "TSeries d6a = new() {0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,1};\n",
- "TSeries d7a = new() {0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0.93,0.27,-0.59,-1,-0.71,0.05,0.75,1,0.67,0,-0.67,-0.99,-0.85,-0.34,0.31,0.81,1,0.82,0.35,-0.22,-0.71,-0.98,-0.95,-0.66,-0.2,0.31,0.72,0.96,0.98,0.78,0.43,-0.01,-0.43,-0.77,-0.96,-0.99,-0.85,-0.58,-0.23,0.16,0.51,0.79,0.95,1,0.92,0.73,0.47,0.15,-0.17,-0.47,-0.72,-0.9,-0.99,-0.99,-0.9,-0.74,-0.52,-0.26,0.01,0.28,0.53,0.73,0.88,0.97,1,0.97};\n",
- "TSeries d8a = new() {-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,0.03,-0.4,-0.47,0.19,-0.4,-0.23,0.31,0.41,0.19,0.16,-0.5,-0.31,-0.21,0.25,0.18,-0.48,-0.1,0.38,0.29,-0.38,-0.08,-0.21,0.34,0.01,-0.46,0.28,-0.48,0.11,0.02,-0.37,0.19,-0.2,0.1,0.24,0.08,-0.22,-0.12,0.15,0.36,-0.43,-0.03,-0.32,0.45,-0.5,-0.04,-0.04,-0.08,-0.18,0.13,-0.33,-0.19,0.36,-0.39,0.2,-0.31,0.28,-0.13,-0.07,-0.29,0.37,0.03,-0.25,-0.06,-0.3,-0.08,-0.09};\n",
- "TSeries d9a = new() {-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,0,0.03,0.11,-0.1,-0.43,-0.08,0.36,-0.04,-0.04,-0.21,-0.3,0.26,0.2,0.28,0.2,0.27,-0.01,-0.1,-0.23,-0.13,-0.41,-0.23,-0.07,-0.21,0.32,-0.18,-0.48,0.3,0.46,-0.2,0.52,-0.81,-0.25,-0.21,-0.12,-0.18,0.18,0.52,0.29,0.44,0.18,-1.2,0.38,0.24,0.06,0.28,0.34,0.3,-0.13,0.19,-0.5,0.59,-0.36,0.22,-0.23,0.24,0.39,0.13,-0.33,-0.57,-0.23,0.49,-0.13,0.76,0.59,0.61};\n",
- "TSeries d10a = new() {-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0,-0.28,0.41,-0.54,0.65,-0.75,0.84,-0.91,0.96,-0.99,1,-0.99,0.96,-0.92,0.85,-0.77,0.67,-0.56,0.44,-0.3,0.17,-0.03,-0.11,0.25,-0.39,0.51,-0.63,0.73,-0.82,0.89,-0.95,0.98,-1,0.99,-0.97,0.93,-0.86,0.78,-0.69,0.58,-0.46,0.33,-0.19,0.05,0.09,-0.23,0.36,-0.49,0.61,-0.71,0.81,-0.88,0.94,-0.98,1,-1,0.98,-0.94,0.88,-0.8,0.71,-0.6,0.48,-0.35,0.22,-0.08,-0.06};\n",
- "TSeries d11a = new() {-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,0,0.14,-0.76,-0.96,-0.28,0.66,0.99,0.41,-0.54,-1,-0.54,0.42,0.99,0.65,-0.29,-0.96,-0.75,0.15,0.91,0.84,-0.01,-0.85,-0.91,-0.13,0.76,0.96,0.27,-0.66,-0.99,-0.4,0.55,1,0.53,-0.43,-0.99,-0.64,0.3,0.96,0.75,-0.16,-0.92,-0.83,0.02,0.85,0.9,0.12,-0.77,-0.95,-0.26,0.67,0.99,0.4,-0.56,-1,-0.52,0.44,0.99,0.64,-0.3,-0.97,-0.74,0.17,0.92,0.83,-0.03,-0.86};\n",
- "TSeries d12a = new() {-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0,0,0.05,-0.25,-0.32,-0.09,0.22,0.33,0.14,-0.18,-0.33,-0.18,0.14,0.33,0.22,-0.1,-0.32,-0.25,0.05,0.3,0.28,0,-0.28,-0.3,-0.04,0.25,0.32,0.09,-0.22,-0.33,-0.13,0.18,0.33,0.18,0.86,0.67,0.79,1.1,1.32,1.25,0.95,0.69,0.72,1.01,1.28,1.3,1.04,0.74,0.68,0.91,1.22,1.33,1.13,0.81,0.67,0.83,1.15,1.33,1.21,0.9,0.68,0.75,1.06,1.31,1.28,0.99,0.71};\n",
- "TSeries d13a = new() {-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0,0,2.7,-0.8,-0.8,3.6,9.3,11.95,10.05,6.3,5,8.3,14.1,17.95,17.25,13.55,11.2,13.25,18.75,23.55,24.2,20.95,17.75,18.45,23.35,28.8,30.8,28.35,24.7,24.05,28,33.75,37,35.65,31.85,28.05,-3.2,1.5,4.8,3.75,-0.8,-4.6,-4.15,0.1,4.25,4.5,0.6,-3.85,-4.75,-1.3,3.35,4.95,2,-2.8,-5,-2.6,2.2,4.95,3.2,-1.5,-4.85,-3.7,0.85,4.6,4.15,-0.15,-4.3};\n",
- "TSeries d14a = new() {-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0,0,0.59,0.83,0.74,0.5,0.91,1.36,0.93,0.87,0.6,0.38,0.78,0.53,0.42,0.14,0.01,-0.45,-0.71,-0.99,-1,-1.36,-1.22,-1.07,-1.17,-0.56,-0.95,-1.11,-0.16,0.18,-0.28,0.64,-0.5,0.24,0.45,0.67,0.72,1.15,1.52,1.28,1.38,1.03,-0.47,0.96,0.65,0.28,0.3,0.17,-0.07,-0.67,-0.51,-1.33,-0.33,-1.34,-0.78,-1.21,-0.68,-0.43,-0.56,-0.87,-0.93,-0.4,0.52,0.1,1.18,1.18,1.35};\n",
- "TSeries d15a = new() {0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,1.3,0.3,-0.48,-1.1,-1.14,-0.03,1.11,0.96,0.63,-0.21,-0.97,-0.73,-0.65,-0.06,0.51,1.08,0.99,0.72,0.12,-0.35,-1.12,-1.21,-1.02,-0.87,0.12,0.13,0.24,1.26,1.44,0.58,0.95,-0.82,-0.68,-0.98,-1.08,-1.17,-0.67,-0.06,0.06,0.6,0.69,-0.41,1.33,1.24,0.98,1.01,0.81,0.45,-0.3,-0.28,-1.22,-0.31,-1.35,-0.77,-1.13,-0.5,-0.13,-0.13,-0.32,-0.29,0.3,1.22,0.75,1.73,1.59,1.58};\n",
- "TSeries d16a = new() {175.6,175.1,175.6,175.1,175.6,175.1,175.6,175.1,175.6,175.1,175.6,175.1,175.6,175.1,175.6,175.6,175.1,175.6,175.1,175.6,175.1,175.6,175.1,175.6,175.1,175.6,175.1,175.6,175.1,175.6,175.44,176.27,176.04,176.99,175.49,175.68,174.34,176.4,174.05,174.4,174.2,176.16,175,177.72,174.33,176.96,174.62,174.76,170.9,171.12,171.05,170.01,169.24,172.64,171.96,175.72,174.16,175.81,177.3,178.38,176.75,177.19,175.55,178.49,176.52,178.45,178.04,178.25,177.8,176.97,172.94,174.92,173.98,172.29,171.19,172.54,172.11,175.32,175.63,176.65,173.8,176.04,172.74,175.24,171.84,171.54,172.17,171.85,172.38,170.78,173.49,173.69,171.71,174.38,173.99,174.83};"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "metadata": {
- "dotnet_interactive": {
- "language": "csharp"
- },
- "polyglot_notebook": {
- "kernelName": "csharp"
- }
- },
- "outputs": [],
- "source": [
- "int period = 10;\n",
- "int cut = 26;\n",
- "\n",
- "EMA_Series d1b = new(d1a, period);\n",
- "EMA_Series d2b = new(d2a, period);\n",
- "EMA_Series d3b = new(d3a, period);\n",
- "EMA_Series d4b = new(d4a, period);\n",
- "EMA_Series d5b = new(d5a, period);\n",
- "EMA_Series d6b = new(d6a, period);\n",
- "EMA_Series d7b = new(d7a, period);\n",
- "EMA_Series d8b = new(d8a, period);\n",
- "EMA_Series d9b = new(d9a, period);\n",
- "EMA_Series d10b = new(d10a, period);\n",
- "EMA_Series d11b = new(d11a, period);\n",
- "EMA_Series d12b = new(d12a, period);\n",
- "EMA_Series d13b = new(d13a, period);\n",
- "EMA_Series d14b = new(d14a, period);\n",
- "EMA_Series d15b = new(d15a, period);\n",
- "EMA_Series d16b = new(d16a, period);\n",
- "\n",
- "List x = Enumerable.Range(-cut,96).ToList();\n",
- "GenericChart.GenericChart ch1a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d1a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
- "GenericChart.GenericChart ch1b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d1b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
- "GenericChart.GenericChart ch2a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d2a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
- "GenericChart.GenericChart ch2b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d2b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
- "GenericChart.GenericChart ch3a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d3a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
- "GenericChart.GenericChart ch3b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d3b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
- "GenericChart.GenericChart ch4a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d4a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
- "GenericChart.GenericChart ch4b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d4b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
- "GenericChart.GenericChart ch5a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d5a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
- "GenericChart.GenericChart ch5b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d5b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
- "GenericChart.GenericChart ch6a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d6a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
- "GenericChart.GenericChart ch6b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d6b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
- "GenericChart.GenericChart ch7a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d7a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
- "GenericChart.GenericChart ch7b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d7b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
- "GenericChart.GenericChart ch8a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d8a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
- "GenericChart.GenericChart ch8b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d8b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
- "GenericChart.GenericChart ch9a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d9a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
- "GenericChart.GenericChart ch9b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d9b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
- "GenericChart.GenericChart ch10a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d10a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
- "GenericChart.GenericChart ch10b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d10b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
- "GenericChart.GenericChart ch11a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d11a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
- "GenericChart.GenericChart ch11b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d11b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
- "GenericChart.GenericChart ch12a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d12a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
- "GenericChart.GenericChart ch12b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d12b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
- "GenericChart.GenericChart ch13a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d13a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
- "GenericChart.GenericChart ch13b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d13b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
- "GenericChart.GenericChart ch14a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d14a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
- "GenericChart.GenericChart ch14b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d14b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
- "GenericChart.GenericChart ch15a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d15a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
- "GenericChart.GenericChart ch15b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d15b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
- "GenericChart.GenericChart ch16a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d16a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
- "GenericChart.GenericChart ch16b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d16b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
- "\n",
- "var ch1 = Chart.Combine(new []{ch1a,ch1b});\n",
- "var ch2 = Chart.Combine(new []{ch2a,ch2b});\n",
- "var ch3 = Chart.Combine(new []{ch3a,ch3b});\n",
- "var ch4 = Chart.Combine(new []{ch4a,ch4b});\n",
- "var ch5 = Chart.Combine(new []{ch5a,ch5b});\n",
- "var ch6 = Chart.Combine(new []{ch6a,ch6b});\n",
- "var ch7 = Chart.Combine(new []{ch7a,ch7b});\n",
- "var ch8 = Chart.Combine(new []{ch8a,ch8b});\n",
- "var ch9 = Chart.Combine(new []{ch9a,ch9b});\n",
- "var ch10 = Chart.Combine(new []{ch10a,ch10b});\n",
- "var ch11 = Chart.Combine(new []{ch11a,ch11b});\n",
- "var ch12 = Chart.Combine(new []{ch12a,ch12b});\n",
- "var ch13 = Chart.Combine(new []{ch13a,ch13b});\n",
- "var ch14 = Chart.Combine(new []{ch14a,ch14b});\n",
- "var ch15 = Chart.Combine(new []{ch15a,ch15b});\n",
- "var ch16 = Chart.Combine(new []{ch16a,ch16b});\n",
- "\n",
- "Layout layout = new Layout(); layout.SetValue(\"showlegend\",false);\n",
- "var chart1 = new []{ch1,ch2,ch3,ch4,ch5,ch6,ch7,ch8,ch9,ch10,ch11,ch12,ch13,ch14,ch15,ch16};\n",
- "var full = Chart.Grid>(8,2).Invoke(chart1).WithSize(1000,2200).WithMargin(Margin.init(30,20,20,30,7,false)).WithLayout(layout);\n",
- "full.SaveSVG(\"EMA_chart\", Width: 1000, Height: 2200);"
- ]
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": ".NET (C#)",
- "language": "C#",
- "name": ".net-csharp"
- },
- "polyglot_notebook": {
- "kernelInfo": {
- "defaultKernelName": "csharp",
- "items": [
- {
- "aliases": [
- "c#",
- "C#"
- ],
- "languageName": "C#",
- "name": "csharp"
- },
- {
- "aliases": [],
- "name": ".NET"
- },
- {
- "aliases": [
- "f#",
- "F#"
- ],
- "languageName": "F#",
- "name": "fsharp"
- },
- {
- "aliases": [],
- "languageName": "HTML",
- "name": "html"
- },
- {
- "aliases": [],
- "languageName": "KQL",
- "name": "kql"
- },
- {
- "aliases": [],
- "languageName": "Mermaid",
- "name": "mermaid"
- },
- {
- "aliases": [
- "powershell"
- ],
- "languageName": "PowerShell",
- "name": "pwsh"
- },
- {
- "aliases": [],
- "languageName": "SQL",
- "name": "sql"
- },
- {
- "aliases": [],
- "name": "value"
- },
- {
- "aliases": [
- "frontend"
- ],
- "name": "vscode"
- },
- {
- "aliases": [
- "js"
- ],
- "languageName": "JavaScript",
- "name": "javascript"
- },
- {
- "aliases": [],
- "name": "webview"
- }
- ]
- }
- }
- },
- "nbformat": 4,
- "nbformat_minor": 2
-}
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {
+ "dotnet_interactive": {
+ "language": "csharp"
+ }
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/plain": [
+ "Loading extensions from `C:\\Users\\miha\\.nuget\\packages\\plotly.net.interactive\\3.0.2\\interactive-extensions\\dotnet\\Plotly.NET.Interactive.dll`"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "//#r \"nuget: QuanTAlib;\"\n",
+ "\n",
+ "#r \"nuget: Plotly.NET;\"\n",
+ "#r \"nuget: Plotly.NET.Interactive;\"\n",
+ "#r \"nuget: Plotly.NET.ImageExport;\"\n",
+ "#r \"..\\..\\Source\\bin\\Debug\\net6.0\\QuanTAlib.dll\"\n",
+ "\n",
+ "using QuanTAlib;\n",
+ "using Plotly.NET;\n",
+ "using Plotly.NET.LayoutObjects;\n",
+ "using Plotly.NET.ImageExport;"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {
+ "dotnet_interactive": {
+ "language": "csharp"
+ },
+ "polyglot_notebook": {
+ "kernelName": "csharp"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "TSeries d1a = new() {0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};\n",
+ "TSeries d2a = new() {0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};\n",
+ "TSeries d3a = new() {0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};\n",
+ "TSeries d4a = new() {0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2};\n",
+ "TSeries d5a = new() {0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0.32,0.56,0.72,0.84,0.93,0.99,1,0.97,0.91,0.81,0.68,0.52,0.33,0.14,-0.06,-0.26,-0.44,-0.61,-0.76,-0.87,-0.95,-0.99,-1,-0.96,-0.88,-0.77,-0.63,-0.46,-0.28,-0.08,0.12,0.31,0.49,0.66,0.79,0.9,0.97,1,0.99,0.94,0.85,0.73,0.58,0.41,0.22,0.02,-0.17,-0.37,-0.54,-0.7,-0.83,-0.92,-0.98,-1,-0.98,-0.92,-0.82,-0.69,-0.54,-0.36,-0.17,0.03,0.23,0.42,0.59,0.74};\n",
+ "TSeries d6a = new() {0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,1};\n",
+ "TSeries d7a = new() {0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0.93,0.27,-0.59,-1,-0.71,0.05,0.75,1,0.67,0,-0.67,-0.99,-0.85,-0.34,0.31,0.81,1,0.82,0.35,-0.22,-0.71,-0.98,-0.95,-0.66,-0.2,0.31,0.72,0.96,0.98,0.78,0.43,-0.01,-0.43,-0.77,-0.96,-0.99,-0.85,-0.58,-0.23,0.16,0.51,0.79,0.95,1,0.92,0.73,0.47,0.15,-0.17,-0.47,-0.72,-0.9,-0.99,-0.99,-0.9,-0.74,-0.52,-0.26,0.01,0.28,0.53,0.73,0.88,0.97,1,0.97};\n",
+ "TSeries d8a = new() {-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,0.03,-0.4,-0.47,0.19,-0.4,-0.23,0.31,0.41,0.19,0.16,-0.5,-0.31,-0.21,0.25,0.18,-0.48,-0.1,0.38,0.29,-0.38,-0.08,-0.21,0.34,0.01,-0.46,0.28,-0.48,0.11,0.02,-0.37,0.19,-0.2,0.1,0.24,0.08,-0.22,-0.12,0.15,0.36,-0.43,-0.03,-0.32,0.45,-0.5,-0.04,-0.04,-0.08,-0.18,0.13,-0.33,-0.19,0.36,-0.39,0.2,-0.31,0.28,-0.13,-0.07,-0.29,0.37,0.03,-0.25,-0.06,-0.3,-0.08,-0.09};\n",
+ "TSeries d9a = new() {-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,0,0.03,0.11,-0.1,-0.43,-0.08,0.36,-0.04,-0.04,-0.21,-0.3,0.26,0.2,0.28,0.2,0.27,-0.01,-0.1,-0.23,-0.13,-0.41,-0.23,-0.07,-0.21,0.32,-0.18,-0.48,0.3,0.46,-0.2,0.52,-0.81,-0.25,-0.21,-0.12,-0.18,0.18,0.52,0.29,0.44,0.18,-1.2,0.38,0.24,0.06,0.28,0.34,0.3,-0.13,0.19,-0.5,0.59,-0.36,0.22,-0.23,0.24,0.39,0.13,-0.33,-0.57,-0.23,0.49,-0.13,0.76,0.59,0.61};\n",
+ "TSeries d10a = new() {-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0,-0.28,0.41,-0.54,0.65,-0.75,0.84,-0.91,0.96,-0.99,1,-0.99,0.96,-0.92,0.85,-0.77,0.67,-0.56,0.44,-0.3,0.17,-0.03,-0.11,0.25,-0.39,0.51,-0.63,0.73,-0.82,0.89,-0.95,0.98,-1,0.99,-0.97,0.93,-0.86,0.78,-0.69,0.58,-0.46,0.33,-0.19,0.05,0.09,-0.23,0.36,-0.49,0.61,-0.71,0.81,-0.88,0.94,-0.98,1,-1,0.98,-0.94,0.88,-0.8,0.71,-0.6,0.48,-0.35,0.22,-0.08,-0.06};\n",
+ "TSeries d11a = new() {-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,0,0.14,-0.76,-0.96,-0.28,0.66,0.99,0.41,-0.54,-1,-0.54,0.42,0.99,0.65,-0.29,-0.96,-0.75,0.15,0.91,0.84,-0.01,-0.85,-0.91,-0.13,0.76,0.96,0.27,-0.66,-0.99,-0.4,0.55,1,0.53,-0.43,-0.99,-0.64,0.3,0.96,0.75,-0.16,-0.92,-0.83,0.02,0.85,0.9,0.12,-0.77,-0.95,-0.26,0.67,0.99,0.4,-0.56,-1,-0.52,0.44,0.99,0.64,-0.3,-0.97,-0.74,0.17,0.92,0.83,-0.03,-0.86};\n",
+ "TSeries d12a = new() {-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0,0,0.05,-0.25,-0.32,-0.09,0.22,0.33,0.14,-0.18,-0.33,-0.18,0.14,0.33,0.22,-0.1,-0.32,-0.25,0.05,0.3,0.28,0,-0.28,-0.3,-0.04,0.25,0.32,0.09,-0.22,-0.33,-0.13,0.18,0.33,0.18,0.86,0.67,0.79,1.1,1.32,1.25,0.95,0.69,0.72,1.01,1.28,1.3,1.04,0.74,0.68,0.91,1.22,1.33,1.13,0.81,0.67,0.83,1.15,1.33,1.21,0.9,0.68,0.75,1.06,1.31,1.28,0.99,0.71};\n",
+ "TSeries d13a = new() {-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0,0,2.7,-0.8,-0.8,3.6,9.3,11.95,10.05,6.3,5,8.3,14.1,17.95,17.25,13.55,11.2,13.25,18.75,23.55,24.2,20.95,17.75,18.45,23.35,28.8,30.8,28.35,24.7,24.05,28,33.75,37,35.65,31.85,28.05,-3.2,1.5,4.8,3.75,-0.8,-4.6,-4.15,0.1,4.25,4.5,0.6,-3.85,-4.75,-1.3,3.35,4.95,2,-2.8,-5,-2.6,2.2,4.95,3.2,-1.5,-4.85,-3.7,0.85,4.6,4.15,-0.15,-4.3};\n",
+ "TSeries d14a = new() {-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0,0,0.59,0.83,0.74,0.5,0.91,1.36,0.93,0.87,0.6,0.38,0.78,0.53,0.42,0.14,0.01,-0.45,-0.71,-0.99,-1,-1.36,-1.22,-1.07,-1.17,-0.56,-0.95,-1.11,-0.16,0.18,-0.28,0.64,-0.5,0.24,0.45,0.67,0.72,1.15,1.52,1.28,1.38,1.03,-0.47,0.96,0.65,0.28,0.3,0.17,-0.07,-0.67,-0.51,-1.33,-0.33,-1.34,-0.78,-1.21,-0.68,-0.43,-0.56,-0.87,-0.93,-0.4,0.52,0.1,1.18,1.18,1.35};\n",
+ "TSeries d15a = new() {0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,1.3,0.3,-0.48,-1.1,-1.14,-0.03,1.11,0.96,0.63,-0.21,-0.97,-0.73,-0.65,-0.06,0.51,1.08,0.99,0.72,0.12,-0.35,-1.12,-1.21,-1.02,-0.87,0.12,0.13,0.24,1.26,1.44,0.58,0.95,-0.82,-0.68,-0.98,-1.08,-1.17,-0.67,-0.06,0.06,0.6,0.69,-0.41,1.33,1.24,0.98,1.01,0.81,0.45,-0.3,-0.28,-1.22,-0.31,-1.35,-0.77,-1.13,-0.5,-0.13,-0.13,-0.32,-0.29,0.3,1.22,0.75,1.73,1.59,1.58};\n",
+ "TSeries d16a = new() {175.6,175.1,175.6,175.1,175.6,175.1,175.6,175.1,175.6,175.1,175.6,175.1,175.6,175.1,175.6,175.6,175.1,175.6,175.1,175.6,175.1,175.6,175.1,175.6,175.1,175.6,175.1,175.6,175.1,175.6,175.44,176.27,176.04,176.99,175.49,175.68,174.34,176.4,174.05,174.4,174.2,176.16,175,177.72,174.33,176.96,174.62,174.76,170.9,171.12,171.05,170.01,169.24,172.64,171.96,175.72,174.16,175.81,177.3,178.38,176.75,177.19,175.55,178.49,176.52,178.45,178.04,178.25,177.8,176.97,172.94,174.92,173.98,172.29,171.19,172.54,172.11,175.32,175.63,176.65,173.8,176.04,172.74,175.24,171.84,171.54,172.17,171.85,172.38,170.78,173.49,173.69,171.71,174.38,173.99,174.83};"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {
+ "dotnet_interactive": {
+ "language": "csharp"
+ },
+ "polyglot_notebook": {
+ "kernelName": "csharp"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "int period = 10;\n",
+ "int cut = 26;\n",
+ "\n",
+ "EMA_Series d1b = new(d1a, period);\n",
+ "EMA_Series d2b = new(d2a, period);\n",
+ "EMA_Series d3b = new(d3a, period);\n",
+ "EMA_Series d4b = new(d4a, period);\n",
+ "EMA_Series d5b = new(d5a, period);\n",
+ "EMA_Series d6b = new(d6a, period);\n",
+ "EMA_Series d7b = new(d7a, period);\n",
+ "EMA_Series d8b = new(d8a, period);\n",
+ "EMA_Series d9b = new(d9a, period);\n",
+ "EMA_Series d10b = new(d10a, period);\n",
+ "EMA_Series d11b = new(d11a, period);\n",
+ "EMA_Series d12b = new(d12a, period);\n",
+ "EMA_Series d13b = new(d13a, period);\n",
+ "EMA_Series d14b = new(d14a, period);\n",
+ "EMA_Series d15b = new(d15a, period);\n",
+ "EMA_Series d16b = new(d16a, period);\n",
+ "\n",
+ "List x = Enumerable.Range(-cut,96).ToList();\n",
+ "GenericChart.GenericChart ch1a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d1a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
+ "GenericChart.GenericChart ch1b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d1b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
+ "GenericChart.GenericChart ch2a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d2a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
+ "GenericChart.GenericChart ch2b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d2b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
+ "GenericChart.GenericChart ch3a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d3a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
+ "GenericChart.GenericChart ch3b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d3b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
+ "GenericChart.GenericChart ch4a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d4a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
+ "GenericChart.GenericChart ch4b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d4b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
+ "GenericChart.GenericChart ch5a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d5a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
+ "GenericChart.GenericChart ch5b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d5b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
+ "GenericChart.GenericChart ch6a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d6a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
+ "GenericChart.GenericChart ch6b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d6b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
+ "GenericChart.GenericChart ch7a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d7a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
+ "GenericChart.GenericChart ch7b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d7b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
+ "GenericChart.GenericChart ch8a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d8a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
+ "GenericChart.GenericChart ch8b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d8b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
+ "GenericChart.GenericChart ch9a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d9a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
+ "GenericChart.GenericChart ch9b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d9b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
+ "GenericChart.GenericChart ch10a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d10a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
+ "GenericChart.GenericChart ch10b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d10b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
+ "GenericChart.GenericChart ch11a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d11a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
+ "GenericChart.GenericChart ch11b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d11b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
+ "GenericChart.GenericChart ch12a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d12a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
+ "GenericChart.GenericChart ch12b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d12b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
+ "GenericChart.GenericChart ch13a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d13a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
+ "GenericChart.GenericChart ch13b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d13b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
+ "GenericChart.GenericChart ch14a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d14a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
+ "GenericChart.GenericChart ch14b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d14b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
+ "GenericChart.GenericChart ch15a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d15a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
+ "GenericChart.GenericChart ch15b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d15b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
+ "GenericChart.GenericChart ch16a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d16a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
+ "GenericChart.GenericChart ch16b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d16b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
+ "\n",
+ "var ch1 = Chart.Combine(new []{ch1a,ch1b});\n",
+ "var ch2 = Chart.Combine(new []{ch2a,ch2b});\n",
+ "var ch3 = Chart.Combine(new []{ch3a,ch3b});\n",
+ "var ch4 = Chart.Combine(new []{ch4a,ch4b});\n",
+ "var ch5 = Chart.Combine(new []{ch5a,ch5b});\n",
+ "var ch6 = Chart.Combine(new []{ch6a,ch6b});\n",
+ "var ch7 = Chart.Combine(new []{ch7a,ch7b});\n",
+ "var ch8 = Chart.Combine(new []{ch8a,ch8b});\n",
+ "var ch9 = Chart.Combine(new []{ch9a,ch9b});\n",
+ "var ch10 = Chart.Combine(new []{ch10a,ch10b});\n",
+ "var ch11 = Chart.Combine(new []{ch11a,ch11b});\n",
+ "var ch12 = Chart.Combine(new []{ch12a,ch12b});\n",
+ "var ch13 = Chart.Combine(new []{ch13a,ch13b});\n",
+ "var ch14 = Chart.Combine(new []{ch14a,ch14b});\n",
+ "var ch15 = Chart.Combine(new []{ch15a,ch15b});\n",
+ "var ch16 = Chart.Combine(new []{ch16a,ch16b});\n",
+ "\n",
+ "Layout layout = new Layout(); layout.SetValue(\"showlegend\",false);\n",
+ "var chart1 = new []{ch1,ch2,ch3,ch4,ch5,ch6,ch7,ch8,ch9,ch10,ch11,ch12,ch13,ch14,ch15,ch16};\n",
+ "var full = Chart.Grid>(8,2).Invoke(chart1).WithSize(1000,2200).WithMargin(Margin.init(30,20,20,30,7,false)).WithLayout(layout);\n",
+ "full.SaveSVG(\"EMA_chart\", Width: 1000, Height: 2200);"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": ".NET (C#)",
+ "language": "C#",
+ "name": ".net-csharp"
+ },
+ "polyglot_notebook": {
+ "kernelInfo": {
+ "defaultKernelName": "csharp",
+ "items": [
+ {
+ "aliases": [
+ "c#",
+ "C#"
+ ],
+ "languageName": "C#",
+ "name": "csharp"
+ },
+ {
+ "aliases": [],
+ "name": ".NET"
+ },
+ {
+ "aliases": [
+ "f#",
+ "F#"
+ ],
+ "languageName": "F#",
+ "name": "fsharp"
+ },
+ {
+ "aliases": [],
+ "languageName": "HTML",
+ "name": "html"
+ },
+ {
+ "aliases": [],
+ "languageName": "KQL",
+ "name": "kql"
+ },
+ {
+ "aliases": [],
+ "languageName": "Mermaid",
+ "name": "mermaid"
+ },
+ {
+ "aliases": [
+ "powershell"
+ ],
+ "languageName": "PowerShell",
+ "name": "pwsh"
+ },
+ {
+ "aliases": [],
+ "languageName": "SQL",
+ "name": "sql"
+ },
+ {
+ "aliases": [],
+ "name": "value"
+ },
+ {
+ "aliases": [
+ "frontend"
+ ],
+ "name": "vscode"
+ },
+ {
+ "aliases": [
+ "js"
+ ],
+ "languageName": "JavaScript",
+ "name": "javascript"
+ },
+ {
+ "aliases": [],
+ "name": "webview"
+ }
+ ]
+ }
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/docs/img/SMA_chart.ipynb b/docs/img/SMA_chart.ipynb
index 3f10a68a..5d631e45 100644
--- a/docs/img/SMA_chart.ipynb
+++ b/docs/img/SMA_chart.ipynb
@@ -1,242 +1,242 @@
-{
- "cells": [
- {
- "cell_type": "code",
- "execution_count": 5,
- "metadata": {
- "dotnet_interactive": {
- "language": "csharp"
- }
- },
- "outputs": [
- {
- "data": {
- "text/html": [
- ""
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- }
- ],
- "source": [
- "//#r \"nuget: QuanTAlib;\"\n",
- "\n",
- "#r \"nuget: Plotly.NET;\"\n",
- "#r \"nuget: Plotly.NET.Interactive;\"\n",
- "#r \"nuget: Plotly.NET.ImageExport;\"\n",
- "#r \"..\\..\\Source\\bin\\Debug\\net6.0\\QuanTAlib.dll\"\n",
- "\n",
- "using QuanTAlib;\n",
- "using Plotly.NET;\n",
- "using Plotly.NET.LayoutObjects;\n",
- "using Plotly.NET.ImageExport;"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 6,
- "metadata": {
- "dotnet_interactive": {
- "language": "csharp"
- },
- "polyglot_notebook": {
- "kernelName": "csharp"
- }
- },
- "outputs": [],
- "source": [
- "TSeries d1a = new() {0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};\n",
- "TSeries d2a = new() {0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};\n",
- "TSeries d3a = new() {0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};\n",
- "TSeries d4a = new() {0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2};\n",
- "TSeries d5a = new() {0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0.32,0.56,0.72,0.84,0.93,0.99,1,0.97,0.91,0.81,0.68,0.52,0.33,0.14,-0.06,-0.26,-0.44,-0.61,-0.76,-0.87,-0.95,-0.99,-1,-0.96,-0.88,-0.77,-0.63,-0.46,-0.28,-0.08,0.12,0.31,0.49,0.66,0.79,0.9,0.97,1,0.99,0.94,0.85,0.73,0.58,0.41,0.22,0.02,-0.17,-0.37,-0.54,-0.7,-0.83,-0.92,-0.98,-1,-0.98,-0.92,-0.82,-0.69,-0.54,-0.36,-0.17,0.03,0.23,0.42,0.59,0.74};\n",
- "TSeries d6a = new() {0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,1};\n",
- "TSeries d7a = new() {0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0.93,0.27,-0.59,-1,-0.71,0.05,0.75,1,0.67,0,-0.67,-0.99,-0.85,-0.34,0.31,0.81,1,0.82,0.35,-0.22,-0.71,-0.98,-0.95,-0.66,-0.2,0.31,0.72,0.96,0.98,0.78,0.43,-0.01,-0.43,-0.77,-0.96,-0.99,-0.85,-0.58,-0.23,0.16,0.51,0.79,0.95,1,0.92,0.73,0.47,0.15,-0.17,-0.47,-0.72,-0.9,-0.99,-0.99,-0.9,-0.74,-0.52,-0.26,0.01,0.28,0.53,0.73,0.88,0.97,1,0.97};\n",
- "TSeries d8a = new() {-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,0.03,-0.4,-0.47,0.19,-0.4,-0.23,0.31,0.41,0.19,0.16,-0.5,-0.31,-0.21,0.25,0.18,-0.48,-0.1,0.38,0.29,-0.38,-0.08,-0.21,0.34,0.01,-0.46,0.28,-0.48,0.11,0.02,-0.37,0.19,-0.2,0.1,0.24,0.08,-0.22,-0.12,0.15,0.36,-0.43,-0.03,-0.32,0.45,-0.5,-0.04,-0.04,-0.08,-0.18,0.13,-0.33,-0.19,0.36,-0.39,0.2,-0.31,0.28,-0.13,-0.07,-0.29,0.37,0.03,-0.25,-0.06,-0.3,-0.08,-0.09};\n",
- "TSeries d9a = new() {-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,0,0.03,0.11,-0.1,-0.43,-0.08,0.36,-0.04,-0.04,-0.21,-0.3,0.26,0.2,0.28,0.2,0.27,-0.01,-0.1,-0.23,-0.13,-0.41,-0.23,-0.07,-0.21,0.32,-0.18,-0.48,0.3,0.46,-0.2,0.52,-0.81,-0.25,-0.21,-0.12,-0.18,0.18,0.52,0.29,0.44,0.18,-1.2,0.38,0.24,0.06,0.28,0.34,0.3,-0.13,0.19,-0.5,0.59,-0.36,0.22,-0.23,0.24,0.39,0.13,-0.33,-0.57,-0.23,0.49,-0.13,0.76,0.59,0.61};\n",
- "TSeries d10a = new() {-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0,-0.28,0.41,-0.54,0.65,-0.75,0.84,-0.91,0.96,-0.99,1,-0.99,0.96,-0.92,0.85,-0.77,0.67,-0.56,0.44,-0.3,0.17,-0.03,-0.11,0.25,-0.39,0.51,-0.63,0.73,-0.82,0.89,-0.95,0.98,-1,0.99,-0.97,0.93,-0.86,0.78,-0.69,0.58,-0.46,0.33,-0.19,0.05,0.09,-0.23,0.36,-0.49,0.61,-0.71,0.81,-0.88,0.94,-0.98,1,-1,0.98,-0.94,0.88,-0.8,0.71,-0.6,0.48,-0.35,0.22,-0.08,-0.06};\n",
- "TSeries d11a = new() {-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,0,0.14,-0.76,-0.96,-0.28,0.66,0.99,0.41,-0.54,-1,-0.54,0.42,0.99,0.65,-0.29,-0.96,-0.75,0.15,0.91,0.84,-0.01,-0.85,-0.91,-0.13,0.76,0.96,0.27,-0.66,-0.99,-0.4,0.55,1,0.53,-0.43,-0.99,-0.64,0.3,0.96,0.75,-0.16,-0.92,-0.83,0.02,0.85,0.9,0.12,-0.77,-0.95,-0.26,0.67,0.99,0.4,-0.56,-1,-0.52,0.44,0.99,0.64,-0.3,-0.97,-0.74,0.17,0.92,0.83,-0.03,-0.86};\n",
- "TSeries d12a = new() {-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0,0,0.05,-0.25,-0.32,-0.09,0.22,0.33,0.14,-0.18,-0.33,-0.18,0.14,0.33,0.22,-0.1,-0.32,-0.25,0.05,0.3,0.28,0,-0.28,-0.3,-0.04,0.25,0.32,0.09,-0.22,-0.33,-0.13,0.18,0.33,0.18,0.86,0.67,0.79,1.1,1.32,1.25,0.95,0.69,0.72,1.01,1.28,1.3,1.04,0.74,0.68,0.91,1.22,1.33,1.13,0.81,0.67,0.83,1.15,1.33,1.21,0.9,0.68,0.75,1.06,1.31,1.28,0.99,0.71};\n",
- "TSeries d13a = new() {-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0,0,2.7,-0.8,-0.8,3.6,9.3,11.95,10.05,6.3,5,8.3,14.1,17.95,17.25,13.55,11.2,13.25,18.75,23.55,24.2,20.95,17.75,18.45,23.35,28.8,30.8,28.35,24.7,24.05,28,33.75,37,35.65,31.85,28.05,-3.2,1.5,4.8,3.75,-0.8,-4.6,-4.15,0.1,4.25,4.5,0.6,-3.85,-4.75,-1.3,3.35,4.95,2,-2.8,-5,-2.6,2.2,4.95,3.2,-1.5,-4.85,-3.7,0.85,4.6,4.15,-0.15,-4.3};\n",
- "TSeries d14a = new() {-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0,0,0.59,0.83,0.74,0.5,0.91,1.36,0.93,0.87,0.6,0.38,0.78,0.53,0.42,0.14,0.01,-0.45,-0.71,-0.99,-1,-1.36,-1.22,-1.07,-1.17,-0.56,-0.95,-1.11,-0.16,0.18,-0.28,0.64,-0.5,0.24,0.45,0.67,0.72,1.15,1.52,1.28,1.38,1.03,-0.47,0.96,0.65,0.28,0.3,0.17,-0.07,-0.67,-0.51,-1.33,-0.33,-1.34,-0.78,-1.21,-0.68,-0.43,-0.56,-0.87,-0.93,-0.4,0.52,0.1,1.18,1.18,1.35};\n",
- "TSeries d15a = new() {0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,1.3,0.3,-0.48,-1.1,-1.14,-0.03,1.11,0.96,0.63,-0.21,-0.97,-0.73,-0.65,-0.06,0.51,1.08,0.99,0.72,0.12,-0.35,-1.12,-1.21,-1.02,-0.87,0.12,0.13,0.24,1.26,1.44,0.58,0.95,-0.82,-0.68,-0.98,-1.08,-1.17,-0.67,-0.06,0.06,0.6,0.69,-0.41,1.33,1.24,0.98,1.01,0.81,0.45,-0.3,-0.28,-1.22,-0.31,-1.35,-0.77,-1.13,-0.5,-0.13,-0.13,-0.32,-0.29,0.3,1.22,0.75,1.73,1.59,1.58};\n",
- "TSeries d16a = new() {175.6,175.1,175.6,175.1,175.6,175.1,175.6,175.1,175.6,175.1,175.6,175.1,175.6,175.1,175.6,175.6,175.1,175.6,175.1,175.6,175.1,175.6,175.1,175.6,175.1,175.6,175.1,175.6,175.1,175.6,175.44,176.27,176.04,176.99,175.49,175.68,174.34,176.4,174.05,174.4,174.2,176.16,175,177.72,174.33,176.96,174.62,174.76,170.9,171.12,171.05,170.01,169.24,172.64,171.96,175.72,174.16,175.81,177.3,178.38,176.75,177.19,175.55,178.49,176.52,178.45,178.04,178.25,177.8,176.97,172.94,174.92,173.98,172.29,171.19,172.54,172.11,175.32,175.63,176.65,173.8,176.04,172.74,175.24,171.84,171.54,172.17,171.85,172.38,170.78,173.49,173.69,171.71,174.38,173.99,174.83};"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "dotnet_interactive": {
- "language": "csharp"
- },
- "polyglot_notebook": {
- "kernelName": "csharp"
- }
- },
- "outputs": [],
- "source": [
- "int period = 10;\n",
- "int cut = 26;\n",
- "\n",
- "SMA_Series d1b = new(d1a, period);\n",
- "SMA_Series d2b = new(d2a, period);\n",
- "SMA_Series d3b = new(d3a, period);\n",
- "SMA_Series d4b = new(d4a, period);\n",
- "SMA_Series d5b = new(d5a, period);\n",
- "SMA_Series d6b = new(d6a, period);\n",
- "SMA_Series d7b = new(d7a, period);\n",
- "SMA_Series d8b = new(d8a, period);\n",
- "SMA_Series d9b = new(d9a, period);\n",
- "SMA_Series d10b = new(d10a, period);\n",
- "SMA_Series d11b = new(d11a, period);\n",
- "SMA_Series d12b = new(d12a, period);\n",
- "SMA_Series d13b = new(d13a, period);\n",
- "SMA_Series d14b = new(d14a, period);\n",
- "SMA_Series d15b = new(d15a, period);\n",
- "SMA_Series d16b = new(d16a, period);\n",
- "\n",
- "List x = Enumerable.Range(-cut,96).ToList();\n",
- "GenericChart.GenericChart ch1a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d1a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
- "GenericChart.GenericChart ch1b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d1b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
- "GenericChart.GenericChart ch2a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d2a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
- "GenericChart.GenericChart ch2b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d2b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
- "GenericChart.GenericChart ch3a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d3a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
- "GenericChart.GenericChart ch3b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d3b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
- "GenericChart.GenericChart ch4a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d4a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
- "GenericChart.GenericChart ch4b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d4b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
- "GenericChart.GenericChart ch5a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d5a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
- "GenericChart.GenericChart ch5b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d5b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
- "GenericChart.GenericChart ch6a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d6a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
- "GenericChart.GenericChart ch6b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d6b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
- "GenericChart.GenericChart ch7a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d7a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
- "GenericChart.GenericChart ch7b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d7b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
- "GenericChart.GenericChart ch8a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d8a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
- "GenericChart.GenericChart ch8b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d8b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
- "GenericChart.GenericChart ch9a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d9a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
- "GenericChart.GenericChart ch9b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d9b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
- "GenericChart.GenericChart ch10a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d10a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
- "GenericChart.GenericChart ch10b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d10b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
- "GenericChart.GenericChart ch11a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d11a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
- "GenericChart.GenericChart ch11b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d11b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
- "GenericChart.GenericChart ch12a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d12a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
- "GenericChart.GenericChart ch12b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d12b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
- "GenericChart.GenericChart ch13a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d13a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
- "GenericChart.GenericChart ch13b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d13b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
- "GenericChart.GenericChart ch14a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d14a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
- "GenericChart.GenericChart ch14b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d14b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
- "GenericChart.GenericChart ch15a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d15a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
- "GenericChart.GenericChart ch15b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d15b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
- "GenericChart.GenericChart ch16a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d16a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
- "GenericChart.GenericChart ch16b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d16b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
- "\n",
- "var ch1 = Chart.Combine(new []{ch1a,ch1b});\n",
- "var ch2 = Chart.Combine(new []{ch2a,ch2b});\n",
- "var ch3 = Chart.Combine(new []{ch3a,ch3b});\n",
- "var ch4 = Chart.Combine(new []{ch4a,ch4b});\n",
- "var ch5 = Chart.Combine(new []{ch5a,ch5b});\n",
- "var ch6 = Chart.Combine(new []{ch6a,ch6b});\n",
- "var ch7 = Chart.Combine(new []{ch7a,ch7b});\n",
- "var ch8 = Chart.Combine(new []{ch8a,ch8b});\n",
- "var ch9 = Chart.Combine(new []{ch9a,ch9b});\n",
- "var ch10 = Chart.Combine(new []{ch10a,ch10b});\n",
- "var ch11 = Chart.Combine(new []{ch11a,ch11b});\n",
- "var ch12 = Chart.Combine(new []{ch12a,ch12b});\n",
- "var ch13 = Chart.Combine(new []{ch13a,ch13b});\n",
- "var ch14 = Chart.Combine(new []{ch14a,ch14b});\n",
- "var ch15 = Chart.Combine(new []{ch15a,ch15b});\n",
- "var ch16 = Chart.Combine(new []{ch16a,ch16b});\n",
- "\n",
- "Layout layout = new Layout(); layout.SetValue(\"showlegend\",false);\n",
- "var chart1 = new []{ch1,ch2,ch3,ch4,ch5,ch6,ch7,ch8,ch9,ch10,ch11,ch12,ch13,ch14,ch15,ch16};\n",
- "var full = Chart.Grid>(8,2).Invoke(chart1).WithSize(1000,2200).WithMargin(Margin.init(30,20,20,30,7,false)).WithLayout(layout);\n",
- "full.SaveSVG(\"SMA_chart\", Width: 1000, Height: 2200);"
- ]
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": ".NET (C#)",
- "language": "C#",
- "name": ".net-csharp"
- },
- "polyglot_notebook": {
- "kernelInfo": {
- "defaultKernelName": "csharp",
- "items": [
- {
- "aliases": [
- "c#",
- "C#"
- ],
- "languageName": "C#",
- "name": "csharp"
- },
- {
- "aliases": [],
- "name": ".NET"
- },
- {
- "aliases": [
- "f#",
- "F#"
- ],
- "languageName": "F#",
- "name": "fsharp"
- },
- {
- "aliases": [],
- "languageName": "HTML",
- "name": "html"
- },
- {
- "aliases": [],
- "languageName": "KQL",
- "name": "kql"
- },
- {
- "aliases": [],
- "languageName": "Mermaid",
- "name": "mermaid"
- },
- {
- "aliases": [
- "powershell"
- ],
- "languageName": "PowerShell",
- "name": "pwsh"
- },
- {
- "aliases": [],
- "languageName": "SQL",
- "name": "sql"
- },
- {
- "aliases": [],
- "name": "value"
- },
- {
- "aliases": [
- "frontend"
- ],
- "name": "vscode"
- },
- {
- "aliases": [
- "js"
- ],
- "languageName": "JavaScript",
- "name": "javascript"
- },
- {
- "aliases": [],
- "name": "webview"
- }
- ]
- }
- }
- },
- "nbformat": 4,
- "nbformat_minor": 2
-}
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {
+ "dotnet_interactive": {
+ "language": "csharp"
+ }
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "//#r \"nuget: QuanTAlib;\"\n",
+ "\n",
+ "#r \"nuget: Plotly.NET;\"\n",
+ "#r \"nuget: Plotly.NET.Interactive;\"\n",
+ "#r \"nuget: Plotly.NET.ImageExport;\"\n",
+ "#r \"..\\..\\Source\\bin\\Debug\\net6.0\\QuanTAlib.dll\"\n",
+ "\n",
+ "using QuanTAlib;\n",
+ "using Plotly.NET;\n",
+ "using Plotly.NET.LayoutObjects;\n",
+ "using Plotly.NET.ImageExport;"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {
+ "dotnet_interactive": {
+ "language": "csharp"
+ },
+ "polyglot_notebook": {
+ "kernelName": "csharp"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "TSeries d1a = new() {0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};\n",
+ "TSeries d2a = new() {0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};\n",
+ "TSeries d3a = new() {0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};\n",
+ "TSeries d4a = new() {0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2};\n",
+ "TSeries d5a = new() {0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0.32,0.56,0.72,0.84,0.93,0.99,1,0.97,0.91,0.81,0.68,0.52,0.33,0.14,-0.06,-0.26,-0.44,-0.61,-0.76,-0.87,-0.95,-0.99,-1,-0.96,-0.88,-0.77,-0.63,-0.46,-0.28,-0.08,0.12,0.31,0.49,0.66,0.79,0.9,0.97,1,0.99,0.94,0.85,0.73,0.58,0.41,0.22,0.02,-0.17,-0.37,-0.54,-0.7,-0.83,-0.92,-0.98,-1,-0.98,-0.92,-0.82,-0.69,-0.54,-0.36,-0.17,0.03,0.23,0.42,0.59,0.74};\n",
+ "TSeries d6a = new() {0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,1};\n",
+ "TSeries d7a = new() {0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0.93,0.27,-0.59,-1,-0.71,0.05,0.75,1,0.67,0,-0.67,-0.99,-0.85,-0.34,0.31,0.81,1,0.82,0.35,-0.22,-0.71,-0.98,-0.95,-0.66,-0.2,0.31,0.72,0.96,0.98,0.78,0.43,-0.01,-0.43,-0.77,-0.96,-0.99,-0.85,-0.58,-0.23,0.16,0.51,0.79,0.95,1,0.92,0.73,0.47,0.15,-0.17,-0.47,-0.72,-0.9,-0.99,-0.99,-0.9,-0.74,-0.52,-0.26,0.01,0.28,0.53,0.73,0.88,0.97,1,0.97};\n",
+ "TSeries d8a = new() {-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,0.03,-0.4,-0.47,0.19,-0.4,-0.23,0.31,0.41,0.19,0.16,-0.5,-0.31,-0.21,0.25,0.18,-0.48,-0.1,0.38,0.29,-0.38,-0.08,-0.21,0.34,0.01,-0.46,0.28,-0.48,0.11,0.02,-0.37,0.19,-0.2,0.1,0.24,0.08,-0.22,-0.12,0.15,0.36,-0.43,-0.03,-0.32,0.45,-0.5,-0.04,-0.04,-0.08,-0.18,0.13,-0.33,-0.19,0.36,-0.39,0.2,-0.31,0.28,-0.13,-0.07,-0.29,0.37,0.03,-0.25,-0.06,-0.3,-0.08,-0.09};\n",
+ "TSeries d9a = new() {-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,0,0.03,0.11,-0.1,-0.43,-0.08,0.36,-0.04,-0.04,-0.21,-0.3,0.26,0.2,0.28,0.2,0.27,-0.01,-0.1,-0.23,-0.13,-0.41,-0.23,-0.07,-0.21,0.32,-0.18,-0.48,0.3,0.46,-0.2,0.52,-0.81,-0.25,-0.21,-0.12,-0.18,0.18,0.52,0.29,0.44,0.18,-1.2,0.38,0.24,0.06,0.28,0.34,0.3,-0.13,0.19,-0.5,0.59,-0.36,0.22,-0.23,0.24,0.39,0.13,-0.33,-0.57,-0.23,0.49,-0.13,0.76,0.59,0.61};\n",
+ "TSeries d10a = new() {-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0,-0.28,0.41,-0.54,0.65,-0.75,0.84,-0.91,0.96,-0.99,1,-0.99,0.96,-0.92,0.85,-0.77,0.67,-0.56,0.44,-0.3,0.17,-0.03,-0.11,0.25,-0.39,0.51,-0.63,0.73,-0.82,0.89,-0.95,0.98,-1,0.99,-0.97,0.93,-0.86,0.78,-0.69,0.58,-0.46,0.33,-0.19,0.05,0.09,-0.23,0.36,-0.49,0.61,-0.71,0.81,-0.88,0.94,-0.98,1,-1,0.98,-0.94,0.88,-0.8,0.71,-0.6,0.48,-0.35,0.22,-0.08,-0.06};\n",
+ "TSeries d11a = new() {-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,0,0.14,-0.76,-0.96,-0.28,0.66,0.99,0.41,-0.54,-1,-0.54,0.42,0.99,0.65,-0.29,-0.96,-0.75,0.15,0.91,0.84,-0.01,-0.85,-0.91,-0.13,0.76,0.96,0.27,-0.66,-0.99,-0.4,0.55,1,0.53,-0.43,-0.99,-0.64,0.3,0.96,0.75,-0.16,-0.92,-0.83,0.02,0.85,0.9,0.12,-0.77,-0.95,-0.26,0.67,0.99,0.4,-0.56,-1,-0.52,0.44,0.99,0.64,-0.3,-0.97,-0.74,0.17,0.92,0.83,-0.03,-0.86};\n",
+ "TSeries d12a = new() {-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0,0,0.05,-0.25,-0.32,-0.09,0.22,0.33,0.14,-0.18,-0.33,-0.18,0.14,0.33,0.22,-0.1,-0.32,-0.25,0.05,0.3,0.28,0,-0.28,-0.3,-0.04,0.25,0.32,0.09,-0.22,-0.33,-0.13,0.18,0.33,0.18,0.86,0.67,0.79,1.1,1.32,1.25,0.95,0.69,0.72,1.01,1.28,1.3,1.04,0.74,0.68,0.91,1.22,1.33,1.13,0.81,0.67,0.83,1.15,1.33,1.21,0.9,0.68,0.75,1.06,1.31,1.28,0.99,0.71};\n",
+ "TSeries d13a = new() {-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0,0,2.7,-0.8,-0.8,3.6,9.3,11.95,10.05,6.3,5,8.3,14.1,17.95,17.25,13.55,11.2,13.25,18.75,23.55,24.2,20.95,17.75,18.45,23.35,28.8,30.8,28.35,24.7,24.05,28,33.75,37,35.65,31.85,28.05,-3.2,1.5,4.8,3.75,-0.8,-4.6,-4.15,0.1,4.25,4.5,0.6,-3.85,-4.75,-1.3,3.35,4.95,2,-2.8,-5,-2.6,2.2,4.95,3.2,-1.5,-4.85,-3.7,0.85,4.6,4.15,-0.15,-4.3};\n",
+ "TSeries d14a = new() {-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0,0,0.59,0.83,0.74,0.5,0.91,1.36,0.93,0.87,0.6,0.38,0.78,0.53,0.42,0.14,0.01,-0.45,-0.71,-0.99,-1,-1.36,-1.22,-1.07,-1.17,-0.56,-0.95,-1.11,-0.16,0.18,-0.28,0.64,-0.5,0.24,0.45,0.67,0.72,1.15,1.52,1.28,1.38,1.03,-0.47,0.96,0.65,0.28,0.3,0.17,-0.07,-0.67,-0.51,-1.33,-0.33,-1.34,-0.78,-1.21,-0.68,-0.43,-0.56,-0.87,-0.93,-0.4,0.52,0.1,1.18,1.18,1.35};\n",
+ "TSeries d15a = new() {0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,1.3,0.3,-0.48,-1.1,-1.14,-0.03,1.11,0.96,0.63,-0.21,-0.97,-0.73,-0.65,-0.06,0.51,1.08,0.99,0.72,0.12,-0.35,-1.12,-1.21,-1.02,-0.87,0.12,0.13,0.24,1.26,1.44,0.58,0.95,-0.82,-0.68,-0.98,-1.08,-1.17,-0.67,-0.06,0.06,0.6,0.69,-0.41,1.33,1.24,0.98,1.01,0.81,0.45,-0.3,-0.28,-1.22,-0.31,-1.35,-0.77,-1.13,-0.5,-0.13,-0.13,-0.32,-0.29,0.3,1.22,0.75,1.73,1.59,1.58};\n",
+ "TSeries d16a = new() {175.6,175.1,175.6,175.1,175.6,175.1,175.6,175.1,175.6,175.1,175.6,175.1,175.6,175.1,175.6,175.6,175.1,175.6,175.1,175.6,175.1,175.6,175.1,175.6,175.1,175.6,175.1,175.6,175.1,175.6,175.44,176.27,176.04,176.99,175.49,175.68,174.34,176.4,174.05,174.4,174.2,176.16,175,177.72,174.33,176.96,174.62,174.76,170.9,171.12,171.05,170.01,169.24,172.64,171.96,175.72,174.16,175.81,177.3,178.38,176.75,177.19,175.55,178.49,176.52,178.45,178.04,178.25,177.8,176.97,172.94,174.92,173.98,172.29,171.19,172.54,172.11,175.32,175.63,176.65,173.8,176.04,172.74,175.24,171.84,171.54,172.17,171.85,172.38,170.78,173.49,173.69,171.71,174.38,173.99,174.83};"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "dotnet_interactive": {
+ "language": "csharp"
+ },
+ "polyglot_notebook": {
+ "kernelName": "csharp"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "int period = 10;\n",
+ "int cut = 26;\n",
+ "\n",
+ "SMA_Series d1b = new(d1a, period);\n",
+ "SMA_Series d2b = new(d2a, period);\n",
+ "SMA_Series d3b = new(d3a, period);\n",
+ "SMA_Series d4b = new(d4a, period);\n",
+ "SMA_Series d5b = new(d5a, period);\n",
+ "SMA_Series d6b = new(d6a, period);\n",
+ "SMA_Series d7b = new(d7a, period);\n",
+ "SMA_Series d8b = new(d8a, period);\n",
+ "SMA_Series d9b = new(d9a, period);\n",
+ "SMA_Series d10b = new(d10a, period);\n",
+ "SMA_Series d11b = new(d11a, period);\n",
+ "SMA_Series d12b = new(d12a, period);\n",
+ "SMA_Series d13b = new(d13a, period);\n",
+ "SMA_Series d14b = new(d14a, period);\n",
+ "SMA_Series d15b = new(d15a, period);\n",
+ "SMA_Series d16b = new(d16a, period);\n",
+ "\n",
+ "List x = Enumerable.Range(-cut,96).ToList();\n",
+ "GenericChart.GenericChart ch1a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d1a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
+ "GenericChart.GenericChart ch1b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d1b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
+ "GenericChart.GenericChart ch2a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d2a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
+ "GenericChart.GenericChart ch2b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d2b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
+ "GenericChart.GenericChart ch3a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d3a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
+ "GenericChart.GenericChart ch3b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d3b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
+ "GenericChart.GenericChart ch4a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d4a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
+ "GenericChart.GenericChart ch4b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d4b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
+ "GenericChart.GenericChart ch5a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d5a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
+ "GenericChart.GenericChart ch5b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d5b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
+ "GenericChart.GenericChart ch6a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d6a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
+ "GenericChart.GenericChart ch6b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d6b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
+ "GenericChart.GenericChart ch7a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d7a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
+ "GenericChart.GenericChart ch7b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d7b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
+ "GenericChart.GenericChart ch8a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d8a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
+ "GenericChart.GenericChart ch8b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d8b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
+ "GenericChart.GenericChart ch9a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d9a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
+ "GenericChart.GenericChart ch9b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d9b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
+ "GenericChart.GenericChart ch10a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d10a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
+ "GenericChart.GenericChart ch10b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d10b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
+ "GenericChart.GenericChart ch11a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d11a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
+ "GenericChart.GenericChart ch11b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d11b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
+ "GenericChart.GenericChart ch12a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d12a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
+ "GenericChart.GenericChart ch12b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d12b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
+ "GenericChart.GenericChart ch13a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d13a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
+ "GenericChart.GenericChart ch13b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d13b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
+ "GenericChart.GenericChart ch14a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d14a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
+ "GenericChart.GenericChart ch14b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d14b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
+ "GenericChart.GenericChart ch15a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d15a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
+ "GenericChart.GenericChart ch15b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d15b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
+ "GenericChart.GenericChart ch16a = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d16a.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 1.0, Color: Color.fromString(\"blue\"));\n",
+ "GenericChart.GenericChart ch16b = Chart2D.Chart.Line(x.GetRange(cut,96-cut),d16b.v.GetRange(cut,96-cut),false,\"\").WithLineStyle(Width: 2.5, Color: Color.fromString(\"red\"));\n",
+ "\n",
+ "var ch1 = Chart.Combine(new []{ch1a,ch1b});\n",
+ "var ch2 = Chart.Combine(new []{ch2a,ch2b});\n",
+ "var ch3 = Chart.Combine(new []{ch3a,ch3b});\n",
+ "var ch4 = Chart.Combine(new []{ch4a,ch4b});\n",
+ "var ch5 = Chart.Combine(new []{ch5a,ch5b});\n",
+ "var ch6 = Chart.Combine(new []{ch6a,ch6b});\n",
+ "var ch7 = Chart.Combine(new []{ch7a,ch7b});\n",
+ "var ch8 = Chart.Combine(new []{ch8a,ch8b});\n",
+ "var ch9 = Chart.Combine(new []{ch9a,ch9b});\n",
+ "var ch10 = Chart.Combine(new []{ch10a,ch10b});\n",
+ "var ch11 = Chart.Combine(new []{ch11a,ch11b});\n",
+ "var ch12 = Chart.Combine(new []{ch12a,ch12b});\n",
+ "var ch13 = Chart.Combine(new []{ch13a,ch13b});\n",
+ "var ch14 = Chart.Combine(new []{ch14a,ch14b});\n",
+ "var ch15 = Chart.Combine(new []{ch15a,ch15b});\n",
+ "var ch16 = Chart.Combine(new []{ch16a,ch16b});\n",
+ "\n",
+ "Layout layout = new Layout(); layout.SetValue(\"showlegend\",false);\n",
+ "var chart1 = new []{ch1,ch2,ch3,ch4,ch5,ch6,ch7,ch8,ch9,ch10,ch11,ch12,ch13,ch14,ch15,ch16};\n",
+ "var full = Chart.Grid>(8,2).Invoke(chart1).WithSize(1000,2200).WithMargin(Margin.init(30,20,20,30,7,false)).WithLayout(layout);\n",
+ "full.SaveSVG(\"SMA_chart\", Width: 1000, Height: 2200);"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": ".NET (C#)",
+ "language": "C#",
+ "name": ".net-csharp"
+ },
+ "polyglot_notebook": {
+ "kernelInfo": {
+ "defaultKernelName": "csharp",
+ "items": [
+ {
+ "aliases": [
+ "c#",
+ "C#"
+ ],
+ "languageName": "C#",
+ "name": "csharp"
+ },
+ {
+ "aliases": [],
+ "name": ".NET"
+ },
+ {
+ "aliases": [
+ "f#",
+ "F#"
+ ],
+ "languageName": "F#",
+ "name": "fsharp"
+ },
+ {
+ "aliases": [],
+ "languageName": "HTML",
+ "name": "html"
+ },
+ {
+ "aliases": [],
+ "languageName": "KQL",
+ "name": "kql"
+ },
+ {
+ "aliases": [],
+ "languageName": "Mermaid",
+ "name": "mermaid"
+ },
+ {
+ "aliases": [
+ "powershell"
+ ],
+ "languageName": "PowerShell",
+ "name": "pwsh"
+ },
+ {
+ "aliases": [],
+ "languageName": "SQL",
+ "name": "sql"
+ },
+ {
+ "aliases": [],
+ "name": "value"
+ },
+ {
+ "aliases": [
+ "frontend"
+ ],
+ "name": "vscode"
+ },
+ {
+ "aliases": [
+ "js"
+ ],
+ "languageName": "JavaScript",
+ "name": "javascript"
+ },
+ {
+ "aliases": [],
+ "name": "webview"
+ }
+ ]
+ }
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/docs/index.html b/docs/index.html
index ae618449..643cf350 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -1,33 +1,33 @@
-
-
-
-
- Document
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ Document
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/indicators.md b/docs/indicators.md
index b731ba85..9faa79f1 100644
--- a/docs/indicators.md
+++ b/docs/indicators.md
@@ -1,174 +1,174 @@
-# Coverage
-
-⭐= Calculation is validated against one or many TA libraries
-
-✔️= Calculation exists but has no cross-validation tests
-
-⛔= Not implemented (yet)
-
-| **BASIC TRANSFORMS** | **QuanTAlib** | **TA-LIB** | **Skender** | **Pandas TA** | **Tulip** |
-|--|:--:|:--:|:--:|:--:|:--:|
-| OC2 - (Open+Close)/2 |️ `.OC2` || CandlePart.OC2 ||
-| HL2 - Median Price | `.HL2` | MEDPRICE | CandlePart.HL2 | hl2 |
-| HLC3 - Typical Price | `.HLC3` | TYPPRICE | CandlePart.HLC3 | hlc3 |
-| OHL3 - (Open+High+Low)/3 | `.OHL3` || CandlePart.OHL3 ||
-| OHLC4 - Average Price | `.OHLC4` | AVGPRICE |️ CandlePart.OHLC4 | ohlc4 | avgprice |
-| HLCC4 - Weighted Price | `.HLCC4` | WCLPRICE | CandlePart.HLCC4 ||
-| MIDPOINT - Midpoint value | `MIDPOINT_Series` | MIDPOINT || midpoint |
-| MIDPRICE - Midpoint price | `MIDPRICE_Series` | MIDPRICE || midprice |
-| MAX - Max value | `MAX_Series` | MAX ||| max |
-| MIN - Min value | `MIN_Series` | MIN ||| min |
-| SUM - Summation | `SUM_Series` | SUM ||| sum |
-| ADD - Addition | `ADD_Series` | ADD ||| add |
-| SUB - Subtraction | `SUB_Series` | SUB ||| sub |
-| MUL - Multiplication | `MUL_Series` | MUL ||| mul |
-| DIV - Division | `DIV_Series` | DIV ||| div |
-|||||
-| **STATISTICS & NUMERICAL ANALYSIS** |
-||||||
-| BIAS - Bias | `BIAS_Series` ||| bias |
-| CORR - Pearson's Correlation Coefficient | `CORR_Series` | CORREL | GetCorrelation ||
-| COVAR - Covariance | `COVAR_Series` || GetCorrelation ||
-| DECAY - Linear Decay ||||| decay |
-| EDECAY - Exponential Decay ||||| edecay |
-| ENTROPY - Entropy | `ENTROPY_Series` ||| entropy |
-| KURTOSIS - Kurtosis | `KURT_Series` ||| kurtosis |
-| LINREG - Linear Regression | `LINREG_Series` || GetSlope ||
-| MAD - Mean Absolute Deviation | `MAD_Series` || GetSma | mad |
-| MAPE - Mean Absolute Percent Error | `MAPE_Series` || GetSma ||
-| MED - Median value | `MED_Series` ||| median |
-| MSE - Mean Squared Error | `MSE_Series` || GetSma ||
-| SKEW - Skewness |||| skew |
-| SDEV - Standard Deviation (Volatility) | `SDEV_Series` | STDDEV | GetStdDev | stdev |
-| SSDEV - Sample Standard Deviation | `SSDEV_Series` ||| stdev |
-| SMAPE - Symmetric Mean Absolute Percent Error | `SMAPE_Series` ||||
-| VAR - Population Variance | `VAR_Series` | VAR || variance |
-| SVAR - Sample Variance | `SVAR_Series` ||| variance |
-| QUANTILE - Quantile |||| quantile |
-| WMAPE - Weighted Mean Absolute Percent Error | `WMAPE_Series` ||||
-| ZSCORE - Number of standard deviations from mean | `ZSCORE_Series` || GetStdDev | zscore |
-||||||
-| **TREND INDICATORS & AVERAGES** |
-||||||
-| AFIRMA - Autoregressive Finite Impulse Response Moving Average |||||
-| ALMA - Arnaud Legoux Moving Average | `ALMA_Series` || GetAlma | alma |
-| ARIMA - Autoregressive Integrated Moving Average |||||
-| DEMA - Double EMA Average | `DEMA_Series` | DEMA | GetDema | dema | dema |
-| EMA - Exponential Moving Average | `EMA_Series` | EMA | GetEma | ema | ema |
-| EPMA - Endpoint Moving Average ||| GetEpma ||
-| FRAMA - Fractal Adaptive Moving Average |||||
-| FWMA - Fibonacci's Weighted Moving Average |||| fwma |
-| HILO - Gann High-Low Activator |||| hilo |
-| HEMA - Hull/EMA Average | `HEMA_Series` ||||
-| Hilbert Transform Instantaneous Trendline || HT_TRENDLINE | GetHtTrendline ||
-| HMA - Hull Moving Average | `HMA_Series` || GetHma | hma | hma |
-| HWMA - Holt-Winter Moving Average |||| hwma |
-| JMA - Jurik Moving Average | `JMA_Series` ||| jma |
-| KAMA - Kaufman's Adaptive Moving Average | `KAMA_Series` | KAMA | GetKama | kama | kama |
-| KDJ - KDJ Indicator (trend reversal) |||| kdj |
-| LSMA - Least Squares Moving Average |||||
-| MACD - Moving Average Convergence/Divergence | `MACD_Series` | MACD | GetMacd | macd |
-| MAMA - MESA Adaptive Moving Average | `MAMA_Series` | MAMA | GetMama ||
-| MCGD - McGinley Dynamic |||| mcgd |
-| MMA - Modified Moving Average |||||
-| PPMA - Pivot Point Moving Average |||||
-| PWMA - Pascal's Weighted Moving Average |||| pwma |
-| RMA - WildeR's Moving Average | `RMA_Series` ||| rma |
-| SINWMA - Sine Weighted Moving Average |||| sinwma |
-| ⭐ [SMA - Simple Moving Average](SMA.md) | `SMA_Series` | ⭐ SMA | ⭐ GetSma | ⭐ sma | ⭐ sma |
-| SMMA - Smoothed Moving Average | `SMMA_Series` || GetSmma ||
-| SSF - Ehler's Super Smoother Filter |||| ssf |
-| SUPERTREND - Supertrend |||| supertrend |
-| SWMA - Symmetric Weighted Moving Average |||| swma |
-| T3 - Tillson T3 Moving Average | `T3_Series` | T3 | GetT3 | t3 |
-| TEMA - Triple EMA Average | `TEMA_Series` | TEMA | GetTema | tema |
-| TRIMA - Triangular Moving Average | `TRIMA_Series` | TRIMA || trima |
-| TSF - Time Series Forecast || TSF |||
-| VIDYA - Variable Index Dynamic Average |||| vidya |
-| VORTEX - Vortex Indicator |||| vortex |
-| WMA - Weighted Moving Average | `WMA_Series` | WMA | GetWma | wma |
-| ZLEMA - Zero Lag EMA Average | `ZLEMA_Series` ||| zlma |
-||||||
-| **VOLATILITY INDICATORS** |
-||||||
-| ADL - Chaikin Accumulation Distribution Line | `ADL_Series` | AD | GetAdl | ad | ad |
-| ADOSC - Chaikin Accumulation Distribution Oscillator | `ADOSC_Series` | ADOSC| GetAdl | adosc | adosc |
-| ATR - Average True Range | `ATR_Series` | ATR | GetAtr | atr | atr |
-| ATRP - Average True Range Percent | `ATRP_Series` || GetAtr ||
-| BETA - Beta coefficient || BETA | GetBeta ||
-| BBANDS - Bollinger Bands® | `BBANDS_Series` | BBANDS | GetBollingerBands || bbands |
-| CHAND - Chandelier Exit ||| GetChandelier ||
-| CRSI - Connor RSI ||| GetConnorsRsi ||
-| CVI - Chaikins Volatility ||||| cvi |
-| DON - Donchian Channels ||| GetDonchian ||
-| FCB - Fractal Chaos Bands ||| GetFcb ||
-| FISHER - Fisher Transform ||| GetFcb || fisher |
-| HV - Historical Volatility |||||
-| ICH - Ichimoku ||| GetIchimoku ||
-| KEL - Keltner Channels ||| GetKeltner ||
-| NATR - Normalized Average True Range || NATR | GetAtr ||
-| CHN - Price Channel Indicator |||||
-| RSI - Relative Strength Index | `RSI_Series` | RSI | GetRsi | rsi |
-| SAR - Parabolic Stop and Reverse || SAR | GetParabolicSar ||
-| SRSI - Stochastic RSI || STOCHRSI | GetStochRsi ||
-| STARC - Starc Bands |||||
-| TR - True Range | `TR_Series` | TRANGE | GetTr | true_range |
-| UI - Ulcer Index |||||
-| VSTOP - Volatility Stop |||||
-||||||
-| **MOMENTUM INDICATORS & OSCILLATORS** |
-||||||
-| AC - Acceleration Oscillator |||||
-| ADX - Average Directional Movement Index || ADX | GetAdx || adx |
-| ADXR - Average Directional Movement Index Rating || ADXR | GetAdx || adxr |
-| AO - Awesome Oscillator ||| GetAwesome || ao |
-| APO - Absolute Price Oscillator || APO ||| apo |
-| AROON - Aroon oscillator || AROON | GetAroon || aroon |
-| BOP - Balance of Power || BOP | GetBop || bop |
-| CCI - Commodity Channel Index | `CCI_Series` | CCI | GetCci || cci |
-| CFO - Chande Forcast Oscillator |||||
-| CMO - Chande Momentum Oscillator || CMO | GetCmo || cmo |
-| COG - Center of Gravity |||||
-| COPPOCK - Coppock Curve |||||
-| CTI - Ehler's Correlation Trend Indicator |||||
-| DPO - Detrended Price Oscillator ||| GetDpo ||
-| DMI - Directional Movement Index || DX | GetAdx ||
-| EFI - Elder Ray's Force Index ||| GetElderRay ||
-| FOSC - Forecast oscillator ||||| fosc |
-| GAT - Alligator oscillator ||| GetGator ||
-| HURST - Hurst Exponent ||| GetHurst ||
-| KRI - Kairi Relative Index |||||
-| KVO - Klinger Volume Oscillator |||||
-| MFI - Money Flow Index || MFI | GetMfi ||
-| MOM - Momentum || MOM |||
-| NVI - Negative Volume Index |||||
-| PO - Price Oscillator |||||
-| PPO - Percentage Price Oscillator || PPO |||
-| PMO - Price Momentum Oscillator |||||
-| PVI - Positive Volume Index |||||
-| ROC - Rate of Change || MOM | GetRoc ||
-| RVGI - Relative Vigor Index |||||
-| SMI - Stochastic Momentum Index |||||
-| STC - Schaff Trend Cycle |||||
-| STOCH - Stochastic Oscillator || STOCH | GetStoch ||
-| TRIX - 1-day ROC of TEMA || TRIX | GetTrix ||
-| TSI - True Strength Index |||||
-| UO - Ultimate Oscillator || ULTOSC | GetUltimate ||
-| WILLR - Larry Williams' %R || WILLR | GetWilliamsR ||
-| WGAT - Williams Alligator |||||
-||||||
-| **VOLUME INDICATORS** |
-||||||
-| AOBV - Archer On-Balance Volume |||||
-| CMF - Chaikin Money Flow |||||
-| EOM - Ease of Movement ||||| emv |
-| KVO - Klinger Volume Oscilaltor ||||| kvo |
-| OBV - On-Balance Volume | `OBV_Series` | OBV | GetObv ||
-| PRS - Price Relative Strength ||||
-| PVOL - Price-Volume |||||
-| PVO - Percentage Volume Oscillator |||||
-| PVR - Price Volume Rank |||||
-| PVT - Price Volume Trend |||||
-| VP - Volume Profile |||||
-| VWAP - Volume Weighted Average Price |||||
-| VWMA - Volume Weighted Moving Average |||||
+# Coverage
+
+⭐= Calculation is validated against several TA libraries
+
+✔️= Validation tests passed
+
+❌= Wrong implementation
+
+| **BASIC TRANSFORMS** | **QuanTAlib** | **TA-LIB** | **Skender** | **Pandas TA** | **Tulip** |
+|--|:--:|:--:|:--:|:--:|:--:|
+| OC2 - (Open+Close)/2 |️ `.OC2` || CandlePart.OC2 ||
+| HL2 - Median Price | `.HL2` | MEDPRICE | CandlePart.HL2 | hl2 |
+| HLC3 - Typical Price | `.HLC3` | TYPPRICE | CandlePart.HLC3 | hlc3 |
+| OHL3 - (Open+High+Low)/3 | `.OHL3` || CandlePart.OHL3 ||
+| OHLC4 - Average Price | `.OHLC4` | AVGPRICE |️ CandlePart.OHLC4 | ohlc4 | avgprice |
+| HLCC4 - Weighted Price | `.HLCC4` | WCLPRICE | CandlePart.HLCC4 ||
+| MIDPOINT - Midpoint value | `MIDPOINT_Series` | MIDPOINT || midpoint |
+| MIDPRICE - Midpoint price | `MIDPRICE_Series` | MIDPRICE || midprice |
+| MAX - Max value | `MAX_Series` | MAX ||| max |
+| MIN - Min value | `MIN_Series` | MIN ||| min |
+| SUM - Summation | `SUM_Series` | SUM ||| sum |
+| ADD - Addition | `ADD_Series` | ADD ||| add |
+| SUB - Subtraction | `SUB_Series` | SUB ||| sub |
+| MUL - Multiplication | `MUL_Series` | MUL ||| mul |
+| DIV - Division | `DIV_Series` | DIV ||| div |
+|||||
+| **STATISTICS & NUMERICAL ANALYSIS** |
+||||||
+| ⭐BIAS - Bias | `BIAS_Series` ||| ✔️bias |
+| CORR - Pearson's Correlation Coefficient | `CORR_Series` | CORREL | GetCorrelation ||
+| COVAR - Covariance | `COVAR_Series` || GetCorrelation ||
+| DECAY - Linear Decay ||||| decay |
+| EDECAY - Exponential Decay ||||| edecay |
+| ENTROPY - Entropy | `ENTROPY_Series` ||| entropy |
+| KURTOSIS - Kurtosis | `KURT_Series` ||| kurtosis |
+| LINREG - Linear Regression | `LINREG_Series` || GetSlope ||
+| MAD - Mean Absolute Deviation | `MAD_Series` || GetSma | mad |
+| MAPE - Mean Absolute Percent Error | `MAPE_Series` || GetSma ||
+| MED - Median value | `MED_Series` ||| median |
+| MSE - Mean Squared Error | `MSE_Series` || GetSma ||
+| SKEW - Skewness |||| skew |
+| SDEV - Standard Deviation (Volatility) | `SDEV_Series` | STDDEV | GetStdDev | stdev |
+| SSDEV - Sample Standard Deviation | `SSDEV_Series` ||| stdev |
+| SMAPE - Symmetric Mean Absolute Percent Error | `SMAPE_Series` ||||
+| VAR - Population Variance | `VAR_Series` | VAR || variance |
+| SVAR - Sample Variance | `SVAR_Series` ||| variance |
+| QUANTILE - Quantile |||| quantile |
+| WMAPE - Weighted Mean Absolute Percent Error | `WMAPE_Series` ||||
+| ZSCORE - Number of standard deviations from mean | `ZSCORE_Series` || GetStdDev | zscore |
+||||||
+| **TREND INDICATORS & AVERAGES** |
+||||||
+| AFIRMA - Autoregressive Finite Impulse Response Moving Average |||||
+| ALMA - Arnaud Legoux Moving Average | `ALMA_Series` || GetAlma | alma |
+| ARIMA - Autoregressive Integrated Moving Average |||||
+| ⭐DEMA - Double EMA Average | `DEMA_Series` | ✔️DEMA | ✔️GetDema | ✔️dema | ✔️dema |
+| ⭐EMA - Exponential Moving Average | `EMA_Series` | ✔️EMA | ✔️GetEma | ✔️ema | ✔️ema |
+| EPMA - Endpoint Moving Average ||| GetEpma ||
+| FRAMA - Fractal Adaptive Moving Average |||||
+| FWMA - Fibonacci's Weighted Moving Average |||| fwma |
+| HILO - Gann High-Low Activator |||| hilo |
+| HEMA - Hull/EMA Average | `HEMA_Series` ||||
+| Hilbert Transform Instantaneous Trendline || HT_TRENDLINE | GetHtTrendline ||
+| ⭐HMA - Hull Moving Average | `HMA_Series` || ✔️GetHma | ✔️hma | ✔️hma |
+| HWMA - Holt-Winter Moving Average |||| hwma |
+| JMA - Jurik Moving Average | `JMA_Series` ||| jma ||
+| KAMA - Kaufman's Adaptive Moving Average | `KAMA_Series` | KAMA | GetKama | kama | kama |
+| KDJ - KDJ Indicator (trend reversal) |||| kdj |
+| LSMA - Least Squares Moving Average |||||
+| MACD - Moving Average Convergence/Divergence | `MACD_Series` | MACD | GetMacd | macd |
+| MAMA - MESA Adaptive Moving Average | `MAMA_Series` | MAMA | GetMama ||
+| MCGD - McGinley Dynamic |||| mcgd |
+| MMA - Modified Moving Average |||||
+| PPMA - Pivot Point Moving Average |||||
+| PWMA - Pascal's Weighted Moving Average |||| pwma |
+| RMA - WildeR's Moving Average | `RMA_Series` ||| rma |
+| SINWMA - Sine Weighted Moving Average |||| sinwma |
+| ⭐[SMA - Simple Moving Average](SMA.md) | `SMA_Series` | ✔️SMA | ✔️GetSma | ✔️sma | ✔️sma |
+| SMMA - Smoothed Moving Average | `SMMA_Series` || GetSmma ||
+| SSF - Ehler's Super Smoother Filter |||| ssf |
+| SUPERTREND - Supertrend |||| supertrend |
+| SWMA - Symmetric Weighted Moving Average |||| swma |
+| T3 - Tillson T3 Moving Average | `T3_Series` | T3 | GetT3 | t3 |
+| TEMA - Triple EMA Average | `TEMA_Series` | TEMA | GetTema | tema |
+| TRIMA - Triangular Moving Average | `TRIMA_Series` | TRIMA || trima |
+| TSF - Time Series Forecast || TSF |||
+| VIDYA - Variable Index Dynamic Average |||| vidya |
+| VORTEX - Vortex Indicator |||| vortex |
+| WMA - Weighted Moving Average | `WMA_Series` | WMA | GetWma | wma |
+| ZLEMA - Zero Lag EMA Average | `ZLEMA_Series` ||| zlma |
+||||||
+| **VOLATILITY INDICATORS** |
+||||||
+| ⭐ADL - Chaikin Accumulation Distribution Line | `ADL_Series` | ✔️AD | ✔️GetAdl | ✔️ad | ✔️ad |
+| ⭐ADOSC - Chaikin Accumulation Distribution Oscillator | `ADOSC_Series` | ✔️ADOSC| | ✔️adosc | ✔️adosc |
+| ⭐ATR - Average True Range | `ATR_Series` | ✔️ATR | ✔️GetAtr | ✔️atr | ✔️atr |
+| ATRP - Average True Range Percent | `ATRP_Series` || GetAtr ||
+| BETA - Beta coefficient || BETA | GetBeta ||
+| BBANDS - Bollinger Bands® | `BBANDS_Series` | BBANDS | GetBollingerBands || bbands |
+| CHAND - Chandelier Exit ||| GetChandelier ||
+| CRSI - Connor RSI ||| GetConnorsRsi ||
+| CVI - Chaikins Volatility ||||| cvi |
+| DON - Donchian Channels ||| GetDonchian ||
+| FCB - Fractal Chaos Bands ||| GetFcb ||
+| FISHER - Fisher Transform ||| GetFcb || fisher |
+| HV - Historical Volatility |||||
+| ICH - Ichimoku ||| GetIchimoku ||
+| KEL - Keltner Channels ||| GetKeltner ||
+| NATR - Normalized Average True Range || NATR | GetAtr ||
+| CHN - Price Channel Indicator |||||
+| RSI - Relative Strength Index | `RSI_Series` | RSI | GetRsi | rsi |
+| SAR - Parabolic Stop and Reverse || SAR | GetParabolicSar ||
+| SRSI - Stochastic RSI || STOCHRSI | GetStochRsi ||
+| STARC - Starc Bands |||||
+| TR - True Range | `TR_Series` | TRANGE | GetTr | true_range |
+| UI - Ulcer Index |||||
+| VSTOP - Volatility Stop |||||
+||||||
+| **MOMENTUM INDICATORS & OSCILLATORS** |
+||||||
+| AC - Acceleration Oscillator |||||
+| ADX - Average Directional Movement Index || ADX | GetAdx || adx |
+| ADXR - Average Directional Movement Index Rating || ADXR | GetAdx || adxr |
+| AO - Awesome Oscillator ||| GetAwesome || ao |
+| APO - Absolute Price Oscillator || APO ||| apo |
+| AROON - Aroon oscillator || AROON | GetAroon || aroon |
+| BOP - Balance of Power || BOP | GetBop || bop |
+| CCI - Commodity Channel Index | `CCI_Series` | CCI | GetCci || cci |
+| CFO - Chande Forcast Oscillator |||||
+| CMO - Chande Momentum Oscillator | `CMO_Series` | ❌CMO | ❌GetCmo | ❌cmo | cmo |
+| COG - Center of Gravity |||||
+| COPPOCK - Coppock Curve |||||
+| CTI - Ehler's Correlation Trend Indicator |||||
+| DPO - Detrended Price Oscillator ||| GetDpo ||
+| DMI - Directional Movement Index || DX | GetAdx ||
+| EFI - Elder Ray's Force Index ||| GetElderRay ||
+| FOSC - Forecast oscillator ||||| fosc |
+| GAT - Alligator oscillator ||| GetGator ||
+| HURST - Hurst Exponent ||| GetHurst ||
+| KRI - Kairi Relative Index |||||
+| KVO - Klinger Volume Oscillator |||||
+| MFI - Money Flow Index || MFI | GetMfi ||
+| MOM - Momentum || MOM |||
+| NVI - Negative Volume Index |||||
+| PO - Price Oscillator |||||
+| PPO - Percentage Price Oscillator || PPO |||
+| PMO - Price Momentum Oscillator |||||
+| PVI - Positive Volume Index |||||
+| ROC - Rate of Change || MOM | GetRoc ||
+| RVGI - Relative Vigor Index |||||
+| SMI - Stochastic Momentum Index |||||
+| STC - Schaff Trend Cycle |||||
+| STOCH - Stochastic Oscillator || STOCH | GetStoch ||
+| TRIX - 1-day ROC of TEMA | TRIX | TRIX | GetTrix | trix |
+| TSI - True Strength Index |||||
+| UO - Ultimate Oscillator || ULTOSC | GetUltimate ||
+| WILLR - Larry Williams' %R || WILLR | GetWilliamsR ||
+| WGAT - Williams Alligator |||||
+||||||
+| **VOLUME INDICATORS** |
+||||||
+| AOBV - Archer On-Balance Volume |||||
+| CMF - Chaikin Money Flow |||||
+| EOM - Ease of Movement ||||| emv |
+| KVO - Klinger Volume Oscilaltor ||||| kvo |
+| OBV - On-Balance Volume | `OBV_Series` | OBV | GetObv ||
+| PRS - Price Relative Strength ||||
+| PVOL - Price-Volume |||||
+| PVO - Percentage Volume Oscillator |||||
+| PVR - Price Volume Rank |||||
+| PVT - Price Volume Trend |||||
+| VP - Volume Profile |||||
+| VWAP - Volume Weighted Average Price |||||
+| VWMA - Volume Weighted Moving Average |||||