0.1.21 MAMA

This commit is contained in:
Miha Kralj
2022-11-17 22:10:11 -08:00
59 changed files with 1648 additions and 1625 deletions
+7 -1
View File
@@ -3,10 +3,12 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17 # Visual Studio Version 17
VisualStudioVersion = 17.2.32210.308 VisualStudioVersion = 17.2.32210.308
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuanTAlib", "Source\QuanTAlib.csproj", "{AAE21F8A-9BC2-4647-A9EB-4DC86C569080}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QuanTAlib", "Source\QuanTAlib.csproj", "{AAE21F8A-9BC2-4647-A9EB-4DC86C569080}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tests", "Tests\Tests.csproj", "{283EACC9-3AF6-4DAE-9C1C-0F7F8C8CD70D}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tests", "Tests\Tests.csproj", "{283EACC9-3AF6-4DAE-9C1C-0F7F8C8CD70D}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Quantower", "Quantower\Quantower.csproj", "{693713F9-F33A-4B33-8F98-63794CA9734C}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@@ -21,6 +23,10 @@ Global
{283EACC9-3AF6-4DAE-9C1C-0F7F8C8CD70D}.Debug|Any CPU.Build.0 = Debug|Any CPU {283EACC9-3AF6-4DAE-9C1C-0F7F8C8CD70D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{283EACC9-3AF6-4DAE-9C1C-0F7F8C8CD70D}.Release|Any CPU.ActiveCfg = Release|Any CPU {283EACC9-3AF6-4DAE-9C1C-0F7F8C8CD70D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{283EACC9-3AF6-4DAE-9C1C-0F7F8C8CD70D}.Release|Any CPU.Build.0 = Release|Any CPU {283EACC9-3AF6-4DAE-9C1C-0F7F8C8CD70D}.Release|Any CPU.Build.0 = Release|Any CPU
{693713F9-F33A-4B33-8F98-63794CA9734C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{693713F9-F33A-4B33-8F98-63794CA9734C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{693713F9-F33A-4B33-8F98-63794CA9734C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{693713F9-F33A-4B33-8F98-63794CA9734C}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
+2 -2
View File
@@ -19,13 +19,13 @@ public class ENTP_chart : Indicator
private TBars bars; private TBars bars;
/////// ///////
private ENTP_Series indicator; private ENTROPY_Series indicator;
/////// ///////
public ENTP_chart() public ENTP_chart()
{ {
this.SeparateWindow = true; this.SeparateWindow = true;
this.Name = "ENTP - Entropy (Unpredictability)"; this.Name = "ENTROPY - Entropy (Unpredictability)";
this.Description = "Entropy description"; this.Description = "Entropy description";
this.AddLineSeries("ENTROPY", Color.RoyalBlue, 3, LineStyle.Solid); this.AddLineSeries("ENTROPY", Color.RoyalBlue, 3, LineStyle.Solid);
} }
+2 -2
View File
@@ -19,13 +19,13 @@ public class KURT_chart : Indicator
private TBars bars; private TBars bars;
/////// ///////
private KURT_Series indicator; private KURTOSIS_Series indicator;
/////// ///////
public KURT_chart() public KURT_chart()
{ {
this.SeparateWindow = true; this.SeparateWindow = true;
this.Name = "KURT - Kurtosis (Flatness)"; this.Name = "KURTOSIS - Kurtosis (Flatness)";
this.Description = "Kurtosis description"; this.Description = "Kurtosis description";
this.AddLineSeries("KURTOSIS", Color.RoyalBlue, 3, LineStyle.Solid); this.AddLineSeries("KURTOSIS", Color.RoyalBlue, 3, LineStyle.Solid);
} }
+1 -1
View File
@@ -19,7 +19,7 @@ public class MED_chart : Indicator
private TBars bars; private TBars bars;
/////// ///////
private MED_Series indicator; private MEDIAN_Series indicator;
/////// ///////
public MED_chart() public MED_chart()
+4
View File
@@ -13,6 +13,7 @@
<PlatformTarget>AnyCPU</PlatformTarget> <PlatformTarget>AnyCPU</PlatformTarget>
<Nullable>disable</Nullable> <Nullable>disable</Nullable>
<SignAssembly>False</SignAssembly> <SignAssembly>False</SignAssembly>
<CodeAnalysisRuleSet>..\.sonarlint\mihakralj_quantalibcsharp.ruleset</CodeAnalysisRuleSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<Optimize>True</Optimize> <Optimize>True</Optimize>
@@ -36,6 +37,9 @@
<Target Name="CopyCustomContent" AfterTargets="AfterBuild"> <Target Name="CopyCustomContent" AfterTargets="AfterBuild">
<Copy SourceFiles=".\bin\$(Configuration)\net48\Quantower_QTAlib.dll" DestinationFolder="\Quantower\Settings\Scripts\Indicators\QuanTAlib" /> <Copy SourceFiles=".\bin\$(Configuration)\net48\Quantower_QTAlib.dll" DestinationFolder="\Quantower\Settings\Scripts\Indicators\QuanTAlib" />
</Target> </Target>
<ItemGroup>
<AdditionalFiles Include="..\.sonarlint\mihakralj_quantalib\CSharp\SonarLint.xml" Link="SonarLint.xml" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<Reference Include="TradingPlatform.BusinessLayer"> <Reference Include="TradingPlatform.BusinessLayer">
<HintPath>C:\Quantower\TradingPlatform\v1.124.6\bin\TradingPlatform.BusinessLayer.dll</HintPath> <HintPath>C:\Quantower\TradingPlatform\v1.124.6\bin\TradingPlatform.BusinessLayer.dll</HintPath>
+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) 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, (System.DateTime t, double v) result = ((TValue1.t > TValue2.t) ? TValue1.t : TValue2.t, TValue1.v+TValue2.v);
TValue1.v+TValue2.v);
if (update) { base[base.Count - 1] = result; } else { base.Add(result); } if (update) { base[base.Count - 1] = result; } else { base.Add(result); }
} }
} }
+4 -12
View File
@@ -1,5 +1,6 @@
namespace QuanTAlib; namespace QuanTAlib;
using System; using System;
using System.Linq;
/* <summary> /* <summary>
MAX - Maximum value in the given period in the series. 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) public override void Add((DateTime t, double v) TValue, bool update)
{ {
if (update) { this._buffer[this._buffer.Count - 1] = TValue.v; } Add_Replace_Trim(_buffer, TValue.v, _p, update);
else { this._buffer.Add(TValue.v); } double _max = _buffer.Max();
if (this._buffer.Count > this._p && this._p != 0) { this._buffer.RemoveAt(0); }
double _max = TValue.v; base.Add((TValue.t, _max), update, _NaN);
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);
} }
} }
+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) public override void Add((DateTime t, double v) TValue, bool update)
{ {
if (update) Add_Replace_Trim(_buffer, TValue.v, _p, update);
{ this._buffer[this._buffer.Count - 1] = TValue.v; }
else
{ this._buffer.Add(TValue.v); }
if (this._buffer.Count > this._p && this._p != 0)
{ this._buffer.RemoveAt(0); }
double _max = TValue.v; double _max = TValue.v;
double _min = TValue.v; double _min = TValue.v;
@@ -37,8 +32,6 @@ public class MIDPOINT_Series : Single_TSeries_Indicator
} }
double _mid = (_max + _min) * 0.5; double _mid = (_max + _min) * 0.5;
var result = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _mid); base.Add((TValue.t, _mid), update, _NaN);
base.Add(result, update);
} }
} }
+6 -24
View File
@@ -1,5 +1,6 @@
namespace QuanTAlib; namespace QuanTAlib;
using System; using System;
using System.Linq;
/* <summary> /* <summary>
MIDPRICE: Midpoint price (highhest high + lowest low)/2 in the given period in the series. 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) public override void Add((DateTime t, double o, double h, double l, double c, double v) TBar, bool update)
{ {
if (update) Add_Replace_Trim(_bufferhi, TBar.h, _p, update);
{ Add_Replace_Trim(_bufferlo, TBar.l, _p, update);
this._bufferhi[this._bufferhi.Count - 1] = TBar.h;
this._bufferlo[this._bufferlo.Count - 1] = TBar.l;
}
else
{
this._bufferhi.Add(TBar.h);
this._bufferlo.Add(TBar.l);
}
if (this._bufferhi.Count > this._p && this._p != 0)
{ this._bufferhi.RemoveAt(0); }
if (this._bufferlo.Count > this._p && this._p != 0)
{ this._bufferlo.RemoveAt(0); }
double _max = TBar.h; double _max = _bufferhi.Max();
double _min = TBar.l; double _min = _bufferlo.Min();
for (int i = 0; i < this._bufferhi.Count; i++)
{
_max = Math.Max(this._bufferhi[i], _max);
_min = Math.Min(this._bufferlo[i], _min);
}
double _mid = (_max + _min) * 0.5; double _mid = (_max + _min) * 0.5;
var result = (TBar.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _mid); base.Add((TBar.t, _mid), update, _NaN);
base.Add(result, update);
} }
} }
+4 -12
View File
@@ -1,5 +1,6 @@
namespace QuanTAlib; namespace QuanTAlib;
using System; using System;
using System.Linq;
/* <summary> /* <summary>
MIN - Minimum value in the given period in the series. 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) public override void Add((System.DateTime t, double v) TValue, bool update)
{ {
if (update) { this._buffer[this._buffer.Count - 1] = TValue.v; } Add_Replace_Trim(_buffer, TValue.v, _p, update);
else { this._buffer.Add(TValue.v); }
if (this._buffer.Count > this._p && this._p != 0) { this._buffer.RemoveAt(0); }
double _min = TValue.v; double _min = _buffer.Min();
for (int i = 0; i < this._buffer.Count; i++) base.Add((TValue.t, _min), update, _NaN);
{
_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);
} }
} }
@@ -1,5 +1,7 @@
namespace QuanTAlib; namespace QuanTAlib;
using System; using System;
using System.Collections.Generic;
/* <summary> /* <summary>
Abstract classes with all scaffolding required to build indicators. Abstract classes with all scaffolding required to build indicators.
All abstracts support period, NaN, and all permutations of Add() methods. All abstracts support period, NaN, and all permutations of Add() methods.
@@ -13,32 +15,7 @@ Abstract classes with all scaffolding required to build indicators.
Single_TBars_Indicator - One OHLCV TBars in, one TSeries out. Single_TBars_Indicator - One OHLCV TBars in, one TSeries out.
</summary> */ </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 public abstract class Pair_TSeries_Indicator : TSeries
{ {
@@ -118,31 +95,18 @@ public abstract class Pair_TSeries_Indicator : TSeries
public void Add() => this.Add(update: false); public void Add() => this.Add(update: false);
public new void Sub(object source, TSeriesEventArgs e) => this.Add(e.update); public new void Sub(object source, TSeriesEventArgs e) => this.Add(e.update);
}
public abstract class Single_TBars_Indicator : TSeries protected static void Add_Replace(List<double> l, double v, bool update)
{
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; if (update)
this._bars = source; { l[l.Count - 1] = v; }
this._NaN = useNaN; else
this._bars.Pub += this.Sub; { 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); }
} }
// 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);
} }
+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") public Alphavantage_Feed(string Symbol = "IBM", string APIkey = "demo")
{ {
System.Net.Http.HttpClient client = new(); 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; string req = "https://www.alphavantage.co/query?function=TIME_SERIES_DAILY_ADJUSTED" + "&symbol=" + Symbol + "&apikey=" + APIkey;
var msg = client.GetStringAsync(req).Result; var msg = client.GetStringAsync(req).Result;
var jres = JsonSerializer.Deserialize<JsonDocument>(msg).RootElement; 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"); } if (json.ValueKind == JsonValueKind.Undefined) {throw new InvalidOperationException("Stock symbol "+Symbol+" not found"); }
foreach (var val in json.EnumerateObject()) { base.Add(GetOHLC(val)); } foreach (var val in json.EnumerateObject()) { base.Add(GetOHLC(val)); }
+1
View File
@@ -15,6 +15,7 @@ Yahoo Finance - Free API feed to collect daily market quotes
public class Yahoo_Feed : TBars public class Yahoo_Feed : TBars
{ {
public Yahoo_Feed(string Symbol = "IBM", int Period = 252) { public Yahoo_Feed(string Symbol = "IBM", int Period = 252) {
Period = (int)(Period*1.45);
string requestUrl = "https://query1.finance.yahoo.com/v8/finance/chart/"+ string requestUrl = "https://query1.finance.yahoo.com/v8/finance/chart/"+
Symbol+"?interval=1d&period1="+ Symbol+"?interval=1d&period1="+
(int)new DateTimeOffset(DateTime.UtcNow.AddDays(-Period+1)).ToUnixTimeSeconds()+"&period2="+ (int)new DateTimeOffset(DateTime.UtcNow.AddDays(-Period+1)).ToUnixTimeSeconds()+"&period2="+
+6 -6
View File
@@ -1,5 +1,7 @@
namespace QuanTAlib; namespace QuanTAlib;
using System; using System;
using System.Linq;
using static System.Net.Mime.MediaTypeNames;
/* <summary> /* <summary>
CCI: Commodity Channel Index 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); } if (this._tp.Count > this._p) { this._tp.RemoveAt(0); }
// average TP over _tp buffer // average TP over _tp buffer
double _avgTp = 0; double _avgTp = _tp.Average();
for (int i = 0; i < this._tp.Count; i++) { _avgTp+=this._tp[i]; }
_avgTp /= this._tp.Count;
// average Deviation over _tp buffer // average Deviation over _tp buffer
double _avgDv = 0; double _avgDv = 0;
for (int i = 0; i < this._tp.Count; i++) { _avgDv += Math.Abs(_avgTp - this._tp[i]); } for (int i = 0; i < this._tp.Count; i++) { _avgDv += Math.Abs(_avgTp - this._tp[i]); }
_avgDv /= this._tp.Count; _avgDv /= this._tp.Count;
double _cci = (_avgDv == 0) ? double.NaN : (this._tp[this._tp.Count-1] - _avgTp) / (0.015 * _avgDv); 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((TBar.t, _cci), update, _NaN);
base.Add(result, update); }
}
} }
+1 -1
View File
@@ -2,7 +2,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<Title>QuanTAlib</Title> <Title>QuanTAlib</Title>
<Version>0.1.20</Version> <Version>0.1.21</Version>
<Product>Library of Technical Indicators for .NET</Product> <Product>Library of Technical Indicators for .NET</Product>
<Description>Quantitative Technical Analysis library for both real-time (streaming) and historical data analysis</Description> <Description>Quantitative Technical Analysis library for both real-time (streaming) and historical data analysis</Description>
<RepositoryType>git</RepositoryType> <RepositoryType>git</RepositoryType>
+5 -10
View File
@@ -1,5 +1,6 @@
namespace QuanTAlib; namespace QuanTAlib;
using System; using System;
using System.Linq;
/* <summary> /* <summary>
BIAS: Rate of change between the source and a moving average. 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) public override void Add((System.DateTime t, double v) TValue, bool update)
{ {
if (update) { this._buffer[this._buffer.Count - 1] = TValue.v; } Add_Replace_Trim(_buffer, TValue.v, _p, update);
else { this._buffer.Add(TValue.v); }
if (this._buffer.Count > this._p && this._p != 0) { this._buffer.RemoveAt(0); }
double _sma = 0; double _sma = _buffer.Average();
for (int i = 0; i < this._buffer.Count; i++) { _sma += this._buffer[i]; } double _bias = (_buffer[_buffer.Count - 1] / ((_sma != 0) ? _sma : 1)) - 1;
_sma /= this._buffer.Count;
double _bias = (this._buffer[this._buffer.Count - 1] / ((_sma != 0) ? _sma : 1)) - 1;
var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _bias); base.Add((TValue.t, _bias), update, _NaN);
base.Add(result, update);
} }
} }
+17 -35
View File
@@ -1,5 +1,7 @@
namespace QuanTAlib; namespace QuanTAlib;
using System; using System;
using System.Collections.Generic;
using System.Linq;
/* <summary> /* <summary>
CORR: Pearson's Correlation Coefficient CORR: Pearson's Correlation Coefficient
@@ -28,43 +30,23 @@ public class CORR_Series : Pair_TSeries_Indicator
public override void Add((System.DateTime t, double v) TValue1, (System.DateTime t, double v) TValue2, bool update) public override void Add((System.DateTime t, double v) TValue1, (System.DateTime t, double v) TValue2, bool update)
{ {
if (update) Add_Replace_Trim(_x, TValue1.v, _p, update);
{ Add_Replace_Trim(_xx, TValue1.v * TValue1.v, _p, update);
_x[_x.Count - 1] = TValue1.v; Add_Replace_Trim(_y, TValue2.v, _p, update);
_xx[_xx.Count - 1] = TValue1.v * TValue1.v; Add_Replace_Trim(_yy, TValue2.v * TValue2.v, _p, update);
_y[_y.Count - 1] = TValue2.v; Add_Replace_Trim(_xy, TValue1.v * TValue2.v, _p, update);
_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; double _sumx = _x.Sum();
for (int i = 0; i < _x.Count; i++) { _sumx += _x[i]; } double _sumxx = _xx.Sum();
double _sumxx = 0; double _sumy = _y.Sum();
for (int i = 0; i < _xx.Count; i++) { _sumxx += _xx[i]; } double _sumyy = _yy.Sum();
double _sumy = 0; double _sumxy = _xy.Sum();
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 _covar = (_sumxx - _sumx * _sumx / _p) * (_sumyy - _sumy * _sumy / _p);
double _cor = (_div != 0) ? (_sumxy - _sumx * _sumy / _p) / Math.Sqrt(_div) : 0.0; 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); 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); } if (update) { base[base.Count - 1] = result; } else { base.Add(result); }
}
}
} }
+9 -36
View File
@@ -1,5 +1,6 @@
namespace QuanTAlib; namespace QuanTAlib;
using System; using System;
using System.Linq;
/* <summary> /* <summary>
COVAR: Covariance COVAR: Covariance
@@ -19,49 +20,21 @@ public class COVAR_Series : Pair_TSeries_Indicator
} }
private readonly System.Collections.Generic.List<double> _x = new(); 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> _y = new();
private readonly System.Collections.Generic.List<double> _yy = new();
private readonly System.Collections.Generic.List<double> _xy = 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) public override void Add((System.DateTime t, double v) TValue1, (System.DateTime t, double v) TValue2, bool update)
{ {
if (update) Add_Replace_Trim(_x, TValue1.v, _p, update);
{ Add_Replace_Trim(_y, TValue2.v, _p, update);
_x[_x.Count - 1] = TValue1.v; Add_Replace_Trim(_xy, TValue1.v * TValue2.v, _p, update);
_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; double _avgx = _x.Average();
for (int i = 0; i < _x.Count; i++) { _sumx += _x[i]; } double _avgy = _y.Average();
double _sumxx = 0; double _avgxy = _xy.Average();
for (int i = 0; i < _xx.Count; i++) { _sumxx += _xx[i]; } double _covar = _avgxy - (_avgx * _avgy);
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 _covar = (_sumxy / _p) - ((_sumx / _p) * (_sumy / _p));
var result = (TValue1.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _covar); 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); } if (update) { base[base.Count - 1] = result; } else { base.Add(result); }
} }
} }
@@ -1,5 +1,6 @@
namespace QuanTAlib; namespace QuanTAlib;
using System; using System;
using System.Linq;
/* <summary> /* <summary>
ENTP: Entropy ENTP: Entropy
@@ -16,9 +17,9 @@ Sources:
</summary> */ </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; this._logbase = logbase;
if (base._data.Count > 0) { base.Add(base._data); } 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) public override void Add((System.DateTime t, double v) TValue, bool update)
{ {
if (update) { this._buffer[this._buffer.Count - 1] = TValue.v; } Add_Replace_Trim(_buffer, TValue.v, _p, update);
else { this._buffer.Add(TValue.v); } double _sum = _buffer.Sum();
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]; }
double _pp = this._buffer[this._buffer.Count - 1] / _sum; double _pp = this._buffer[this._buffer.Count - 1] / _sum;
double _ppp = -_pp * Math.Log(_pp) / Math.Log(this._logbase); double _ppp = -_pp * Math.Log(_pp) / Math.Log(this._logbase);
if (update) { this._buff2[this._buff2.Count - 1] = _ppp; } Add_Replace_Trim(_buff2, _ppp, _p, update);
else { this._buff2.Add(_ppp); } double _entp = _buff2.Sum();
if (this._buff2.Count > this._p && this._p != 0) { this._buff2.RemoveAt(0); }
double _entp = 0; base.Add((TValue.t, _entp), update, _NaN);
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);
} }
} }
@@ -1,5 +1,6 @@
namespace QuanTAlib; namespace QuanTAlib;
using System; using System;
using System.Linq;
/* <summary> /* <summary>
KURT: Kurtosis of population KURT: Kurtosis of population
@@ -23,9 +24,9 @@ Sources:
</summary> */ </summary> */
public class KURT_Series : Single_TSeries_Indicator public class KURTOSIS_Series : Single_TSeries_Indicator
{ {
public KURT_Series(TSeries source, int period, double logbase = 2.0, bool useNaN = false) : base(source, period, useNaN) public KURTOSIS_Series(TSeries source, int period, double logbase = 2.0, bool useNaN = false) : base(source, period, useNaN)
{ {
this._logbase = logbase; this._logbase = logbase;
if (base._data.Count > 0) { base.Add(base._data); } if (base._data.Count > 0) { base.Add(base._data); }
@@ -35,22 +36,16 @@ public class KURT_Series : Single_TSeries_Indicator
public override void Add((System.DateTime t, double v) TValue, bool update) public override void Add((System.DateTime t, double v) TValue, bool update)
{ {
if (update) { this._buffer[this._buffer.Count - 1] = TValue.v; } Add_Replace_Trim(_buffer, TValue.v, _p, update);
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 _n = this._buffer.Count;
double _avg = _buffer.Average();
double _avg = 0;
for (int i = 0; i < this._buffer.Count; i++) { _avg += this._buffer[i]; }
_avg /= _n;
double _s2 = 0; double _s2 = 0;
double _s4 = 0; double _s4 = 0;
for (int i = 0; i < this._buffer.Count; i++) for (int i = 0; i < this._buffer.Count; i++)
{ {
_s2 += (this._buffer[i] - _avg) * (this._buffer[i] - _avg); _s2 += (_buffer[i] - _avg) * (_buffer[i] - _avg);
_s4 += (this._buffer[i] - _avg) * (this._buffer[i] - _avg) * (this._buffer[i] - _avg) * (this._buffer[i] - _avg); _s4 += (_buffer[i] - _avg) * (_buffer[i] - _avg) * (_buffer[i] - _avg) * (_buffer[i] - _avg);
} }
double _Vx = _s2 / (_n - 1); double _Vx = _s2 / (_n - 1);
+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) public override void Add((System.DateTime t, double v) TValue, bool update)
{ {
if (update) { this._buffer[this._buffer.Count - 1] = TValue.v; } Add_Replace_Trim(_buffer, TValue.v, _p, update);
else { this._buffer.Add(TValue.v); }
if (this._buffer.Count > this._p) { this._buffer.RemoveAt(0); }
int _len = this._buffer.Count; int _len = this._buffer.Count;
@@ -79,7 +77,7 @@ public class LINREG_Series : Single_TSeries_Indicator
double _RSquared = arrr * arrr; double _RSquared = arrr * arrr;
var ret = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _slope); 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); ret = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _intercept);
Intercept.Add(ret, update); Intercept.Add(ret, update);
+4 -8
View File
@@ -1,5 +1,6 @@
namespace QuanTAlib; namespace QuanTAlib;
using System; using System;
using System.Linq;
/* <summary> /* <summary>
MAD: Mean Absolute Deviation 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) public override void Add((System.DateTime t, double v) TValue, bool update)
{ {
if (update) { this._buffer[this._buffer.Count - 1] = TValue.v; } Add_Replace_Trim(_buffer, TValue.v, _p, update);
else { _buffer.Add(TValue.v); }
if (_buffer.Count > this._p && this._p != 0) { _buffer.RemoveAt(0); }
double _sma = 0; double _sma = _buffer.Average();
for (int i = 0; i < _buffer.Count; i++) { _sma += _buffer[i]; }
_sma /= this._buffer.Count;
double _mad = 0; double _mad = 0;
for (int i = 0; i < _buffer.Count; i++) { _mad += Math.Abs(_buffer[i] - _sma); } for (int i = 0; i < _buffer.Count; i++) { _mad += Math.Abs(_buffer[i] - _sma); }
_mad /= this._buffer.Count; _mad /= this._buffer.Count;
var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _mad); base.Add((TValue.t, _mad), update, _NaN);
base.Add(result, update);
} }
} }
+8 -11
View File
@@ -1,5 +1,6 @@
namespace QuanTAlib; namespace QuanTAlib;
using System; using System;
using System.Linq;
/* <summary> /* <summary>
MAPE: Mean Absolute Percentage Error 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) public override void Add((System.DateTime t, double v) TValue, bool update)
{ {
if (update) { _buffer[_buffer.Count - 1] = TValue.v; } Add_Replace_Trim(_buffer, TValue.v, _p, update);
else { _buffer.Add(TValue.v); } double _sma = _buffer.Average();
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;
double _mape = 0; 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; } for (int i = 0; i < _buffer.Count; i++) {
_mape /= this._buffer.Count; _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((TValue.t, _mape), update, _NaN);
base.Add(result, update);
} }
} }
@@ -1,5 +1,6 @@
namespace QuanTAlib; namespace QuanTAlib;
using System; using System;
using static System.Net.Mime.MediaTypeNames;
/* <summary> /* <summary>
MED - Median value MED - Median value
@@ -20,9 +21,9 @@ Sources:
</summary> */ </summary> */
public class MED_Series : Single_TSeries_Indicator public class MEDIAN_Series : Single_TSeries_Indicator
{ {
public MED_Series(TSeries source, int period, bool useNaN = false) : base(source, period, useNaN) public MEDIAN_Series(TSeries source, int period, bool useNaN = false) : base(source, period, useNaN)
{ {
if (base._data.Count > 0) { base.Add(base._data); } if (base._data.Count > 0) { base.Add(base._data); }
} }
@@ -30,9 +31,7 @@ public class MED_Series : Single_TSeries_Indicator
public override void Add((System.DateTime t, double v) TValue, bool update) public override void Add((System.DateTime t, double v) TValue, bool update)
{ {
if (update) { this._buffer[this._buffer.Count - 1] = TValue.v; } Add_Replace_Trim(_buffer, TValue.v, _p, update);
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); System.Collections.Generic.List<double> _s = new(this._buffer);
_s.Sort(); _s.Sort();
@@ -40,8 +39,6 @@ public class MED_Series : Single_TSeries_Indicator
int _p2 = Math.Max(0, (_s.Count / 2) - 1); int _p2 = Math.Max(0, (_s.Count / 2) - 1);
double _med = (_s.Count % 2 != 0) ? _s[_p1] : (_s[_p1] + _s[_p2]) / 2; double _med = (_s.Count % 2 != 0) ? _s[_p1] : (_s[_p1] + _s[_p2]) / 2;
var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _med); base.Add((TValue.t, _med), update, _NaN);
base.Add(result, update);
} }
} }
+4 -9
View File
@@ -1,5 +1,6 @@
namespace QuanTAlib; namespace QuanTAlib;
using System; using System;
using System.Linq;
/* <summary> /* <summary>
MSE: Mean Square Error 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) public override void Add((System.DateTime t, double v) TValue, bool update)
{ {
if (update) { _buffer[_buffer.Count - 1] = TValue.v; } Add_Replace_Trim(_buffer, TValue.v, _p, update);
else { _buffer.Add(TValue.v); } double _sma = _buffer.Average();
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;
double _mse = 0; double _mse = 0;
for (int i = 0; i < _buffer.Count; i++) { _mse += (_buffer[i] - _sma) * (_buffer[i] - _sma); } for (int i = 0; i < _buffer.Count; i++) { _mse += (_buffer[i] - _sma) * (_buffer[i] - _sma); }
_mse /= this._buffer.Count; _mse /= this._buffer.Count;
var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _mse); base.Add((TValue.t, _mse), update, _NaN);
base.Add(result, update);
} }
} }
+4 -9
View File
@@ -1,5 +1,6 @@
namespace QuanTAlib; namespace QuanTAlib;
using System; using System;
using System.Linq;
/* <summary> /* <summary>
SDEV: Population Standard Deviation 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) public override void Add((System.DateTime t, double v) TValue, bool update)
{ {
if (update) { _buffer[_buffer.Count - 1] = TValue.v; } Add_Replace_Trim(_buffer, TValue.v, _p, update);
else { _buffer.Add(TValue.v); } double _sma = _buffer.Average();
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;
double _pvar = 0; double _pvar = 0;
for (int i = 0; i < _buffer.Count; i++) { _pvar += (_buffer[i] - _sma) * (_buffer[i] - _sma); } for (int i = 0; i < _buffer.Count; i++) { _pvar += (_buffer[i] - _sma) * (_buffer[i] - _sma); }
_pvar /= this._buffer.Count; _pvar /= this._buffer.Count;
double _psdev = Math.Sqrt(_pvar); double _psdev = Math.Sqrt(_pvar);
var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _psdev); base.Add((TValue.t, _psdev), update, _NaN);
base.Add(result, update);
} }
} }
+4 -9
View File
@@ -1,5 +1,6 @@
namespace QuanTAlib; namespace QuanTAlib;
using System; using System;
using System.Linq;
/* <summary> /* <summary>
SMAPE: Symmetric Mean Absolute Percentage Error 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) public override void Add((System.DateTime t, double v) TValue, bool update)
{ {
if (update) { _buffer[_buffer.Count - 1] = TValue.v; } Add_Replace_Trim(_buffer, TValue.v, _p, update);
else { _buffer.Add(TValue.v); } double _sma = _buffer.Average();
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;
double _smape = 0; double _smape = 0;
for (int i = 0; i < _buffer.Count; i++) { _smape += Math.Abs(_buffer[i] - _sma) / (Math.Abs(_buffer[i]) + Math.Abs(_sma)); } 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; _smape /= this._buffer.Count;
var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _smape); base.Add((TValue.t, _smape), update, _NaN);
base.Add(result, update);
} }
} }
+6 -11
View File
@@ -1,5 +1,6 @@
namespace QuanTAlib; namespace QuanTAlib;
using System; using System;
using System.Linq;
/* <summary> /* <summary>
SSDEV: (Corrected) Sample Standard Deviation 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) public override void Add((System.DateTime t, double v) TValue, bool update)
{ {
if (update) { this._buffer[this._buffer.Count - 1] = TValue.v; } Add_Replace_Trim(_buffer, TValue.v, _p, update);
else { this._buffer.Add(TValue.v); } double _sma = _buffer.Average();
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;
double _svar = 0; double _svar = 0;
for (int i = 0; i < this._buffer.Count; i++) { _svar += (this._buffer[i] - _sma) * (this._buffer[i] - _sma); } for (int i = 0; i < this._buffer.Count; i++) { _svar += (_buffer[i] - _sma) * (_buffer[i] - _sma); }
_svar /= (this._buffer.Count > 1) ? this._buffer.Count - 1 : 1; // Bessel's correction _svar /= (_buffer.Count > 1) ? _buffer.Count - 1 : 1; // Bessel's correction
double _ssdev = Math.Sqrt(_svar); double _ssdev = Math.Sqrt(_svar);
var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _ssdev); base.Add((TValue.t, _ssdev), update, _NaN);
base.Add(result, update);
} }
} }
+4 -9
View File
@@ -1,5 +1,6 @@
namespace QuanTAlib; namespace QuanTAlib;
using System; using System;
using System.Linq;
/* <summary> /* <summary>
SVAR: Sample Variance 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) public override void Add((System.DateTime t, double v) TValue, bool update)
{ {
if (update) { this._buffer[this._buffer.Count - 1] = TValue.v; } Add_Replace_Trim(_buffer, TValue.v, _p, update);
else { this._buffer.Add(TValue.v); } double _sma = _buffer.Average();
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;
double _svar = 0; double _svar = 0;
for (int i = 0; i < this._buffer.Count; i++) { _svar += (this._buffer[i] - _sma) * (this._buffer[i] - _sma); } 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 _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((TValue.t, _svar), update, _NaN);
base.Add(result, update);
} }
} }
+4 -9
View File
@@ -1,5 +1,6 @@
namespace QuanTAlib; namespace QuanTAlib;
using System; using System;
using System.Linq;
/* <summary> /* <summary>
VAR: Population Variance 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) public override void Add((System.DateTime t, double v) TValue, bool update)
{ {
if (update) { _buffer[_buffer.Count - 1] = TValue.v; } Add_Replace_Trim(_buffer, TValue.v, _p, update);
else { _buffer.Add(TValue.v); } double _sma = _buffer.Average();
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;
double _pvar = 0; double _pvar = 0;
for (int i = 0; i < _buffer.Count; i++) { _pvar += (_buffer[i] - _sma) * (_buffer[i] - _sma); } for (int i = 0; i < _buffer.Count; i++) { _pvar += (_buffer[i] - _sma) * (_buffer[i] - _sma); }
_pvar /= this._buffer.Count; _pvar /= this._buffer.Count;
var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _pvar); base.Add((TValue.t, _pvar), update, _NaN);
base.Add(result, update);
} }
} }
+8 -11
View File
@@ -1,9 +1,12 @@
namespace QuanTAlib; namespace QuanTAlib;
using System; using System;
using System.Linq;
/* <summary> /* <summary>
WMAPE: Weighted Mean Absolute Percentage Error 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: Sources:
https://en.wikipedia.org/wiki/WMAPE 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) public override void Add((System.DateTime t, double v) TValue, bool update)
{ {
if (update) { _buffer[_buffer.Count - 1] = TValue.v; } Add_Replace_Trim(_buffer, TValue.v, _p, update);
else { _buffer.Add(TValue.v); } double _sma = _buffer.Average();
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;
double _div = 0; double _div = 0;
double _wmape = 0; double _wmape = 0;
@@ -35,9 +33,8 @@ public class WMAPE_Series : Single_TSeries_Indicator
_wmape += Math.Abs(_buffer[i] - _sma); _wmape += Math.Abs(_buffer[i] - _sma);
_div += Math.Abs(_buffer[i]); _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((TValue.t, _wmape), update, _NaN);
base.Add(result, update);
} }
} }
+4 -9
View File
@@ -1,5 +1,6 @@
namespace QuanTAlib; namespace QuanTAlib;
using System; using System;
using System.Linq;
/* <summary> /* <summary>
ZSCORE: number of standard deviations from SMA 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) public override void Add((System.DateTime t, double v) TValue, bool update)
{ {
if (update) { _buffer[_buffer.Count - 1] = TValue.v; } Add_Replace_Trim(_buffer, TValue.v, _p, update);
else { _buffer.Add(TValue.v); } double _sma = _buffer.Average();
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;
double _pvar = 0; double _pvar = 0;
for (int i = 0; i < _buffer.Count; i++) { _pvar += (_buffer[i] - _sma) * (_buffer[i] - _sma); } 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 _psdev = Math.Sqrt(_pvar);
double _zscore = (_psdev == 0) ? double.NaN : (TValue.v - _sma) / _psdev; 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((TValue.t, _zscore), update, _NaN);
base.Add(result, update);
} }
} }
+37 -41
View File
@@ -20,48 +20,44 @@ TODO: Discrepancy with Pandas-TA (but passes the validation with Skender.GetAlma
public class ALMA_Series : Single_TSeries_Indicator public class ALMA_Series : Single_TSeries_Indicator
{ {
private readonly System.Collections.Generic.List<double> _buffer = new(); private readonly System.Collections.Generic.List<double> _buffer = new();
private readonly double[] _weight; private readonly double[] _weight;
private double _norm; private double _norm;
private readonly double _offset, _sigma; private readonly double _offset, _sigma;
public ALMA_Series(TSeries source, int period, double offset = 0.85, double sigma = 6.0, bool useNaN = false) public ALMA_Series(TSeries source, int period, double offset = 0.85, double sigma = 6.0, bool useNaN = false)
: base(source, period, useNaN) : base(source, period, useNaN)
{
_offset = offset;
_sigma = sigma;
_weight = new double[period];
if (this._data.Count > 0) { base.Add(this._data); }
}
public override void Add((System.DateTime t, double v) TValue, bool update)
{
if (update) { this._buffer[this._buffer.Count - 1] = TValue.v; }
else { this._buffer.Add(TValue.v); }
if (this._buffer.Count > this._p) { this._buffer.RemoveAt(0); }
if (this._buffer.Count <= _p) { calc_weights(); }
double _weightedSum = 0;
for (int i = 0; i < this._buffer.Count; i++) { _weightedSum += _weight[i] * _buffer[i]; }
double _alma = _weightedSum / _norm;
var ret = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _alma);
base.Add(ret, update);
}
private void calc_weights()
{
int _len = this._buffer.Count;
_norm = 0;
double _m = _offset * (_len - 1);
double _s = _len / _sigma;
for (int i = 0; i < _len; i++)
{ {
double _wt = Math.Exp(-((i - _m) * (i - _m)) / (2 * _s * _s)); _offset = offset;
_weight[i] = _wt; _sigma = sigma;
_norm += _wt; _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; namespace QuanTAlib;
using System; using System;
using System.Linq;
/* <summary> /* <summary>
DEMA: Double Exponential Moving Average DEMA: Double Exponential Moving Average
@@ -41,16 +42,9 @@ public class DEMA_Series : Single_TSeries_Indicator
if (this.Count < this._p) if (this.Count < this._p)
{ {
if (update) { _buffer[_buffer.Count - 1] = TValue.v; } Add_Replace_Trim(_buffer, TValue.v, _p, update);
else double _sma = _buffer.Average();
{
_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;
_ema1 = _ema2 = _sma; _ema1 = _ema2 = _sma;
} }
else else
@@ -65,7 +59,6 @@ public class DEMA_Series : Single_TSeries_Indicator
this._lastema1 = _ema1; this._lastema1 = _ema1;
this._lastema2 = _ema2; this._lastema2 = _ema2;
var ret = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _dema); base.Add((TValue.t, _dema), update, _NaN);
base.Add(ret, update);
} }
} }
+5 -12
View File
@@ -1,5 +1,6 @@
namespace QuanTAlib; namespace QuanTAlib;
using System; using System;
using System.Linq;
/* <summary> /* <summary>
EMA: Exponential Moving Average 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) public override void Add((DateTime t, double v) TValue, bool update)
{ {
double _ema = 0; double _ema;
if (update) { this._lastema = this._lastlastema; } if (update) { this._lastema = this._lastlastema; }
if (this.Count < this._p) if (this.Count < this._p)
{ {
if (update) { this._buffer[this._buffer.Count - 1] = TValue.v; } Add_Replace(_buffer, TValue.v, update);
else _ema = _buffer.Average();
{
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;
} }
else else
{ {
@@ -58,7 +52,6 @@ public class EMA_Series : Single_TSeries_Indicator
this._lastlastema = this._lastema; this._lastlastema = this._lastema;
this._lastema = _ema; this._lastema = _ema;
var ret = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _ema); base.Add((TValue.t, _ema), update, _NaN);
base.Add(ret, update);
} }
} }
+6 -14
View File
@@ -2,8 +2,8 @@
using System; using System;
/* <summary> /* <summary>
HEMA: Hull-EMA Moving Average HEMA: Hull-EMA Moving Average - a hybrid indicator
Modified HUll Moving Average; instead of using WMA (Weighted MA) for acalculation, Modified HUll Moving Average; instead of using WMA (Weighted MA) for calculation,
HEMA uses EMA for Hull's formula: HEMA uses EMA for Hull's formula:
EMA1 = EMA(n/2) of price - where k = 4/(n/2 +1) 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._lastema2 = this._lastlastema2;
this._lastema3 = this._lastlastema3; this._lastema3 = this._lastlastema3;
} }
double _ema1 = System.Double.IsNaN(this._lastema1) double _ema1 = System.Double.IsNaN(this._lastema1) ? TValue.v : TValue.v * this._k1 + this._lastema1 * (1 - this._k1);
? TValue.v double _ema2 = System.Double.IsNaN(this._lastema2) ? TValue.v : TValue.v * this._k2 + this._lastema2 * (1 - this._k2);
: 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 _rawhema = (2 * _ema1) - _ema2;
double _ema3 = System.Double.IsNaN(this._lastema3) double _ema3 = System.Double.IsNaN(this._lastema3) ? _rawhema : _rawhema * this._k3 + this._lastema3 * (1 - this._k3);
? _rawhema
: _rawhema * this._k3 + this._lastema3 * (1 - this._k3);
this._lastlastema1 = this._lastema1; this._lastlastema1 = this._lastema1;
this._lastlastema2 = this._lastema2; this._lastlastema2 = this._lastema2;
@@ -58,8 +52,6 @@ public class HEMA_Series : Single_TSeries_Indicator
this._lastema2 = _ema2; this._lastema2 = _ema2;
this._lastema3 = _ema3; this._lastema3 = _ema3;
(System.DateTime t, double v) result = base.Add((TValue.t, _ema3), update, _NaN);
(TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _ema3);
base.Add(result, update);
} }
} }
+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[i] * this._weights[i];
} }
this._wma1 /= (this._buf1.Count * (this._buf1.Count + 1)) * 0.5; this._wma1 /= (this._buf1.Count * (this._buf1.Count + 1)) * 0.5;
this._wma2 = 0; this._wma2 = 0;
@@ -81,7 +80,6 @@ public class HMA_Series : TSeries
{ {
this._wma2 += this._buf2[i] * this._weights[i]; this._wma2 += this._buf2[i] * this._weights[i];
} }
this._wma2 /= (this._buf2.Count * (this._buf2.Count + 1)) * 0.5; this._wma2 /= (this._buf2.Count * (this._buf2.Count + 1)) * 0.5;
if (update) if (update)
@@ -92,6 +90,7 @@ public class HMA_Series : TSeries
{ {
this._buf3.Add(2 * this._wma1 - this._wma2); this._buf3.Add(2 * this._wma1 - this._wma2);
} }
if (this._buf3.Count > (int)Math.Sqrt(this._p)) if (this._buf3.Count > (int)Math.Sqrt(this._p))
{ {
this._buf3.RemoveAt(0); 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)) + double det1 = ((ma2 - this.prev_jma) * (1 - alpha) * (1 - alpha)) +
(this.prev_det1 * alpha * alpha); (this.prev_det1 * alpha * alpha);
this.prev_det1 = det1; this.prev_det1 = det1;
var jma = this.prev_jma + det1; var _jma = this.prev_jma + det1;
this.prev_jma = jma; this.prev_jma = _jma;
(System.DateTime t, double v) result = base.Add((TValue.t, _jma), update, _NaN);
(TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : jma); }
base.Add(result, update);
}
} }
+3 -3
View File
@@ -44,6 +44,7 @@ public class KAMA_Series : Single_TSeries_Indicator
_buffer.Add(TValue.v); _buffer.Add(TValue.v);
} }
if (_buffer.Count > _p + 1) { _buffer.RemoveAt(0); } if (_buffer.Count > _p + 1) { _buffer.RemoveAt(0); }
double _kama = 0; double _kama = 0;
if (this.Count < this._p) { if (this.Count < this._p) {
for (int i = 0; i < this._buffer.Count; i++) { _kama += this._buffer[i]; } for (int i = 0; i < this._buffer.Count; i++) { _kama += this._buffer[i]; }
@@ -59,7 +60,6 @@ public class KAMA_Series : Single_TSeries_Indicator
} }
_lastlastkama = _lastkama; _lastlastkama = _lastkama;
_lastkama = _kama; _lastkama = _kama;
var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _kama); base.Add((TValue.t, _kama), update, _NaN);
base.Add(result, update); }
}
} }
+2 -3
View File
@@ -40,7 +40,6 @@ public class MACD_Series : Single_TSeries_Indicator
_TSfast.Add(TValue, true); _TSfast.Add(TValue, true);
} }
_macd = this._TSmacd[(this.Count < this._TSmacd.Count) ? this.Count : this._TSmacd.Count - 1].v; _macd = this._TSmacd[(this.Count < this._TSmacd.Count) ? this.Count : this._TSmacd.Count - 1].v;
var result = (TValue.t, _macd); base.Add((TValue.t, _macd), update, _NaN);
base.Add(result, update); }
}
} }
+131
View File
@@ -0,0 +1,131 @@
namespace QuanTAlib;
using System;
/* <summary>
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/
</summary> */
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;
i = 0;
if (base._data.Count > 0) { base.Add(base._data); }
}
private int i;
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 override void Add((System.DateTime t, double v) TValue, bool update)
{
if (update) {
i--;
pr.i = pr.i1; pr.i1 = pr.i2; pr.i2 = pr.i3; pr.i3 = pr.i4; pr.i4 = pr.i5; pr.i5 = pr.i6; pr.i6 = pr.io;
i1.i = i1.i1; i1.i1 = i1.i2; i1.i2 = i1.i3; i1.i3 = i1.i4; i1.i4 = i1.i5; i1.i5 = i1.i6; i1.i6 = i1.io;
q1.i = q1.i1; q1.i1 = q1.i2; q1.i2 = q1.i3; q1.i3 = q1.i4; q1.i4 = q1.i5; q1.i5 = q1.i6; q1.i6 = q1.io;
dt.i = dt.i1; dt.i1 = dt.i2; dt.i2 = dt.i3; dt.i3 = dt.i4; dt.i4 = dt.i5; dt.i5 = dt.i6; dt.i6 = dt.io;
sm.i = sm.i1; sm.i1 = sm.i2; sm.i2 = sm.i3; sm.i3 = sm.i4; dt.i4 = sm.i5; sm.i5 = sm.i6; sm.i6 = sm.io;
i2.i = i2.i1; i2.i1 = i2.io;
q2.i = q2.i1; q2.i1 = q2.io;
re.i = re.i1; re.i1 = re.io;
im.i = im.i1; im.i1 = im.io;
pd.i = pd.i1; pd.i1 = pd.io;
ph.i = ph.i1; ph.i1 = ph.io;
mama.i = mama.i1; mama.i1 = mama.io;
fama.i = fama.i1; fama.i1 = fama.io;
}
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);
}
i++;
pr.io = pr.i6; pr.i6 = pr.i5; pr.i5 = pr.i4; pr.i4 = pr.i3; pr.i3 = pr.i2; pr.i2 = pr.i1; pr.i1 = pr.i;
i1.io = i1.i6; i1.i6 = i1.i5; i1.i5 = i1.i4; i1.i4 = i1.i3; i1.i3 = i1.i2; i1.i2 = i1.i1; i1.i1 = i1.i;
q1.io = q1.i6; q1.i6 = q1.i5; q1.i5 = q1.i4; q1.i4 = q1.i3; q1.i3 = q1.i2; q1.i2 = q1.i1; q1.i1 = q1.i;
dt.io = dt.i6; dt.i6 = dt.i5; dt.i5 = dt.i4; dt.i4 = dt.i3; dt.i3 = dt.i2; dt.i2 = dt.i1; dt.i1 = dt.i;
sm.io = sm.i6; sm.i6 = sm.i5; sm.i5 = sm.i4; sm.i4 = sm.i3; sm.i3 = sm.i2; sm.i2 = sm.i1; sm.i1 = sm.i;
i2.io = i2.i1; i2.i1 = i2.i;
q2.io = q2.i1; q2.i1 = q2.i;
re.io = re.i1; re.i1 = re.i;
im.io = im.i1; im.i1 = im.i;
pd.io = pd.i1; pd.i1 = pd.i;
ph.io = ph.i1; ph.i1 = ph.i;
mama.io = mama.i1; mama.i1 = mama.i;
fama.io = fama.i1; fama.i1 = fama.i;
base.Add((TValue.t, mama.i), update, _NaN);
}
}
+6 -13
View File
@@ -1,5 +1,6 @@
namespace QuanTAlib; namespace QuanTAlib;
using System; using System;
using System.Linq;
/* <summary> /* <summary>
RMA: wildeR Moving Average 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) public override void Add((DateTime t, double v) TValue, bool update)
{ {
double _ema = 0; double _ema;
if (update) { this._lastema = this._lastlastema; } if (update) { this._lastema = this._lastlastema; }
if (this.Count < this._p) if (this.Count < this._p)
{ {
if (update) { _buffer[_buffer.Count - 1] = TValue.v; } Add_Replace_Trim(_buffer, TValue.v, _p, update);
else _ema = _buffer.Average();
{
_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;
} }
else else
{ {
@@ -57,7 +51,6 @@ public class RMA_Series : Single_TSeries_Indicator
this._lastlastema = this._lastema; this._lastlastema = this._lastema;
this._lastema = _ema; this._lastema = _ema;
var ret = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _ema); base.Add((TValue.t, _ema), update, _NaN);
base.Add(ret, update); }
}
} }
+4 -10
View File
@@ -1,5 +1,6 @@
namespace QuanTAlib; namespace QuanTAlib;
using System; using System;
using System.Linq;
/* <summary> /* <summary>
SMA: Simple Moving Average 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) public override void Add((System.DateTime t, double v) TValue, bool update)
{ {
if (update) { _buffer[_buffer.Count - 1] = TValue.v; } Add_Replace_Trim(_buffer, TValue.v, _p, update);
else { _buffer.Add(TValue.v); } double _sma = _buffer.Sum() / _buffer.Count;
if (_buffer.Count > this._p && this._p != 0) { _buffer.RemoveAt(0); }
double _sma = 0; base.Add((TValue.t, _sma), update, _NaN);
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);
} }
} }
+5 -12
View File
@@ -1,5 +1,6 @@
namespace QuanTAlib; namespace QuanTAlib;
using System; using System;
using System.Linq;
/* <summary> /* <summary>
SMMA: Smoothed Moving Average SMMA: Smoothed Moving Average
@@ -34,15 +35,8 @@ public class SMMA_Series : Single_TSeries_Indicator
if (this.Count < this._p) if (this.Count < this._p)
{ {
if (update) { this._buffer[this._buffer.Count - 1] = TValue.v; } Add_Replace_Trim(_buffer, TValue.v, _p, update);
else _smma = _buffer.Average();
{
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;
} }
else else
{ {
@@ -52,7 +46,6 @@ public class SMMA_Series : Single_TSeries_Indicator
this._lastlastsmma = this._lastsmma; this._lastlastsmma = this._lastsmma;
this._lastsmma = _smma; this._lastsmma = _smma;
var ret = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _smma); base.Add((TValue.t, _smma), update, _NaN);
base.Add(ret, update); }
}
} }
+5 -13
View File
@@ -1,5 +1,6 @@
namespace QuanTAlib; namespace QuanTAlib;
using System; using System;
using System.Linq;
/* <summary> /* <summary>
TEMA: Triple Exponential Moving Average TEMA: Triple Exponential Moving Average
@@ -44,16 +45,8 @@ public class TEMA_Series : Single_TSeries_Indicator
if (this.Count < this._p) if (this.Count < this._p)
{ {
if (update) { _buffer[_buffer.Count - 1] = TValue.v; } Add_Replace_Trim(_buffer, TValue.v, _p, update);
else double _sma = _buffer.Average();
{
_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;
_ema1 = _ema2 = _ema3 = _sma; _ema1 = _ema2 = _ema3 = _sma;
} }
else else
@@ -72,7 +65,6 @@ public class TEMA_Series : Single_TSeries_Indicator
this._lastema2 = _ema2; this._lastema2 = _ema2;
this._lastema3 = _ema3; this._lastema3 = _ema3;
var ret = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _tema); base.Add((TValue.t, _tema), update, _NaN);
base.Add(ret, update); }
}
} }
+5 -11
View File
@@ -1,5 +1,6 @@
namespace QuanTAlib; namespace QuanTAlib;
using System; using System;
using System.Linq;
/* <summary> /* <summary>
TRIMA: Triangular Moving Average 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 (update) { _buffer1[_buffer1.Count - 1] = TValue.v; } else { _buffer1.Add(TValue.v); }
if (_buffer1.Count > this._p1b && this._p1b != 0) { _buffer1.RemoveAt(0); } if (_buffer1.Count > this._p1b && this._p1b != 0) { _buffer1.RemoveAt(0); }
double _sma1 = _buffer1.Average();
double _sma1 = 0;
for (int i = 0; i < _buffer1.Count; i++) { _sma1 += _buffer1[i]; }
_sma1 /= this._buffer1.Count;
if (update) { _buffer2[_buffer2.Count - 1] = _sma1; } else { _buffer2.Add(_sma1); } if (update) { _buffer2[_buffer2.Count - 1] = _sma1; } else { _buffer2.Add(_sma1); }
if (_buffer2.Count > this._p1a && this._p1a != 0) { _buffer2.RemoveAt(0); } if (_buffer2.Count > this._p1a && this._p1a != 0) { _buffer2.RemoveAt(0); }
double _trima = _buffer2.Average();
double _trima = 0; base.Add((TValue.t, _trima), update, _NaN);
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);
}
} }
+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) public override void Add((System.DateTime t, double v) TValue, bool update)
{ {
if (update) { _buffer[_buffer.Count - 1] = TValue.v; } Add_Replace_Trim(_buffer, TValue.v, _p, update);
else { _buffer.Add(TValue.v); }
if (_buffer.Count > this._p && this._p != 0) { _buffer.RemoveAt(0); }
double _wma = 0; double _wma = 0;
for (int i = 0; i < _buffer.Count; i++) { _wma += _buffer[i] * this._weights[i]; } for (int i = 0; i < _buffer.Count; i++) { _wma += _buffer[i] * this._weights[i]; }
_wma /= (this._buffer.Count * (this._buffer.Count + 1)) * 0.5; _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((TValue.t, _wma), update, _NaN);
base.Add(result, update);
} }
} }
+5 -15
View File
@@ -1,5 +1,6 @@
namespace QuanTAlib; namespace QuanTAlib;
using System; using System;
using System.Linq;
/* <summary> /* <summary>
ZLEMA: Zero Lag Exponential Moving Average ZLEMA: Zero Lag Exponential Moving Average
@@ -45,18 +46,8 @@ public class ZLEMA_Series : Single_TSeries_Indicator
{ this._lastema = this._lastlastema; } { this._lastema = this._lastlastema; }
if (this.Count < this._p) if (this.Count < this._p)
{ {
if (update) Add_Replace_Trim(_buffer, _zl, _p, update);
{ this._buffer[this._buffer.Count - 1] = _zl; } _ema = _buffer.Average();
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;
} }
else else
{ {
@@ -66,7 +57,6 @@ public class ZLEMA_Series : Single_TSeries_Indicator
this._lastlastema = this._lastema; this._lastlastema = this._lastema;
this._lastema = _ema; this._lastema = _ema;
var ret = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _ema); base.Add((TValue.t, _ema), update, _NaN);
base.Add(ret, update); }
}
} }
+2 -3
View File
@@ -37,7 +37,6 @@ public class ADL_Series : Single_TBars_Indicator
this._lastlastadl = this._lastadl; this._lastlastadl = this._lastadl;
this._lastadl = _adl; this._lastadl = _adl;
var ret = (TBar.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _adl); base.Add((TBar.t, _adl), update, _NaN);
base.Add(ret, update); }
}
} }
+3 -3
View File
@@ -3,13 +3,13 @@ using System;
using QuanTAlib; using QuanTAlib;
namespace Statistics; namespace Statistics;
public class KURT_Test public class KURTOSIS_Test
{ {
[Fact] [Fact]
public void Add_Test() public void Add_Test()
{ {
TSeries a = new() { 0, 1, 2, 3, 4, 5 }; TSeries a = new() { 0, 1, 2, 3, 4, 5 };
KURT_Series c = new(a, 3); KURTOSIS_Series c = new(a, 3);
Assert.Equal(6, c.Count); Assert.Equal(6, c.Count);
a.Add(5); a.Add(5);
Assert.Equal(a.Count, c.Count); Assert.Equal(a.Count, c.Count);
@@ -21,7 +21,7 @@ public class KURT_Test
public void Edge_Test() public void Edge_Test()
{ {
TSeries a = new() { double.NaN, double.Epsilon, double.PositiveInfinity, double.MaxValue }; TSeries a = new() { double.NaN, double.Epsilon, double.PositiveInfinity, double.MaxValue };
KURT_Series c = new(a, 3); KURTOSIS_Series c = new(a, 3);
Assert.Equal(a.Count, c.Count); Assert.Equal(a.Count, c.Count);
a.Add(double.NaN); a.Add(double.NaN);
Assert.Equal(a.Count, c.Count); Assert.Equal(a.Count, c.Count);
+2 -2
View File
@@ -9,7 +9,7 @@ public class ENTP_Test
public void Add_Test() public void Add_Test()
{ {
TSeries a = new() { 0, 1, 2, 3, 4, 5 }; TSeries a = new() { 0, 1, 2, 3, 4, 5 };
ENTP_Series c = new(a, 3); ENTROPY_Series c = new(a, 3);
Assert.Equal(6, c.Count); Assert.Equal(6, c.Count);
a.Add(5); a.Add(5);
Assert.Equal(a.Count, c.Count); Assert.Equal(a.Count, c.Count);
@@ -21,7 +21,7 @@ public class ENTP_Test
public void Edge_Test() public void Edge_Test()
{ {
TSeries a = new() { double.NaN, double.Epsilon, double.PositiveInfinity, double.MaxValue }; TSeries a = new() { double.NaN, double.Epsilon, double.PositiveInfinity, double.MaxValue };
ENTP_Series c = new(a, 3); ENTROPY_Series c = new(a, 3);
Assert.Equal(a.Count, c.Count); Assert.Equal(a.Count, c.Count);
a.Add(double.NaN); a.Add(double.NaN);
Assert.Equal(a.Count, c.Count); Assert.Equal(a.Count, c.Count);
+2 -2
View File
@@ -9,7 +9,7 @@ public class MED_Test
public void Add_Test() public void Add_Test()
{ {
TSeries a = new() { 0, 1, 2, 3, 4, 5 }; TSeries a = new() { 0, 1, 2, 3, 4, 5 };
MED_Series c = new(a, 3); MEDIAN_Series c = new(a, 3);
Assert.Equal(6, c.Count); Assert.Equal(6, c.Count);
a.Add(5); a.Add(5);
Assert.Equal(a.Count, c.Count); Assert.Equal(a.Count, c.Count);
@@ -21,7 +21,7 @@ public class MED_Test
public void Edge_Test() public void Edge_Test()
{ {
TSeries a = new() { double.NaN, double.Epsilon, double.PositiveInfinity, double.MaxValue }; TSeries a = new() { double.NaN, double.Epsilon, double.PositiveInfinity, double.MaxValue };
MED_Series c = new(a, 3); MEDIAN_Series c = new(a, 3);
Assert.Equal(a.Count, c.Count); Assert.Equal(a.Count, c.Count);
a.Add(double.NaN); a.Add(double.NaN);
Assert.Equal(a.Count, c.Count); Assert.Equal(a.Count, c.Count);
-4
View File
@@ -15,10 +15,6 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
</PackageReference> </PackageReference>
<PackageReference Include="JetBrains.dotCover.CommandLineTools" Version="2022.3.0-eap07">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0-preview-20221003-04" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0-preview-20221003-04" />
<PackageReference Include="TALib.NETCore" Version="0.4.4" /> <PackageReference Include="TALib.NETCore" Version="0.4.4" />
<PackageReference Include="Skender.Stock.Indicators" Version="2.4.0" /> <PackageReference Include="Skender.Stock.Indicators" Version="2.4.0" />
+26 -18
View File
@@ -11,9 +11,9 @@ public class PandasTA : IDisposable
private readonly Random rnd = new(); private readonly Random rnd = new();
private readonly int period; private readonly int period;
private readonly string OStype; private readonly string OStype;
private dynamic np; private readonly dynamic np;
private dynamic ta; private readonly dynamic ta;
private dynamic df; private readonly dynamic df;
public PandasTA() public PandasTA()
{ {
@@ -85,7 +85,7 @@ public class PandasTA : IDisposable
[Fact] [Fact]
void MEDIAN() void MEDIAN()
{ {
MED_Series QL = new(bars.Close, period); MEDIAN_Series QL = new(bars.Close, period);
var pta = df.ta.median(close: df.close, length: period); var pta = df.ta.median(close: df.close, length: period);
Assert.Equal(Math.Round((double)pta.tail(1), 4), Math.Round(QL.Last().v, 4)); Assert.Equal(Math.Round((double)pta.tail(1), 4), Math.Round(QL.Last().v, 4));
} }
@@ -130,7 +130,15 @@ public class PandasTA : IDisposable
Assert.Equal(Math.Round((double)pta.tail(1), 4), Math.Round(QL.Last().v, 4)); Assert.Equal(Math.Round((double)pta.tail(1), 4), Math.Round(QL.Last().v, 4));
} }
[Fact] [Fact]
void OBV()
{
OBV_Series QL = new(bars);
var pta = df.ta.obv(close: df.close, volume: df.volume);
Assert.Equal(Math.Round((double)pta.tail(1), 4), Math.Round(QL.Last().v, 4));
}
[Fact]
void ATR() void ATR()
{ {
ATR_Series QL = new(bars, period); ATR_Series QL = new(bars, period);
@@ -149,21 +157,21 @@ public class PandasTA : IDisposable
[Fact] [Fact]
void TRIMA() void TRIMA()
{ {
//TODO: return length to variable length (period) when Pandas-TA fixes trima // TODO: return length to variable length (period) when Pandas-TA fixes trima
TRIMA_Series QL = new(bars.Close, 11); TRIMA_Series QL = new(bars.Close, 11);
var pta = df.ta.trima(close: df.close, length: 11); var pta = df.ta.trima(close: df.close, length: 11);
Assert.Equal(Math.Round((double)pta.tail(1), 4), Math.Round(QL.Last().v, 4)); Assert.Equal(Math.Round((double)pta.tail(1), 4), Math.Round(QL.Last().v, 4));
} }
[Fact] [Fact]
void KAMA() void KAMA()
{ {
KAMA_Series QL = new(bars.Close, period); KAMA_Series QL = new(bars.Close, period);
var pta = df.ta.kama(close: df.close, length: period); var pta = df.ta.kama(close: df.close, length: period);
Assert.Equal(Math.Round((double)pta.tail(1), 4), Math.Round(QL.Last().v, 4)); Assert.Equal(Math.Round((double)pta.tail(1), 4), Math.Round(QL.Last().v, 4));
} }
[Fact] [Fact]
void HMA() void HMA()
{ {
HMA_Series QL = new(bars.Close, period, false); HMA_Series QL = new(bars.Close, period, false);
@@ -220,9 +228,9 @@ public class PandasTA : IDisposable
} }
[Fact] [Fact]
void ENTP() void ENTROPY()
{ {
ENTP_Series QL = new(bars.Close, period, useNaN: false); ENTROPY_Series QL = new(bars.Close, period, useNaN: false);
var pta = df.ta.entropy(close: df.close, length: period); var pta = df.ta.entropy(close: df.close, length: period);
Assert.Equal(Math.Round((double)pta.tail(1), 4), Math.Round(QL.Last().v, 4)); Assert.Equal(Math.Round((double)pta.tail(1), 4), Math.Round(QL.Last().v, 4));
} }
@@ -268,9 +276,9 @@ public class PandasTA : IDisposable
} }
[Fact] [Fact]
void KURT() void KURTOSIS()
{ {
KURT_Series QL = new(bars.Close, period, useNaN: false); KURTOSIS_Series QL = new(bars.Close, period, useNaN: false);
var pta = df.ta.kurtosis(close: df.close, length: period); var pta = df.ta.kurtosis(close: df.close, length: period);
Assert.Equal(Math.Round((double)pta.tail(1), 4), Math.Round(QL.Last().v, 4)); Assert.Equal(Math.Round((double)pta.tail(1), 4), Math.Round(QL.Last().v, 4));
} }
+10 -1
View File
@@ -71,7 +71,16 @@ public class Skender_Stock
Assert.Equal(Math.Round((double)SK.Last().Tema!, 6), Math.Round(QL.Last().v, 6)); Assert.Equal(Math.Round((double)SK.Last().Tema!, 6), Math.Round(QL.Last().v, 6));
} }
[Fact]
[Fact]
public void MAMA() {
MAMA_Series QL = new(bars.HL2, fastlimit: 0.5, slowlimit: 0.05);
var SK = quotes.GetMama(fastLimit: 0.5, slowLimit: 0.05);
Assert.Equal(Math.Round((double)SK.Last().Mama!, 6), Math.Round(QL.Last().v, 6));
}
[Fact]
public void MAD() public void MAD()
{ {
MAD_Series QL = new(bars.Close, period, false); MAD_Series QL = new(bars.Close, period, false);
+13 -1
View File
@@ -10,6 +10,7 @@ public class TA_LIB
private readonly Random rnd = new(); private readonly Random rnd = new();
private readonly int period; private readonly int period;
private readonly double[] TALIB; private readonly double[] TALIB;
private readonly double[] TALIB2;
private readonly double[] inopen; private readonly double[] inopen;
private readonly double[] inhigh; private readonly double[] inhigh;
private readonly double[] inlow; private readonly double[] inlow;
@@ -21,6 +22,7 @@ public class TA_LIB
bars = new(5000); bars = new(5000);
period = rnd.Next(28) + 3; period = rnd.Next(28) + 3;
TALIB = new double[bars.Count]; TALIB = new double[bars.Count];
TALIB2 = new double[bars.Count];
inopen = bars.Open.v.ToArray(); inopen = bars.Open.v.ToArray();
inhigh = bars.High.v.ToArray(); inhigh = bars.High.v.ToArray();
inlow = bars.Low.v.ToArray(); inlow = bars.Low.v.ToArray();
@@ -130,7 +132,16 @@ public class TA_LIB
Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
} }
[Fact]
[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);
Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
}
[Fact]
public void TRIMA() public void TRIMA()
{ {
TRIMA_Series QL = new(bars.Close, period, false); TRIMA_Series QL = new(bars.Close, period, false);
@@ -315,4 +326,5 @@ public class TA_LIB
Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
} }
} }
+2 -3
View File
@@ -17,7 +17,6 @@ Quantitative TA Library (**QuanTAlib**) is an easy-to-use C# library for quantit
**QuanTAlib** is written with some specific design criteria in mind - some reasons why there is '_yet another C# TA library_': **QuanTAlib** is written with some specific design criteria in mind - some reasons why there is '_yet another C# TA library_':
- Written in native C# - no code conversion from TA-LIB or other imported/converted TA libraries - Written in native C# - no code conversion from TA-LIB or other imported/converted TA libraries
- No usage of Decimal datatypes, LINQ, interface abstractions, or static classes with tons of methods (all for performance reasons)
- Supports both **historical data analysis** (working on bulk of historical arrays) and **real-time analysis** (adding one data item at the time without the need to re-calculate the whole history) - Supports both **historical data analysis** (working on bulk of historical arrays) and **real-time analysis** (adding one data item at the time without the need to re-calculate the whole history)
- Calculate early data right - no hiding of incomplete calculations with NaN values (unless explicitly requested with useNan: true), data is as valid as mathematically possible from the first value - Calculate early data right - no hiding of incomplete calculations with NaN values (unless explicitly requested with useNan: true), data is as valid as mathematically possible from the first value
- Usage of events - each data series is an event publisher, each indicator is a subscriber - this allows seamless data flow between indicators) - Usage of events - each data series is an event publisher, each indicator is a subscriber - this allows seamless data flow between indicators)
@@ -57,8 +56,8 @@ See [Getting Started](https://github.com/mihakralj/QuanTAlib/blob/main/Docs/gett
| ⭐ BIAS - Bias | `BIAS_Series` ||| bias | | ⭐ BIAS - Bias | `BIAS_Series` ||| bias |
| ⭐ CORR - Pearson's Correlation Coefficient | `CORR_Series` | CORREL | GetCorrelation || | ⭐ CORR - Pearson's Correlation Coefficient | `CORR_Series` | CORREL | GetCorrelation ||
| ⭐ COVAR - Covariance | `COVAR_Series` || GetCorrelation || | ⭐ COVAR - Covariance | `COVAR_Series` || GetCorrelation ||
| ⭐ ENTP - Entropy | `ENTP_Series` ||| entropy | | ⭐ ENTROPY - Entropy | `ENTROPY_Series` ||| entropy |
| ⭐ KURT - Kurtosis | `KURT_Series` ||| kurtosis | | ⭐ KURTOSIS - Kurtosis | `KURT_Series` ||| kurtosis |
| ⭐ LINREG - Linear Regression | `LINREG_Series` || GetSlope || | ⭐ LINREG - Linear Regression | `LINREG_Series` || GetSlope ||
| ⭐ MAD - Mean Absolute Deviation | `MAD_Series` || GetSma | mad | | ⭐ MAD - Mean Absolute Deviation | `MAD_Series` || GetSma | mad |
| ⭐ MAPE - Mean Absolute Percent Error | `MAPE_Series` || GetSma || | ⭐ MAPE - Mean Absolute Percent Error | `MAPE_Series` || GetSma ||