semver fix


VAR test fix


new: COVAR, ZSCORE, CORR, LINREG


versioning


refactoring
This commit is contained in:
Miha Kralj
2022-11-17 11:05:20 -08:00
parent fd2a686ba5
commit 73e3420379
59 changed files with 1225 additions and 1285 deletions
+1 -2
View File
@@ -23,8 +23,7 @@ public class ADD_Series : Pair_TSeries_Indicator
public override void Add((System.DateTime t, double v)TValue1, (System.DateTime t, double v)TValue2, bool update)
{
(System.DateTime t, double v) result = ((TValue1.t > TValue2.t) ? TValue1.t : TValue2.t,
TValue1.v+TValue2.v);
(System.DateTime t, double v) result = ((TValue1.t > TValue2.t) ? TValue1.t : TValue2.t, TValue1.v+TValue2.v);
if (update) { base[base.Count - 1] = result; } else { base.Add(result); }
}
}
+4 -12
View File
@@ -1,5 +1,6 @@
namespace QuanTAlib;
using System;
using System.Linq;
/* <summary>
MAX - Maximum value in the given period in the series.
@@ -16,18 +17,9 @@ public class MAX_Series : Single_TSeries_Indicator
public override void Add((DateTime t, double v) TValue, bool update)
{
if (update) { this._buffer[this._buffer.Count - 1] = TValue.v; }
else { this._buffer.Add(TValue.v); }
if (this._buffer.Count > this._p && this._p != 0) { this._buffer.RemoveAt(0); }
Add_Replace_Trim(_buffer, TValue.v, _p, update);
double _max = _buffer.Max();
double _max = TValue.v;
for (int i = 0; i < this._buffer.Count; i++)
{
_max = Math.Max(this._buffer[i], _max);
}
var result = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _max);
base.Add(result, update);
base.Add((TValue.t, _max), update, _NaN);
}
}
+2 -9
View File
@@ -21,12 +21,7 @@ public class MIDPOINT_Series : Single_TSeries_Indicator
public override void Add((DateTime t, double v) TValue, bool update)
{
if (update)
{ this._buffer[this._buffer.Count - 1] = TValue.v; }
else
{ this._buffer.Add(TValue.v); }
if (this._buffer.Count > this._p && this._p != 0)
{ this._buffer.RemoveAt(0); }
Add_Replace_Trim(_buffer, TValue.v, _p, update);
double _max = TValue.v;
double _min = TValue.v;
@@ -37,8 +32,6 @@ public class MIDPOINT_Series : Single_TSeries_Indicator
}
double _mid = (_max + _min) * 0.5;
var result = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _mid);
base.Add(result, update);
base.Add((TValue.t, _mid), update, _NaN);
}
}
+6 -24
View File
@@ -1,5 +1,6 @@
namespace QuanTAlib;
using System;
using System.Linq;
/* <summary>
MIDPRICE: Midpoint price (highhest high + lowest low)/2 in the given period in the series.
@@ -19,32 +20,13 @@ public class MIDPRICE_Series : Single_TBars_Indicator
public override void Add((DateTime t, double o, double h, double l, double c, double v) TBar, bool update)
{
if (update)
{
this._bufferhi[this._bufferhi.Count - 1] = TBar.h;
this._bufferlo[this._bufferlo.Count - 1] = TBar.l;
}
else
{
this._bufferhi.Add(TBar.h);
this._bufferlo.Add(TBar.l);
}
if (this._bufferhi.Count > this._p && this._p != 0)
{ this._bufferhi.RemoveAt(0); }
if (this._bufferlo.Count > this._p && this._p != 0)
{ this._bufferlo.RemoveAt(0); }
Add_Replace_Trim(_bufferhi, TBar.h, _p, update);
Add_Replace_Trim(_bufferlo, TBar.l, _p, update);
double _max = TBar.h;
double _min = TBar.l;
for (int i = 0; i < this._bufferhi.Count; i++)
{
_max = Math.Max(this._bufferhi[i], _max);
_min = Math.Min(this._bufferlo[i], _min);
}
double _max = _bufferhi.Max();
double _min = _bufferlo.Min();
double _mid = (_max + _min) * 0.5;
var result = (TBar.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _mid);
base.Add(result, update);
base.Add((TBar.t, _mid), update, _NaN);
}
}
+4 -12
View File
@@ -1,5 +1,6 @@
namespace QuanTAlib;
using System;
using System.Linq;
/* <summary>
MIN - Minimum value in the given period in the series.
@@ -16,18 +17,9 @@ public class MIN_Series : Single_TSeries_Indicator
public override void Add((System.DateTime t, double v) TValue, bool update)
{
if (update) { this._buffer[this._buffer.Count - 1] = TValue.v; }
else { this._buffer.Add(TValue.v); }
if (this._buffer.Count > this._p && this._p != 0) { this._buffer.RemoveAt(0); }
Add_Replace_Trim(_buffer, TValue.v, _p, update);
double _min = TValue.v;
for (int i = 0; i < this._buffer.Count; i++)
{
_min = Math.Min(this._buffer[i], _min);
}
var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _min);
base.Add(result, update);
double _min = _buffer.Min();
base.Add((TValue.t, _min), update, _NaN);
}
}
@@ -1,148 +1,112 @@
namespace QuanTAlib;
using System;
/* <summary>
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.
</summary> */
public abstract class Single_TSeries_Indicator : TSeries
{
protected readonly int _p;
protected readonly bool _NaN;
protected readonly TSeries _data;
// 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._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 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);
}
public abstract class Pair_TSeries_Indicator : TSeries
{
protected readonly int _p;
protected readonly bool _NaN;
protected readonly TSeries _d1;
protected readonly TSeries _d2;
protected readonly double _dd1, _dd2;
// Chainable Constructors - add them at the end of primary constructors if needed
protected Pair_TSeries_Indicator(TSeries source1, TSeries source2, int period, bool useNaN)
{
this._p = period;
this._NaN = useNaN;
this._d1 = source1;
this._d2 = source2;
this._dd1 = double.NaN;
this._dd2 = double.NaN;
this._d1.Pub += this.Sub;
this._d2.Pub += this.Sub;
}
protected Pair_TSeries_Indicator(TSeries source1, TSeries source2)
{
this._d1 = source1;
this._d2 = source2;
this._dd1 = double.NaN;
this._dd2 = double.NaN;
this._d1.Pub += this.Sub;
this._d2.Pub += this.Sub;
}
protected Pair_TSeries_Indicator(TSeries source1, double dd2)
{
this._d1 = source1;
this._d2 = new();
this._dd1 = double.NaN;
this._dd2 = dd2;
this._d1.Pub += this.Sub;
}
protected Pair_TSeries_Indicator(double dd1, TSeries source2)
{
this._d1 = new();
this._d2 = source2;
this._dd1 = dd1;
this._dd2 = double.NaN;
this._d2.Pub += this.Sub;
}
// overridable Add(Tvalue, Tvalue) method to add/update a single value at the end of the list
public virtual void Add((System.DateTime t, double v)TValue1, (System.DateTime t, double v)TValue2, bool update) => base.Add(TValue: (TValue1.t, 0), update: update); // default inserts zeros
// potentially overridable Add() bulk variations (could be replaced with faster bulk algos)
public virtual void Add(TSeries d1, TSeries d2) { for (int i = 0; i < d1.Count; i++) { this.Add(d1[i], d2[i], update: false); }}
public virtual void Add(TSeries d1, double dd2) { for (int i = 0; i < d1.Count; i++) { this.Add(d1[i], (d1[i].t, dd2), update: false); }}
public virtual void Add(double dd1, TSeries d2) { for (int i = 0; i < d2.Count; i++) { this.Add((d2[i].t, dd1), d2[i], update: false); }}
public void Add((System.DateTime t, double v)TValue1, (System.DateTime t, double v)TValue2) => this.Add(TValue1, TValue2, update: false);
public void Add(bool update)
{
if ((this._dd1 is double.NaN) && (this._dd2 is double.NaN))
{
// (Series, Series)
if (update || (this._d1.Count > this.Count && this._d2.Count > this.Count))
{ this.Add(this._d1[this._d1.Count - 1], this._d2[this._d2.Count - 1], update); }
}
else if ((this._dd2 is not double.NaN) && (this._dd1 is double.NaN))
{
// (Series, Double)
this.Add(TValue1: this._d1[this._d1.Count - 1], TValue2: (this._d1[this._d1.Count - 1].t, this._dd2), update: update);
}
else
{
// (Double, Series)
this.Add(TValue1: (this._d2[this._d2.Count - 1].t, this._dd1), TValue2: this._d2[this._d2.Count - 1], update: update);
}
}
public void Add() => this.Add(update: false);
public new void Sub(object source, TSeriesEventArgs e) => this.Add(e.update);
}
public abstract class Single_TBars_Indicator : TSeries
{
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;
}
// 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);
// 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);
}
namespace QuanTAlib;
using System;
using System.Collections.Generic;
/* <summary>
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.
</summary> */
public abstract class Pair_TSeries_Indicator : TSeries
{
protected readonly int _p;
protected readonly bool _NaN;
protected readonly TSeries _d1;
protected readonly TSeries _d2;
protected readonly double _dd1, _dd2;
// Chainable Constructors - add them at the end of primary constructors if needed
protected Pair_TSeries_Indicator(TSeries source1, TSeries source2, int period, bool useNaN)
{
this._p = period;
this._NaN = useNaN;
this._d1 = source1;
this._d2 = source2;
this._dd1 = double.NaN;
this._dd2 = double.NaN;
this._d1.Pub += this.Sub;
this._d2.Pub += this.Sub;
}
protected Pair_TSeries_Indicator(TSeries source1, TSeries source2)
{
this._d1 = source1;
this._d2 = source2;
this._dd1 = double.NaN;
this._dd2 = double.NaN;
this._d1.Pub += this.Sub;
this._d2.Pub += this.Sub;
}
protected Pair_TSeries_Indicator(TSeries source1, double dd2)
{
this._d1 = source1;
this._d2 = new();
this._dd1 = double.NaN;
this._dd2 = dd2;
this._d1.Pub += this.Sub;
}
protected Pair_TSeries_Indicator(double dd1, TSeries source2)
{
this._d1 = new();
this._d2 = source2;
this._dd1 = dd1;
this._dd2 = double.NaN;
this._d2.Pub += this.Sub;
}
// overridable Add(Tvalue, Tvalue) method to add/update a single value at the end of the list
public virtual void Add((System.DateTime t, double v)TValue1, (System.DateTime t, double v)TValue2, bool update) => base.Add(TValue: (TValue1.t, 0), update: update); // default inserts zeros
// potentially overridable Add() bulk variations (could be replaced with faster bulk algos)
public virtual void Add(TSeries d1, TSeries d2) { for (int i = 0; i < d1.Count; i++) { this.Add(d1[i], d2[i], update: false); }}
public virtual void Add(TSeries d1, double dd2) { for (int i = 0; i < d1.Count; i++) { this.Add(d1[i], (d1[i].t, dd2), update: false); }}
public virtual void Add(double dd1, TSeries d2) { for (int i = 0; i < d2.Count; i++) { this.Add((d2[i].t, dd1), d2[i], update: false); }}
public void Add((System.DateTime t, double v)TValue1, (System.DateTime t, double v)TValue2) => this.Add(TValue1, TValue2, update: false);
public void Add(bool update)
{
if ((this._dd1 is double.NaN) && (this._dd2 is double.NaN))
{
// (Series, Series)
if (update || (this._d1.Count > this.Count && this._d2.Count > this.Count))
{ this.Add(this._d1[this._d1.Count - 1], this._d2[this._d2.Count - 1], update); }
}
else if ((this._dd2 is not double.NaN) && (this._dd1 is double.NaN))
{
// (Series, Double)
this.Add(TValue1: this._d1[this._d1.Count - 1], TValue2: (this._d1[this._d1.Count - 1].t, this._dd2), update: update);
}
else
{
// (Double, Series)
this.Add(TValue1: (this._d2[this._d2.Count - 1].t, this._dd1), TValue2: this._d2[this._d2.Count - 1], update: update);
}
}
public void Add() => this.Add(update: false);
public new void Sub(object source, TSeriesEventArgs e) => this.Add(e.update);
protected static void Add_Replace(List<double> l, double v, bool update)
{
if (update)
{ l[l.Count - 1] = v; }
else
{ l.Add(v); }
}
protected static void Add_Replace_Trim(List<double> l, double v, int p, bool update)
{
Add_Replace(l, v, update);
if (l.Count > p && p != 0)
{ l.RemoveAt(0); }
}
}
+66
View File
@@ -0,0 +1,66 @@
namespace QuanTAlib;
using System;
using System.Collections.Generic;
/* <summary>
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.
</summary> */
public abstract class Single_TBars_Indicator : TSeries
{
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;
}
// 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);
}
// 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<double> l, double v, bool update)
{
if (update)
{ l[l.Count - 1] = v; }
else
{ l.Add(v); }
}
protected static void Add_Replace_Trim(List<double> l, double v, int p, bool update)
{
Add_Replace(l, v, update);
if (l.Count > p && p != 0)
{ l.RemoveAt(0); }
}
}
+63
View File
@@ -0,0 +1,63 @@
namespace QuanTAlib;
using System;
using System.Collections.Generic;
/* <summary>
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.
</summary> */
public abstract class Single_TSeries_Indicator : TSeries
{
protected readonly int _p;
protected readonly bool _NaN;
protected readonly TSeries _data;
// 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._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)
{
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<double> l, double v, bool update)
{
if (update)
{ l[l.Count - 1] = v; }
else
{ l.Add(v); }
}
protected static void Add_Replace_Trim(List<double> l, double v, int p, bool update)
{
Add_Replace(l, v, update);
if (l.Count > p && p!=0)
{ l.RemoveAt(0); }
}
}
+1 -2
View File
@@ -17,12 +17,11 @@ public class Alphavantage_Feed : TBars
public Alphavantage_Feed(string Symbol = "IBM", string APIkey = "demo")
{
System.Net.Http.HttpClient client = new();
JsonElement json = new();
string req = "https://www.alphavantage.co/query?function=TIME_SERIES_DAILY_ADJUSTED" + "&symbol=" + Symbol + "&apikey=" + APIkey;
var msg = client.GetStringAsync(req).Result;
var jres = JsonSerializer.Deserialize<JsonDocument>(msg).RootElement;
jres.TryGetProperty("Time Series (Daily)", out json);
jres.TryGetProperty("Time Series (Daily)", out JsonElement json);
if (json.ValueKind == JsonValueKind.Undefined) {throw new InvalidOperationException("Stock symbol "+Symbol+" not found"); }
foreach (var val in json.EnumerateObject()) { base.Add(GetOHLC(val)); }
+4 -3
View File
@@ -9,12 +9,13 @@ Yahoo Finance - Free API feed to collect daily market quotes
Period: number of days of collected history (default: 252)
Usage:
Yahoo_Feed ticker = new("MSFT", 20)
</summary> */
public class Yahoo_Feed : TBars
{
public Yahoo_Feed(string Symbol = "IBM", int Period = 252) {
Period = (int)(Period*1.45);
string requestUrl = "https://query1.finance.yahoo.com/v8/finance/chart/"+
Symbol+"?interval=1d&period1="+
(int)new DateTimeOffset(DateTime.UtcNow.AddDays(-Period+1)).ToUnixTimeSeconds()+"&period2="+
@@ -22,7 +23,7 @@ public class Yahoo_Feed : TBars
System.Net.Http.HttpClient client = new();
var msg = client.GetStringAsync(requestUrl).Result;
var jresult = JsonSerializer.Deserialize<JsonDocument>(msg).RootElement;
jresult.TryGetProperty("chart",out JsonElement json);
json.TryGetProperty("result",out json);
json[0].TryGetProperty("timestamp",out JsonElement datetime);
@@ -33,7 +34,7 @@ public class Yahoo_Feed : TBars
json[0].TryGetProperty("low",out JsonElement low);
json[0].TryGetProperty("close",out JsonElement close);
json[0].TryGetProperty("volume",out JsonElement volume);
for (int i=0; i<datetime.GetArrayLength(); i++) {
DateTime d = DateTimeOffset.FromUnixTimeSeconds(long.Parse(datetime[i].GetRawText())).DateTime;
double o = Math.Round(double.Parse(open[i].GetRawText()),3);
+6 -6
View File
@@ -1,5 +1,7 @@
namespace QuanTAlib;
using System;
using System.Linq;
using static System.Net.Mime.MediaTypeNames;
/* <summary>
CCI: Commodity Channel Index
@@ -32,18 +34,16 @@ public class CCI_Series : Single_TBars_Indicator
if (this._tp.Count > this._p) { this._tp.RemoveAt(0); }
// average TP over _tp buffer
double _avgTp = 0;
for (int i = 0; i < this._tp.Count; i++) { _avgTp+=this._tp[i]; }
_avgTp /= this._tp.Count;
double _avgTp = _tp.Average();
// average Deviation over _tp buffer
double _avgDv = 0;
for (int i = 0; i < this._tp.Count; i++) { _avgDv += Math.Abs(_avgTp - this._tp[i]); }
_avgDv /= this._tp.Count;
double _cci = (_avgDv == 0) ? double.NaN : (this._tp[this._tp.Count-1] - _avgTp) / (0.015 * _avgDv);
var result = (TBar.t, (this.Count < this._p && this._NaN) ? double.NaN : _cci);
base.Add(result, update);
}
base.Add((TBar.t, _cci), update, _NaN);
}
}
+2 -10
View File
@@ -2,6 +2,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Title>QuanTAlib</Title>
<Version>0.1.20</Version>
<Product>Library of Technical Indicators for .NET</Product>
<Description>Quantitative Technical Analysis library for both real-time (streaming) and historical data analysis</Description>
<RepositoryType>git</RepositoryType>
@@ -31,7 +32,6 @@
</PackageTags>
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
<PackageLicenseFile></PackageLicenseFile>
<SynchReleaseVersion>false</SynchReleaseVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DebugType>full</DebugType>
@@ -51,7 +51,7 @@
<PackageIcon>QuanTAlib2.png</PackageIcon>
<PackageIconUrl>https://raw.githubusercontent.com/mihakralj/QuanTAlib/main/.github/QuanTAlib2.png</PackageIconUrl>
<EnforceCodeStyleInBuild>True</EnforceCodeStyleInBuild>
<CodeAnalysisRuleSet>..\.sonarlint\mihakralj_quantalibcsharp.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRuleSet>QuanTAlib.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<AdditionalFiles Include="..\.sonarlint\mihakralj_quantalib\CSharp\SonarLint.xml" Link="SonarLint.xml" />
@@ -67,12 +67,4 @@
<PackagePath></PackagePath>
</None>
</ItemGroup>
<ItemGroup>
<PackageReference Include="GitVersion.MsBuild" Version="5.11.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="System.Text.Json" Version="7.0.0" />
</ItemGroup>
</Project>
+5
View File
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<RuleSet Name="SonarQube - QuanTAlib QuanTAlib" ToolsVersion="17.0">
<Include Path="..\.sonarlint\mihakralj_quantalibcsharp.ruleset" Action="Default" />
<Include Path="..\.sonarlint\mihakralj_quantalibcsharp.ruleset" Action="Default" />
</RuleSet>
+5 -10
View File
@@ -1,5 +1,6 @@
namespace QuanTAlib;
using System;
using System.Linq;
/* <summary>
BIAS: Rate of change between the source and a moving average.
@@ -23,17 +24,11 @@ public class BIAS_Series : Single_TSeries_Indicator
public override void Add((System.DateTime t, double v) TValue, bool update)
{
if (update) { this._buffer[this._buffer.Count - 1] = TValue.v; }
else { this._buffer.Add(TValue.v); }
if (this._buffer.Count > this._p && this._p != 0) { this._buffer.RemoveAt(0); }
Add_Replace_Trim(_buffer, TValue.v, _p, update);
double _sma = 0;
for (int i = 0; i < this._buffer.Count; i++) { _sma += this._buffer[i]; }
_sma /= this._buffer.Count;
double _bias = (this._buffer[this._buffer.Count - 1] / ((_sma != 0) ? _sma : 1)) - 1;
double _sma = _buffer.Average();
double _bias = (_buffer[_buffer.Count - 1] / ((_sma != 0) ? _sma : 1)) - 1;
var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _bias);
base.Add(result, update);
base.Add((TValue.t, _bias), update, _NaN);
}
}
+35 -53
View File
@@ -1,5 +1,7 @@
namespace QuanTAlib;
using System;
using System.Collections.Generic;
using System.Linq;
/* <summary>
CORR: Pearson's Correlation Coefficient
@@ -14,57 +16,37 @@ Sources:
</summary> */
public class CORR_Series : Pair_TSeries_Indicator
{
public CORR_Series(TSeries d1, TSeries d2, int period, bool useNaN = false) : base(d1, d2, period, useNaN)
{
if (base._d1.Count > 0 && base._d2.Count > 0) { for (int i = 0; i < base._d1.Count; i++) { this.Add(base._d1[i], base._d2[i], false); } }
}
private readonly System.Collections.Generic.List<double> _x = new();
private readonly System.Collections.Generic.List<double> _xx = new();
private readonly System.Collections.Generic.List<double> _y = new();
private readonly System.Collections.Generic.List<double> _yy = new();
private readonly System.Collections.Generic.List<double> _xy = new();
public override void Add((System.DateTime t, double v) TValue1, (System.DateTime t, double v) TValue2, bool update)
{
if (update)
{
_x[_x.Count - 1] = TValue1.v;
_xx[_xx.Count - 1] = TValue1.v * TValue1.v;
_y[_y.Count - 1] = TValue2.v;
_y[_yy.Count - 1] = TValue2.v * TValue2.v;
_xy[_xy.Count - 1] = TValue1.v * TValue2.v;
}
else
{
_x.Add(TValue1.v);
_xx.Add(TValue1.v * TValue1.v);
_y.Add(TValue2.v);
_yy.Add(TValue2.v * TValue2.v);
_xy.Add(TValue1.v * TValue2.v);
}
if (_x.Count > this._p) { _x.RemoveAt(0); }
if (_xx.Count > this._p) { _xx.RemoveAt(0); }
if (_y.Count > this._p) { _y.RemoveAt(0); }
if (_yy.Count > this._p) { _yy.RemoveAt(0); }
if (_xy.Count > this._p) { _xy.RemoveAt(0); }
double _sumx = 0;
for (int i = 0; i < _x.Count; i++) { _sumx += _x[i]; }
double _sumxx = 0;
for (int i = 0; i < _xx.Count; i++) { _sumxx += _xx[i]; }
double _sumy = 0;
for (int i = 0; i < _y.Count; i++) { _sumy += _y[i]; }
double _sumyy = 0;
for (int i = 0; i < _yy.Count; i++) { _sumyy += _yy[i]; }
double _sumxy = 0;
for (int i = 0; i < _xy.Count; i++) { _sumxy += _xy[i]; }
double _div = (_sumxx - _sumx * _sumx / _p) * (_sumyy - _sumy * _sumy / _p);
double _cor = (_div != 0) ? (_sumxy - _sumx * _sumy / _p) / Math.Sqrt(_div) : 0.0;
var result = (TValue1.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _cor);
if (update) { base[base.Count - 1] = result; } else { base.Add(result); }
{
public CORR_Series(TSeries d1, TSeries d2, int period, bool useNaN = false) : base(d1, d2, period, useNaN)
{
if (base._d1.Count > 0 && base._d2.Count > 0) { for (int i = 0; i < base._d1.Count; i++) { this.Add(base._d1[i], base._d2[i], false); } }
}
}
private readonly System.Collections.Generic.List<double> _x = new();
private readonly System.Collections.Generic.List<double> _xx = new();
private readonly System.Collections.Generic.List<double> _y = new();
private readonly System.Collections.Generic.List<double> _yy = new();
private readonly System.Collections.Generic.List<double> _xy = new();
public override void Add((System.DateTime t, double v) TValue1, (System.DateTime t, double v) TValue2, bool update)
{
Add_Replace_Trim(_x, TValue1.v, _p, update);
Add_Replace_Trim(_xx, TValue1.v * TValue1.v, _p, update);
Add_Replace_Trim(_y, TValue2.v, _p, update);
Add_Replace_Trim(_yy, TValue2.v * TValue2.v, _p, update);
Add_Replace_Trim(_xy, TValue1.v * TValue2.v, _p, update);
double _sumx = _x.Sum();
double _sumxx = _xx.Sum();
double _sumy = _y.Sum();
double _sumyy = _yy.Sum();
double _sumxy = _xy.Sum();
double _covar = (_sumxx - _sumx * _sumx / _p) * (_sumyy - _sumy * _sumy / _p);
double _cor = (_covar != 0) ? (_sumxy - _sumx * _sumy / _p) / Math.Sqrt(_covar) : 0.0;
var result = (TValue1.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _cor);
if (update) { base[base.Count - 1] = result; } else { base.Add(result); }
}
}
+40
View File
@@ -0,0 +1,40 @@
namespace QuanTAlib;
using System;
using System.Linq;
/* <summary>
COVAR: Covariance
Covariance is defined as the expected value (or mean) of the product
of their deviations from their individual expected values.
Sources:
https://en.wikipedia.org/wiki/Covariance
</summary> */
public class COVAR_Series : Pair_TSeries_Indicator
{
public COVAR_Series(TSeries d1, TSeries d2, int period, bool useNaN = false) : base(d1, d2, period, useNaN)
{
if (base._d1.Count > 0 && base._d2.Count > 0) { for (int i = 0; i < base._d1.Count; i++) { this.Add(base._d1[i], base._d2[i], false); } }
}
private readonly System.Collections.Generic.List<double> _x = new();
private readonly System.Collections.Generic.List<double> _y = new();
private readonly System.Collections.Generic.List<double> _xy = new();
public override void Add((System.DateTime t, double v) TValue1, (System.DateTime t, double v) TValue2, bool update)
{
Add_Replace_Trim(_x, TValue1.v, _p, update);
Add_Replace_Trim(_y, TValue2.v, _p, update);
Add_Replace_Trim(_xy, TValue1.v * TValue2.v, _p, update);
double _avgx = _x.Average();
double _avgy = _y.Average();
double _avgxy = _xy.Average();
double _covar = _avgxy - (_avgx * _avgy);
var result = (TValue1.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _covar);
if (update) { base[base.Count - 1] = result; } else { base.Add(result); }
}
}
@@ -1,5 +1,6 @@
namespace QuanTAlib;
using System;
using System.Linq;
/* <summary>
ENTP: Entropy
@@ -16,9 +17,9 @@ Sources:
</summary> */
public class ENTP_Series : Single_TSeries_Indicator
public class ENTROPY_Series : Single_TSeries_Indicator
{
public ENTP_Series(TSeries source, int period, double logbase = 2.0, bool useNaN = false) : base(source, period, useNaN)
public ENTROPY_Series(TSeries source, int period, double logbase = 2.0, bool useNaN = false) : base(source, period, useNaN)
{
this._logbase = logbase;
if (base._data.Count > 0) { base.Add(base._data); }
@@ -29,24 +30,15 @@ public class ENTP_Series : Single_TSeries_Indicator
public override void Add((System.DateTime t, double v) TValue, bool update)
{
if (update) { this._buffer[this._buffer.Count - 1] = TValue.v; }
else { this._buffer.Add(TValue.v); }
if (this._buffer.Count > this._p && this._p != 0) { this._buffer.RemoveAt(0); }
double _sum = 0;
for (int i = 0; i < this._buffer.Count; i++) { _sum += this._buffer[i]; }
Add_Replace_Trim(_buffer, TValue.v, _p, update);
double _sum = _buffer.Sum();
double _pp = this._buffer[this._buffer.Count - 1] / _sum;
double _ppp = -_pp * Math.Log(_pp) / Math.Log(this._logbase);
if (update) { this._buff2[this._buff2.Count - 1] = _ppp; }
else { this._buff2.Add(_ppp); }
if (this._buff2.Count > this._p && this._p != 0) { this._buff2.RemoveAt(0); }
Add_Replace_Trim(_buff2, _ppp, _p, update);
double _entp = _buff2.Sum();
double _entp = 0;
for (int i = 0; i < this._buff2.Count; i++) { _entp += this._buff2[i]; }
var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _entp);
base.Add(result, update);
base.Add((TValue.t, _entp), update, _NaN);
}
}
@@ -1,62 +1,57 @@
namespace QuanTAlib;
using System;
/* <summary>
KURT: Kurtosis of population
Kurtosis characterizes the relative peakedness or flatness of a distribution
compared with the normal distribution. Positive kurtosis indicates a relatively
peaked distribution. Negative kurtosis indicates a relatively flat distribution.
The normal curve is called Mesokurtic curve. If the curve of a distribution is
more outlier prone (or heavier-tailed) than a normal or mesokurtic curve then
it is referred to as a Leptokurtic curve. If a curve is less outlier prone (or
lighter-tailed) than a normal curve, it is called as a platykurtic curve.
Calculation:
sum4 = Σ(close-SMA)^4
sum2 = (Σ(close-SMA)^2)^2
KURT = length * (sum4/sum2)
Sources:
https://en.wikipedia.org/wiki/Kurtosis
https://stats.oarc.ucla.edu/other/mult-pkg/faq/general/faq-whats-with-the-different-formulas-for-kurtosis/
</summary> */
public class KURT_Series : Single_TSeries_Indicator
{
public KURT_Series(TSeries source, int period, double logbase = 2.0, bool useNaN = false) : base(source, period, useNaN)
{
this._logbase = logbase;
if (base._data.Count > 0) { base.Add(base._data); }
}
protected double _logbase;
private readonly System.Collections.Generic.List<double> _buffer = new();
public override void Add((System.DateTime t, double v) TValue, bool update)
{
if (update) { this._buffer[this._buffer.Count - 1] = TValue.v; }
else { this._buffer.Add(TValue.v); }
if (this._buffer.Count > this._p && this._p != 0) { this._buffer.RemoveAt(0); }
double _n = this._buffer.Count;
double _avg = 0;
for (int i = 0; i < this._buffer.Count; i++) { _avg += this._buffer[i]; }
_avg /= _n;
double _s2 = 0;
double _s4 = 0;
for (int i = 0; i < this._buffer.Count; i++)
{
_s2 += (this._buffer[i] - _avg) * (this._buffer[i] - _avg);
_s4 += (this._buffer[i] - _avg) * (this._buffer[i] - _avg) * (this._buffer[i] - _avg) * (this._buffer[i] - _avg);
}
double _Vx = _s2 / (_n - 1);
double _kurt = (_n > 3) ? ((((_n * (_n + 1)) / (((_n - 1) * (_n - 2)) * (_n - 3))) * (_s4 / (_Vx * _Vx))) - (3 * (((_n - 1) * (_n - 1)) / ((_n - 2) * (_n - 3))))) : Double.NaN;
var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? Double.NaN : _kurt);
base.Add(result, update);
}
namespace QuanTAlib;
using System;
using System.Linq;
/* <summary>
KURT: Kurtosis of population
Kurtosis characterizes the relative peakedness or flatness of a distribution
compared with the normal distribution. Positive kurtosis indicates a relatively
peaked distribution. Negative kurtosis indicates a relatively flat distribution.
The normal curve is called Mesokurtic curve. If the curve of a distribution is
more outlier prone (or heavier-tailed) than a normal or mesokurtic curve then
it is referred to as a Leptokurtic curve. If a curve is less outlier prone (or
lighter-tailed) than a normal curve, it is called as a platykurtic curve.
Calculation:
sum4 = Σ(close-SMA)^4
sum2 = (Σ(close-SMA)^2)^2
KURT = length * (sum4/sum2)
Sources:
https://en.wikipedia.org/wiki/Kurtosis
https://stats.oarc.ucla.edu/other/mult-pkg/faq/general/faq-whats-with-the-different-formulas-for-kurtosis/
</summary> */
public class KURTOSIS_Series : Single_TSeries_Indicator
{
public KURTOSIS_Series(TSeries source, int period, double logbase = 2.0, bool useNaN = false) : base(source, period, useNaN)
{
this._logbase = logbase;
if (base._data.Count > 0) { base.Add(base._data); }
}
protected double _logbase;
private readonly System.Collections.Generic.List<double> _buffer = new();
public override void Add((System.DateTime t, double v) TValue, bool update)
{
Add_Replace_Trim(_buffer, TValue.v, _p, update);
double _n = this._buffer.Count;
double _avg = _buffer.Average();
double _s2 = 0;
double _s4 = 0;
for (int i = 0; i < this._buffer.Count; i++)
{
_s2 += (_buffer[i] - _avg) * (_buffer[i] - _avg);
_s4 += (_buffer[i] - _avg) * (_buffer[i] - _avg) * (_buffer[i] - _avg) * (_buffer[i] - _avg);
}
double _Vx = _s2 / (_n - 1);
double _kurt = (_n > 3) ? ((((_n * (_n + 1)) / (((_n - 1) * (_n - 2)) * (_n - 3))) * (_s4 / (_Vx * _Vx))) - (3 * (((_n - 1) * (_n - 1)) / ((_n - 2) * (_n - 3))))) : Double.NaN;
var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? Double.NaN : _kurt);
base.Add(result, update);
}
}
+2 -4
View File
@@ -34,9 +34,7 @@ public class LINREG_Series : Single_TSeries_Indicator
public override void Add((System.DateTime t, double v) TValue, bool update)
{
if (update) { this._buffer[this._buffer.Count - 1] = TValue.v; }
else { this._buffer.Add(TValue.v); }
if (this._buffer.Count > this._p) { this._buffer.RemoveAt(0); }
Add_Replace_Trim(_buffer, TValue.v, _p, update);
int _len = this._buffer.Count;
@@ -79,7 +77,7 @@ public class LINREG_Series : Single_TSeries_Indicator
double _RSquared = arrr * arrr;
var ret = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _slope);
base.Add(ret, update);
base.Add(ret, update, _NaN);
ret = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _intercept);
Intercept.Add(ret, update);
+4 -8
View File
@@ -1,5 +1,6 @@
namespace QuanTAlib;
using System;
using System.Linq;
/* <summary>
MAD: Mean Absolute Deviation
@@ -24,19 +25,14 @@ public class MAD_Series : Single_TSeries_Indicator
public override void Add((System.DateTime t, double v) TValue, bool update)
{
if (update) { this._buffer[this._buffer.Count - 1] = TValue.v; }
else { _buffer.Add(TValue.v); }
if (_buffer.Count > this._p && this._p != 0) { _buffer.RemoveAt(0); }
Add_Replace_Trim(_buffer, TValue.v, _p, update);
double _sma = 0;
for (int i = 0; i < _buffer.Count; i++) { _sma += _buffer[i]; }
_sma /= this._buffer.Count;
double _sma = _buffer.Average();
double _mad = 0;
for (int i = 0; i < _buffer.Count; i++) { _mad += Math.Abs(_buffer[i] - _sma); }
_mad /= this._buffer.Count;
var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _mad);
base.Add(result, update);
base.Add((TValue.t, _mad), update, _NaN);
}
}
+8 -11
View File
@@ -1,5 +1,6 @@
namespace QuanTAlib;
using System;
using System.Linq;
/* <summary>
MAPE: Mean Absolute Percentage Error
@@ -27,19 +28,15 @@ public class MAPE_Series : Single_TSeries_Indicator
public override void Add((System.DateTime t, double v) TValue, bool update)
{
if (update) { _buffer[_buffer.Count - 1] = TValue.v; }
else { _buffer.Add(TValue.v); }
if (_buffer.Count > this._p && this._p != 0) { _buffer.RemoveAt(0); }
double _sma = 0;
for (int i = 0; i < _buffer.Count; i++) { _sma += _buffer[i]; }
_sma /= this._buffer.Count;
Add_Replace_Trim(_buffer, TValue.v, _p, update);
double _sma = _buffer.Average();
double _mape = 0;
for (int i = 0; i < _buffer.Count; i++) { _mape += (_buffer[i] != 0) ? Math.Abs(_buffer[i] - _sma) / Math.Abs(_buffer[i]) : double.PositiveInfinity; }
_mape /= this._buffer.Count;
for (int i = 0; i < _buffer.Count; i++) {
_mape += (_buffer[i] != 0) ? Math.Abs(_buffer[i] - _sma) / Math.Abs(_buffer[i]) : double.PositiveInfinity;
}
_mape /= (_buffer.Count>0) ? _buffer.Count : 1;
var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _mape);
base.Add(result, update);
base.Add((TValue.t, _mape), update, _NaN);
}
}
@@ -1,47 +1,44 @@
namespace QuanTAlib;
using System;
/* <summary>
MED - Median value
Median of numbers is the middlemost value of the given set of numbers.
It separates the higher half and the lower half of a given data sample.
At least half of the observations are smaller than or equal to median
and at least half of the observations are greater than or equal to the median.
If the number of values is odd, the middlemost observation of the sorted
list is the median of the given data. If the number of values is even,
median is the average of (n/2)th and [(n/2) + 1]th values of the sorted list.
If period = 0 => period is max
Sources:
https://corporatefinanceinstitute.com/resources/knowledge/other/median/
https://en.wikipedia.org/wiki/Median
</summary> */
public class MED_Series : Single_TSeries_Indicator
{
public MED_Series(TSeries source, int period, bool useNaN = false) : base(source, period, useNaN)
{
if (base._data.Count > 0) { base.Add(base._data); }
}
private readonly System.Collections.Generic.List<double> _buffer = new();
public override void Add((System.DateTime t, double v) TValue, bool update)
{
if (update) { this._buffer[this._buffer.Count - 1] = TValue.v; }
else { this._buffer.Add(TValue.v); }
if (this._buffer.Count > this._p && this._p != 0) { this._buffer.RemoveAt(0); }
System.Collections.Generic.List<double> _s = new(this._buffer);
_s.Sort();
int _p1 = _s.Count / 2;
int _p2 = Math.Max(0, (_s.Count / 2) - 1);
double _med = (_s.Count % 2 != 0) ? _s[_p1] : (_s[_p1] + _s[_p2]) / 2;
var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _med);
base.Add(result, update);
}
}
namespace QuanTAlib;
using System;
using static System.Net.Mime.MediaTypeNames;
/* <summary>
MED - Median value
Median of numbers is the middlemost value of the given set of numbers.
It separates the higher half and the lower half of a given data sample.
At least half of the observations are smaller than or equal to median
and at least half of the observations are greater than or equal to the median.
If the number of values is odd, the middlemost observation of the sorted
list is the median of the given data. If the number of values is even,
median is the average of (n/2)th and [(n/2) + 1]th values of the sorted list.
If period = 0 => period is max
Sources:
https://corporatefinanceinstitute.com/resources/knowledge/other/median/
https://en.wikipedia.org/wiki/Median
</summary> */
public class MEDIAN_Series : Single_TSeries_Indicator
{
public MEDIAN_Series(TSeries source, int period, bool useNaN = false) : base(source, period, useNaN)
{
if (base._data.Count > 0) { base.Add(base._data); }
}
private readonly System.Collections.Generic.List<double> _buffer = new();
public override void Add((System.DateTime t, double v) TValue, bool update)
{
Add_Replace_Trim(_buffer, TValue.v, _p, update);
System.Collections.Generic.List<double> _s = new(this._buffer);
_s.Sort();
int _p1 = _s.Count / 2;
int _p2 = Math.Max(0, (_s.Count / 2) - 1);
double _med = (_s.Count % 2 != 0) ? _s[_p1] : (_s[_p1] + _s[_p2]) / 2;
base.Add((TValue.t, _med), update, _NaN);
}
}
+4 -9
View File
@@ -1,5 +1,6 @@
namespace QuanTAlib;
using System;
using System.Linq;
/* <summary>
MSE: Mean Square Error
@@ -20,19 +21,13 @@ public class MSE_Series : Single_TSeries_Indicator
public override void Add((System.DateTime t, double v) TValue, bool update)
{
if (update) { _buffer[_buffer.Count - 1] = TValue.v; }
else { _buffer.Add(TValue.v); }
if (_buffer.Count > this._p && this._p != 0) { _buffer.RemoveAt(0); }
double _sma = 0;
for (int i = 0; i < _buffer.Count; i++) { _sma += _buffer[i]; }
_sma /= this._buffer.Count;
Add_Replace_Trim(_buffer, TValue.v, _p, update);
double _sma = _buffer.Average();
double _mse = 0;
for (int i = 0; i < _buffer.Count; i++) { _mse += (_buffer[i] - _sma) * (_buffer[i] - _sma); }
_mse /= this._buffer.Count;
var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _mse);
base.Add(result, update);
base.Add((TValue.t, _mse), update, _NaN);
}
}
+4 -9
View File
@@ -1,5 +1,6 @@
namespace QuanTAlib;
using System;
using System.Linq;
/* <summary>
SDEV: Population Standard Deviation
@@ -25,20 +26,14 @@ public class SDEV_Series : Single_TSeries_Indicator
public override void Add((System.DateTime t, double v) TValue, bool update)
{
if (update) { _buffer[_buffer.Count - 1] = TValue.v; }
else { _buffer.Add(TValue.v); }
if (_buffer.Count > this._p && this._p != 0) { _buffer.RemoveAt(0); }
double _sma = 0;
for (int i = 0; i < _buffer.Count; i++) { _sma += _buffer[i]; }
_sma /= this._buffer.Count;
Add_Replace_Trim(_buffer, TValue.v, _p, update);
double _sma = _buffer.Average();
double _pvar = 0;
for (int i = 0; i < _buffer.Count; i++) { _pvar += (_buffer[i] - _sma) * (_buffer[i] - _sma); }
_pvar /= this._buffer.Count;
double _psdev = Math.Sqrt(_pvar);
var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _psdev);
base.Add(result, update);
base.Add((TValue.t, _psdev), update, _NaN);
}
}
+4 -9
View File
@@ -1,5 +1,6 @@
namespace QuanTAlib;
using System;
using System.Linq;
/* <summary>
SMAPE: Symmetric Mean Absolute Percentage Error
@@ -20,19 +21,13 @@ public class SMAPE_Series : Single_TSeries_Indicator
public override void Add((System.DateTime t, double v) TValue, bool update)
{
if (update) { _buffer[_buffer.Count - 1] = TValue.v; }
else { _buffer.Add(TValue.v); }
if (_buffer.Count > this._p && this._p != 0) { _buffer.RemoveAt(0); }
double _sma = 0;
for (int i = 0; i < _buffer.Count; i++) { _sma += _buffer[i]; }
_sma /= this._buffer.Count;
Add_Replace_Trim(_buffer, TValue.v, _p, update);
double _sma = _buffer.Average();
double _smape = 0;
for (int i = 0; i < _buffer.Count; i++) { _smape += Math.Abs(_buffer[i] - _sma) / (Math.Abs(_buffer[i]) + Math.Abs(_sma)); }
_smape /= this._buffer.Count;
var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _smape);
base.Add(result, update);
base.Add((TValue.t, _smape), update, _NaN);
}
}
+6 -11
View File
@@ -1,5 +1,6 @@
namespace QuanTAlib;
using System;
using System.Linq;
/* <summary>
SSDEV: (Corrected) Sample Standard Deviation
@@ -25,20 +26,14 @@ public class SSDEV_Series : Single_TSeries_Indicator
public override void Add((System.DateTime t, double v) TValue, bool update)
{
if (update) { this._buffer[this._buffer.Count - 1] = TValue.v; }
else { this._buffer.Add(TValue.v); }
if (this._buffer.Count > this._p && this._p != 0) { this._buffer.RemoveAt(0); }
double _sma = 0;
for (int i = 0; i < this._buffer.Count; i++) { _sma += this._buffer[i]; }
_sma /= this._buffer.Count;
Add_Replace_Trim(_buffer, TValue.v, _p, update);
double _sma = _buffer.Average();
double _svar = 0;
for (int i = 0; i < this._buffer.Count; i++) { _svar += (this._buffer[i] - _sma) * (this._buffer[i] - _sma); }
_svar /= (this._buffer.Count > 1) ? this._buffer.Count - 1 : 1; // Bessel's correction
for (int i = 0; i < this._buffer.Count; i++) { _svar += (_buffer[i] - _sma) * (_buffer[i] - _sma); }
_svar /= (_buffer.Count > 1) ? _buffer.Count - 1 : 1; // Bessel's correction
double _ssdev = Math.Sqrt(_svar);
var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _ssdev);
base.Add(result, update);
base.Add((TValue.t, _ssdev), update, _NaN);
}
}
+4 -9
View File
@@ -1,5 +1,6 @@
namespace QuanTAlib;
using System;
using System.Linq;
/* <summary>
SVAR: Sample Variance
@@ -25,19 +26,13 @@ public class SVAR_Series : Single_TSeries_Indicator
public override void Add((System.DateTime t, double v) TValue, bool update)
{
if (update) { this._buffer[this._buffer.Count - 1] = TValue.v; }
else { this._buffer.Add(TValue.v); }
if (this._buffer.Count > this._p && this._p != 0) { this._buffer.RemoveAt(0); }
double _sma = 0;
for (int i = 0; i < this._buffer.Count; i++) { _sma += this._buffer[i]; }
_sma /= this._buffer.Count;
Add_Replace_Trim(_buffer, TValue.v, _p, update);
double _sma = _buffer.Average();
double _svar = 0;
for (int i = 0; i < this._buffer.Count; i++) { _svar += (this._buffer[i] - _sma) * (this._buffer[i] - _sma); }
_svar /= (this._buffer.Count > 1) ? this._buffer.Count - 1 : 1; // Bessel's correction
var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _svar);
base.Add(result, update);
base.Add((TValue.t, _svar), update, _NaN);
}
}
+4 -9
View File
@@ -1,5 +1,6 @@
namespace QuanTAlib;
using System;
using System.Linq;
/* <summary>
VAR: Population Variance
@@ -25,19 +26,13 @@ public class VAR_Series : Single_TSeries_Indicator
public override void Add((System.DateTime t, double v) TValue, bool update)
{
if (update) { _buffer[_buffer.Count - 1] = TValue.v; }
else { _buffer.Add(TValue.v); }
if (_buffer.Count > this._p && this._p != 0) { _buffer.RemoveAt(0); }
double _sma = 0;
for (int i = 0; i < _buffer.Count; i++) { _sma += _buffer[i]; }
_sma /= this._buffer.Count;
Add_Replace_Trim(_buffer, TValue.v, _p, update);
double _sma = _buffer.Average();
double _pvar = 0;
for (int i = 0; i < _buffer.Count; i++) { _pvar += (_buffer[i] - _sma) * (_buffer[i] - _sma); }
_pvar /= this._buffer.Count;
var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _pvar);
base.Add(result, update);
base.Add((TValue.t, _pvar), update, _NaN);
}
}
+8 -11
View File
@@ -1,9 +1,12 @@
namespace QuanTAlib;
using System;
using System.Linq;
/* <summary>
WMAPE: Weighted Mean Absolute Percentage Error
Measures the size of the error in percentage terms
Measures the size of the error in percentage terms. Improves problems with MAPE
when there are zero or close-to-zero values because there would be a division by zero
or values of MAPE tending to infinity.
Sources:
https://en.wikipedia.org/wiki/WMAPE
@@ -20,13 +23,8 @@ public class WMAPE_Series : Single_TSeries_Indicator
public override void Add((System.DateTime t, double v) TValue, bool update)
{
if (update) { _buffer[_buffer.Count - 1] = TValue.v; }
else { _buffer.Add(TValue.v); }
if (_buffer.Count > this._p && this._p != 0) { _buffer.RemoveAt(0); }
double _sma = 0;
for (int i = 0; i < _buffer.Count; i++) { _sma += _buffer[i]; }
_sma /= this._buffer.Count;
Add_Replace_Trim(_buffer, TValue.v, _p, update);
double _sma = _buffer.Average();
double _div = 0;
double _wmape = 0;
@@ -35,9 +33,8 @@ public class WMAPE_Series : Single_TSeries_Indicator
_wmape += Math.Abs(_buffer[i] - _sma);
_div += Math.Abs(_buffer[i]);
}
_wmape /= _div;
_wmape = (_div!=0) ? _wmape/_div : double.PositiveInfinity;
var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _wmape);
base.Add(result, update);
base.Add((TValue.t, _wmape), update, _NaN);
}
}
+4 -9
View File
@@ -1,5 +1,6 @@
namespace QuanTAlib;
using System;
using System.Linq;
/* <summary>
ZSCORE: number of standard deviations from SMA
@@ -31,13 +32,8 @@ public class ZSCORE_Series : Single_TSeries_Indicator
public override void Add((System.DateTime t, double v) TValue, bool update)
{
if (update) { _buffer[_buffer.Count - 1] = TValue.v; }
else { _buffer.Add(TValue.v); }
if (_buffer.Count > this._p && this._p != 0) { _buffer.RemoveAt(0); }
double _sma = 0;
for (int i = 0; i < _buffer.Count; i++) { _sma += _buffer[i]; }
_sma /= this._buffer.Count;
Add_Replace_Trim(_buffer, TValue.v, _p, update);
double _sma = _buffer.Average();
double _pvar = 0;
for (int i = 0; i < _buffer.Count; i++) { _pvar += (_buffer[i] - _sma) * (_buffer[i] - _sma); }
@@ -45,7 +41,6 @@ public class ZSCORE_Series : Single_TSeries_Indicator
double _psdev = Math.Sqrt(_pvar);
double _zscore = (_psdev == 0) ? double.NaN : (TValue.v - _sma) / _psdev;
var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _zscore);
base.Add(result, update);
base.Add((TValue.t, _zscore), update, _NaN);
}
}
+41 -45
View File
@@ -19,49 +19,45 @@ TODO: Discrepancy with Pandas-TA (but passes the validation with Skender.GetAlma
</summary> */
public class ALMA_Series : Single_TSeries_Indicator
{
private readonly System.Collections.Generic.List<double> _buffer = new();
private readonly double[] _weight;
private double _norm;
private readonly double _offset, _sigma;
public ALMA_Series(TSeries source, int period, double offset = 0.85, double sigma = 6.0, bool useNaN = false)
: base(source, period, useNaN)
{
_offset = offset;
_sigma = sigma;
_weight = new double[period];
if (this._data.Count > 0) { base.Add(this._data); }
}
public override void Add((System.DateTime t, double v) TValue, bool update)
{
if (update) { this._buffer[this._buffer.Count - 1] = TValue.v; }
else { this._buffer.Add(TValue.v); }
if (this._buffer.Count > this._p) { this._buffer.RemoveAt(0); }
if (this._buffer.Count <= _p) { calc_weights(); }
double _weightedSum = 0;
for (int i = 0; i < this._buffer.Count; i++) { _weightedSum += _weight[i] * _buffer[i]; }
double _alma = _weightedSum / _norm;
var ret = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _alma);
base.Add(ret, update);
}
private void calc_weights()
{
int _len = this._buffer.Count;
_norm = 0;
double _m = _offset * (_len - 1);
double _s = _len / _sigma;
for (int i = 0; i < _len; i++)
{
double _wt = Math.Exp(-((i - _m) * (i - _m)) / (2 * _s * _s));
_weight[i] = _wt;
_norm += _wt;
}
}
{
private readonly System.Collections.Generic.List<double> _buffer = new();
private readonly double[] _weight;
private double _norm;
private readonly double _offset, _sigma;
public ALMA_Series(TSeries source, int period, double offset = 0.85, double sigma = 6.0, bool useNaN = false)
: base(source, period, useNaN)
{
_offset = offset;
_sigma = sigma;
_weight = new double[period];
if (this._data.Count > 0) { base.Add(this._data); }
}
public override void Add((System.DateTime t, double v) TValue, bool update)
{
Add_Replace_Trim(_buffer, TValue.v, _p, update);
if (this._buffer.Count <= _p)
{
int _len = this._buffer.Count;
_norm = 0;
double _m = _offset * (_len - 1);
double _s = _len / _sigma;
for (int i = 0; i < _len; i++)
{
double _wt = Math.Exp(-((i - _m) * (i - _m)) / (2 * _s * _s));
_weight[i] = _wt;
_norm += _wt;
}
}
double _weightedSum = 0;
for (int i = 0; i < this._buffer.Count; i++)
{ _weightedSum += _weight[i] * _buffer[i]; }
double _alma = _weightedSum / _norm;
base.Add((TValue.t, _alma), update, _NaN);
}
}
+4 -11
View File
@@ -1,5 +1,6 @@
namespace QuanTAlib;
using System;
using System.Linq;
/* <summary>
DEMA: Double Exponential Moving Average
@@ -41,16 +42,9 @@ public class DEMA_Series : Single_TSeries_Indicator
if (this.Count < this._p)
{
if (update) { _buffer[_buffer.Count - 1] = TValue.v; }
else
{
_buffer.Add(TValue.v);
}
if (_buffer.Count > this._p) { _buffer.RemoveAt(0); }
Add_Replace_Trim(_buffer, TValue.v, _p, update);
double _sma = _buffer.Average();
double _sma = 0;
for (int i = 0; i < _buffer.Count; i++) { _sma += _buffer[i]; }
_sma /= this._buffer.Count;
_ema1 = _ema2 = _sma;
}
else
@@ -65,7 +59,6 @@ public class DEMA_Series : Single_TSeries_Indicator
this._lastema1 = _ema1;
this._lastema2 = _ema2;
var ret = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _dema);
base.Add(ret, update);
base.Add((TValue.t, _dema), update, _NaN);
}
}
+5 -12
View File
@@ -1,5 +1,6 @@
namespace QuanTAlib;
using System;
using System.Linq;
/* <summary>
EMA: Exponential Moving Average
@@ -35,20 +36,13 @@ public class EMA_Series : Single_TSeries_Indicator
public override void Add((DateTime t, double v) TValue, bool update)
{
double _ema = 0;
double _ema;
if (update) { this._lastema = this._lastlastema; }
if (this.Count < this._p)
{
if (update) { this._buffer[this._buffer.Count - 1] = TValue.v; }
else
{
this._buffer.Add(TValue.v);
}
if (this._buffer.Count > this._p) { this._buffer.RemoveAt(0); }
for (int i = 0; i < this._buffer.Count; i++) { _ema += this._buffer[i]; }
_ema /= this._buffer.Count;
Add_Replace(_buffer, TValue.v, update);
_ema = _buffer.Average();
}
else
{
@@ -58,7 +52,6 @@ public class EMA_Series : Single_TSeries_Indicator
this._lastlastema = this._lastema;
this._lastema = _ema;
var ret = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _ema);
base.Add(ret, update);
base.Add((TValue.t, _ema), update, _NaN);
}
}
+6 -14
View File
@@ -2,8 +2,8 @@
using System;
/* <summary>
HEMA: Hull-EMA Moving Average
Modified HUll Moving Average; instead of using WMA (Weighted MA) for acalculation,
HEMA: Hull-EMA Moving Average - a hybrid indicator
Modified HUll Moving Average; instead of using WMA (Weighted MA) for calculation,
HEMA uses EMA for Hull's formula:
EMA1 = EMA(n/2) of price - where k = 4/(n/2 +1)
@@ -39,17 +39,11 @@ public class HEMA_Series : Single_TSeries_Indicator
this._lastema2 = this._lastlastema2;
this._lastema3 = this._lastlastema3;
}
double _ema1 = System.Double.IsNaN(this._lastema1)
? TValue.v
: TValue.v * this._k1 + this._lastema1 * (1 - this._k1);
double _ema2 = System.Double.IsNaN(this._lastema2)
? TValue.v
: TValue.v * this._k2 + this._lastema2 * (1 - this._k2);
double _ema1 = System.Double.IsNaN(this._lastema1) ? TValue.v : TValue.v * this._k1 + this._lastema1 * (1 - this._k1);
double _ema2 = System.Double.IsNaN(this._lastema2) ? TValue.v : TValue.v * this._k2 + this._lastema2 * (1 - this._k2);
double _rawhema = (2 * _ema1) - _ema2;
double _ema3 = System.Double.IsNaN(this._lastema3)
? _rawhema
: _rawhema * this._k3 + this._lastema3 * (1 - this._k3);
double _ema3 = System.Double.IsNaN(this._lastema3) ? _rawhema : _rawhema * this._k3 + this._lastema3 * (1 - this._k3);
this._lastlastema1 = this._lastema1;
this._lastlastema2 = this._lastema2;
@@ -58,8 +52,6 @@ public class HEMA_Series : Single_TSeries_Indicator
this._lastema2 = _ema2;
this._lastema3 = _ema3;
(System.DateTime t, double v) result =
(TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _ema3);
base.Add(result, update);
base.Add((TValue.t, _ema3), update, _NaN);
}
}
+1 -2
View File
@@ -73,7 +73,6 @@ public class HMA_Series : TSeries
{
this._wma1 += this._buf1[i] * this._weights[i];
}
this._wma1 /= (this._buf1.Count * (this._buf1.Count + 1)) * 0.5;
this._wma2 = 0;
@@ -81,7 +80,6 @@ public class HMA_Series : TSeries
{
this._wma2 += this._buf2[i] * this._weights[i];
}
this._wma2 /= (this._buf2.Count * (this._buf2.Count + 1)) * 0.5;
if (update)
@@ -92,6 +90,7 @@ public class HMA_Series : TSeries
{
this._buf3.Add(2 * this._wma1 - this._wma2);
}
if (this._buf3.Count > (int)Math.Sqrt(this._p))
{
this._buf3.RemoveAt(0);
+4 -7
View File
@@ -150,12 +150,9 @@ public class JMA_Series : Single_TSeries_Indicator
double det1 = ((ma2 - this.prev_jma) * (1 - alpha) * (1 - alpha)) +
(this.prev_det1 * alpha * alpha);
this.prev_det1 = det1;
var jma = this.prev_jma + det1;
this.prev_jma = jma;
var _jma = this.prev_jma + det1;
this.prev_jma = _jma;
(System.DateTime t, double v) result =
(TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : jma);
base.Add(result, update);
}
base.Add((TValue.t, _jma), update, _NaN);
}
}
+3 -3
View File
@@ -44,6 +44,7 @@ public class KAMA_Series : Single_TSeries_Indicator
_buffer.Add(TValue.v);
}
if (_buffer.Count > _p + 1) { _buffer.RemoveAt(0); }
double _kama = 0;
if (this.Count < this._p) {
for (int i = 0; i < this._buffer.Count; i++) { _kama += this._buffer[i]; }
@@ -59,7 +60,6 @@ public class KAMA_Series : Single_TSeries_Indicator
}
_lastlastkama = _lastkama;
_lastkama = _kama;
var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _kama);
base.Add(result, update);
}
base.Add((TValue.t, _kama), update, _NaN);
}
}
+2 -3
View File
@@ -40,7 +40,6 @@ public class MACD_Series : Single_TSeries_Indicator
_TSfast.Add(TValue, true);
}
_macd = this._TSmacd[(this.Count < this._TSmacd.Count) ? this.Count : this._TSmacd.Count - 1].v;
var result = (TValue.t, _macd);
base.Add(result, update);
}
base.Add((TValue.t, _macd), update, _NaN);
}
}
+6 -13
View File
@@ -1,5 +1,6 @@
namespace QuanTAlib;
using System;
using System.Linq;
/* <summary>
RMA: wildeR Moving Average
@@ -34,20 +35,13 @@ public class RMA_Series : Single_TSeries_Indicator
public override void Add((DateTime t, double v) TValue, bool update)
{
double _ema = 0;
double _ema;
if (update) { this._lastema = this._lastlastema; }
if (this.Count < this._p)
{
if (update) { _buffer[_buffer.Count - 1] = TValue.v; }
else
{
_buffer.Add(TValue.v);
}
if (_buffer.Count > this._p) { _buffer.RemoveAt(0); }
for (int i = 0; i < _buffer.Count; i++) { _ema += _buffer[i]; }
_ema /= this._buffer.Count;
Add_Replace_Trim(_buffer, TValue.v, _p, update);
_ema = _buffer.Average();
}
else
{
@@ -57,7 +51,6 @@ public class RMA_Series : Single_TSeries_Indicator
this._lastlastema = this._lastema;
this._lastema = _ema;
var ret = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _ema);
base.Add(ret, update);
}
base.Add((TValue.t, _ema), update, _NaN);
}
}
+4 -10
View File
@@ -1,5 +1,6 @@
namespace QuanTAlib;
using System;
using System.Linq;
/* <summary>
SMA: Simple Moving Average
@@ -26,16 +27,9 @@ public class SMA_Series : Single_TSeries_Indicator
public override void Add((System.DateTime t, double v) TValue, bool update)
{
if (update) { _buffer[_buffer.Count - 1] = TValue.v; }
else { _buffer.Add(TValue.v); }
if (_buffer.Count > this._p && this._p != 0) { _buffer.RemoveAt(0); }
Add_Replace_Trim(_buffer, TValue.v, _p, update);
double _sma = _buffer.Sum() / _buffer.Count;
double _sma = 0;
for (int i = 0; i < _buffer.Count; i++) { _sma += _buffer[i]; }
_sma /= this._buffer.Count;
var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _sma);
base.Add(result, update);
base.Add((TValue.t, _sma), update, _NaN);
}
}
+5 -12
View File
@@ -1,5 +1,6 @@
namespace QuanTAlib;
using System;
using System.Linq;
/* <summary>
SMMA: Smoothed Moving Average
@@ -34,15 +35,8 @@ public class SMMA_Series : Single_TSeries_Indicator
if (this.Count < this._p)
{
if (update) { this._buffer[this._buffer.Count - 1] = TValue.v; }
else
{
this._buffer.Add(TValue.v);
}
if (this._buffer.Count > this._p) { this._buffer.RemoveAt(0); }
for (int i = 0; i < this._buffer.Count; i++) { _smma += this._buffer[i]; }
_smma /= this._buffer.Count;
Add_Replace_Trim(_buffer, TValue.v, _p, update);
_smma = _buffer.Average();
}
else
{
@@ -52,7 +46,6 @@ public class SMMA_Series : Single_TSeries_Indicator
this._lastlastsmma = this._lastsmma;
this._lastsmma = _smma;
var ret = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _smma);
base.Add(ret, update);
}
base.Add((TValue.t, _smma), update, _NaN);
}
}
+5 -13
View File
@@ -1,5 +1,6 @@
namespace QuanTAlib;
using System;
using System.Linq;
/* <summary>
TEMA: Triple Exponential Moving Average
@@ -44,16 +45,8 @@ public class TEMA_Series : Single_TSeries_Indicator
if (this.Count < this._p)
{
if (update) { _buffer[_buffer.Count - 1] = TValue.v; }
else
{
_buffer.Add(TValue.v);
}
if (_buffer.Count > this._p) { _buffer.RemoveAt(0); }
double _sma = 0;
for (int i = 0; i < _buffer.Count; i++) { _sma += _buffer[i]; }
_sma /= this._buffer.Count;
Add_Replace_Trim(_buffer, TValue.v, _p, update);
double _sma = _buffer.Average();
_ema1 = _ema2 = _ema3 = _sma;
}
else
@@ -72,7 +65,6 @@ public class TEMA_Series : Single_TSeries_Indicator
this._lastema2 = _ema2;
this._lastema3 = _ema3;
var ret = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _tema);
base.Add(ret, update);
}
base.Add((TValue.t, _tema), update, _NaN);
}
}
+5 -11
View File
@@ -1,5 +1,6 @@
namespace QuanTAlib;
using System;
using System.Linq;
/* <summary>
TRIMA: Triangular Moving Average
@@ -31,19 +32,12 @@ public class TRIMA_Series : Single_TSeries_Indicator
{
if (update) { _buffer1[_buffer1.Count - 1] = TValue.v; } else { _buffer1.Add(TValue.v); }
if (_buffer1.Count > this._p1b && this._p1b != 0) { _buffer1.RemoveAt(0); }
double _sma1 = 0;
for (int i = 0; i < _buffer1.Count; i++) { _sma1 += _buffer1[i]; }
_sma1 /= this._buffer1.Count;
double _sma1 = _buffer1.Average();
if (update) { _buffer2[_buffer2.Count - 1] = _sma1; } else { _buffer2.Add(_sma1); }
if (_buffer2.Count > this._p1a && this._p1a != 0) { _buffer2.RemoveAt(0); }
double _trima = _buffer2.Average();
double _trima = 0;
for (int i = 0; i < _buffer2.Count; i++) { _trima += _buffer2[i]; }
_trima /= this._buffer2.Count;
var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _trima);
base.Add(result, update);
}
base.Add((TValue.t, _trima), update, _NaN);
}
}
+2 -6
View File
@@ -24,16 +24,12 @@ public class WMA_Series : Single_TSeries_Indicator
public override void Add((System.DateTime t, double v) TValue, bool update)
{
if (update) { _buffer[_buffer.Count - 1] = TValue.v; }
else { _buffer.Add(TValue.v); }
if (_buffer.Count > this._p && this._p != 0) { _buffer.RemoveAt(0); }
Add_Replace_Trim(_buffer, TValue.v, _p, update);
double _wma = 0;
for (int i = 0; i < _buffer.Count; i++) { _wma += _buffer[i] * this._weights[i]; }
_wma /= (this._buffer.Count * (this._buffer.Count + 1)) * 0.5;
var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _wma);
base.Add(result, update);
base.Add((TValue.t, _wma), update, _NaN);
}
}
+5 -15
View File
@@ -1,5 +1,6 @@
namespace QuanTAlib;
using System;
using System.Linq;
/* <summary>
ZLEMA: Zero Lag Exponential Moving Average
@@ -45,18 +46,8 @@ public class ZLEMA_Series : Single_TSeries_Indicator
{ this._lastema = this._lastlastema; }
if (this.Count < this._p)
{
if (update)
{ this._buffer[this._buffer.Count - 1] = _zl; }
else
{
this._buffer.Add(_zl);
}
if (this._buffer.Count > this._p)
{ this._buffer.RemoveAt(0); }
for (int i = 0; i < this._buffer.Count; i++)
{ _ema += this._buffer[i]; }
_ema /= this._buffer.Count;
Add_Replace_Trim(_buffer, _zl, _p, update);
_ema = _buffer.Average();
}
else
{
@@ -66,7 +57,6 @@ public class ZLEMA_Series : Single_TSeries_Indicator
this._lastlastema = this._lastema;
this._lastema = _ema;
var ret = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _ema);
base.Add(ret, update);
}
base.Add((TValue.t, _ema), update, _NaN);
}
}
+2 -3
View File
@@ -37,7 +37,6 @@ public class ADL_Series : Single_TBars_Indicator
this._lastlastadl = this._lastadl;
this._lastadl = _adl;
var ret = (TBar.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _adl);
base.Add(ret, update);
}
base.Add((TBar.t, _adl), update, _NaN);
}
}