diff --git a/.github/workflows/Publish.yml b/.github/workflows/Publish.yml index bab332b0..835aafd1 100644 --- a/.github/workflows/Publish.yml +++ b/.github/workflows/Publish.yml @@ -61,6 +61,7 @@ jobs: /d:sonar.exclusions="**/TestResults/**/*,**/bin/**/*,**/obj/**/*,**/*.html,**/coverage/**/*,**/CoverageReport/**/*,**/*.md,**/*.css,**/docs/**/*,**/archive/**/*,**/notebooks/**/*" ` /d:sonar.test.exclusions="**Tests.cs,**/obj/**/*,**/bin/**/*" ` /d:sonar.cpd.exclusions="**Tests.cs" ` + /d:sonar.scanner.scanAll="false" ` /d:sonar.cs.roslyn.ignoreIssues="false" ` /d:sonar.issue.ignore.multicriteria="e1" ` /d:sonar.issue.ignore.multicriteria.e1.ruleKey="csharpsquid:S1944,csharpsquid:S2053,csharpsquid:S2222,csharpsquid:S2259,csharpsquid:S2583,csharpsquid:S2589,csharpsquid:S3329,csharpsquid:S3655,csharpsquid:S3900,csharpsquid:S3949,csharpsquid:S3966,csharpsquid:S4158,csharpsquid:S4347,csharpsquid:S5773,csharpsquid:S6781" ` @@ -102,7 +103,7 @@ jobs: coverage-reports: '*cover*.xml' - name: Upload Coverage to Codecov - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@v4 with: files: 'cover*' verbose: true @@ -158,7 +159,7 @@ jobs: fetch-depth: 0 - name: Setup NuGet - uses: nuget/setup-nuget@v1 + uses: nuget/setup-nuget@v2 - name: Setup MSBuild uses: microsoft/setup-msbuild@v1 diff --git a/Tests/test_updates_volatility.cs b/Tests/test_updates_volatility.cs index bf9fabec..8bb6e5c4 100644 --- a/Tests/test_updates_volatility.cs +++ b/Tests/test_updates_volatility.cs @@ -26,6 +26,22 @@ public class VolatilityUpdateTests return new TBar(DateTime.Now, open, high, low, close, 1000, IsNew); } + [Fact] + public void Adr_Update() + { + var indicator = new Adr(period: 14); + TBar r = GetRandomBar(true); + double initialValue = indicator.Calc(r); + + for (int i = 0; i < RandomUpdates; i++) + { + indicator.Calc(GetRandomBar(IsNew: false)); + } + double finalValue = indicator.Calc(new TBar(r.Time, r.Open, r.High, r.Low, r.Close, r.Volume, IsNew: false)); + + Assert.Equal(initialValue, finalValue, precision); + } + [Fact] public void Atr_Update() { @@ -42,6 +58,38 @@ public class VolatilityUpdateTests Assert.Equal(initialValue, finalValue, precision); } + [Fact] + public void Ap_Update() + { + var indicator = new Ap(period: 20); + TBar r = GetRandomBar(true); + double initialValue = indicator.Calc(r); + + for (int i = 0; i < RandomUpdates; i++) + { + indicator.Calc(GetRandomBar(IsNew: false)); + } + double finalValue = indicator.Calc(new TBar(r.Time, r.Open, r.High, r.Low, r.Close, r.Volume, IsNew: false)); + + Assert.Equal(initialValue, finalValue, precision); + } + + [Fact] + public void Atrp_Update() + { + var indicator = new Atrp(period: 14); + TBar r = GetRandomBar(true); + double initialValue = indicator.Calc(r); + + for (int i = 0; i < RandomUpdates; i++) + { + indicator.Calc(GetRandomBar(IsNew: false)); + } + double finalValue = indicator.Calc(new TBar(r.Time, r.Open, r.High, r.Low, r.Close, r.Volume, IsNew: false)); + + Assert.Equal(initialValue, finalValue, precision); + } + [Fact] public void Historical_Update() { diff --git a/Tests/test_updates_volume.cs b/Tests/test_updates_volume.cs index 66058a26..b6aa92b6 100644 --- a/Tests/test_updates_volume.cs +++ b/Tests/test_updates_volume.cs @@ -319,4 +319,68 @@ public class VolumeUpdateTests Assert.Equal(initialValue, finalValue, precision); } + + [Fact] + public void Vf_Update() + { + var indicator = new Vf(period: 13); + TBar r = GetRandomBar(true); + double initialValue = indicator.Calc(r); + + for (int i = 0; i < RandomUpdates; i++) + { + indicator.Calc(GetRandomBar(IsNew: false)); + } + double finalValue = indicator.Calc(new TBar(r.Time, r.Open, r.High, r.Low, r.Close, r.Volume, IsNew: false)); + + Assert.Equal(initialValue, finalValue, precision); + } + + [Fact] + public void Vp_Update() + { + var indicator = new Vp(period: 14); + TBar r = GetRandomBar(true); + double initialValue = indicator.Calc(r); + + for (int i = 0; i < RandomUpdates; i++) + { + indicator.Calc(GetRandomBar(IsNew: false)); + } + double finalValue = indicator.Calc(new TBar(r.Time, r.Open, r.High, r.Low, r.Close, r.Volume, IsNew: false)); + + Assert.Equal(initialValue, finalValue, precision); + } + + [Fact] + public void Vwap_Update() + { + var indicator = new Vwap(); + TBar r = GetRandomBar(true); + double initialValue = indicator.Calc(r); + + for (int i = 0; i < RandomUpdates; i++) + { + indicator.Calc(GetRandomBar(IsNew: false)); + } + double finalValue = indicator.Calc(new TBar(r.Time, r.Open, r.High, r.Low, r.Close, r.Volume, IsNew: false)); + + Assert.Equal(initialValue, finalValue, precision); + } + + [Fact] + public void Vwma_Update() + { + var indicator = new Vwma(period: 20); + TBar r = GetRandomBar(true); + double initialValue = indicator.Calc(r); + + for (int i = 0; i < RandomUpdates; i++) + { + indicator.Calc(GetRandomBar(IsNew: false)); + } + double finalValue = indicator.Calc(new TBar(r.Time, r.Open, r.High, r.Low, r.Close, r.Volume, IsNew: false)); + + Assert.Equal(initialValue, finalValue, precision); + } } diff --git a/lib/averages/Dema.cs b/lib/averages/Dema.cs index d0673ae4..87437214 100644 --- a/lib/averages/Dema.cs +++ b/lib/averages/Dema.cs @@ -18,7 +18,6 @@ namespace QuanTAlib; /// public class Dema : AbstractBase { - private readonly int _period; private readonly double _k; private readonly double _epsilon = 1e-10; private double _lastEma1, _p_lastEma1; @@ -31,8 +30,7 @@ public class Dema : AbstractBase { throw new ArgumentOutOfRangeException(nameof(period), "Period must be greater than or equal to 1."); } - _period = period; - _k = 2.0 / (_period + 1); + _k = 2.0 / (period + 1); Name = "Dema"; double percentile = 0.85; //targeting 85th percentile of correctness of converging EMA WarmupPeriod = (int)System.Math.Ceiling(-period * System.Math.Log(1 - percentile)); diff --git a/lib/averages/Dsma.cs b/lib/averages/Dsma.cs index 70f80191..dd3d3916 100644 --- a/lib/averages/Dsma.cs +++ b/lib/averages/Dsma.cs @@ -22,7 +22,6 @@ namespace QuanTAlib; public class Dsma : AbstractBase { - private readonly int _period; private readonly CircularBuffer _buffer; private readonly double _c1, _c2, _c3; private readonly double _scaleFactor; @@ -50,7 +49,6 @@ public class Dsma : AbstractBase { throw new ArgumentOutOfRangeException(nameof(scaleFactor), "Scale factor must be between 0 and 1 (exclusive)."); } - _period = period; _periodRecip = 1.0 / period; _scaleFactor = scaleFactor; _buffer = new CircularBuffer(period); diff --git a/lib/averages/Epma.cs b/lib/averages/Epma.cs index 170a0319..7ea87ff9 100644 --- a/lib/averages/Epma.cs +++ b/lib/averages/Epma.cs @@ -27,7 +27,6 @@ public class Epma : AbstractBase { private readonly int _period; private readonly Convolution _convolution; - private readonly double[] _baseKernel; /// The number of data points used in the EPMA calculation. /// Thrown when period is less than 1. @@ -38,7 +37,7 @@ public class Epma : AbstractBase throw new System.ArgumentException("Period must be greater than or equal to 1.", nameof(period)); } _period = period; - _baseKernel = GenerateKernel(_period); + double[] _baseKernel = GenerateKernel(_period); _convolution = new Convolution(_baseKernel); Name = "Epma"; WarmupPeriod = period; diff --git a/lib/averages/Fwma.cs b/lib/averages/Fwma.cs index bff1bf4d..63d35481 100644 --- a/lib/averages/Fwma.cs +++ b/lib/averages/Fwma.cs @@ -27,7 +27,6 @@ namespace QuanTAlib; public class Fwma : AbstractBase { private readonly Convolution _convolution; - private readonly double[] _kernel; /// The number of data points used in the FWMA calculation. /// Thrown when period is less than 1. @@ -37,7 +36,7 @@ public class Fwma : AbstractBase { throw new System.ArgumentException("Period must be greater than or equal to 1.", nameof(period)); } - _kernel = GenerateKernel(period); + double[] _kernel = GenerateKernel(period); _convolution = new Convolution(_kernel); Name = "Fwma"; WarmupPeriod = period; diff --git a/lib/averages/Gma.cs b/lib/averages/Gma.cs index 71d80a88..19e9da11 100644 --- a/lib/averages/Gma.cs +++ b/lib/averages/Gma.cs @@ -27,7 +27,6 @@ namespace QuanTAlib; public class Gma : AbstractBase { private readonly Convolution _convolution; - private readonly double[] _kernel; /// The number of data points used in the GMA calculation. /// Thrown when period is less than 1. @@ -37,7 +36,7 @@ public class Gma : AbstractBase { throw new System.ArgumentException("Period must be greater than or equal to 1.", nameof(period)); } - _kernel = GenerateKernel(period); + double[] _kernel = GenerateKernel(period); _convolution = new Convolution(_kernel); Name = "Gma"; WarmupPeriod = period; diff --git a/lib/averages/Hma.cs b/lib/averages/Hma.cs index 20e4b833..f4f08312 100644 --- a/lib/averages/Hma.cs +++ b/lib/averages/Hma.cs @@ -29,11 +29,6 @@ namespace QuanTAlib; public class Hma : AbstractBase { private readonly Convolution _wmaHalf, _wmaFull, _wmaFinal; - private readonly int _period; - private readonly int _sqrtPeriod; - private readonly double[] _kernelHalf; - private readonly double[] _kernelFull; - private readonly double[] _kernelFinal; /// The number of data points used in the HMA calculation. Must be at least 2. /// Thrown when period is less than 2. @@ -43,13 +38,12 @@ public class Hma : AbstractBase { throw new System.ArgumentException("Period must be greater than or equal to 2.", nameof(period)); } - _period = period; - _sqrtPeriod = (int)System.Math.Sqrt(period); + int _sqrtPeriod = (int)System.Math.Sqrt(period); // Generate all kernels once - _kernelHalf = GenerateWmaKernel(period / 2); - _kernelFull = GenerateWmaKernel(period); - _kernelFinal = GenerateWmaKernel(_sqrtPeriod); + double[] _kernelHalf = GenerateWmaKernel(period / 2); + double[] _kernelFull = GenerateWmaKernel(period); + double[] _kernelFinal = GenerateWmaKernel(_sqrtPeriod); // Initialize convolutions with pre-generated kernels _wmaHalf = new Convolution(_kernelHalf); diff --git a/lib/averages/Sinema.cs b/lib/averages/Sinema.cs index a58d59b3..41b04263 100644 --- a/lib/averages/Sinema.cs +++ b/lib/averages/Sinema.cs @@ -29,7 +29,6 @@ namespace QuanTAlib; public class Sinema : AbstractBase { private readonly Convolution _convolution; - private readonly double[] _kernel; /// The number of data points used in the SINEMA calculation. /// Thrown when period is less than 1. @@ -39,7 +38,7 @@ public class Sinema : AbstractBase { throw new System.ArgumentException("Period must be greater than or equal to 1.", nameof(period)); } - _kernel = GenerateKernel(period); + double[] _kernel = GenerateKernel(period); _convolution = new Convolution(_kernel); Name = "Sinema"; WarmupPeriod = period; diff --git a/lib/averages/Sma.cs b/lib/averages/Sma.cs index 784abfd7..41ef584d 100644 --- a/lib/averages/Sma.cs +++ b/lib/averages/Sma.cs @@ -28,7 +28,6 @@ namespace QuanTAlib; public class Sma : AbstractBase { private readonly CircularBuffer _buffer; - private readonly int _period; /// The number of data points used in the SMA calculation. /// Thrown when period is less than 1. @@ -38,7 +37,6 @@ public class Sma : AbstractBase { throw new System.ArgumentOutOfRangeException(nameof(period), "Period must be greater than or equal to 1."); } - _period = period; _buffer = new CircularBuffer(period); Name = "Sma"; WarmupPeriod = period; diff --git a/lib/averages/T3.cs b/lib/averages/T3.cs index f0d3402f..d1875db1 100644 --- a/lib/averages/T3.cs +++ b/lib/averages/T3.cs @@ -29,7 +29,6 @@ namespace QuanTAlib; public class T3 : AbstractBase { private readonly int _period; - private readonly double _vfactor; private readonly bool _useSma; private readonly double _k; private readonly double _c1, _c2, _c3, _c4; @@ -49,7 +48,6 @@ public class T3 : AbstractBase throw new System.ArgumentException("Period must be greater than or equal to 1.", nameof(period)); } _period = period; - _vfactor = vfactor; _useSma = useSma; WarmupPeriod = period; @@ -70,7 +68,7 @@ public class T3 : AbstractBase _buffer5 = new(period); _buffer6 = new(period); - Name = $"T3({_period}, {_vfactor})"; + Name = $"T3({_period}, {vfactor})"; Init(); } diff --git a/lib/quantalib.csproj b/lib/quantalib.csproj index 5b87dfa0..a54f910e 100644 --- a/lib/quantalib.csproj +++ b/lib/quantalib.csproj @@ -12,7 +12,7 @@ readme.md QuanTAlib QuanTAlib - 0.0.0.0 + 0.0.0.1 True AnyCPU full diff --git a/quantower/Averages/_Averages.csproj b/quantower/Averages/_Averages.csproj index 8d946a96..651c18c5 100644 --- a/quantower/Averages/_Averages.csproj +++ b/quantower/Averages/_Averages.csproj @@ -2,7 +2,7 @@ Averages Indicator - 0.0.0.0 + 0.0.0.1 bin\$(Configuration)\ true true diff --git a/quantower/Momentum/_Momentum.csproj b/quantower/Momentum/_Momentum.csproj index 00cb1a71..e249d4a8 100644 --- a/quantower/Momentum/_Momentum.csproj +++ b/quantower/Momentum/_Momentum.csproj @@ -2,7 +2,7 @@ Momentum Indicator - 0.0.0.0 + 0.0.0.1 bin\$(Configuration)\ true true diff --git a/quantower/Oscillators/_Oscillators.csproj b/quantower/Oscillators/_Oscillators.csproj index ed3a39fe..6b20b9df 100644 --- a/quantower/Oscillators/_Oscillators.csproj +++ b/quantower/Oscillators/_Oscillators.csproj @@ -2,7 +2,7 @@ Oscillators Indicator - 0.0.0.0 + 0.0.0.1 bin\$(Configuration)\ true true diff --git a/quantower/Statistics/_Statistics.csproj b/quantower/Statistics/_Statistics.csproj index 4904fae6..d78a01e2 100644 --- a/quantower/Statistics/_Statistics.csproj +++ b/quantower/Statistics/_Statistics.csproj @@ -2,7 +2,7 @@ Statistics Indicator - 0.0.0.0 + 0.0.0.1 bin\$(Configuration)\ true true diff --git a/quantower/Volatility/_Volatility.csproj b/quantower/Volatility/_Volatility.csproj index 0a8f58d8..eefb1d1a 100644 --- a/quantower/Volatility/_Volatility.csproj +++ b/quantower/Volatility/_Volatility.csproj @@ -2,7 +2,7 @@ Volatility Indicator - 0.0.0.0 + 0.0.0.1 bin\$(Configuration)\ true true diff --git a/quantower/Volume/_Volume.csproj b/quantower/Volume/_Volume.csproj index 13266f2a..281f89b3 100644 --- a/quantower/Volume/_Volume.csproj +++ b/quantower/Volume/_Volume.csproj @@ -2,7 +2,7 @@ Volume Indicator - 0.0.0.0 + 0.0.0.1 bin\$(Configuration)\ true true