From 593da0883cd7ebc44eef732b6e64798dff77b708 Mon Sep 17 00:00:00 2001 From: Dave Skender <8432125+DaveSkender@users.noreply.github.com> Date: Sun, 28 Jul 2024 20:35:39 -0400 Subject: [PATCH 01/38] cosmetic: rename removal test --- tests/indicators/_common/Observables/Cache.Manager.Tests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/indicators/_common/Observables/Cache.Manager.Tests.cs b/tests/indicators/_common/Observables/Cache.Manager.Tests.cs index 0fddb9a57..de2ff04db 100644 --- a/tests/indicators/_common/Observables/Cache.Manager.Tests.cs +++ b/tests/indicators/_common/Observables/Cache.Manager.Tests.cs @@ -10,7 +10,7 @@ public class CacheMgmtTests : TestBase public void ModifyWithAct() => Assert.Inconclusive("test not implemented"); [TestMethod] - public void Purge() + public void Remove() { QuoteHub provider = new(); SmaHub observer = provider.ToSma(20); From bbc233267ebb54ba3bc30c897812b318bee1822e Mon Sep 17 00:00:00 2001 From: Dave Skender <8432125+DaveSkender@users.noreply.github.com> Date: Sun, 28 Jul 2024 20:59:34 -0400 Subject: [PATCH 02/38] docs: fix BasicData internal link refs --- docs/_data/aliases.yml | 10 +++++----- docs/_indicators/{Use.md => QuotePart.md} | 13 ++++++++++--- src/_common/Use (QuotePart)/Use.Api.cs | 13 +++++++------ 3 files changed, 22 insertions(+), 14 deletions(-) rename docs/_indicators/{Use.md => QuotePart.md} (84%) diff --git a/docs/_data/aliases.yml b/docs/_data/aliases.yml index 9950409f0..5d1bf4b87 100644 --- a/docs/_data/aliases.yml +++ b/docs/_data/aliases.yml @@ -59,23 +59,23 @@ type: price-characteristic - title: HL2 - permalink: /indicators/BasicQuote/ + permalink: /indicators/quotepart/ type: price-transform - title: HLC3 - permalink: /indicators/BasicQuote/ + permalink: /indicators/quotepart/ type: price-transform - title: OC2 - permalink: /indicators/BasicQuote/ + permalink: /indicators/quotepart/ type: price-transform - title: OHL3 - permalink: /indicators/BasicQuote/ + permalink: /indicators/quotepart/ type: price-transform - title: OHLC4 - permalink: /indicators/BasicQuote/ + permalink: /indicators/quotepart/ type: price-transform - title: Price Channels diff --git a/docs/_indicators/Use.md b/docs/_indicators/QuotePart.md similarity index 84% rename from docs/_indicators/Use.md rename to docs/_indicators/QuotePart.md index 236eb9ad8..d4f7491c8 100644 --- a/docs/_indicators/Use.md +++ b/docs/_indicators/QuotePart.md @@ -1,19 +1,26 @@ --- -title: Basic quote transform +title: Quote parts and basic transforms description: Basic quote transforms (e.g. HL2, OHL3, etc.) and isolation of individual price quote candle parts from a full OHLCV quote. -permalink: /indicators/Use/ +permalink: /indicators/quotepart/ +redirect-from: + - /indicators/Use/ + - /indicators/BasicQuote/ type: price-transform layout: indicator --- # {{ page.title }} -Returns a reusable (chainable) basic quote transform (e.g. HL2, OHL3, etc.) by isolating a single value or calculated value from the full OHLCV quote candle parts. +Returns a reusable (chainable) basic quote transform (e.g. HL2, OHL3, etc.) by isolating a single component part value or calculated value from the full OHLCV quote candle parts. ```csharp // C# usage syntax IReadOnlyList results = quotes.Use(candlePart); + +// alternate syntax +IReadOnlyList results = + quotes.GetQuotePart(candlePart); ``` ## Parameters diff --git a/src/_common/Use (QuotePart)/Use.Api.cs b/src/_common/Use (QuotePart)/Use.Api.cs index 8150b23cf..4bd12cde5 100644 --- a/src/_common/Use (QuotePart)/Use.Api.cs +++ b/src/_common/Use (QuotePart)/Use.Api.cs @@ -5,19 +5,20 @@ namespace Skender.Stock.Indicators; public static partial class QuotePartUtility { // SERIES, from Quotes - public static IReadOnlyList Use( - this IEnumerable quotes, + public static IReadOnlyList Use( + this IEnumerable quotes, CandlePart candlePart) + where TQuote : IQuote => quotes .OrderBy(q => q.Timestamp) .Select(q => q.ToQuotePart(candlePart)) .ToList(); - // SERIES, from Quotes - public static IReadOnlyList Use( - this IEnumerable quotes, + // SERIES, from Quotes (QuotePart alias) + /// + public static IReadOnlyList GetQuotePart( + this IEnumerable quotes, CandlePart candlePart) - where TQuote : IQuote => quotes .OrderBy(q => q.Timestamp) .Select(q => q.ToQuotePart(candlePart)) From 0607d6990182b4fd567f593cffe97bfa981aba81 Mon Sep 17 00:00:00 2001 From: Dave Skender <8432125+DaveSkender@users.noreply.github.com> Date: Sun, 28 Jul 2024 22:18:56 -0400 Subject: [PATCH 03/38] simplify ATR Stop result class (to double) --- docs/_indicators/AtrStop.md | 6 +-- src/_common/ObsoleteV3.md | 2 + src/a-d/Alligator/Alligator.StreamHub.cs | 3 -- src/a-d/AtrStop/AtrStop.Models.cs | 6 +-- src/a-d/AtrStop/AtrStop.Series.cs | 8 ++-- src/a-d/AtrStop/AtrStop.StreamHub.cs | 37 +++++++++---------- .../a-d/AtrStop/AtrStop.Series.Tests.cs | 24 ++++++------ 7 files changed, 41 insertions(+), 45 deletions(-) diff --git a/docs/_indicators/AtrStop.md b/docs/_indicators/AtrStop.md index e2ef0271e..c1db90504 100644 --- a/docs/_indicators/AtrStop.md +++ b/docs/_indicators/AtrStop.md @@ -57,11 +57,11 @@ IReadOnlyList **`Timestamp`** _`DateTime`_ - date from evaluated `TQuote` -**`AtrStop`** _`decimal`_ - ATR Trailing Stop line contains both Upper and Lower segments +**`AtrStop`** _`double`_ - ATR Trailing Stop line contains both Upper and Lower segments -**`BuyStop`** _`decimal`_ - Upper band only (green) +**`BuyStop`** _`double`_ - Upper band only (green) -**`SellStop`** _`decimal`_ - Lower band only (red) +**`SellStop`** _`double`_ - Lower band only (red) **`Atr`** _`double`_ - Average True Range diff --git a/src/_common/ObsoleteV3.md b/src/_common/ObsoleteV3.md index a366d1ca5..ae1815186 100644 --- a/src/_common/ObsoleteV3.md +++ b/src/_common/ObsoleteV3.md @@ -93,6 +93,8 @@ Items marked with 🚩 require special attention since they will not produc - `GetBaseQuote()` indicator and related `BasicData` return types were removed since they are redundant to the `Use()` method and `QuotePart` return types, respectively. +- `AtrStopResult` values were changed from `decimal` to `double` numeric return types. + - `SyncSeries()` utility function and related `SyncType` enum were removed. This was primarily an internal utility, but was part of the public API to support user who wanted to build custom indicator development. Internally, we've refactored indicators to auto-initialize and heal, so they no longer require re-sizing to support explicit warmup periods. - `ToTupleCollection()` utility method was deprecated. This was available to support custom indicator development, but is no longer needed. We've discontinued using _tuples_ as an interface to chainable indicators. diff --git a/src/a-d/Alligator/Alligator.StreamHub.cs b/src/a-d/Alligator/Alligator.StreamHub.cs index 36fd43477..a8a4e93ae 100644 --- a/src/a-d/Alligator/Alligator.StreamHub.cs +++ b/src/a-d/Alligator/Alligator.StreamHub.cs @@ -91,7 +91,6 @@ internal override void Add(Act act, TIn newIn, int? index) if (i >= TeethPeriods + TeethOffset - 1) { AlligatorResult prev = Cache[i - 1]; - double prevTooth = prev.Teeth.Null2NaN(); // first/reset value: calculate SMA @@ -118,13 +117,11 @@ internal override void Add(Act act, TIn newIn, int? index) if (i >= LipsPeriods + LipsOffset - 1) { AlligatorResult prev = Cache[i - 1]; - double prevLips = prev.Lips.Null2NaN(); // first/reset value: calculate SMA if (double.IsNaN(prevLips)) { - // TODO: refactor - add offset to, and use Sma.Increment(...,offset) double sum = 0; for (int p = i - LipsPeriods - LipsOffset + 1; p <= i - LipsOffset; p++) { diff --git a/src/a-d/AtrStop/AtrStop.Models.cs b/src/a-d/AtrStop/AtrStop.Models.cs index 69c7b1b46..5966930c6 100644 --- a/src/a-d/AtrStop/AtrStop.Models.cs +++ b/src/a-d/AtrStop/AtrStop.Models.cs @@ -20,8 +20,8 @@ namespace Skender.Stock.Indicators; /// public record AtrStopResult( DateTime Timestamp, - decimal? AtrStop = null, - decimal? BuyStop = null, - decimal? SellStop = null, + double? AtrStop = null, + double? BuyStop = null, + double? SellStop = null, double? Atr = null ) : ISeries; diff --git a/src/a-d/AtrStop/AtrStop.Series.cs b/src/a-d/AtrStop/AtrStop.Series.cs index 70521e8dd..39980810d 100644 --- a/src/a-d/AtrStop/AtrStop.Series.cs +++ b/src/a-d/AtrStop/AtrStop.Series.cs @@ -84,8 +84,8 @@ private static List CalcAtrStop( r = new( Timestamp: q.Timestamp, - AtrStop: (decimal)upperBand, - BuyStop: (decimal)upperBand, + AtrStop: upperBand, + BuyStop: upperBand, SellStop: null, Atr: atr); } @@ -97,9 +97,9 @@ private static List CalcAtrStop( r = new( Timestamp: q.Timestamp, - AtrStop: (decimal)lowerBand, + AtrStop: lowerBand, BuyStop: null, - SellStop: (decimal)lowerBand, + SellStop: lowerBand, Atr: atr); } diff --git a/src/a-d/AtrStop/AtrStop.StreamHub.cs b/src/a-d/AtrStop/AtrStop.StreamHub.cs index 33ec3d9cc..c366a38a4 100644 --- a/src/a-d/AtrStop/AtrStop.StreamHub.cs +++ b/src/a-d/AtrStop/AtrStop.StreamHub.cs @@ -57,23 +57,20 @@ public override void OnNext((Act, TIn, int?) value) return; } - // find last synchronized band position (before deviance) - int lastSyncIndex = Cache.FindLastIndex( - x => x.Timestamp < item.Timestamp - && x.AtrStop == (IsBullish ? x.SellStop : x.BuyStop)); + int i = index ?? Provider.GetIndex(item, false); - // rebuild from last know reversal point - if (lastSyncIndex > LookbackPeriods) + // reset to the prior stop points + if (i > LookbackPeriods) { - AtrStopResult lastSyncPoint = Cache[lastSyncIndex]; + AtrStopResult resetStop = Cache[i - 1]; // reset prevailing direction and bands - IsBullish = lastSyncPoint.AtrStop == lastSyncPoint.SellStop; - UpperBand = (double?)lastSyncPoint.BuyStop ?? default; - LowerBand = (double?)lastSyncPoint.SellStop ?? default; + IsBullish = resetStop.AtrStop >= resetStop.SellStop; + UpperBand = resetStop.BuyStop ?? default; + LowerBand = resetStop.SellStop ?? default; // rebuild cache AFTER last sync point - RebuildCache(lastSyncIndex + 1, lastSyncIndex + 1); + RebuildCache(i, i); } // full rebuild if no prior reversal @@ -100,12 +97,12 @@ internal override void Add(Act act, TIn newIn, int? index) } QuoteD newQ = newIn.ToQuoteD(); - QuoteD prevQ = Provider.Results[i - 1].ToQuoteD(); + double prevClose = (double)Provider.Results[i - 1].Close; // initialize direction on first evaluation if (i == LookbackPeriods) { - IsBullish = newQ.Close >= prevQ.Close; + IsBullish = newQ.Close >= prevClose; } // calculate ATR @@ -117,7 +114,7 @@ internal override void Add(Act act, TIn newIn, int? index) LookbackPeriods, newQ.High, newQ.Low, - prevQ.Close, + prevClose, Cache[i - 1].Atr ?? double.NaN); } @@ -156,13 +153,13 @@ internal override void Add(Act act, TIn newIn, int? index) } // new upper band: can only go down, or reverse - if (upperEval < UpperBand || prevQ.Close > UpperBand) + if (upperEval < UpperBand || prevClose > UpperBand) { UpperBand = upperEval; } // new lower band: can only go up, or reverse - if (lowerEval > LowerBand || prevQ.Close < LowerBand) + if (lowerEval > LowerBand || prevClose < LowerBand) { LowerBand = lowerEval; } @@ -178,8 +175,8 @@ internal override void Add(Act act, TIn newIn, int? index) r = new( Timestamp: newQ.Timestamp, - AtrStop: (decimal)UpperBand, - BuyStop: (decimal)UpperBand, + AtrStop: UpperBand, + BuyStop: UpperBand, SellStop: null, Atr: atr); } @@ -191,9 +188,9 @@ internal override void Add(Act act, TIn newIn, int? index) r = new( Timestamp: newQ.Timestamp, - AtrStop: (decimal)LowerBand, + AtrStop: LowerBand, BuyStop: null, - SellStop: (decimal)LowerBand, + SellStop: LowerBand, Atr: atr); } diff --git a/tests/indicators/a-d/AtrStop/AtrStop.Series.Tests.cs b/tests/indicators/a-d/AtrStop/AtrStop.Series.Tests.cs index a7cb7546d..f77308259 100644 --- a/tests/indicators/a-d/AtrStop/AtrStop.Series.Tests.cs +++ b/tests/indicators/a-d/AtrStop/AtrStop.Series.Tests.cs @@ -23,27 +23,27 @@ public override void Standard() Assert.AreEqual(null, r20.SellStop); AtrStopResult r21 = results[21]; - Assert.AreEqual(211.13m, r21.AtrStop.Round(4)); + Assert.AreEqual(211.13, r21.AtrStop.Round(4)); Assert.AreEqual(null, r21.BuyStop); Assert.AreEqual(r21.AtrStop, r21.SellStop); AtrStopResult r151 = results[151]; - Assert.AreEqual(232.7861m, r151.AtrStop.Round(4)); + Assert.AreEqual(232.7861, r151.AtrStop.Round(4)); Assert.AreEqual(null, r151.BuyStop); Assert.AreEqual(r151.AtrStop, r151.SellStop); AtrStopResult r152 = results[152]; - Assert.AreEqual(236.3913m, r152.AtrStop.Round(4)); + Assert.AreEqual(236.3913, r152.AtrStop.Round(4)); Assert.AreEqual(r152.AtrStop, r152.BuyStop); Assert.AreEqual(null, r152.SellStop); AtrStopResult r249 = results[249]; - Assert.AreEqual(253.8863m, r249.AtrStop.Round(4)); + Assert.AreEqual(253.8863, r249.AtrStop.Round(4)); Assert.AreEqual(null, r249.BuyStop); Assert.AreEqual(r249.AtrStop, r249.SellStop); AtrStopResult r501 = results[501]; - Assert.AreEqual(246.3232m, r501.AtrStop.Round(4)); + Assert.AreEqual(246.3232, r501.AtrStop.Round(4)); Assert.AreEqual(r501.AtrStop, r501.BuyStop); Assert.AreEqual(null, r501.SellStop); } @@ -68,27 +68,27 @@ public void HighLow() Assert.AreEqual(null, r20.SellStop); AtrStopResult r21 = results[21]; - Assert.AreEqual(210.23m, r21.AtrStop.Round(4)); + Assert.AreEqual(210.23, r21.AtrStop.Round(4)); Assert.AreEqual(null, r21.BuyStop); Assert.AreEqual(r21.AtrStop, r21.SellStop); AtrStopResult r69 = results[69]; - Assert.AreEqual(221.0594m, r69.AtrStop.Round(4)); + Assert.AreEqual(221.0594, r69.AtrStop.Round(4)); Assert.AreEqual(null, r69.BuyStop); Assert.AreEqual(r69.AtrStop, r69.SellStop); AtrStopResult r70 = results[70]; - Assert.AreEqual(226.4624m, r70.AtrStop.Round(4)); + Assert.AreEqual(226.4624, r70.AtrStop.Round(4)); Assert.AreEqual(r70.AtrStop, r70.BuyStop); Assert.AreEqual(null, r70.SellStop); AtrStopResult r249 = results[249]; - Assert.AreEqual(253.4863m, r249.AtrStop.Round(4)); + Assert.AreEqual(253.4863, r249.AtrStop.Round(4)); Assert.AreEqual(null, r249.BuyStop); Assert.AreEqual(r249.AtrStop, r249.SellStop); AtrStopResult r501 = results[501]; - Assert.AreEqual(252.6932m, r501.AtrStop.Round(4)); + Assert.AreEqual(252.6932, r501.AtrStop.Round(4)); Assert.AreEqual(r501.AtrStop, r501.BuyStop); Assert.AreEqual(null, r501.SellStop); } @@ -130,7 +130,7 @@ public void Condense() Assert.AreEqual(481, results.Count); AtrStopResult last = results[^1]; - Assert.AreEqual(246.3232m, last.AtrStop.Round(4)); + Assert.AreEqual(246.3232, last.AtrStop.Round(4)); Assert.AreEqual(last.AtrStop, last.BuyStop); Assert.AreEqual(null, last.SellStop); } @@ -149,7 +149,7 @@ public void Removed() Assert.AreEqual(481, results.Count); AtrStopResult last = results[^1]; - Assert.AreEqual(246.3232m, last.AtrStop.Round(4)); + Assert.AreEqual(246.3232, last.AtrStop.Round(4)); Assert.AreEqual(last.AtrStop, last.BuyStop); Assert.AreEqual(null, last.SellStop); } From 71c453fae93a2951d7b05776f2862cd02f7e335b Mon Sep 17 00:00:00 2001 From: Dave Skender <8432125+DaveSkender@users.noreply.github.com> Date: Mon, 29 Jul 2024 02:39:38 -0400 Subject: [PATCH 04/38] fix Use.Api.cs Signed-off-by: Dave Skender <8432125+DaveSkender@users.noreply.github.com> --- src/_common/Use (QuotePart)/Use.Api.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/_common/Use (QuotePart)/Use.Api.cs b/src/_common/Use (QuotePart)/Use.Api.cs index 4bd12cde5..14e981797 100644 --- a/src/_common/Use (QuotePart)/Use.Api.cs +++ b/src/_common/Use (QuotePart)/Use.Api.cs @@ -17,8 +17,9 @@ public static IReadOnlyList Use( // SERIES, from Quotes (QuotePart alias) /// public static IReadOnlyList GetQuotePart( - this IEnumerable quotes, + this IEnumerable quotes, CandlePart candlePart) + where TQuote : IQuote => quotes .OrderBy(q => q.Timestamp) .Select(q => q.ToQuotePart(candlePart)) From 9eace3be431deb01ecaf71314a6ec861a4e16346 Mon Sep 17 00:00:00 2001 From: Dave Skender <8432125+DaveSkender@users.noreply.github.com> Date: Tue, 30 Jul 2024 11:38:11 -0400 Subject: [PATCH 05/38] tuneup Dynamic --- src/_common/ObsoleteV3.cs | 25 +++++++---- src/a-d/Dynamic/Dynamic.Api.cs | 5 ++- src/a-d/Dynamic/Dynamic.StaticSeries.cs | 44 ++++++++----------- ...Dynamic.Common.cs => Dynamic.Utilities.cs} | 14 +++++- 4 files changed, 49 insertions(+), 39 deletions(-) rename src/a-d/Dynamic/{Dynamic.Common.cs => Dynamic.Utilities.cs} (63%) diff --git a/src/_common/ObsoleteV3.cs b/src/_common/ObsoleteV3.cs index 54bf03653..df7368e01 100644 --- a/src/_common/ObsoleteV3.cs +++ b/src/_common/ObsoleteV3.cs @@ -8,8 +8,10 @@ namespace Skender.Stock.Indicators; // OBSOLETE IN v3 public static partial class Indicator { + // GENERAL INDICATOR METHODS + [ExcludeFromCodeCoverage] - [Obsolete("Use alternate 'GetX' variant.", false)] // v3.0.0 + [Obsolete("Use alternate 'GetX' variant. Tuple arguments were removed.", false)] // v3.0.0 public static IEnumerable GetAlligator( this IEnumerable<(DateTime d, double v)> priceTuples, int jawPeriods = 13, @@ -26,6 +28,15 @@ public static IEnumerable GetAlligator( teethPeriods, teethOffset, lipsPeriods, lipsOffset); + [ExcludeFromCodeCoverage] + [Obsolete("Replace `GetEma(..)` with `ToEma(..)`", false)] // v3.0.0 + public static IEnumerable GetEma( + this IEnumerable quotes, int lookbackPeriods) + where TQuote : IQuote + => Api.ToEma(quotes, lookbackPeriods); + + // REMOVAL OF INTEGRATED SMAs (evaluates to ERRORs) + [ExcludeFromCodeCoverage] [Obsolete("Use a chained `results.GetSma(smaPeriods)` to generate a moving average.", true)] // v3.0.0 public static IEnumerable GetAdl( @@ -33,13 +44,6 @@ public static IEnumerable GetAdl( where TQuote : IQuote => quotes.ToSortedList().CalcAdl(); - [ExcludeFromCodeCoverage] - [Obsolete("Replace `GetEma(..)` with `ToEma(..)`", true)] // v3.0.0 - public static IEnumerable GetEma( - this IEnumerable quotes, int lookbackPeriods) - where TQuote : IQuote - => quotes.ToEma(lookbackPeriods); - [ExcludeFromCodeCoverage] [Obsolete("Use a chained `results.GetSma(smaPeriods)` to generate a moving average.", true)] // v3.0.0 public static IEnumerable GetObv( @@ -75,6 +79,8 @@ public static IEnumerable GetTrix( where TQuote : IQuote => quotes.Use(CandlePart.Close).ToList().CalcTrix(lookbackPeriods); + // UTILITIES + [ExcludeFromCodeCoverage] [Obsolete("This method no longer defaults to Close. Rename Use() to Use(CandlePart.Close) for an explicit conversion.", false)] // v3.0.0 public static IEnumerable<(DateTime Timestamp, double Value)> Use( @@ -89,7 +95,6 @@ public static IEnumerable GetTrix( where TResult : IReusable => reusable.Select(x => (x.Timestamp, x.Value)).OrderBy(x => x.Timestamp).ToCollection(); - [ExcludeFromCodeCoverage] [Obsolete("Refactor to use `List.First(c => c.Timestamp == lookupDate)`", false)] // v3.0.0 public static TSeries Find(this IEnumerable series, DateTime lookupDate) @@ -101,6 +106,8 @@ public static int FindIndex(this List series, DateTime lookupD where TSeries : ISeries => series?.FindIndex(x => x.Timestamp == lookupDate) ?? -1; } +// CLASSES AND INTERFACES + [Obsolete("Rename `IReusableResult` to `IReusable`", true)] // v3.0.0 public interface IReusableResult : IReusable; diff --git a/src/a-d/Dynamic/Dynamic.Api.cs b/src/a-d/Dynamic/Dynamic.Api.cs index 34e906f2f..55f47ec05 100644 --- a/src/a-d/Dynamic/Dynamic.Api.cs +++ b/src/a-d/Dynamic/Dynamic.Api.cs @@ -1,7 +1,8 @@ namespace Skender.Stock.Indicators; -// McGINLEY DYNAMIC -public static partial class Indicator +// McGINLEY DYNAMIC (API) + +public static partial class MgDynamic { // SERIES, from CHAIN public static IReadOnlyList GetDynamic( diff --git a/src/a-d/Dynamic/Dynamic.StaticSeries.cs b/src/a-d/Dynamic/Dynamic.StaticSeries.cs index 87ef22fee..452fb3cc6 100644 --- a/src/a-d/Dynamic/Dynamic.StaticSeries.cs +++ b/src/a-d/Dynamic/Dynamic.StaticSeries.cs @@ -2,7 +2,7 @@ namespace Skender.Stock.Indicators; // McGINLEY DYNAMIC (SERIES) -public static partial class Indicator +public static partial class MgDynamic { private static List CalcDynamic( this List source, @@ -17,33 +17,25 @@ private static List CalcDynamic( int length = source.Count; List results = new(length); - double prevDyn = double.NaN; - - // roll through source values, to get preliminary data - for (int i = 0; i < length; i++) + // skip first period + if (length > 0) { - T s = source[i]; - double dyn; - - // re/initialize - if (double.IsNaN(prevDyn)) - { - dyn = double.NaN; - prevDyn = s.Value; - } - - // normal Dynamic - else - { - dyn = prevDyn + (s.Value - prevDyn) / - (kFactor * lookbackPeriods * Math.Pow(s.Value / prevDyn, 4)); - - prevDyn = dyn; - } + results.Add(new(source[0].Timestamp, null)); + } - results.Add(new( - Timestamp: s.Timestamp, - Dynamic: dyn.NaN2Null())); + // roll through source values + for (int i = 1; i < length; i++) + { + double? dyn = Increment( + lookbackPeriods, + kFactor, + newVal: source[i].Value, + prevDyn: results[i - 1].Dynamic ?? source[i - 1].Value + ).NaN2Null(); + + results.Add(new DynamicResult( + Timestamp: source[i].Timestamp, + Dynamic: dyn)); } return results; diff --git a/src/a-d/Dynamic/Dynamic.Common.cs b/src/a-d/Dynamic/Dynamic.Utilities.cs similarity index 63% rename from src/a-d/Dynamic/Dynamic.Common.cs rename to src/a-d/Dynamic/Dynamic.Utilities.cs index cb71fd2a6..5228d3c4d 100644 --- a/src/a-d/Dynamic/Dynamic.Common.cs +++ b/src/a-d/Dynamic/Dynamic.Utilities.cs @@ -1,9 +1,19 @@ namespace Skender.Stock.Indicators; -// McGINLEY DYNAMIC (COMMON) +// McGINLEY DYNAMIC (UTILITIES) -public static class MgDynamic +public static partial class MgDynamic { + // increment calculation + public static double Increment( + int lookbackPeriods, + double kFactor, + double newVal, + double prevDyn) + => prevDyn + ( + (newVal - prevDyn) + / (kFactor * lookbackPeriods * Math.Pow(newVal / prevDyn, 4))); + // parameter validation internal static void Validate( int lookbackPeriods, From 9448839c7995d20b76fb6b35bdcfe090b7f9940c Mon Sep 17 00:00:00 2001 From: Dave Skender <8432125+DaveSkender@users.noreply.github.com> Date: Tue, 30 Jul 2024 11:39:06 -0400 Subject: [PATCH 06/38] tuneup CMO --- src/a-d/Cmo/Cmo.StaticSeries.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/a-d/Cmo/Cmo.StaticSeries.cs b/src/a-d/Cmo/Cmo.StaticSeries.cs index 3ec0801d5..93b8549a0 100644 --- a/src/a-d/Cmo/Cmo.StaticSeries.cs +++ b/src/a-d/Cmo/Cmo.StaticSeries.cs @@ -38,10 +38,13 @@ private static List CalcCmo( // determine tick direction and size (bool? isUp, double value) tick = (null, Math.Abs(s.Value - prevValue)); - tick.isUp = double.IsNaN(tick.value) ? null - : (s.Value > prevValue ? true - : (s.Value < prevValue ? false - : null)); + tick.isUp = double.IsNaN(tick.value) + ? null + : s.Value > prevValue + ? true + : s.Value < prevValue + ? false + : null; ticks.Add(tick); From 64c557cbc6fb44b5dc82ebfe0edc05002518b19b Mon Sep 17 00:00:00 2001 From: Dave Skender <8432125+DaveSkender@users.noreply.github.com> Date: Tue, 30 Jul 2024 11:40:30 -0400 Subject: [PATCH 07/38] tuneup MACD --- src/m-r/Macd/Macd.StaticSeries.cs | 65 +++++++++---------------------- 1 file changed, 19 insertions(+), 46 deletions(-) diff --git a/src/m-r/Macd/Macd.StaticSeries.cs b/src/m-r/Macd/Macd.StaticSeries.cs index e9ee2a55e..8eedf8bc3 100644 --- a/src/m-r/Macd/Macd.StaticSeries.cs +++ b/src/m-r/Macd/Macd.StaticSeries.cs @@ -29,57 +29,30 @@ private static List CalcMacd( // roll through source values for (int i = 0; i < length; i++) { - T s = source[i]; - - // re-initialize Fast EMA - double emaFast; - - if (double.IsNaN(lastEmaFast) && i >= fastPeriods - 1) - { - double sum = 0; - for (int p = i - fastPeriods + 1; p <= i; p++) - { - T ps = source[p]; - sum += ps.Value; - } - - emaFast = sum / fastPeriods; - } - else - { - emaFast = Ema.Increment(kFast, lastEmaFast, s.Value); - } - - // re-initialize Slow EMA - double emaSlow; - - if (double.IsNaN(lastEmaSlow) && i >= slowPeriods - 1) - { - double sum = 0; - for (int p = i - slowPeriods + 1; p <= i; p++) - { - T ps = source[p]; - sum += ps.Value; - } - - emaSlow = sum / slowPeriods; - } - else - { - emaSlow = Ema.Increment(kSlow, lastEmaSlow, s.Value); - } - + // Fast EMA + double emaFast + = i >= fastPeriods - 1 && results[i - 1].FastEma is null + ? Sma.Increment(source, fastPeriods, i) + : Ema.Increment(kFast, lastEmaFast, source[i].Value); + + // Slow EMA + double emaSlow + = i >= slowPeriods - 1 && results[i - 1].SlowEma is null + ? Sma.Increment(source, slowPeriods, i) + : Ema.Increment(kSlow, lastEmaSlow, source[i].Value); + + // MACD double macd = emaFast - emaSlow; - // re-initialize Signal EMA + // Signal double signal; - if (double.IsNaN(lastEmaMacd) && i >= signalPeriods + slowPeriods - 2) + if (i >= signalPeriods + slowPeriods - 2 && results[i - 1].Signal is null) { double sum = macd; for (int p = i - signalPeriods + 1; p < i; p++) { - sum += ((IReusable)results[p]).Value; + sum += results[p].Value; } signal = sum / signalPeriods; @@ -89,9 +62,9 @@ private static List CalcMacd( signal = Ema.Increment(kMacd, lastEmaMacd, macd); } - // write results - results.Add(new( - Timestamp: s.Timestamp, + // results + results.Add(new MacdResult( + Timestamp: source[i].Timestamp, Macd: macd.NaN2Null(), Signal: signal.NaN2Null(), Histogram: (macd - signal).NaN2Null(), From 49d3a7f14e78932c461263673009c40a5b6e26a6 Mon Sep 17 00:00:00 2001 From: Dave Skender <8432125+DaveSkender@users.noreply.github.com> Date: Tue, 30 Jul 2024 11:59:30 -0400 Subject: [PATCH 08/38] tune KAMA --- src/e-k/Kama/Kama.Api.cs | 3 +- src/e-k/Kama/Kama.Common.cs | 33 --------------------- src/e-k/Kama/Kama.StaticSeries.cs | 30 ++++++++++--------- src/e-k/Kama/Kama.Utilities.cs | 28 +++++++++++++++++- src/s-z/Sma/Sma.StreamHub.cs | 2 +- src/s-z/Sma/Sma.Utilities.cs | 49 +++++++++++++++++++++++++++++-- 6 files changed, 92 insertions(+), 53 deletions(-) delete mode 100644 src/e-k/Kama/Kama.Common.cs diff --git a/src/e-k/Kama/Kama.Api.cs b/src/e-k/Kama/Kama.Api.cs index b499a392f..8c9484f62 100644 --- a/src/e-k/Kama/Kama.Api.cs +++ b/src/e-k/Kama/Kama.Api.cs @@ -1,7 +1,8 @@ namespace Skender.Stock.Indicators; // KAUFMAN's ADAPTIVE MOVING AVERAGE (API) -public static partial class Indicator + +public static partial class Kama { // SERIES, from CHAIN public static IReadOnlyList GetKama( diff --git a/src/e-k/Kama/Kama.Common.cs b/src/e-k/Kama/Kama.Common.cs deleted file mode 100644 index 7cc5bf300..000000000 --- a/src/e-k/Kama/Kama.Common.cs +++ /dev/null @@ -1,33 +0,0 @@ -namespace Skender.Stock.Indicators; - -// KAUFMAN's ADAPTIVE MOVING AVERAGE (COMMON) - -public static class Kama -{ - // parameter validation - internal static void Validate( - int erPeriods, - int fastPeriods, - int slowPeriods) - { - // check parameter arguments - if (erPeriods <= 0) - { - throw new ArgumentOutOfRangeException(nameof(erPeriods), erPeriods, - "Efficiency Ratio periods must be greater than 0 for KAMA."); - } - - if (fastPeriods <= 0) - { - throw new ArgumentOutOfRangeException(nameof(fastPeriods), fastPeriods, - "Fast EMA periods must be greater than 0 for KAMA."); - } - - if (slowPeriods <= fastPeriods) - { - throw new ArgumentOutOfRangeException(nameof(slowPeriods), slowPeriods, - "Slow EMA periods must be greater than Fast EMA period for KAMA."); - } - } - -} diff --git a/src/e-k/Kama/Kama.StaticSeries.cs b/src/e-k/Kama/Kama.StaticSeries.cs index 460717c9a..e98e34034 100644 --- a/src/e-k/Kama/Kama.StaticSeries.cs +++ b/src/e-k/Kama/Kama.StaticSeries.cs @@ -2,7 +2,7 @@ namespace Skender.Stock.Indicators; // KAUFMAN's ADAPTIVE MOVING AVERAGE (SERIES) -public static partial class Indicator +public static partial class Kama { private static List CalcKama( this List source, @@ -26,27 +26,22 @@ private static List CalcKama( // roll through source values for (int i = 0; i < length; i++) { - T s = source[i]; - // skip incalculable periods if (i < erPeriods - 1) { - results.Add(new(s.Timestamp)); + results.Add(new(source[i].Timestamp)); continue; } double er; double kama; - if (double.IsNaN(prevKama)) - { - er = double.NaN; - kama = s.Value; - } - else + if (results[i - 1].Kama is not null) { + double newVal = source[i].Value; + // ER period change - double change = Math.Abs(s.Value - source[i - erPeriods].Value); + double change = Math.Abs(newVal - source[i - erPeriods].Value); // volatility double sumPv = 0; @@ -64,19 +59,26 @@ private static List CalcKama( double sc = (er * (scFast - scSlow)) + scSlow; // squared later // kama calculation - kama = prevKama + (sc * sc * (s.Value - prevKama)); + kama = prevKama + (sc * sc * (newVal - prevKama)); } // handle flatline case else { er = 0; - kama = s.Value; + kama = source[i].Value; } } + // re/initialize + else + { + er = double.NaN; + kama = source[i].Value; + } + results.Add(new KamaResult( - Timestamp: s.Timestamp, + Timestamp: source[i].Timestamp, Er: er.NaN2Null(), Kama: kama.NaN2Null())); diff --git a/src/e-k/Kama/Kama.Utilities.cs b/src/e-k/Kama/Kama.Utilities.cs index bb7cc3086..3f844acab 100644 --- a/src/e-k/Kama/Kama.Utilities.cs +++ b/src/e-k/Kama/Kama.Utilities.cs @@ -1,6 +1,6 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +public static partial class Kama { // remove recommended periods /// @@ -13,4 +13,30 @@ public static IReadOnlyList RemoveWarmupPeriods( return results.Remove(Math.Max(erPeriods + 100, 10 * erPeriods)); } + + // parameter validation + internal static void Validate( + int erPeriods, + int fastPeriods, + int slowPeriods) + { + // check parameter arguments + if (erPeriods <= 0) + { + throw new ArgumentOutOfRangeException(nameof(erPeriods), erPeriods, + "Efficiency Ratio periods must be greater than 0 for KAMA."); + } + + if (fastPeriods <= 0) + { + throw new ArgumentOutOfRangeException(nameof(fastPeriods), fastPeriods, + "Fast EMA periods must be greater than 0 for KAMA."); + } + + if (slowPeriods <= fastPeriods) + { + throw new ArgumentOutOfRangeException(nameof(slowPeriods), slowPeriods, + "Slow EMA periods must be greater than Fast EMA period for KAMA."); + } + } } diff --git a/src/s-z/Sma/Sma.StreamHub.cs b/src/s-z/Sma/Sma.StreamHub.cs index aea31bcc7..6029cefb7 100644 --- a/src/s-z/Sma/Sma.StreamHub.cs +++ b/src/s-z/Sma/Sma.StreamHub.cs @@ -37,7 +37,7 @@ internal override void Add(Act act, TIn newIn, int? index) // candidate result SmaResult r = new( Timestamp: newIn.Timestamp, - Sma: Sma.Increment(Provider.Results, i, LookbackPeriods).NaN2Null()); + Sma: Sma.Increment(Provider.Results, LookbackPeriods, i).NaN2Null()); // save and send Motify(act, r, i); diff --git a/src/s-z/Sma/Sma.Utilities.cs b/src/s-z/Sma/Sma.Utilities.cs index 1880cdd1f..53d5bef2c 100644 --- a/src/s-z/Sma/Sma.Utilities.cs +++ b/src/s-z/Sma/Sma.Utilities.cs @@ -2,10 +2,51 @@ namespace Skender.Stock.Indicators; public static partial class Sma { - internal static double Increment( + /// + /// Simple moving average calculation + /// + /// List of chainable values + /// + /// Window to evaluate, prior to 'endIndex' + /// + /// + /// Index position to evaluate or last position when . + /// + /// IReusable (chainable) type + /// + /// Simple moving average or + /// if incalculable + /// values are in range. + /// + internal static double? Average( this IReadOnlyList values, - int endIndex, - int lookbackPeriods) + int lookbackPeriods, + int? endIndex = null) + where T : IReusable + + // TODO: unused SMA utility, either make public or remove + + => Increment( + values, + lookbackPeriods, + endIndex ?? values.Count - 1) + .NaN2Null(); + + /// + /// Simple moving average calculation + /// + /// List of chainable values + /// Window to evaluate, prior to 'endIndex' + /// Index position to evaluate. + /// IReusable (chainable) type + /// + /// Simple moving average or + /// when incalculable. + /// + internal static double Increment( + IReadOnlyList values, + int lookbackPeriods, + int endIndex) where T : IReusable { int offset = lookbackPeriods - 1; @@ -24,6 +65,8 @@ internal static double Increment( } return sum / lookbackPeriods; + + // TODO: apply this SMA increment method more widely in other indicators (see EMA example) } // parameter validation From 052bad10728c9b1b5103d8fe47aa8d35d9f3b2b0 Mon Sep 17 00:00:00 2001 From: Dave Skender <8432125+DaveSkender@users.noreply.github.com> Date: Tue, 30 Jul 2024 12:13:17 -0400 Subject: [PATCH 09/38] tuneup Alligator --- src/a-d/Alligator/Alligator.StaticSeries.cs | 23 ++++++++++-------- src/a-d/Alligator/Alligator.StreamHub.cs | 26 ++++++++++----------- 2 files changed, 26 insertions(+), 23 deletions(-) diff --git a/src/a-d/Alligator/Alligator.StaticSeries.cs b/src/a-d/Alligator/Alligator.StaticSeries.cs index fffcf84e0..887a98b9e 100644 --- a/src/a-d/Alligator/Alligator.StaticSeries.cs +++ b/src/a-d/Alligator/Alligator.StaticSeries.cs @@ -37,10 +37,8 @@ internal static List CalcAlligator( // calculate alligator's jaw, when in range if (i >= jawPeriods + jawOffset - 1) { - double prevJaw = results[i - 1].Jaw.Null2NaN(); - // first/reset value: calculate SMA - if (double.IsNaN(prevJaw)) + if (results[i - 1].Jaw is null) { double sum = 0; for (int p = i - jawPeriods - jawOffset + 1; p <= i - jawOffset; p++) @@ -54,6 +52,8 @@ internal static List CalcAlligator( // remaining values: SMMA else { + double prevJaw = results[i - 1].Jaw.Null2NaN(); + jaw = ((prevJaw * (jawPeriods - 1)) + source[i - jawOffset].Value) / jawPeriods; } } @@ -61,10 +61,8 @@ internal static List CalcAlligator( // calculate alligator's teeth, when in range if (i >= teethPeriods + teethOffset - 1) { - double prevTooth = results[i - 1].Teeth.Null2NaN(); - // first/reset value: calculate SMA - if (double.IsNaN(prevTooth)) + if (results[i - 1].Teeth is null) { double sum = 0; for (int p = i - teethPeriods - teethOffset + 1; p <= i - teethOffset; p++) @@ -78,6 +76,8 @@ internal static List CalcAlligator( // remaining values: SMMA else { + double prevTooth = results[i - 1].Teeth.Null2NaN(); + teeth = ((prevTooth * (teethPeriods - 1)) + source[i - teethOffset].Value) / teethPeriods; } } @@ -85,10 +85,8 @@ internal static List CalcAlligator( // calculate alligator's lips, when in range if (i >= lipsPeriods + lipsOffset - 1) { - double prevLips = results[i - 1].Lips.Null2NaN(); - // first/reset value: calculate SMA - if (double.IsNaN(prevLips)) + if (results[i - 1].Lips is null) { double sum = 0; for (int p = i - lipsPeriods - lipsOffset + 1; p <= i - lipsOffset; p++) @@ -102,13 +100,18 @@ internal static List CalcAlligator( // remaining values: SMMA else { + double prevLips = results[i - 1].Lips.Null2NaN(); + lips = ((prevLips * (lipsPeriods - 1)) + source[i - lipsOffset].Value) / lipsPeriods; } } // result results.Add(new AlligatorResult( - source[i].Timestamp, jaw.NaN2Null(), teeth.NaN2Null(), lips.NaN2Null())); + source[i].Timestamp, + jaw.NaN2Null(), + teeth.NaN2Null(), + lips.NaN2Null())); } return results; diff --git a/src/a-d/Alligator/Alligator.StreamHub.cs b/src/a-d/Alligator/Alligator.StreamHub.cs index 3816358f7..ba68d8bf0 100644 --- a/src/a-d/Alligator/Alligator.StreamHub.cs +++ b/src/a-d/Alligator/Alligator.StreamHub.cs @@ -64,11 +64,8 @@ internal override void Add(Act act, TIn newIn, int? index) // calculate alligator's jaw, when in range if (i >= JawPeriods + JawOffset - 1) { - AlligatorResult prev = Cache[i - 1]; - double prevJaw = prev.Jaw.Null2NaN(); - // first/reset value: calculate SMA - if (double.IsNaN(prevJaw)) + if (Cache[i - 1].Jaw is null) { double sum = 0; for (int p = i - JawPeriods - JawOffset + 1; p <= i - JawOffset; p++) @@ -82,7 +79,9 @@ internal override void Add(Act act, TIn newIn, int? index) // remaining values: SMMA else { + double prevJaw = Cache[i - 1].Jaw.Null2NaN(); double newVal = Provider.Results[i - JawOffset].Hl2OrValue(); + jaw = ((prevJaw * (JawPeriods - 1)) + newVal) / JawPeriods; } } @@ -90,11 +89,8 @@ internal override void Add(Act act, TIn newIn, int? index) // calculate alligator's teeth, when in range if (i >= TeethPeriods + TeethOffset - 1) { - AlligatorResult prev = Cache[i - 1]; - double prevTooth = prev.Teeth.Null2NaN(); - // first/reset value: calculate SMA - if (double.IsNaN(prevTooth)) + if (Cache[i - 1].Teeth is null) { double sum = 0; for (int p = i - TeethPeriods - TeethOffset + 1; p <= i - TeethOffset; p++) @@ -108,7 +104,9 @@ internal override void Add(Act act, TIn newIn, int? index) // remaining values: SMMA else { + double prevTooth = Cache[i - 1].Teeth.Null2NaN(); double newVal = Provider.Results[i - TeethOffset].Hl2OrValue(); + teeth = ((prevTooth * (TeethPeriods - 1)) + newVal) / TeethPeriods; } } @@ -116,11 +114,8 @@ internal override void Add(Act act, TIn newIn, int? index) // calculate alligator's lips, when in range if (i >= LipsPeriods + LipsOffset - 1) { - AlligatorResult prev = Cache[i - 1]; - double prevLips = prev.Lips.Null2NaN(); - // first/reset value: calculate SMA - if (double.IsNaN(prevLips)) + if (Cache[i - 1].Lips is null) { double sum = 0; for (int p = i - LipsPeriods - LipsOffset + 1; p <= i - LipsOffset; p++) @@ -134,14 +129,19 @@ internal override void Add(Act act, TIn newIn, int? index) // remaining values: SMMA else { + double prevLips = Cache[i - 1].Lips.Null2NaN(); double newVal = Provider.Results[i - LipsOffset].Hl2OrValue(); + lips = ((prevLips * (LipsPeriods - 1)) + newVal) / LipsPeriods; } } // candidate result AlligatorResult r = new( - newIn.Timestamp, jaw.NaN2Null(), teeth.NaN2Null(), lips.NaN2Null()); + newIn.Timestamp, + jaw.NaN2Null(), + teeth.NaN2Null(), + lips.NaN2Null()); // save and send Motify(act, r, i); From 4951454ad16503144ba03fbb8143b46e02c7ee41 Mon Sep 17 00:00:00 2001 From: Dave Skender <8432125+DaveSkender@users.noreply.github.com> Date: Tue, 30 Jul 2024 12:27:07 -0400 Subject: [PATCH 10/38] tuneup EMA --- src/_common/Reusable/Reusable.Utilities.cs | 6 +++++ src/e-k/Ema/Ema.StaticSeries.cs | 23 ++++--------------- src/e-k/Ema/Ema.StreamHub.cs | 10 ++++---- tests/performance/Perf.StreamHub.Externals.cs | 4 ++-- 4 files changed, 17 insertions(+), 26 deletions(-) diff --git a/src/_common/Reusable/Reusable.Utilities.cs b/src/_common/Reusable/Reusable.Utilities.cs index ddef2bb6f..d49655a27 100644 --- a/src/_common/Reusable/Reusable.Utilities.cs +++ b/src/_common/Reusable/Reusable.Utilities.cs @@ -37,6 +37,9 @@ public static IReadOnlyList Condense( x => double.IsNaN(x.Value)); return resultsList; + + // TODO: remove specific indicator 'Condense()' methods + // that are now redundant to this generic method (not all are) } /// @@ -62,6 +65,9 @@ internal static IReadOnlyList RemoveWarmupPeriods( .FindIndex(x => !double.IsNaN(x.Value)); return results.Remove(removePeriods); + + // TODO: remove specific indicator 'RemoveWarmupPeriods()' methods + // that are now redundant to this generic method (not all are) } // convert TQuote element to a basic chainable class diff --git a/src/e-k/Ema/Ema.StaticSeries.cs b/src/e-k/Ema/Ema.StaticSeries.cs index c072fc51b..89ea3ed14 100644 --- a/src/e-k/Ema/Ema.StaticSeries.cs +++ b/src/e-k/Ema/Ema.StaticSeries.cs @@ -31,26 +31,13 @@ internal static List CalcEma( continue; } - double ema; + double ema = results[i - 1].Ema is not null - // when no prior EMA, reset as SMA - if (double.IsNaN(lastEma)) - { - double sum = 0; - for (int p = i - lookbackPeriods + 1; p <= i; p++) - { - T ps = source[p]; - sum += ps.Value; - } - - ema = sum / lookbackPeriods; - } + // calculate EMA (normally) + ? Ema.Increment(k, lastEma, s.Value) - // normal EMA - else - { - ema = Increment(k, lastEma, s.Value); - } + // when no prior EMA, reset as SMA + : Sma.Increment(source, lookbackPeriods, i); EmaResult r = new( Timestamp: s.Timestamp, diff --git a/src/e-k/Ema/Ema.StreamHub.cs b/src/e-k/Ema/Ema.StreamHub.cs index 1cf61eaa8..5bb96c4e6 100644 --- a/src/e-k/Ema/Ema.StreamHub.cs +++ b/src/e-k/Ema/Ema.StreamHub.cs @@ -33,15 +33,13 @@ internal override void Add(Act act, TIn newIn, int? index) if (i >= LookbackPeriods - 1) { - IReusable last = Cache[i - 1]; - - ema = !double.IsNaN(last.Value) + ema = Cache[i - 1].Ema is not null // normal - ? Ema.Increment(K, last.Value, newIn.Value) + ? Ema.Increment(K, Cache[i - 1].Value, newIn.Value) - // re/initialize - : Sma.Increment(Provider.Results, i, LookbackPeriods); + // re/initialize as SMA + : Sma.Increment(Provider.Results, LookbackPeriods, i); } // warmup periods are never calculable diff --git a/tests/performance/Perf.StreamHub.Externals.cs b/tests/performance/Perf.StreamHub.Externals.cs index aa6706217..467356e75 100644 --- a/tests/performance/Perf.StreamHub.Externals.cs +++ b/tests/performance/Perf.StreamHub.Externals.cs @@ -33,8 +33,8 @@ public void Cleanup() // TODO: replace with external data cache model, when available [Benchmark(Baseline = true)] - public object GetEma() => quotes.ToEma(14); + public object EmaSeries() => quotes.ToEma(14); [Benchmark] - public object EmaHub() => provider.ToEma(14).Results; + public object EmaStream() => provider.ToEma(14).Results; } From c13f772966fa09c3b28f4e99423ee9799b6e49a3 Mon Sep 17 00:00:00 2001 From: Dave Skender <8432125+DaveSkender@users.noreply.github.com> Date: Tue, 30 Jul 2024 16:22:57 -0400 Subject: [PATCH 11/38] refactor: update convergence tests --- tests/other/Convergence.Tests.cs | 216 +++++++++++++++---------------- 1 file changed, 108 insertions(+), 108 deletions(-) diff --git a/tests/other/Convergence.Tests.cs b/tests/other/Convergence.Tests.cs index c47c7dd16..232a52a47 100644 --- a/tests/other/Convergence.Tests.cs +++ b/tests/other/Convergence.Tests.cs @@ -11,11 +11,11 @@ public void Adx() { foreach (int qty in QuotesQuantities) { - IEnumerable qts = Data.GetLongish(qty); - IEnumerable r = qts.GetAdx(); + IReadOnlyList qts = Data.GetLongish(qty); + IReadOnlyList r = qts.GetAdx(); - AdxResult l = r.LastOrDefault(); - Console.WriteLine($"ADX(14) on {l.Timestamp:d} with {qts.Count(),4} historical qts: {l.Adx:N8}"); + AdxResult l = r[^1]; + Console.WriteLine($"ADX(14) on {l.Timestamp:d} with {qts.Count,4} historical qts: {l.Adx:N8}"); } } @@ -24,13 +24,13 @@ public void Alligator() { foreach (int qty in QuotesQuantities) { - IEnumerable quotes = Data.GetLongish(qty); - IEnumerable r = quotes.GetAlligator(); + IReadOnlyList quotes = Data.GetLongish(qty); + IReadOnlyList r = quotes.GetAlligator(); - AlligatorResult l = r.LastOrDefault(); + AlligatorResult l = r[^1]; Console.WriteLine( "ALLIGATOR(13,8,5) on {0:d} with {1,4} periods: Jaw {2:N8}", - l.Timestamp, quotes.Count(), l.Jaw); + l.Timestamp, quotes.Count, l.Jaw); } } @@ -39,11 +39,11 @@ public void Atr() { foreach (int qty in QuotesQuantities) { - IEnumerable qts = Data.GetLongish(qty); - IEnumerable r = qts.GetAtr(); + IReadOnlyList qts = Data.GetLongish(qty); + IReadOnlyList r = qts.GetAtr(); - AtrResult l = r.LastOrDefault(); - Console.WriteLine($"ATR(14) on {l.Timestamp:d} with {qts.Count(),4} periods: {l.Atr:N8}"); + AtrResult l = r[^1]; + Console.WriteLine($"ATR(14) on {l.Timestamp:d} with {qts.Count,4} periods: {l.Atr:N8}"); } } @@ -52,11 +52,11 @@ public void ChaikinOsc() { foreach (int qty in QuotesQuantities) { - IEnumerable qts = Data.GetLongish(qty); - IEnumerable r = qts.GetChaikinOsc(); + IReadOnlyList qts = Data.GetLongish(qty); + IReadOnlyList r = qts.GetChaikinOsc(); - ChaikinOscResult l = r.LastOrDefault(); - Console.WriteLine($"CHAIKIN OSC on {l.Timestamp:d} with {qts.Count(),4} periods: {l.Oscillator:N8}"); + ChaikinOscResult l = r[^1]; + Console.WriteLine($"CHAIKIN OSC on {l.Timestamp:d} with {qts.Count,4} periods: {l.Oscillator:N8}"); } } @@ -65,11 +65,11 @@ public void ConnorsRsi() { foreach (int qty in QuotesQuantities) { - IEnumerable qts = Data.GetLongish(qty); - IEnumerable r = qts.GetConnorsRsi(3, 2, 10); + IReadOnlyList qts = Data.GetLongish(qty); + IReadOnlyList r = qts.GetConnorsRsi(3, 2, 10); - ConnorsRsiResult l = r.LastOrDefault(); - Console.WriteLine($"CRSI on {l.Timestamp:d} with {qts.Count(),4} periods: {l.ConnorsRsi:N8}"); + ConnorsRsiResult l = r[^1]; + Console.WriteLine($"CRSI on {l.Timestamp:d} with {qts.Count,4} periods: {l.ConnorsRsi:N8}"); } } @@ -78,11 +78,11 @@ public void Dema() { foreach (int qty in QuotesQuantities) { - IEnumerable qts = Data.GetLongish(qty); - IEnumerable r = qts.GetDema(15); + IReadOnlyList qts = Data.GetLongish(qty); + IReadOnlyList r = qts.GetDema(15); - DemaResult l = r.LastOrDefault(); - Console.WriteLine($"DEMA(15) on {l.Timestamp:d} with {qts.Count(),4} periods: {l.Dema:N8}"); + DemaResult l = r[^1]; + Console.WriteLine($"DEMA(15) on {l.Timestamp:d} with {qts.Count,4} periods: {l.Dema:N8}"); } } @@ -91,11 +91,11 @@ public void Dynamic() { foreach (int qty in QuotesQuantities) { - IEnumerable qts = Data.GetLongish(qty); - IEnumerable r = qts.GetDynamic(100); + IReadOnlyList qts = Data.GetLongish(qty); + IReadOnlyList r = qts.GetDynamic(100); - DynamicResult l = r.LastOrDefault(); - Console.WriteLine($"DYNAMIC(15) on {l.Timestamp:d} with {qts.Count(),4} periods: {l.Dynamic:N8}"); + DynamicResult l = r[^1]; + Console.WriteLine($"DYNAMIC(15) on {l.Timestamp:d} with {qts.Count,4} periods: {l.Dynamic:N8}"); } } @@ -104,11 +104,11 @@ public void Ema() { foreach (int qty in QuotesQuantities) { - IEnumerable qts = Data.GetLongish(qty); - IEnumerable r = qts.ToEma(15); + IReadOnlyList qts = Data.GetLongish(qty); + IReadOnlyList r = qts.ToEma(15); - EmaResult l = r.LastOrDefault(); - Console.WriteLine($"EMA(15) on {l.Timestamp:d} with {qts.Count(),4} periods: {l.Ema:N8}"); + EmaResult l = r[^1]; + Console.WriteLine($"EMA(15) on {l.Timestamp:d} with {qts.Count,4} periods: {l.Ema:N8}"); } } @@ -117,11 +117,11 @@ public void FisherTransform() { foreach (int qty in QuotesQuantities) { - IEnumerable qts = Data.GetLongish(qty); - IEnumerable r = qts.GetFisherTransform(); + IReadOnlyList qts = Data.GetLongish(qty); + IReadOnlyList r = qts.GetFisherTransform(); - FisherTransformResult l = r.LastOrDefault(); - Console.WriteLine($"FT(10) on {l.Timestamp:d} with {qts.Count(),4} periods: {l.Fisher:N8}"); + FisherTransformResult l = r[^1]; + Console.WriteLine($"FT(10) on {l.Timestamp:d} with {qts.Count,4} periods: {l.Fisher:N8}"); } } @@ -130,13 +130,13 @@ public void Gator() { foreach (int qty in QuotesQuantities) { - IEnumerable quotes = Data.GetLongish(qty); - IEnumerable r = quotes.GetGator(); + IReadOnlyList quotes = Data.GetLongish(qty); + IReadOnlyList r = quotes.GetGator(); - GatorResult l = r.LastOrDefault(); + GatorResult l = r[^1]; Console.WriteLine( "GATOR() on {0:d} with {1,4} periods: Upper {2:N8} Lower {3:N8}", - l.Timestamp, quotes.Count(), l.Upper, l.Lower); + l.Timestamp, quotes.Count, l.Upper, l.Lower); } } @@ -145,11 +145,11 @@ public void HtTrendline() { foreach (int qty in QuotesQuantities) { - IEnumerable qts = Data.GetLongish(qty); - IEnumerable r = qts.GetHtTrendline(); + IReadOnlyList qts = Data.GetLongish(qty); + IReadOnlyList r = qts.GetHtTrendline(); - HtlResult l = r.LastOrDefault(); - Console.WriteLine($"HTL on {l.Timestamp:d} with {qts.Count(),4} periods: {l.Trendline:N8}"); + HtlResult l = r[^1]; + Console.WriteLine($"HTL on {l.Timestamp:d} with {qts.Count,4} periods: {l.Trendline:N8}"); } } @@ -158,11 +158,11 @@ public void Kama() { foreach (int qty in QuotesQuantities) { - IEnumerable qts = Data.GetLongish(qty); - IEnumerable r = qts.GetKama(); + IReadOnlyList qts = Data.GetLongish(qty); + IReadOnlyList r = qts.GetKama(); - KamaResult l = r.LastOrDefault(); - Console.WriteLine($"KAMA(10) on {l.Timestamp:d} with {qts.Count(),4} periods: {l.Kama:N8}"); + KamaResult l = r[^1]; + Console.WriteLine($"KAMA(10) on {l.Timestamp:d} with {qts.Count,4} periods: {l.Kama:N8}"); } } @@ -171,11 +171,11 @@ public void Keltner() { foreach (int qty in QuotesQuantities) { - IEnumerable qts = Data.GetLongish(qty); - IEnumerable r = qts.GetKeltner(100); + IReadOnlyList qts = Data.GetLongish(qty); + IReadOnlyList r = qts.GetKeltner(100); - KeltnerResult l = r.LastOrDefault(); - Console.WriteLine($"KC-UP on {l.Timestamp:d} with {qts.Count(),4} periods: {l.UpperBand:N8}"); + KeltnerResult l = r[^1]; + Console.WriteLine($"KC-UP on {l.Timestamp:d} with {qts.Count,4} periods: {l.UpperBand:N8}"); } } @@ -184,11 +184,11 @@ public void Macd() { foreach (int qty in QuotesQuantities) { - IEnumerable qts = Data.GetLongish(15 + qty); - IEnumerable r = qts.GetMacd(); + IReadOnlyList qts = Data.GetLongish(15 + qty); + IReadOnlyList r = qts.GetMacd(); - MacdResult l = r.LastOrDefault(); - Console.WriteLine($"MACD on {l.Timestamp:d} with {qts.Count(),4} periods: {l.Macd:N8}"); + MacdResult l = r[^1]; + Console.WriteLine($"MACD on {l.Timestamp:d} with {qts.Count,4} periods: {l.Macd:N8}"); } } @@ -197,11 +197,11 @@ public void Mama() { foreach (int qty in QuotesQuantities) { - IEnumerable qts = Data.GetLongish(qty); - IEnumerable r = qts.GetMama(); + IReadOnlyList qts = Data.GetLongish(qty); + IReadOnlyList r = qts.GetMama(); - MamaResult l = r.LastOrDefault(); - Console.WriteLine($"MAMA on {l.Timestamp:d} with {qts.Count(),4} periods: {l.Mama:N8}"); + MamaResult l = r[^1]; + Console.WriteLine($"MAMA on {l.Timestamp:d} with {qts.Count,4} periods: {l.Mama:N8}"); } } @@ -210,11 +210,11 @@ public void Pmo() { foreach (int qty in QuotesQuantities) { - IEnumerable qts = Data.GetLongish(qty); - IEnumerable r = qts.GetPmo(); + IReadOnlyList qts = Data.GetLongish(qty); + IReadOnlyList r = qts.GetPmo(); - PmoResult l = r.LastOrDefault(); - Console.WriteLine($"PMO on {l.Timestamp:d} with {qts.Count(),4} periods: {l.Pmo:N8}"); + PmoResult l = r[^1]; + Console.WriteLine($"PMO on {l.Timestamp:d} with {qts.Count,4} periods: {l.Pmo:N8}"); } } @@ -223,11 +223,11 @@ public void Pvo() { foreach (int qty in QuotesQuantities) { - IEnumerable qts = Data.GetLongish(qty); - IEnumerable r = qts.GetPvo(); + IReadOnlyList qts = Data.GetLongish(qty); + IReadOnlyList r = qts.GetPvo(); - PvoResult l = r.LastOrDefault(); - Console.WriteLine($"PVO on {l.Timestamp:d} with {qts.Count(),4} periods: {l.Pvo:N8}"); + PvoResult l = r[^1]; + Console.WriteLine($"PVO on {l.Timestamp:d} with {qts.Count,4} periods: {l.Pvo:N8}"); } } @@ -236,11 +236,11 @@ public void Rsi() { foreach (int qty in QuotesQuantities) { - IEnumerable qts = Data.GetLongish(qty); - IEnumerable r = qts.GetRsi(); + IReadOnlyList qts = Data.GetLongish(qty); + IReadOnlyList r = qts.GetRsi(); - RsiResult l = r.LastOrDefault(); - Console.WriteLine($"RSI(14) on {l.Timestamp:d} with {qts.Count(),4} periods: {l.Rsi:N8}"); + RsiResult l = r[^1]; + Console.WriteLine($"RSI(14) on {l.Timestamp:d} with {qts.Count,4} periods: {l.Rsi:N8}"); } } @@ -249,11 +249,11 @@ public void Smi() { foreach (int qty in QuotesQuantities) { - IEnumerable qts = Data.GetDefault(qty); - IEnumerable r = qts.GetSmi(14, 20, 5); + IReadOnlyList qts = Data.GetDefault(qty); + IReadOnlyList r = qts.GetSmi(14, 20, 5); - SmiResult l = r.LastOrDefault(); - Console.WriteLine($"SMI on {l.Timestamp:d} with {qts.Count(),4} periods: {l.Smi:N8}"); + SmiResult l = r[^1]; + Console.WriteLine($"SMI on {l.Timestamp:d} with {qts.Count,4} periods: {l.Smi:N8}"); } } @@ -262,11 +262,11 @@ public void Smma() { foreach (int qty in QuotesQuantities) { - IEnumerable qts = Data.GetLongish(qty); - IEnumerable r = qts.GetSmma(15); + IReadOnlyList qts = Data.GetLongish(qty); + IReadOnlyList r = qts.GetSmma(15); - SmmaResult l = r.LastOrDefault(); - Console.WriteLine($"SMMA(15) on {l.Timestamp:d} with {qts.Count(),4} periods: {l.Smma:N8}"); + SmmaResult l = r[^1]; + Console.WriteLine($"SMMA(15) on {l.Timestamp:d} with {qts.Count,4} periods: {l.Smma:N8}"); } } @@ -275,11 +275,11 @@ public void StarcBands() { foreach (int qty in QuotesQuantities) { - IEnumerable qts = Data.GetLongish(qty); - IEnumerable r = qts.GetStarcBands(20); + IReadOnlyList qts = Data.GetLongish(qty); + IReadOnlyList r = qts.GetStarcBands(20); - StarcBandsResult l = r.LastOrDefault(); - Console.WriteLine($"STARC UPPER on {l.Timestamp:d} with {qts.Count(),4} periods: {l.UpperBand:N8}"); + StarcBandsResult l = r[^1]; + Console.WriteLine($"STARC UPPER on {l.Timestamp:d} with {qts.Count,4} periods: {l.UpperBand:N8}"); } } @@ -288,11 +288,11 @@ public void StochRsi() { foreach (int qty in QuotesQuantities.Where(x => x <= 502)) { - IEnumerable qts = Data.GetDefault(qty); - IEnumerable r = qts.GetStochRsi(14, 14, 3); + IReadOnlyList qts = Data.GetDefault(qty); + IReadOnlyList r = qts.GetStochRsi(14, 14, 3); - StochRsiResult l = r.LastOrDefault(); - Console.WriteLine($"SRSI on {l.Timestamp:d} with {qts.Count(),4} periods: {l.StochRsi:N8}"); + StochRsiResult l = r[^1]; + Console.WriteLine($"SRSI on {l.Timestamp:d} with {qts.Count,4} periods: {l.StochRsi:N8}"); } } @@ -301,11 +301,11 @@ public void T3() { foreach (int qty in QuotesQuantities) { - IEnumerable qts = Data.GetLongish(qty); - IEnumerable r = qts.GetT3(20); + IReadOnlyList qts = Data.GetLongish(qty); + IReadOnlyList r = qts.GetT3(20); - T3Result l = r.LastOrDefault(); - Console.WriteLine($"T3 on {l.Timestamp:d} with {qts.Count(),4} periods: {l.T3:N8}"); + T3Result l = r[^1]; + Console.WriteLine($"T3 on {l.Timestamp:d} with {qts.Count,4} periods: {l.T3:N8}"); } } @@ -314,11 +314,11 @@ public void Tema() { foreach (int qty in QuotesQuantities) { - IEnumerable qts = Data.GetLongish(qty); - IEnumerable r = qts.GetTema(15); + IReadOnlyList qts = Data.GetLongish(qty); + IReadOnlyList r = qts.GetTema(15); - TemaResult l = r.LastOrDefault(); - Console.WriteLine($"TEMA on {l.Timestamp:d} with {qts.Count(),4} periods: {l.Tema:N8}"); + TemaResult l = r[^1]; + Console.WriteLine($"TEMA on {l.Timestamp:d} with {qts.Count,4} periods: {l.Tema:N8}"); } } @@ -327,11 +327,11 @@ public void Trix() { foreach (int qty in QuotesQuantities) { - IEnumerable qts = Data.GetLongish(qty); - IEnumerable r = qts.GetTrix(15); + IReadOnlyList qts = Data.GetLongish(qty); + IReadOnlyList r = qts.GetTrix(15); - TrixResult l = r.LastOrDefault(); - Console.WriteLine($"TRIX on {l.Timestamp:d} with {qts.Count(),4} periods: {l.Trix:N8}"); + TrixResult l = r[^1]; + Console.WriteLine($"TRIX on {l.Timestamp:d} with {qts.Count,4} periods: {l.Trix:N8}"); } } @@ -340,11 +340,11 @@ public void Tsi() { foreach (int qty in QuotesQuantities) { - IEnumerable qts = Data.GetLongish(20 + qty); - IEnumerable r = qts.GetTsi(); + IReadOnlyList qts = Data.GetLongish(20 + qty); + IReadOnlyList r = qts.GetTsi(); - TsiResult l = r.LastOrDefault(); - Console.WriteLine($"TSI on {l.Timestamp:d} with {qts.Count(),4} periods: {l.Tsi:N8}"); + TsiResult l = r[^1]; + Console.WriteLine($"TSI on {l.Timestamp:d} with {qts.Count,4} periods: {l.Tsi:N8}"); } } @@ -353,11 +353,11 @@ public void Vortex() { foreach (int qty in QuotesQuantities) { - IEnumerable qts = Data.GetLongish(qty); - IEnumerable r = qts.GetVortex(14); + IReadOnlyList qts = Data.GetLongish(qty); + IReadOnlyList r = qts.GetVortex(14); - VortexResult l = r.LastOrDefault(); - Console.WriteLine($"VI+ on {l.Timestamp:d} with {qts.Count(),4} periods: {l.Pvi:N8}"); + VortexResult l = r[^1]; + Console.WriteLine($"VI+ on {l.Timestamp:d} with {qts.Count,4} periods: {l.Pvi:N8}"); } } } From 16984a3cf16b8b191eece3919066e6341a1d51d5 Mon Sep 17 00:00:00 2001 From: Dave Skender <8432125+DaveSkender@users.noreply.github.com> Date: Tue, 30 Jul 2024 16:23:23 -0400 Subject: [PATCH 12/38] update incrementing (experiemental) --- src/_common/Incrementals/IIncremental.cs | 60 +++++++--- src/e-k/Ema/Ema.Api.cs | 2 +- src/e-k/Ema/Ema.Increments.cs | 63 ++++++++--- tests/indicators/TestBase.cs | 4 +- .../e-k/Ema/Ema.Increments.Tests.cs | 104 ++++++++++++++++-- ...ies.Tests.cs => Ema.StaticSeries.Tests.cs} | 0 tests/performance/Perf.Increments.cs | 84 +++++++++++--- tests/performance/Perf.StreamHub.Externals.cs | 4 +- tests/performance/Perf.StreamHub.cs | 4 +- 9 files changed, 262 insertions(+), 63 deletions(-) rename tests/indicators/e-k/Ema/{Ema.StaticSeries.StaticSeries.Tests.cs => Ema.StaticSeries.Tests.cs} (100%) diff --git a/src/_common/Incrementals/IIncremental.cs b/src/_common/Incrementals/IIncremental.cs index f96393d45..361c53e60 100644 --- a/src/_common/Incrementals/IIncremental.cs +++ b/src/_common/Incrementals/IIncremental.cs @@ -1,44 +1,68 @@ namespace Skender.Stock.Indicators; -public interface IIncrementalPrice - where TQuote : IQuote +public interface IIncrementReusable { /// - /// Converts incremental price into + /// Converts an incremental value into /// the next incremental indicator value /// and added it to the list. /// /// Date context - /// Next price value - void Add(DateTime timestamp, double price); + /// Next value + void AddValue(DateTime timestamp, double value); /// - /// Converts incremental quotes into + /// Converts an incremental reusable value into /// the next incremental indicator value /// and added it to the list. /// - /// Next quote value - void Add(TQuote quote); + /// Next value + void AddValue(IReusable value); - // TODO: convert ToStreamHub(); + /// + /// Converts batch of reusable values into + /// the next incremental indicator values + /// and added them to the list. + /// + /// + /// Chronologically ordered batch of IReuslable info + /// + void AddValues(IReadOnlyList values); } -public interface IIncrementalQuote - where TQuote : IQuote +public interface IIncrementQuote { - /// - void Add(TQuote quote); + /// + /// Converts an incremental quote into + /// the next incremental indicator value + /// and added it to the list. + /// + /// Next quote value + void AddValue(IQuote quote); + + /// + /// Converts batch of quotes into + /// the next incremental indicator values + /// and added them to the list. + /// + /// + /// Chronologically ordered batch of quotes + /// + void AddValues(IReadOnlyList quotes); } /// /// This produces the same results as the equivalent -/// time-series indicator, but is optimized for array-based operations. +/// time-series indicator, but is optimized for primitive type operations. /// Since it does not retain a date context, -/// all new values provided to the +/// all new values provided to the /// method are expected to be in chronological order. /// -public interface IIncrementalValue +public interface IIncrementPrimitive { - /// - void Add(double price); + /// + void AddValue(double value); + + /// + void AddValues(double[] values); } diff --git a/src/e-k/Ema/Ema.Api.cs b/src/e-k/Ema/Ema.Api.cs index 3d78301b9..0facae954 100644 --- a/src/e-k/Ema/Ema.Api.cs +++ b/src/e-k/Ema/Ema.Api.cs @@ -4,7 +4,7 @@ namespace Skender.Stock.Indicators; public static partial class Api { - // SERIES, from CHAIN + //SERIES, from CHAIN public static IReadOnlyList ToEma( this IEnumerable results, int lookbackPeriods) diff --git a/src/e-k/Ema/Ema.Increments.cs b/src/e-k/Ema/Ema.Increments.cs index 8ef01a65c..8a79acd5a 100644 --- a/src/e-k/Ema/Ema.Increments.cs +++ b/src/e-k/Ema/Ema.Increments.cs @@ -2,12 +2,15 @@ namespace Skender.Stock.Indicators; // EXPONENTIAL MOVING AVERAGE (INCREMENTING LIST) -public class EmaList : List, IEma, IIncrementalPrice - where TQuote : IQuote +/// +/// Exponential Moving Average (EMA) +/// from incremental reusable values. +/// +public class EmaInc : List, IEma, IIncrementQuote, IIncrementReusable { private readonly List _buffer; - public EmaList(int lookbackPeriods) + public EmaInc(int lookbackPeriods) { Ema.Validate(lookbackPeriods); LookbackPeriods = lookbackPeriods; @@ -19,10 +22,10 @@ public EmaList(int lookbackPeriods) public int LookbackPeriods { get; init; } public double K { get; init; } - public void Add(DateTime timestamp, double price) + public void AddValue(DateTime timestamp, double value) { // update buffer - _buffer.Add(price); + _buffer.Add(value); if (_buffer.Count > LookbackPeriods) { @@ -55,22 +58,42 @@ public void Add(DateTime timestamp, double price) // calculate EMA normally base.Add(new EmaResult( timestamp, - Ema.Increment(K, this[^1].Ema, price))); + Ema.Increment(K, this[^1].Ema, value))); } - public void Add(TQuote quote) - => Add(quote.Timestamp, quote.Value); + public void AddValue(IReusable value) + => AddValue(value.Timestamp, value.Value); + + public void AddValues(IReadOnlyList values) + { + for (int i = 0; i < values.Count; i++) + { + AddValue(values[i].Timestamp, values[i].Value); + } + } + + public void AddValue(IQuote quote) + => AddValue(quote.Timestamp, quote.Value); + + public void AddValues(IReadOnlyList quotes) + { + for (int i = 0; i < quotes.Count; i++) + { + AddValue(quotes[i]); + } + } } /// -/// Exponential Moving Average (EMA) without date context (array-based). +/// Exponential Moving Average (EMA) +/// from incremental primatives, without date context. /// -/// -public class EmaArray : List, IEma, IIncrementalValue +/// +public class EmaIncPrimitive : List, IEma, IIncrementPrimitive { private readonly List _buffer; - public EmaArray(int lookbackPeriods) + public EmaIncPrimitive(int lookbackPeriods) { Ema.Validate(lookbackPeriods); LookbackPeriods = lookbackPeriods; @@ -82,10 +105,10 @@ public EmaArray(int lookbackPeriods) public int LookbackPeriods { get; init; } public double K { get; init; } - public void Add(double price) + public void AddValue(double value) { // update buffer - _buffer.Add(price); + _buffer.Add(value); if (_buffer.Count > LookbackPeriods) { @@ -95,7 +118,7 @@ public void Add(double price) // add nulls for incalculable periods if (Count < LookbackPeriods - 1) { - Add(null); + base.Add(null); return; } @@ -113,6 +136,14 @@ public void Add(double price) } // calculate EMA normally - base.Add(Ema.Increment(K, this[^1], price)); + base.Add(Ema.Increment(K, this[^1], value)); + } + + public void AddValues(double[] values) + { + for (int i = 0; i < values.Length; i++) + { + AddValue(values[i]); + } } } diff --git a/tests/indicators/TestBase.cs b/tests/indicators/TestBase.cs index e34f90f0c..9a13fe65e 100644 --- a/tests/indicators/TestBase.cs +++ b/tests/indicators/TestBase.cs @@ -54,10 +54,10 @@ public abstract class StaticSeriesTestBase : TestBase public abstract class IncrementsTestBase : TestBase { [TestMethod] - public abstract void Standard(); + public abstract void FromQuote(); [TestMethod] - public abstract void ValueBased(); + public abstract void FromQuoteBatch(); } /// diff --git a/tests/indicators/e-k/Ema/Ema.Increments.Tests.cs b/tests/indicators/e-k/Ema/Ema.Increments.Tests.cs index 8f698717f..8272d8594 100644 --- a/tests/indicators/e-k/Ema/Ema.Increments.Tests.cs +++ b/tests/indicators/e-k/Ema/Ema.Increments.Tests.cs @@ -3,14 +3,41 @@ namespace Increments; [TestClass] public class Ema : IncrementsTestBase { + private static readonly double[] primatives + = Quotes + .Select(x => (double)x.Close) + .ToArray(); + + private static readonly IReadOnlyList reusables + = Quotes + .Cast() + .ToList(); + + [TestMethod] + public void FromReusable() + { + EmaInc sut = new(14); + + foreach (IReusable item in reusables) + { + sut.AddValue(item.Timestamp, item.Value); + } + + IReadOnlyList series + = Quotes.ToEma(14); + + sut.Should().HaveCount(Quotes.Count); + sut.Should().BeEquivalentTo(series); + } + [TestMethod] - public override void Standard() + public void FromReusableItem() { - EmaList sut = new(14); + EmaInc sut = new(14); - foreach (Quote quote in Quotes) + foreach (IReusable item in reusables) { - sut.Add(quote); + sut.AddValue(item); } IReadOnlyList series @@ -21,15 +48,76 @@ IReadOnlyList series } [TestMethod] - public override void ValueBased() + public void FromReusableBatch() + { + EmaInc sut = new(14); + + sut.AddValues(reusables); + + IReadOnlyList series + = Quotes.ToEma(14); + + sut.Should().HaveCount(Quotes.Count); + sut.Should().BeEquivalentTo(series); + } + + [TestMethod] + public override void FromQuote() { - EmaArray sut = new(14); + EmaInc sut = new(14); - foreach (Quote quote in Quotes) + foreach (Quote q in Quotes) { - sut.Add(quote.Value); + sut.AddValue(q); } + IReadOnlyList series + = Quotes.ToEma(14); + + sut.Should().HaveCount(Quotes.Count); + sut.Should().BeEquivalentTo(series); + } + + [TestMethod] + public override void FromQuoteBatch() + { + EmaInc sut = new(14); + + sut.AddValues(Quotes); + + IReadOnlyList series + = Quotes.ToEma(14); + + sut.Should().HaveCount(Quotes.Count); + sut.Should().BeEquivalentTo(series); + } + + [TestMethod] + public void FromPrimitive() + { + EmaIncPrimitive sut = new(14); + + foreach (double p in primatives) + { + sut.AddValue(p); + } + + List series = Quotes + .ToEma(14) + .Select(x => x.Ema) + .ToList(); + + sut.Should().HaveCount(Quotes.Count); + sut.Should().BeEquivalentTo(series); + } + + [TestMethod] + public void FromPrimitiveBatch() + { + EmaIncPrimitive sut = new(14); + + sut.AddValues(primatives); + List series = Quotes .ToEma(14) .Select(x => x.Ema) diff --git a/tests/indicators/e-k/Ema/Ema.StaticSeries.StaticSeries.Tests.cs b/tests/indicators/e-k/Ema/Ema.StaticSeries.Tests.cs similarity index 100% rename from tests/indicators/e-k/Ema/Ema.StaticSeries.StaticSeries.Tests.cs rename to tests/indicators/e-k/Ema/Ema.StaticSeries.Tests.cs diff --git a/tests/performance/Perf.Increments.cs b/tests/performance/Perf.Increments.cs index 91833f894..c38662c38 100644 --- a/tests/performance/Perf.Increments.cs +++ b/tests/performance/Perf.Increments.cs @@ -5,8 +5,23 @@ namespace Performance; [ShortRunJob] public class Incrementals { - private static readonly IReadOnlyList quotes = Data.GetDefault(); - private static readonly double[] values = Data.GetDefault().Select(x => x.Value).ToArray(); + private static readonly IReadOnlyList quotes + = Data.GetDefault(); + + private static readonly List quotesList + = quotes + .ToSortedList(); + + private static readonly double[] primatives + = quotes + .Select(x => x.Value) + .ToArray(); + + private static readonly IReadOnlyList reusables + = quotes + .Cast() + .ToList(); + private readonly QuoteHub provider = new(); [GlobalSetup] @@ -20,47 +35,84 @@ public void Cleanup() } [Benchmark] - public object EmaListQ() + public object EmaIncRusBatch() { - EmaList sut = new(14); + EmaInc sut = new(14); + sut.AddValues(reusables); + return sut; + } - for (int i = 0; i < quotes.Count; i++) + [Benchmark] + public object EmaIncRus() + { + EmaInc sut = new(14); + + for (int i = 0; i < reusables.Count; i++) { - sut.Add(quotes[i]); + sut.AddValue(reusables[i].Timestamp, reusables[i].Value); } return sut; } [Benchmark] - public object EmaListP() + public object EmaIncQotBatch() { - EmaList sut = new(14); + EmaInc sut = new(14); + sut.AddValues(quotes); + return sut; + } + + [Benchmark] + public object EmaIncQot() + { + EmaInc sut = new(14); for (int i = 0; i < quotes.Count; i++) { - sut.Add(quotes[i].Timestamp, quotes[i].Value); + sut.AddValue(quotes[i]); } return sut; } [Benchmark] - public object EmaArray() + public object EmaIncPrmBatch() { - EmaArray sut = new(14); + EmaIncPrimitive sut = new(14); + sut.AddValues(primatives); + return sut; + } - for (int i = 0; i < values.Length; i++) + [Benchmark] + public object EmaIncPrm() + { + EmaIncPrimitive sut = new(14); + + for (int i = 0; i < primatives.Length; i++) { - sut.Add(values[i]); + sut.AddValue(primatives[i]); } return sut; } + // TIME-SERIES EQUIVALENTS + + [Benchmark(Baseline = true)] + public object EmaSeriesEqiv() => quotesList.CalcEma(14); + + [Benchmark] + public object EmaSeriesOrig() => quotes.ToEma(14); + [Benchmark] - public object EmaSeries() => quotes.ToEma(14); + public object EmaIncremEqiv() + { + EmaInc ema = new(14); + ema.AddValues(quotes.ToSortedList()); + return ema; + } - // [Benchmark] - // public object EmaStream() => provider.ToEma(14).Results; + [Benchmark] + public object EmaStreamEqiv() => provider.ToEma(14).Results; } diff --git a/tests/performance/Perf.StreamHub.Externals.cs b/tests/performance/Perf.StreamHub.Externals.cs index 467356e75..befa94676 100644 --- a/tests/performance/Perf.StreamHub.Externals.cs +++ b/tests/performance/Perf.StreamHub.Externals.cs @@ -5,7 +5,9 @@ namespace Performance; [ShortRunJob] public class StreamExternal { - private static readonly IReadOnlyList quotes = Data.GetDefault(); + private static readonly IReadOnlyList quotes + = Data.GetDefault(); + private readonly QuoteHub provider = new(); /* SETUP/CLEANUP - runs before and after each. diff --git a/tests/performance/Perf.StreamHub.cs b/tests/performance/Perf.StreamHub.cs index cc3dffb85..e0892cc03 100644 --- a/tests/performance/Perf.StreamHub.cs +++ b/tests/performance/Perf.StreamHub.cs @@ -5,7 +5,9 @@ namespace Performance; [ShortRunJob] public class StreamIndicators { - private static readonly IReadOnlyList quotes = Data.GetDefault(); + private static readonly IReadOnlyList quotes + = Data.GetDefault(); + private readonly QuoteHub provider = new(); /* SETUP/CLEANUP - runs before and after each. From 17e284f376c6e320aee395c5d7dc8442301011ed Mon Sep 17 00:00:00 2001 From: Dave Skender <8432125+DaveSkender@users.noreply.github.com> Date: Tue, 30 Jul 2024 17:10:13 -0400 Subject: [PATCH 13/38] restore Add() syntax --- src/_common/Incrementals/IIncremental.cs | 20 ++--- src/e-k/Ema/Ema.Increments.cs | 24 +++--- .../e-k/Ema/Ema.Increments.Tests.cs | 77 ++++++------------- tests/performance/Perf.Increments.cs | 31 +++++--- 4 files changed, 67 insertions(+), 85 deletions(-) diff --git a/src/_common/Incrementals/IIncremental.cs b/src/_common/Incrementals/IIncremental.cs index 361c53e60..611613f74 100644 --- a/src/_common/Incrementals/IIncremental.cs +++ b/src/_common/Incrementals/IIncremental.cs @@ -9,7 +9,7 @@ public interface IIncrementReusable /// /// Date context /// Next value - void AddValue(DateTime timestamp, double value); + void Add(DateTime timestamp, double value); /// /// Converts an incremental reusable value into @@ -17,7 +17,7 @@ public interface IIncrementReusable /// and added it to the list. /// /// Next value - void AddValue(IReusable value); + void Add(IReusable value); /// /// Converts batch of reusable values into @@ -27,7 +27,7 @@ public interface IIncrementReusable /// /// Chronologically ordered batch of IReuslable info /// - void AddValues(IReadOnlyList values); + void Add(IReadOnlyList values); } public interface IIncrementQuote @@ -38,7 +38,7 @@ public interface IIncrementQuote /// and added it to the list. /// /// Next quote value - void AddValue(IQuote quote); + void Add(IQuote quote); /// /// Converts batch of quotes into @@ -48,21 +48,21 @@ public interface IIncrementQuote /// /// Chronologically ordered batch of quotes /// - void AddValues(IReadOnlyList quotes); + void Add(IReadOnlyList quotes); } /// /// This produces the same results as the equivalent /// time-series indicator, but is optimized for primitive type operations. /// Since it does not retain a date context, -/// all new values provided to the +/// all new values provided to the /// method are expected to be in chronological order. /// public interface IIncrementPrimitive { - /// - void AddValue(double value); + /// + void Add(double value); - /// - void AddValues(double[] values); + /// + void Add(double[] values); } diff --git a/src/e-k/Ema/Ema.Increments.cs b/src/e-k/Ema/Ema.Increments.cs index 8a79acd5a..1cafeadf7 100644 --- a/src/e-k/Ema/Ema.Increments.cs +++ b/src/e-k/Ema/Ema.Increments.cs @@ -22,7 +22,7 @@ public EmaInc(int lookbackPeriods) public int LookbackPeriods { get; init; } public double K { get; init; } - public void AddValue(DateTime timestamp, double value) + public void Add(DateTime timestamp, double value) { // update buffer _buffer.Add(value); @@ -61,25 +61,25 @@ public void AddValue(DateTime timestamp, double value) Ema.Increment(K, this[^1].Ema, value))); } - public void AddValue(IReusable value) - => AddValue(value.Timestamp, value.Value); + public void Add(IReusable value) + => Add(value.Timestamp, value.Value); - public void AddValues(IReadOnlyList values) + public void Add(IReadOnlyList values) { for (int i = 0; i < values.Count; i++) { - AddValue(values[i].Timestamp, values[i].Value); + Add(values[i].Timestamp, values[i].Value); } } - public void AddValue(IQuote quote) - => AddValue(quote.Timestamp, quote.Value); + public void Add(IQuote quote) + => Add(quote.Timestamp, quote.Value); - public void AddValues(IReadOnlyList quotes) + public void Add(IReadOnlyList quotes) { for (int i = 0; i < quotes.Count; i++) { - AddValue(quotes[i]); + Add(quotes[i]); } } } @@ -105,7 +105,7 @@ public EmaIncPrimitive(int lookbackPeriods) public int LookbackPeriods { get; init; } public double K { get; init; } - public void AddValue(double value) + public void Add(double value) { // update buffer _buffer.Add(value); @@ -139,11 +139,11 @@ public void AddValue(double value) base.Add(Ema.Increment(K, this[^1], value)); } - public void AddValues(double[] values) + public void Add(double[] values) { for (int i = 0; i < values.Length; i++) { - AddValue(values[i]); + Add(values[i]); } } } diff --git a/tests/indicators/e-k/Ema/Ema.Increments.Tests.cs b/tests/indicators/e-k/Ema/Ema.Increments.Tests.cs index 8272d8594..275aa31f0 100644 --- a/tests/indicators/e-k/Ema/Ema.Increments.Tests.cs +++ b/tests/indicators/e-k/Ema/Ema.Increments.Tests.cs @@ -3,6 +3,8 @@ namespace Increments; [TestClass] public class Ema : IncrementsTestBase { + private const int lookbackPeriods = 14; + private static readonly double[] primatives = Quotes .Select(x => (double)x.Close) @@ -13,19 +15,24 @@ private static readonly IReadOnlyList reusables .Cast() .ToList(); + private static readonly IReadOnlyList series + = Quotes + .ToEma(lookbackPeriods); + + private static readonly List seriesArray = series + .Select(x => x.Ema) + .ToList(); + [TestMethod] - public void FromReusable() + public void FromReusableSplit() { - EmaInc sut = new(14); + EmaInc sut = new(lookbackPeriods); foreach (IReusable item in reusables) { - sut.AddValue(item.Timestamp, item.Value); + sut.Add(item.Timestamp, item.Value); } - IReadOnlyList series - = Quotes.ToEma(14); - sut.Should().HaveCount(Quotes.Count); sut.Should().BeEquivalentTo(series); } @@ -33,15 +40,9 @@ IReadOnlyList series [TestMethod] public void FromReusableItem() { - EmaInc sut = new(14); + EmaInc sut = new(lookbackPeriods); - foreach (IReusable item in reusables) - { - sut.AddValue(item); - } - - IReadOnlyList series - = Quotes.ToEma(14); + foreach (IReusable item in reusables) { sut.Add(item); } sut.Should().HaveCount(Quotes.Count); sut.Should().BeEquivalentTo(series); @@ -50,12 +51,7 @@ IReadOnlyList series [TestMethod] public void FromReusableBatch() { - EmaInc sut = new(14); - - sut.AddValues(reusables); - - IReadOnlyList series - = Quotes.ToEma(14); + EmaInc sut = new(lookbackPeriods) { reusables }; sut.Should().HaveCount(Quotes.Count); sut.Should().BeEquivalentTo(series); @@ -64,15 +60,9 @@ IReadOnlyList series [TestMethod] public override void FromQuote() { - EmaInc sut = new(14); + EmaInc sut = new(lookbackPeriods); - foreach (Quote q in Quotes) - { - sut.AddValue(q); - } - - IReadOnlyList series - = Quotes.ToEma(14); + foreach (Quote q in Quotes) { sut.Add(q); } sut.Should().HaveCount(Quotes.Count); sut.Should().BeEquivalentTo(series); @@ -81,12 +71,10 @@ IReadOnlyList series [TestMethod] public override void FromQuoteBatch() { - EmaInc sut = new(14); - - sut.AddValues(Quotes); + EmaInc sut = new(lookbackPeriods) { Quotes }; IReadOnlyList series - = Quotes.ToEma(14); + = Quotes.ToEma(lookbackPeriods); sut.Should().HaveCount(Quotes.Count); sut.Should().BeEquivalentTo(series); @@ -95,35 +83,20 @@ IReadOnlyList series [TestMethod] public void FromPrimitive() { - EmaIncPrimitive sut = new(14); + EmaIncPrimitive sut = new(lookbackPeriods); - foreach (double p in primatives) - { - sut.AddValue(p); - } - - List series = Quotes - .ToEma(14) - .Select(x => x.Ema) - .ToList(); + foreach (double p in primatives) { sut.Add(p); } sut.Should().HaveCount(Quotes.Count); - sut.Should().BeEquivalentTo(series); + sut.Should().BeEquivalentTo(seriesArray); } [TestMethod] public void FromPrimitiveBatch() { - EmaIncPrimitive sut = new(14); - - sut.AddValues(primatives); - - List series = Quotes - .ToEma(14) - .Select(x => x.Ema) - .ToList(); + EmaIncPrimitive sut = new(lookbackPeriods) { primatives }; sut.Should().HaveCount(Quotes.Count); - sut.Should().BeEquivalentTo(series); + sut.Should().BeEquivalentTo(seriesArray); } } diff --git a/tests/performance/Perf.Increments.cs b/tests/performance/Perf.Increments.cs index c38662c38..51c83e466 100644 --- a/tests/performance/Perf.Increments.cs +++ b/tests/performance/Perf.Increments.cs @@ -36,20 +36,32 @@ public void Cleanup() [Benchmark] public object EmaIncRusBatch() + { + EmaInc sut = new(14) { reusables }; + return sut; + } + + [Benchmark] + public object EmaIncRusItem() { EmaInc sut = new(14); - sut.AddValues(reusables); + + for (int i = 0; i < reusables.Count; i++) + { + sut.Add(reusables[i]); + } + return sut; } [Benchmark] - public object EmaIncRus() + public object EmaIncRusSplit() { EmaInc sut = new(14); for (int i = 0; i < reusables.Count; i++) { - sut.AddValue(reusables[i].Timestamp, reusables[i].Value); + sut.Add(reusables[i].Timestamp, reusables[i].Value); } return sut; @@ -58,8 +70,7 @@ public object EmaIncRus() [Benchmark] public object EmaIncQotBatch() { - EmaInc sut = new(14); - sut.AddValues(quotes); + EmaInc sut = new(14) { quotes }; return sut; } @@ -70,7 +81,7 @@ public object EmaIncQot() for (int i = 0; i < quotes.Count; i++) { - sut.AddValue(quotes[i]); + sut.Add(quotes[i]); } return sut; @@ -79,8 +90,7 @@ public object EmaIncQot() [Benchmark] public object EmaIncPrmBatch() { - EmaIncPrimitive sut = new(14); - sut.AddValues(primatives); + EmaIncPrimitive sut = new(14) { primatives }; return sut; } @@ -91,7 +101,7 @@ public object EmaIncPrm() for (int i = 0; i < primatives.Length; i++) { - sut.AddValue(primatives[i]); + sut.Add(primatives[i]); } return sut; @@ -108,8 +118,7 @@ public object EmaIncPrm() [Benchmark] public object EmaIncremEqiv() { - EmaInc ema = new(14); - ema.AddValues(quotes.ToSortedList()); + EmaInc ema = new(14) { quotes.ToSortedList() }; return ema; } From e0443578dd869721d6d896911957223d37a8242d Mon Sep 17 00:00:00 2001 From: Dave Skender <8432125+DaveSkender@users.noreply.github.com> Date: Tue, 30 Jul 2024 17:25:36 -0400 Subject: [PATCH 14/38] add null reference checks --- src/e-k/Ema/Ema.Increments.cs | 16 ++++++++++++++-- tests/indicators/_testdata/TestData.Getter.cs | 2 +- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/e-k/Ema/Ema.Increments.cs b/src/e-k/Ema/Ema.Increments.cs index 1cafeadf7..95e310d20 100644 --- a/src/e-k/Ema/Ema.Increments.cs +++ b/src/e-k/Ema/Ema.Increments.cs @@ -62,10 +62,15 @@ public void Add(DateTime timestamp, double value) } public void Add(IReusable value) - => Add(value.Timestamp, value.Value); + { + ArgumentNullException.ThrowIfNull(value); + Add(value.Timestamp, value.Value); + } public void Add(IReadOnlyList values) { + ArgumentNullException.ThrowIfNull(values); + for (int i = 0; i < values.Count; i++) { Add(values[i].Timestamp, values[i].Value); @@ -73,10 +78,15 @@ public void Add(IReadOnlyList values) } public void Add(IQuote quote) - => Add(quote.Timestamp, quote.Value); + { + ArgumentNullException.ThrowIfNull(quote); + Add(quote.Timestamp, quote.Value); + } public void Add(IReadOnlyList quotes) { + ArgumentNullException.ThrowIfNull(quotes); + for (int i = 0; i < quotes.Count; i++) { Add(quotes[i]); @@ -141,6 +151,8 @@ public void Add(double value) public void Add(double[] values) { + ArgumentNullException.ThrowIfNull(values); + for (int i = 0; i < values.Length; i++) { Add(values[i]); diff --git a/tests/indicators/_testdata/TestData.Getter.cs b/tests/indicators/_testdata/TestData.Getter.cs index f049d5485..69d763678 100644 --- a/tests/indicators/_testdata/TestData.Getter.cs +++ b/tests/indicators/_testdata/TestData.Getter.cs @@ -64,7 +64,7 @@ internal static IReadOnlyList GetIntraday(int days = 1564) .Take(days) .ToSortedList(); - // LONGEST DATA ~62 years of S&P 500 daily data + // LONGEST DATA ~62 years of S&P 500 daily data (15,821) internal static IReadOnlyList GetLongest() => File.ReadAllLines("_testdata/data/longest.csv") .Skip(1) From 91eab0e97d74ac1e9973bd5075e97b37fc00e2cc Mon Sep 17 00:00:00 2001 From: Dave Skender <8432125+DaveSkender@users.noreply.github.com> Date: Tue, 30 Jul 2024 19:10:51 -0400 Subject: [PATCH 15/38] update Incrementals to use System.Queue --- src/e-k/Ema/Ema.Increments.cs | 47 ++++++++++++++--------------------- src/s-z/Sma/Sma.Utilities.cs | 14 ++++------- 2 files changed, 24 insertions(+), 37 deletions(-) diff --git a/src/e-k/Ema/Ema.Increments.cs b/src/e-k/Ema/Ema.Increments.cs index 95e310d20..e39bc0782 100644 --- a/src/e-k/Ema/Ema.Increments.cs +++ b/src/e-k/Ema/Ema.Increments.cs @@ -8,7 +8,8 @@ namespace Skender.Stock.Indicators; /// public class EmaInc : List, IEma, IIncrementQuote, IIncrementReusable { - private readonly List _buffer; + private readonly Queue _buffer; + private double _bufferSum; public EmaInc(int lookbackPeriods) { @@ -17,6 +18,7 @@ public EmaInc(int lookbackPeriods) K = 2d / (lookbackPeriods + 1); _buffer = new(lookbackPeriods); + _bufferSum = 0; } public int LookbackPeriods { get; init; } @@ -25,12 +27,12 @@ public EmaInc(int lookbackPeriods) public void Add(DateTime timestamp, double value) { // update buffer - _buffer.Add(value); - - if (_buffer.Count > LookbackPeriods) + if (_buffer.Count == LookbackPeriods) { - _buffer.RemoveAt(0); + _bufferSum -= _buffer.Dequeue(); } + _buffer.Enqueue(value); + _bufferSum += value; // add nulls for incalculable periods if (Count < LookbackPeriods - 1) @@ -39,19 +41,12 @@ public void Add(DateTime timestamp, double value) return; } - // re/initialize + // re/initialize as SMA if (this[^1].Ema is null) { - double sum = 0; - for (int i = 0; i < LookbackPeriods; i++) - { - sum += _buffer[i]; - } - base.Add(new EmaResult( timestamp, - sum / LookbackPeriods)); - + _bufferSum / LookbackPeriods)); return; } @@ -96,12 +91,13 @@ public void Add(IReadOnlyList quotes) /// /// Exponential Moving Average (EMA) -/// from incremental primatives, without date context. +/// from incremental primitives, without date context. /// /// public class EmaIncPrimitive : List, IEma, IIncrementPrimitive { - private readonly List _buffer; + private readonly Queue _buffer; + private double _bufferSum; public EmaIncPrimitive(int lookbackPeriods) { @@ -110,6 +106,7 @@ public EmaIncPrimitive(int lookbackPeriods) K = 2d / (lookbackPeriods + 1); _buffer = new(lookbackPeriods); + _bufferSum = 0; } public int LookbackPeriods { get; init; } @@ -118,12 +115,12 @@ public EmaIncPrimitive(int lookbackPeriods) public void Add(double value) { // update buffer - _buffer.Add(value); - - if (_buffer.Count > LookbackPeriods) + if (_buffer.Count == LookbackPeriods) { - _buffer.RemoveAt(0); + _bufferSum -= _buffer.Dequeue(); } + _buffer.Enqueue(value); + _bufferSum += value; // add nulls for incalculable periods if (Count < LookbackPeriods - 1) @@ -132,16 +129,10 @@ public void Add(double value) return; } - // re/initialize + // re/initialize as SMA if (this[^1] is null) { - double sum = 0; - for (int i = 0; i < LookbackPeriods; i++) - { - sum += _buffer[i]; - } - - base.Add(sum / LookbackPeriods); + base.Add(_bufferSum / LookbackPeriods); return; } diff --git a/src/s-z/Sma/Sma.Utilities.cs b/src/s-z/Sma/Sma.Utilities.cs index 53d5bef2c..b67923dd8 100644 --- a/src/s-z/Sma/Sma.Utilities.cs +++ b/src/s-z/Sma/Sma.Utilities.cs @@ -35,7 +35,7 @@ public static partial class Sma /// /// Simple moving average calculation /// - /// List of chainable values + /// List of chainable values /// Window to evaluate, prior to 'endIndex' /// Index position to evaluate. /// IReusable (chainable) type @@ -44,24 +44,20 @@ public static partial class Sma /// when incalculable. /// internal static double Increment( - IReadOnlyList values, + IReadOnlyList source, int lookbackPeriods, int endIndex) where T : IReusable { - int offset = lookbackPeriods - 1; - - if (endIndex < offset || endIndex >= values.Count) + if (endIndex < lookbackPeriods - 1 || endIndex >= source.Count) { return double.NaN; } double sum = 0; - int startIndex = endIndex - offset; - - for (int i = startIndex; i <= endIndex; i++) + for (int i = endIndex - lookbackPeriods + 1; i <= endIndex; i++) { - sum += values[i].Value; + sum += source[i].Value; } return sum / lookbackPeriods; From 5e3333b51923b4af8cc5528a11f5ec53ad766ea5 Mon Sep 17 00:00:00 2001 From: Dave Skender <8432125+DaveSkender@users.noreply.github.com> Date: Wed, 31 Jul 2024 00:35:52 -0400 Subject: [PATCH 16/38] code cleanup: CMO boolean Signed-off-by: Dave Skender <8432125+DaveSkender@users.noreply.github.com> --- src/a-d/Cmo/Cmo.StaticSeries.cs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/a-d/Cmo/Cmo.StaticSeries.cs b/src/a-d/Cmo/Cmo.StaticSeries.cs index 93b8549a0..747042133 100644 --- a/src/a-d/Cmo/Cmo.StaticSeries.cs +++ b/src/a-d/Cmo/Cmo.StaticSeries.cs @@ -38,14 +38,10 @@ private static List CalcCmo( // determine tick direction and size (bool? isUp, double value) tick = (null, Math.Abs(s.Value - prevValue)); - tick.isUp = double.IsNaN(tick.value) + tick.isUp = double.IsNaN(tick.value) || s.Value == prevValue ? null - : s.Value > prevValue - ? true - : s.Value < prevValue - ? false - : null; - + : s.Value > prevValue; + ticks.Add(tick); // calculate CMO From d911909c986d9a23191b2177ad46ed2d3a4ee8f5 Mon Sep 17 00:00:00 2001 From: Dave Skender <8432125+DaveSkender@users.noreply.github.com> Date: Mon, 5 Aug 2024 00:32:56 -0400 Subject: [PATCH 17/38] rename test file Signed-off-by: Dave Skender <8432125+DaveSkender@users.noreply.github.com> --- ...Series.StaticSeries.Tests.cs => AtrStop.StaticSeries.Tests.cs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tests/indicators/a-d/AtrStop/{AtrStop.StaticSeries.StaticSeries.Tests.cs => AtrStop.StaticSeries.Tests.cs} (100%) diff --git a/tests/indicators/a-d/AtrStop/AtrStop.StaticSeries.StaticSeries.Tests.cs b/tests/indicators/a-d/AtrStop/AtrStop.StaticSeries.Tests.cs similarity index 100% rename from tests/indicators/a-d/AtrStop/AtrStop.StaticSeries.StaticSeries.Tests.cs rename to tests/indicators/a-d/AtrStop/AtrStop.StaticSeries.Tests.cs From 25ef25929fd37468de0d9cf647b06e0f122915fb Mon Sep 17 00:00:00 2001 From: Dave Skender <8432125+DaveSkender@users.noreply.github.com> Date: Wed, 9 Oct 2024 19:42:12 -0400 Subject: [PATCH 18/38] refactor: Performance tuning (simplify caching analysis) (#1235) Signed-off-by: Dave Skender <8432125+DaveSkender@users.noreply.github.com> --- .github/workflows/test-performance.yml | 8 +- .gitignore | 13 +- Stock.Indicators.sln | 2 +- src/_common/BinarySettings.cs | 111 +++++ src/_common/Enums.cs | 38 +- src/_common/Observables/IStreamCache.cs | 138 ------ src/_common/Observables/IStreamHub.cs | 156 +++---- src/_common/Observables/IStreamObservable.cs | 108 +++++ src/_common/Observables/IStreamObserver.cs | 117 +++++ src/_common/Observables/IStreamProvider.cs | 46 -- .../Observables/StreamCache.Utilities.cs | 173 ------- src/_common/Observables/StreamCache.cs | 320 ------------- .../Observables/StreamHub.AddRemove.cs | 52 --- .../Observables/StreamHub.Observable.cs | 119 +++++ src/_common/Observables/StreamHub.Observer.cs | 66 +++ src/_common/Observables/StreamHub.Rebuild.cs | 90 ---- .../Observables/StreamHub.Utilities.cs | 202 +++++++++ src/_common/Observables/StreamHub.cs | 425 ++++++++++++++++-- .../Observables/StreamProvider.Motify.cs | 91 ---- src/_common/Observables/StreamProvider.cs | 64 --- src/_common/Quotes/Quote.StreamHub.cs | 55 ++- src/_common/Use (QuotePart)/Use.StreamHub.cs | 12 +- src/a-d/Adl/Adl.StreamHub.cs | 22 +- src/a-d/Adl/Adl.Utilities.cs | 2 +- src/a-d/Adx/Adx.StaticSeries.cs | 2 +- src/a-d/Alligator/Alligator.StreamHub.cs | 26 +- src/a-d/Atr/Atr.StreamHub.cs | 29 +- src/a-d/AtrStop/AtrStop.StreamHub.cs | 97 ++-- src/a-d/Cmo/Cmo.StaticSeries.cs | 2 +- .../Correlation/Correlation.StaticSeries.cs | 6 +- src/e-k/Ema/Ema.Api.cs | 3 + src/e-k/Ema/Ema.Increments.cs | 4 +- src/e-k/Ema/Ema.StaticSeries.cs | 10 +- src/e-k/Ema/Ema.StreamHub.cs | 35 +- src/m-r/Renko/Renko.StreamHub.cs | 146 ++++-- src/m-r/RenkoAtr/RenkoAtr.StaticSeries.cs | 2 +- src/s-z/Sma/Sma.Incremental.cs | 36 ++ src/s-z/Sma/Sma.StaticSeries.cs | 26 +- src/s-z/Sma/Sma.StreamHub.cs | 18 +- src/s-z/Tr/Tr.StreamHub.cs | 23 +- tests/application/Program.cs | 2 +- tests/indicators/TestBase.cs | 15 +- tests/indicators/Tests.Indicators.csproj | 5 +- ...StaticSeries.Tests.cs => Candles.Tests.cs} | 0 .../_common/Generics/BinarySettingsTests.cs | 73 +++ ...cSeries.Tests.cs => RemoveWarmup.Tests.cs} | 0 ...StaticSeries.Tests.cs => Sorting.Tests.cs} | 0 ...ticSeries.Tests.cs => Transforms.Tests.cs} | 2 +- ...aticSeries.Tests.cs => Numerical.Tests.cs} | 28 +- ....Tests.cs => StreamHub.CacheMgmt.Tests.cs} | 10 +- ...Tests.cs => StreamHub.Observable.Tests.cs} | 18 +- ...s.Tests.cs => StreamHub.Observer.Tests.cs} | 6 +- ...ts.cs => StreamHub.Stackoverflow.Tests.cs} | 112 ++--- ...StreamHub.Utilities.StaticSeries.Tests.cs} | 55 +-- .../_common/Quotes/Quote.Aggregates.Tests.cs | 10 +- .../_common/Quotes/Quote.Exceptions.Tests.cs | 12 +- .../_common/Quotes/Quote.Validation.Tests.cs | 9 +- ...s.Tests.cs => Reusable.Utilities.Tests.cs} | 2 +- ...sts.cs => QuotePart.StaticSeries.Tests.cs} | 2 +- .../QuotePart.StreamHub.Tests.cs | 2 +- ....Tests.cs => QuotePart.Utilities.Tests.cs} | 0 .../indicators/a-d/Adl/Adl.StreamHub.Tests.cs | 6 +- .../Alligator/Alligator.StreamHub.Tests.cs | 4 +- .../indicators/a-d/Atr/Atr.StreamHub.Tests.cs | 2 +- .../a-d/AtrStop/AtrStop.StreamHub.Tests.cs | 4 +- .../e-k/Ema/Ema.Increments.Tests.cs | 10 +- .../indicators/e-k/Ema/Ema.StreamHub.Tests.cs | 4 +- .../m-r/Renko/Renko.StreamHub.Tests.cs | 34 +- .../indicators/s-z/Sma/Sma.StreamHub.Tests.cs | 2 +- tests/indicators/s-z/Tr/Tr.StreamHub.Tests.cs | 2 +- tests/other/PublicApi.Interface.Tests.cs | 4 +- tests/other/Tests.Other.csproj | 4 +- tests/performance/Perf.Increments.cs | 51 ++- tests/performance/Perf.StreamHub.Externals.cs | 2 +- tests/performance/Perf.StreamHub.cs | 18 +- tests/performance/Tests.Performance.csproj | 4 + 76 files changed, 1826 insertions(+), 1583 deletions(-) create mode 100644 src/_common/BinarySettings.cs delete mode 100644 src/_common/Observables/IStreamCache.cs create mode 100644 src/_common/Observables/IStreamObservable.cs create mode 100644 src/_common/Observables/IStreamObserver.cs delete mode 100644 src/_common/Observables/IStreamProvider.cs delete mode 100644 src/_common/Observables/StreamCache.Utilities.cs delete mode 100644 src/_common/Observables/StreamCache.cs delete mode 100644 src/_common/Observables/StreamHub.AddRemove.cs create mode 100644 src/_common/Observables/StreamHub.Observable.cs create mode 100644 src/_common/Observables/StreamHub.Observer.cs delete mode 100644 src/_common/Observables/StreamHub.Rebuild.cs create mode 100644 src/_common/Observables/StreamHub.Utilities.cs delete mode 100644 src/_common/Observables/StreamProvider.Motify.cs delete mode 100644 src/_common/Observables/StreamProvider.cs create mode 100644 src/s-z/Sma/Sma.Incremental.cs rename tests/indicators/_common/Candles/{Candles.StaticSeries.Tests.cs => Candles.Tests.cs} (100%) create mode 100644 tests/indicators/_common/Generics/BinarySettingsTests.cs rename tests/indicators/_common/Generics/{RemoveWarmup.StaticSeries.Tests.cs => RemoveWarmup.Tests.cs} (100%) rename tests/indicators/_common/Generics/{Sorting.StaticSeries.Tests.cs => Sorting.Tests.cs} (100%) rename tests/indicators/_common/Generics/{Transforms.StaticSeries.Tests.cs => Transforms.Tests.cs} (89%) rename tests/indicators/_common/Math/{Numerical.StaticSeries.Tests.cs => Numerical.Tests.cs} (75%) rename tests/indicators/_common/Observables/{Cache.Manager.StaticSeries.Tests.cs => StreamHub.CacheMgmt.Tests.cs} (93%) rename tests/indicators/_common/Observables/{StreamProvider.StaticSeries.Tests.cs => StreamHub.Observable.Tests.cs} (84%) rename tests/indicators/_common/Observables/{StreamObserver.StaticSeries.Tests.cs => StreamHub.Observer.Tests.cs} (91%) rename tests/indicators/_common/Observables/{Stackoverflow.StaticSeries.Tests.cs => StreamHub.Stackoverflow.Tests.cs} (79%) rename tests/indicators/_common/Observables/{Cache.Utilities.StaticSeries.Tests.cs => StreamHub.Utilities.StaticSeries.Tests.cs} (74%) rename tests/indicators/_common/Reusable/{Reusable.Utilities.StaticSeries.Tests.cs => Reusable.Utilities.Tests.cs} (98%) rename tests/indicators/_common/Use (QuotePart)/{Use.StaticSeries.Tests.cs => QuotePart.StaticSeries.Tests.cs} (98%) rename tests/indicators/_common/Use (QuotePart)/{QuotePart.Utilities.StaticSeries.Tests.cs => QuotePart.Utilities.Tests.cs} (100%) diff --git a/.github/workflows/test-performance.yml b/.github/workflows/test-performance.yml index 857f71949..6682f6b06 100644 --- a/.github/workflows/test-performance.yml +++ b/.github/workflows/test-performance.yml @@ -47,7 +47,7 @@ jobs: run: dotnet run -c Release - name: Save test results - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: test-summaries path: tests/performance/BenchmarkDotNet.Artifacts/results @@ -62,3 +62,9 @@ jobs: echo "## Stream indicators (with Quote caching)" >> $GITHUB_STEP_SUMMARY cat Performance.StreamIndicators-report-github.md >> $GITHUB_STEP_SUMMARY + + echo "## Incremental indicators (with buffer)" >> $GITHUB_STEP_SUMMARY + cat Performance.Incrementals-report-github.md >> $GITHUB_STEP_SUMMARY + + echo "## Utilities" >> $GITHUB_STEP_SUMMARY + cat Performance.Utility-report-github.md >> $GITHUB_STEP_SUMMARY diff --git a/.gitignore b/.gitignore index 7a97cd5dc..a517802a1 100644 --- a/.gitignore +++ b/.gitignore @@ -111,12 +111,13 @@ $tf/ # Guidance Automation Toolkit *.gpState -# ReSharper is a .NET coding add-in +# ReSharper IDE extension _ReSharper*/ *.[Rr]e[Ss]harper *.DotSettings.user +*.DotSettings -# JustCode is a .NET coding add-in +# JustCode IDE extension .JustCode # TeamCity is a build add-in @@ -218,7 +219,7 @@ ClientBin/ *.publishsettings orleans.codegen.cs -# Including strong name files can present a security risk +# Including strong name files can present a security risk # (https://github.com/github/gitignore/pull/2483#issue-259490424) #*.snk @@ -314,7 +315,7 @@ __pycache__/ # OpenCover UI analysis results OpenCover/ -# Azure Stream Analytics local run output +# Azure Stream Analytics local run output ASALocalRun/ # MSBuild Binary and Structured Log @@ -323,11 +324,11 @@ ASALocalRun/ # NVidia Nsight GPU debugger configuration file *.nvuser -# MFractors (Xamarin productivity tool) working folder +# MFractors (Xamarin productivity tool) working folder .mfractor/ # Jekyll site _site/ # zip artifacts -.DS_Store \ No newline at end of file +.DS_Store diff --git a/Stock.Indicators.sln b/Stock.Indicators.sln index 6a57b3070..8d241723d 100644 --- a/Stock.Indicators.sln +++ b/Stock.Indicators.sln @@ -8,7 +8,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Configuration", "Configurat .editorconfig = .editorconfig .gitattributes = .gitattributes .gitignore = .gitignore - gitversion.yml = src/gitversion.yml + src\gitversion.yml = src\gitversion.yml EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Indicators", "src\Indicators.csproj", "{8D0F1781-EDA3-4C51-B05D-D33FF1156E49}" diff --git a/src/_common/BinarySettings.cs b/src/_common/BinarySettings.cs new file mode 100644 index 000000000..5ce4f2eac --- /dev/null +++ b/src/_common/BinarySettings.cs @@ -0,0 +1,111 @@ +namespace Skender.Stock.Indicators; + +/// +/// Binary on/off switches for high performance access +/// to behaviors and characteristics. +/// +/// +/// Initializes a new instance of the struct. +/// The Mask parameter is optional and defaults to 0b11111111 where all bits +/// pass through to "combinor" sets. +/// +/// Example of accessing a specific bit: +/// +/// BinarySettings settings = new(0b00000001); // bit 0 is set to 1 +/// bool isBit0Set = settings[0]; // true +/// bool isBit1Set = settings[1]; // false +/// +/// +/// Example of re/setting a specific bit: +/// +/// BinarySettings settings = new(0); +/// settings = settings with { [0] = true }; // set bit 0 to true +/// settings = settings with { [1] = false }; // set bit 1 to false +/// +/// +/// +/// Binary settings. +/// Default is 0b00000000 (binary literal of 0). +/// +/// +/// Mask for settings inheritence. +/// Default is 0b11111111 (binary literal of 255). +/// +public readonly struct BinarySettings( + byte settings, + byte mask = 0b11111111) + : IEquatable +{ + public byte Settings { get; } = settings; + public byte Mask { get; } = mask; + + // use default settings (none) and mask + // important: this explicit parameterless ctor required for struct + public BinarySettings() : this(settings: 0b00000000) { } + + /// + /// Gets the value of the bit at the specified index. + /// + /// The index of the bit to get. + /// True if the bit is set; otherwise, false. + public bool this[short index] + => (Settings & (1 << index)) != 0; + + /// + /// Combines the current settings with another instance + /// using a bitwise OR operation, excluding the bits masked by the parent settings. + /// + /// The parent instance to combine with. + /// + /// A new instance with combined settings. + /// Notably, it does not modify the current read-only instance. + /// + /// + /// + /// The mask is used to determine which bits from the parent settings should be excluded + /// during the combination. By default, the mask is set to 0b11111111, meaning all bits + /// are included. If a different mask is provided, the corresponding bits in the parent + /// settings will be excluded based on the mask. + /// + /// In other words, the mask you provide on instantiation will determine which bits are + /// genetic material passed on to the "combinor" child settings. The child settings will inherit the + /// bits from the parent settings that the parent decides to pass along. + /// + /// + /// Usage example (default mask): + /// + /// BinarySettings srcSettings = new(0b01101001); + /// BinarySettings defSettings = new(0b00000010); + /// BinarySettings newSettings = defSettings.Combine(srcSettings); // result: 0b01101011 + /// + /// Using a custom mask: + /// + /// BinarySettings customMaskSettings = new(0b01101001, 0b11111110); // do not pass 0th bit value + /// BinarySettings newSettingsWithCustomMask = defSettings.Combine(customMaskSettings); // result: 0b01101010 + /// + /// + public BinarySettings Combine(BinarySettings parentSettings) + { + // add parent bits according to their mask template + byte maskedParentSettings = (byte)(parentSettings.Settings & parentSettings.Mask); + + // combine the settings + return new BinarySettings((byte)(Settings | maskedParentSettings), parentSettings.Mask); + } + + public override bool Equals(object? obj) + => obj is BinarySettings other && Equals(other); + + public bool Equals(BinarySettings other) + => Settings == other.Settings && Mask == other.Mask; + + public override int GetHashCode() + => HashCode.Combine(Settings, Mask); + + public static bool operator ==(BinarySettings left, BinarySettings right) + => left.Equals(right); + + public static bool operator !=(BinarySettings left, BinarySettings right) + => !(left == right); +} + diff --git a/src/_common/Enums.cs b/src/_common/Enums.cs index a1e497564..f254baaea 100644 --- a/src/_common/Enums.cs +++ b/src/_common/Enums.cs @@ -1,50 +1,32 @@ namespace Skender.Stock.Indicators; // SHARED ENUMERATIONS -// note: indicator unique ENUMS specified in indicator models +// note: indicator unique ENUMS filed with their models /// /// Cache action instruction or outcome /// -public enum Act +internal enum Act { /// - /// Adds to end of cache + /// Adds item to end of cache or rebuild if older. /// - AddNew, + Add, /// - /// Adds new item to middle of cache + /// Does nothing to cache (aborted). /// - AddOld, + Ignore, /// - /// Updates existing item in cache + /// Insert item without rebuilding cache. /// - Update, + Insert, /// - /// Deletes existing item in cache + /// Reset and rebuild from marker position. /// - Delete, - - /// - /// Does nothing to cache (aborted) - /// - DoNothing, - - /// - /// Delete from first position of cache - /// without rebuilding or recalculating; - /// as part of the auto-pruning process - /// to maintain maximum cache size. - /// - AutoPrune, // TODO: implement. May also have some integrity checks. - - /// - /// Instruction has not yet been determined - /// - Unknown + Rebuild } /// diff --git a/src/_common/Observables/IStreamCache.cs b/src/_common/Observables/IStreamCache.cs deleted file mode 100644 index 95af2aec6..000000000 --- a/src/_common/Observables/IStreamCache.cs +++ /dev/null @@ -1,138 +0,0 @@ -namespace Skender.Stock.Indicators; - -// STREAM CACHE INTERFACES - -/// -/// Stored value cache for streaming hubs -/// -public interface IStreamCache - where TSeries : ISeries -{ - /// - /// Read-only list of the stored values cache. - /// - IReadOnlyList Results { get; } - - /// - /// The cache and provider failed and is no longer operational. - /// - /// - /// This occurs when there is an overflow condition - /// from a circular chain or - /// when there were too many sequential duplicates. - /// - /// Use - /// to remove this flag. - /// - /// - bool IsFaulted { get; } - - /// - /// Resets the flag and - /// overflow counter. Use this after recovering - /// from an error. - /// - /// - /// You may also need to - /// , - /// , or - /// before resuming. - /// - void ResetFault(); - - /// - /// Try to find index position of the provided timestamp - /// - /// Timestamp to seek - /// - /// Index of timestamp or -1 when not found - /// - /// True if found - bool TryFindIndex(DateTime timestamp, out int index); - - /// - /// Get the cache index based on item equality. - /// - /// - /// Timeseries object to find in cache - /// - /// - /// Disable exception when item is not found - /// - /// Index position - /// - /// When items is not found (should never happen). - /// - int GetIndex(TSeries cachedItem, bool noException); - - /// - /// Get the cache index based on a timestamp. - /// - /// - /// Only use this when you are looking for a point in time - /// without a matching item for context. In most cases - /// is more appropriate. - /// - /// - /// Timestamp of cached item - /// - /// - /// Disable exception when item is not found - /// - /// Index position - /// - /// When timestamp is not found (should never happen). - /// - int GetIndex(DateTime timestamp, bool noException); - - /// - /// Get the first cache index on or after a timestamp. - /// - /// - /// Only use this when you are looking for a point in time - /// without a matching item for context. In most cases - /// is more appropriate. - /// - /// - /// Timestamp of cached item - /// - /// First index position or -1 if not found - int GetInsertIndex(DateTime timestamp); - - /// - /// Deletes all cached time-series records, - /// without restore. When applicable, - /// it will cascade delete commands to subscribers. - /// - /// - /// For observers, if your intention is to rebuild from a provider, - /// use alternate . - /// - void ClearCache(); - - /// - /// Deletes newer cached records from point in time, - /// without restore. When applicable, it will cascade delete - /// commands to subscribers. - /// - /// - /// For observers, if your intention is to rebuild from a provider, - /// use alternate . - /// - /// - /// All periods (inclusive) after this DateTime will be removed. - /// - void ClearCache(DateTime fromTimestamp); - - /// - /// Deletes newer cached records from an index position (inclusive), - /// without restore. When applicable, it will cascade delete - /// commands to subscribers. - /// - /// - /// For observers, if your intention is to rebuild from a provider, - /// use alternate . - /// - /// From index, inclusive - void ClearCache(int fromIndex); -} diff --git a/src/_common/Observables/IStreamHub.cs b/src/_common/Observables/IStreamHub.cs index 245c99346..f73b1250d 100644 --- a/src/_common/Observables/IStreamHub.cs +++ b/src/_common/Observables/IStreamHub.cs @@ -1,123 +1,123 @@ namespace Skender.Stock.Indicators; -// STREAM HUB INTERFACES - -#region hub variants - -public interface IQuoteHub - : IStreamHub, IQuoteProvider, IChainProvider - where TIn : IQuote - where TOut : IQuote; - -/// -public interface IReusableHub - : IStreamHub, IChainProvider - where TIn : ISeries - where TOut : IReusable; - -/// -public interface IResultHub - : IStreamHub - where TIn : ISeries - where TOut : ISeries; -#endregion +// STREAM HUB INTERFACE /// -/// Streaming hub (observer and observable provider). +/// Streaming hub: management of observer +/// and observable indicator data /// -public interface IStreamHub - : IObserver<(Act, TIn, int?)>, IStreamProvider +/// +/// Type of inbound provider data. +/// +/// +/// Type of outbound indicator data. +/// +public interface IStreamHub where TIn : ISeries - where TOut : ISeries { /// - /// Current state of subscription to provider. + /// Read-only list of the stored cache values. /// - bool IsSubscribed { get; } + IReadOnlyList Results { get; } /// - /// Unsubscribe from the data provider. - /// - void Unsubscribe(); - - /// - /// Full reset of the provider subscription. + /// The cache and provider failed and is no longer operational. /// /// - /// This unsubscribes from the provider, - /// clears cache, cascading deletes to subscribers, - /// then re-subscribes to the provider (with rebuild). + /// This occurs when there is an overflow condition + /// from a circular chain or + /// when there were too many sequential duplicates. /// - /// This is also used on startup to invoke provider - /// . + /// Use + /// to remove this flag. /// /// - void Reinitialize(); + bool IsFaulted { get; } /// - /// Reset the entire results cache - /// and rebuild it from provider sources, - /// with cascading updates to subscribers. + /// Resets the flag and + /// overflow counter. Use this after recovering + /// from an error. /// /// - /// This is different from . - /// It does not reset the provider subscription. + /// You may also need to + /// , or + /// . /// - void RebuildCache(); + void ResetFault(); /// - /// Reset the entire results cache from a point in time - /// and rebuilds it from provider sources, - /// with cascading updates to subscribers. + /// Add a single new item. + /// We'll determine if it's new or an update. /// - /// - /// All periods (inclusive) after this date/time will - /// be removed and recalculated. + /// + /// New item to add /// - void RebuildCache(DateTime fromTimestamp); + void Add(TIn newIn); /// - /// Resets the results cache from an index position - /// and rebuilds it from provider sources, - /// with cascading updates to subscribers. + /// Add a batch of new items. + /// We'll determine if they're new or updated. /// - /// - /// All periods (inclusive) after this index position will - /// be removed and recalculated. + /// + /// Batch of new items to add /// - void RebuildCache(int fromIndex); + void Add(IEnumerable batchIn); /// - /// Add a single new observed item. - /// We'll determine if it's new or an update. + /// Insert a new item without rebuilding the cache. /// - /// - /// Observed item to add or update - /// - void Add(TIn newIn); - - /// - /// Add a batch of observed items. - /// We'll determine if they're new or updated. - /// - /// - /// Batch of observed items to add or update + /// + /// This is used in situations when inserting an older item + /// and where newer cache entries do not need to be rebuilt. + /// Typically, this is only used for provider-only hubs. + /// + /// + /// Item to insert /// - void Add(IEnumerable newIn); + void Insert(TIn newIn); /// /// Delete an item from the cache. /// /// Cached item to delete - /// Action taken (outcome) - Act Remove(TOut cachedItem); + /// + void Remove(TOut cachedItem); /// - /// Delete an item from the cache. + /// Delete an item from the cache, from a specific position. /// /// Position in cache to delete - /// Action taken (outcome) - Act RemoveAt(int cacheIndex); + /// + void RemoveAt(int cacheIndex); + + /// + /// Deletes newer cached records from point in time (inclusive). + /// + /// + /// For observers, if your intention is to rebuild from a provider, + /// use alternate . + /// + /// + /// All periods (inclusive) after this DateTime will be removed. + /// + /// + /// Notify subscribers of the delete point. + /// + void RemoveRange(DateTime fromTimestamp, bool notify); + + /// + /// Deletes newer cached records from an index position (inclusive). + /// + /// + /// For observers, if your intention is to rebuild from a provider, + /// use alternate . + /// + /// From index, inclusive + /// + /// Notify subscribers of the delete position. + /// + void RemoveRange(int fromIndex, bool notify); /// /// Returns a short text label for the hub diff --git a/src/_common/Observables/IStreamObservable.cs b/src/_common/Observables/IStreamObservable.cs new file mode 100644 index 000000000..394678c6f --- /dev/null +++ b/src/_common/Observables/IStreamObservable.cs @@ -0,0 +1,108 @@ +namespace Skender.Stock.Indicators; + +// STREAM (OBSERVABLE) INTERFACE + +#region chain and quote variants + +/// +public interface IQuoteProvider : IChainProvider + where T : IQuote +{ + IReadOnlyList Quotes { get; } +} + +/// +public interface IChainProvider : IStreamObservable + where T : IReusable; +#endregion + +/// +/// Provider of data + management of and notification to observing subscribers. +/// +/// +/// The object that provides notification information. +/// +public interface IStreamObservable +{ + /// + /// Hub observable properties and behaviors. + /// + /// + /// This struct holds cumulative overrides for + /// a streaming hub. Observer hubs inherit these values cumulatively when + /// instantiated as a , except where masked. + /// + /// Default settings are a binary set of 0b00000000, where 1 values represent + /// exceptional (atypical) behaviors. + /// + /// + /// + /// 0 + /// + /// Disable observer: a non-observing observable (e.g. base provider). + /// + /// + /// + /// 1 + /// + /// Allow duplicates: + /// bypass rebuild analysis and duplicate prevention when caching new results. + /// + /// + /// + /// 2-7 + /// [unused positions] + /// + /// + /// + BinarySettings Properties { get; } + + /// + /// Current number of subscribers + /// + int ObserverCount { get; } + + /// + /// Provider currently has subscribers + /// + bool HasObservers { get; } + + /// + /// Checks if a specific observer is subscribed + /// + /// + /// Subscriber IStreamObserver reference + /// + /// True if subscribed/registered + bool HasSubscriber(IStreamObserver observer); + + /// + /// Notifies the provider that an observer is to receive notifications. + /// + /// + /// The object that is to receive notifications. + /// + /// + /// A reference to an interface that allows observers + /// to stop receiving notifications before the provider + /// has finished sending them. + /// + IDisposable Subscribe(IStreamObserver observer); + + /// + /// Unsubscribe from the data provider. + /// + /// + bool Unsubscribe(IStreamObserver observer); + + /// + /// Unsubscribe all observers (subscribers) + /// + void EndTransmission(); + + /// + /// Get a readonly reference of the observable cache. + /// + /// Read-only list of cached items. + IReadOnlyList GetCacheRef(); +} diff --git a/src/_common/Observables/IStreamObserver.cs b/src/_common/Observables/IStreamObserver.cs new file mode 100644 index 000000000..32398e668 --- /dev/null +++ b/src/_common/Observables/IStreamObserver.cs @@ -0,0 +1,117 @@ +namespace Skender.Stock.Indicators; + +// STREAM (OBSERVER) INTERFACE + +/// +/// Management of observing + processing of streamed inbound data. +/// +/// +/// The object that provides notification information. +/// +public interface IStreamObserver +{ + /// + /// Current state of subscription to provider. + /// + bool IsSubscribed { get; } + + /// + /// Unsubscribe from the data provider. + /// + void Unsubscribe(); + + /// + /// Provides the observer with new data. + /// + /// + /// The current notification information. + /// + /// + /// Notify subscribers of the new item. + /// + /// + /// Provider index hint, if known. + /// + void OnAdd(T item, bool notify, int? indexHint); + + /// + /// Provides the observer with starting point in timeline + /// to rebuild and cascade to all its own subscribers. + /// + /// + /// Starting point in timeline to rebuild. + /// + void OnChange(DateTime fromTimestamp); + + /// + /// Provides the observer with errors from the provider + /// that have produced a faulted state. + /// + /// + /// An exception with additional information about the error. + /// + void OnError(Exception exception); + + /// + /// Provides the observer with final notice that the data + /// provider has finished sending push-based notifications. + /// + /// + /// Completion indicates that publisher will never send + /// additional data. This is only used for finite data + /// streams; and is different from faulted OnError(). + /// + void OnCompleted(); + + /// + /// Full reset of the provider subscription. + /// + /// + /// This unsubscribes from the provider, + /// rebuilds the cache, resets faulted states, + /// and then re-subscribes to the provider. + /// + /// This is done automatically on hub + /// instantiation, so it's only needed if you + /// want to manually reset the hub. + /// + /// + /// If you only need to rebuild the cache, + /// use instead. + /// + /// + void Reinitialize(); + + /// + /// Resets the entire results cache + /// and rebuilds it from provider sources, + /// with cascading updates to subscribers. + /// + /// + /// This is different from . + /// It does not reset the provider subscription. + /// + void Rebuild(); + + /// + /// Resets the results cache from a point in time + /// and rebuilds it from provider sources, + /// with cascading updates to subscribers. + /// + /// + /// All periods (inclusive) after this date/time + /// will be removed and recalculated. + /// + void Rebuild(DateTime fromTimestamp); + + /// + /// Resets the results cache from an index position + /// and rebuilds it from provider sources, + /// with cascading updates to subscribers. + /// + /// + /// All periods (inclusive) after this index position + /// will be removed and recalculated. + /// + void Rebuild(int fromIndex); +} diff --git a/src/_common/Observables/IStreamProvider.cs b/src/_common/Observables/IStreamProvider.cs deleted file mode 100644 index d6b7a71ac..000000000 --- a/src/_common/Observables/IStreamProvider.cs +++ /dev/null @@ -1,46 +0,0 @@ -namespace Skender.Stock.Indicators; - -// STREAM PROVIDER INTERFACES - -/// -public interface IQuoteProvider - : IChainProvider - where TQuote : IQuote; - -/// -public interface IChainProvider - : IStreamProvider - where TReusable : IReusable; - -/// -/// Streaming provider (observable cache) -/// -public interface IStreamProvider - : IObservable<(Act, TSeries, int?)>, IStreamCache - where TSeries : ISeries -{ - /// - /// Currently has subscribers - /// - bool HasSubscribers { get; } - - /// - /// Current number of subscribers - /// - int SubscriberCount { get; } - - /// - /// Checks if a specific observer is subscribed - /// - /// - /// Subscriber IObserver reference - /// - /// True if subscribed/registered - bool HasSubscriber( - IObserver<(Act, TSeries, int?)> observer); - - /// - /// Unsubscribe all observers (subscribers) - /// - void EndTransmission(); -} diff --git a/src/_common/Observables/StreamCache.Utilities.cs b/src/_common/Observables/StreamCache.Utilities.cs deleted file mode 100644 index 1f0727567..000000000 --- a/src/_common/Observables/StreamCache.Utilities.cs +++ /dev/null @@ -1,173 +0,0 @@ -namespace Skender.Stock.Indicators; - -// STREAM CACHE (UTILITIES) - -/// -public abstract partial class StreamCache - : IStreamCache - where TSeries : ISeries -{ - // clear cache without restore - /// - public void ClearCache() => ClearCache(0); - public abstract void ClearCache(DateTime fromTimestamp); - public abstract void ClearCache(int fromIndex); - - // reset fault flag and condition - /// - public void ResetFault() - { - OverflowCount = 0; - IsFaulted = false; - } - - // try/get the cache index based on a timestamp - /// - public bool TryFindIndex(DateTime timestamp, out int index) - { - index = GetIndex(timestamp, true); - return index != -1; - } - - // get the cache index based on item equality - /// - public int GetIndex(TSeries cachedItem, bool noException) - { - int low = 0; - int high = Cache.Count - 1; - int firstMatchIndex = -1; - - while (low <= high) - { - int mid = low + ((high - low) / 2); - int comparison = Cache[mid].Timestamp.CompareTo(cachedItem.Timestamp); - - if (comparison == 0) - { - // Found a match by Timestamp, - // store the index of the first match - if (firstMatchIndex == -1) - { - firstMatchIndex = mid; - } - - // Verify with Equals for an exact match - if (Cache[mid].Equals(cachedItem)) - { - return mid; // exact match found - } - - // Continue searching to the left for - // the first occurrence - high = mid - 1; - } - else if (comparison < 0) - { - low = mid + 1; - } - else - { - high = mid - 1; - } - } - - // If a timestamp match was found but no exact - // match, try to find an exact match in the range - // of duplicate timestamps (e.g. Renko bricks), - // biased towards later duplicats. - if (firstMatchIndex != -1) - { - // Find the last occurrence of the matching timestamp - int lastMatchIndex = firstMatchIndex; - for (int i = firstMatchIndex + 1; i < Cache.Count && Cache[i].Timestamp == cachedItem.Timestamp; i++) - { - lastMatchIndex = i; - } - - // Search for an exact match starting from the last occurrence - for (int i = lastMatchIndex; i >= firstMatchIndex; i--) - { - if (Cache[i].Equals(cachedItem)) - { - return i; // exact match found among duplicates - } - } - } - - if (noException) - { - return -1; - } - else - { - // not found - throw new ArgumentException( - "Matching source history not found.", nameof(cachedItem)); - } - } - - // get the cache index based on a timestamp - /// - public int GetIndex(DateTime timestamp, bool noException) - { - int low = 0; - int high = Cache.Count - 1; - - while (low <= high) - { - int mid = low + ((high - low) / 2); - DateTime midTimestamp = Cache[mid].Timestamp; - - if (midTimestamp == timestamp) - { - return mid; - } - else if (midTimestamp < timestamp) - { - low = mid + 1; - } - else - { - high = mid - 1; - } - } - - if (noException) - { - return -1; - } - else - { - // not found - throw new ArgumentException( - "Matching source history not found.", nameof(timestamp)); - } - } - - // get first cache index at or greater than timestamp - /// - public int GetInsertIndex(DateTime timestamp) - { - int low = 0; - int high = Cache.Count; - while (low < high) - { - int mid = low + ((high - low) / 2); - if (Cache[mid].Timestamp < timestamp) - { - low = mid + 1; - } - else - { - high = mid; - } - } - - // At this point, low is the index of the first - // element that is greater than or equal to timestamp - // or Cache.Count if all elements are less than timestamp. - // If low is equal to Cache.Count, it means there are - // no elements greater than or equal to timestamp. - return low < Cache.Count ? low : -1; - } -} diff --git a/src/_common/Observables/StreamCache.cs b/src/_common/Observables/StreamCache.cs deleted file mode 100644 index dc7e773ae..000000000 --- a/src/_common/Observables/StreamCache.cs +++ /dev/null @@ -1,320 +0,0 @@ -namespace Skender.Stock.Indicators; - -// STREAM CACHE (BASE) - -/// -public abstract partial class StreamCache - : IStreamCache - where TSeries : ISeries -{ - #region PROPERTIES - - /// - public IReadOnlyList Results => Cache; - - /// - public bool IsFaulted { get; private set; } - - /// - /// Cache of stored values (base). - /// - internal List Cache { get; private set; } = []; - - /// - /// Most recent arrival to cache. - /// - internal TSeries? LastArrival { get; private set; } - - /// - /// Current count of repeated arrivals. - /// An overflow condition is triggered after 100. - /// - internal byte OverflowCount { get; private set; } - #endregion - - // CACHE MODIFICATION - - /// - /// Analyze new arrival to determine caching instruction; - /// then follow-on with caching action. - /// - /// Cacheable time-series object - /// Action taken (outcome) - /// - /// Item to modify is not found. - /// - /// - /// Too many sequential duplicates were detected. - /// - internal Act Modify(TSeries item) - { - // check overflow - if (CheckOverflow(item) is Act.DoNothing) - { - // duplicate found - return Act.DoNothing; - } - - // DETERMINE ACTion INSTRUCTION - - Act act; - int length = Cache.Count; - int? index = null; - - // first - if (length == 0) - { - act = Act.AddNew; - return Modify(act, item, index); - } - - TSeries last = Cache[length - 1]; - - // newer - if (item.Timestamp > last.Timestamp) - { - act = Act.AddNew; - } - - // repeat or late arrival - else - { - // seek duplicate - index = GetIndex(item.Timestamp, true); - - // replace duplicate - if (index >= 0) - { - act = Act.Update; - } - else - { - act = Act.AddOld; - index = null; - } - } - - // perform actual modification, return final action - return Modify(act, item, index); - } - - /// - /// Update cache, per "act" instruction, without analysis. - /// - /// - /// Since this does not analyze the action, it is not - /// recommended for use outside of the cache management system. - /// For example, it will not prevent duplicates or overflow. - /// - /// Caching instruction - /// Cacheable time-series object - /// Index, if already known (optional) - /// Action taken (outcome) - /// - /// Item to modify is not found. - /// - /// - /// Too many sequential duplicates were detected. - /// - /// - /// Action type is unknown. - /// - protected Act Modify(Act act, TSeries item, int? index) - { - // execute action - switch (act) - { - case Act.AddNew: - - Cache.Add(item); - - break; - - case Act.AddOld: - - // find - int ao = index ?? GetInsertIndex(item.Timestamp); - - // insert - if (ao != -1) - { - Cache.Insert(ao, item); - } - - // failure to find newer index - else - { - Cache.Add(item); - } - - break; - - case Act.Update: - - // find - int uo = index ?? GetIndex(item.Timestamp, false); - - // duplicate - if (item.Equals(Cache[uo])) - { - return Act.DoNothing; - } - - // replace - Cache[uo] = item; - - break; - - case Act.Delete: - - // find - int d = index ?? GetIndex(item.Timestamp, false); - - // delete - Cache.RemoveAt(d); - - break; - - case Act.DoNothing: - - break; - - case Act.Unknown: - - return Modify(item); - - // should never get here - default: - - throw new InvalidOperationException( - "Undefined cache action."); - } - - IsFaulted = false; - return act; - } - - /// - /// Analyze and DELETE new arrivals from cache, - /// after validating best instruction. - /// - /// Cacheable time-series object - /// Action taken (outcome) - /// - /// Too many sequential duplicates were detected. - /// - protected Act Purge(TSeries item) - { - // check format and overflow - if (CheckOverflow(item) is Act.DoNothing) - { - return Act.DoNothing; - } - - // find position - int index = GetIndex(item, true); - - if (index < 0) - { - // not found - return Act.DoNothing; - } - - // delete - return Modify(Act.Delete, item, index); - } - - /// - /// DELETE item from cache at index position, - /// without validating or analyzing the action - /// - /// Action taken (outcome) - /// - /// Index is out of range (not found). - /// - protected Act Purge(int index) - { - if (index < 0 || index >= Cache.Count) - { - // not found - return Act.DoNothing; - } - - TSeries item = Cache[index]; - - // delete - return Modify(Act.Delete, item, index); - } - - /// - /// Validate inbound item and compare to prior arrivals - /// to gracefully manage and prevent overflow conditions. - /// - /// Cacheable time-series object - /// - /// A "do nothing" act instruction if duplicate or 'null' - /// when no overflow condition is detected. - /// - /// - /// Too many sequential duplicates were detected. - /// - private Act? CheckOverflow(TSeries item) - { - Act? act = null; - - // skip first arrival - if (LastArrival is null) - { - LastArrival = item; - return act; - } - - // check for overflow condition - if (item.Timestamp == LastArrival.Timestamp) - { - // note: we have a better IsEqual() comparison method below, - // but it is too expensive as an initial quick evaluation. - - OverflowCount++; - - if (OverflowCount > 100) - { - const string msg = """ - A repeated stream update exceeded the 100 attempt threshold. - Check and remove circular chains or check your stream provider. - Provider terminated. - """; - - IsFaulted = true; - - throw new OverflowException(msg); - - // note: overflow exception is also further handled by providers, - // where it will EndTransmission(); and then throw error to user. - } - - // aggressive property value comparison - // TODO: not handling add-back after delete, registers as dup - if (item.Equals(LastArrival)) - { - // to prevent propogation - // of identical cache entry - act = Act.DoNothing; - } - - // same date with different values - // continues as an update - else - { - LastArrival = item; - } - } - else - { - OverflowCount = 0; - LastArrival = item; - } - - return act; - } -} diff --git a/src/_common/Observables/StreamHub.AddRemove.cs b/src/_common/Observables/StreamHub.AddRemove.cs deleted file mode 100644 index 014108567..000000000 --- a/src/_common/Observables/StreamHub.AddRemove.cs +++ /dev/null @@ -1,52 +0,0 @@ - -namespace Skender.Stock.Indicators; - -// STREAM HUB (ADD/REMOVE) - -public abstract partial class StreamHub -{ - public void Add(TIn newIn) - => OnNext((Act.Unknown, newIn, null)); - - public void Add(IEnumerable newIn) - { - foreach (TIn quote in newIn.ToSortedList()) - { - OnNext((Act.Unknown, quote, null)); - } - } - - public virtual Act Remove(TOut cachedItem) - => RemoveAt(GetIndex(cachedItem, false)); - - public Act RemoveAt(int cacheIndex) - { - TOut thisItem = Cache[cacheIndex]; - - try - { - Act act = Purge(cacheIndex); - NotifyObservers(act, thisItem, cacheIndex); - return act; - } - catch (OverflowException) - { - EndTransmission(); - throw; - } - } - - /// - /// Builds incremental indicator and adds to cache. - /// - /// - /// Caching instruction hint from provider - /// - /// - /// New inbound item from provider - /// - /// - /// Index position of item in provider cache - /// - internal abstract void Add(Act act, TIn item, int? index); -} diff --git a/src/_common/Observables/StreamHub.Observable.cs b/src/_common/Observables/StreamHub.Observable.cs new file mode 100644 index 000000000..5f6ec2269 --- /dev/null +++ b/src/_common/Observables/StreamHub.Observable.cs @@ -0,0 +1,119 @@ +namespace Skender.Stock.Indicators; + +// STREAM HUB (OBSERVABLE) + +public abstract partial class StreamHub : IStreamObservable +{ + private readonly HashSet> _observers = new(); + + /// + public bool HasObservers => _observers.Count > 0; + + /// + public int ObserverCount => _observers.Count; + + /// + public IReadOnlyList ReadCache => Cache; + + /// + public virtual BinarySettings Properties { get; init; } = new(0); // default 0b00000000 + + #region SUBSCRIPTION SERVICES + + /// + public IDisposable Subscribe(IStreamObserver observer) + { + _observers.Add(observer); + return new Unsubscriber(_observers, observer); + } + + /// + public bool Unsubscribe(IStreamObserver observer) + => _observers.Remove(observer); + + /// + public bool HasSubscriber(IStreamObserver observer) + => _observers.Contains(observer); + + /// + /// A disposable subscription to the stream provider. + /// Unsubscribed with + /// + /// + /// Registry of all subscribers (by ref) + /// + /// + /// Your unique subscription as provided. + /// + private class Unsubscriber( + ISet> observers, + IStreamObserver observer) : IDisposable + { + private readonly ISet> _observers = observers; + private readonly IStreamObserver _observer = observer; + + /// + /// Remove single observer. + /// + public void Dispose() => _observers.Remove(_observer); + } + + /// + public void EndTransmission() + { + foreach (IStreamObserver observer + in _observers.ToArray()) + { + if (_observers.Contains(observer)) + { + // subscriber removes itself + observer.OnCompleted(); + } + } + + _observers.Clear(); + } + #endregion + + #region SUBSCRIBER NOTIFICATIONS + + /// + /// Sends new TSeries item to subscribers. + /// + /// TSeries item to send. + /// Provider index hint. + private void NotifyObserversOnAdd(TOut item, int? indexHint) + { + // send to subscribers + foreach (IStreamObserver o in _observers.ToArray()) + { + o.OnAdd(item, notify: true, indexHint); + } + } + + /// + /// Sends rebuilds point in time to all subscribers. + /// + /// Rebuild starting positions. + private void NotifyObserversOnChange(DateTime fromTimestamp) + { + foreach (IStreamObserver o in _observers.ToArray()) + { + o.OnChange(fromTimestamp); + } + } + + /// + /// Sends error (exception) to all subscribers. + /// + /// The exception to send. + private void NotifyObserversOnError(Exception exception) + { + // send to subscribers + foreach (IStreamObserver o in _observers.ToArray()) + { + o.OnError(exception); + } + } + #endregion +} diff --git a/src/_common/Observables/StreamHub.Observer.cs b/src/_common/Observables/StreamHub.Observer.cs new file mode 100644 index 000000000..c2b374336 --- /dev/null +++ b/src/_common/Observables/StreamHub.Observer.cs @@ -0,0 +1,66 @@ +namespace Skender.Stock.Indicators; + +// STREAM HUB (OBSERVER) + +public abstract partial class StreamHub : IStreamObserver +{ + /// + public bool IsSubscribed => Provider.HasSubscriber(this); + + /// + /// Data provider that this observer subscribes to. + /// + protected IStreamObservable Provider { get; init; } + + /// + /// Subscription token for managing the subscription lifecycle. + /// + private IDisposable? Subscription { get; set; } + + /// + /// Lock object to ensure thread safety during unsubscription. + /// + private readonly object _unsubscribeLock = new(); + + // Observer methods + + /// + public virtual void OnAdd(TIn item, bool notify, int? indexHint) + { + // Convert the input item to the output type and append it to the cache. + // Override this method if the input and output types are not indexed 1:1. + + (TOut result, int _) = ToIndicator(item, indexHint); // TODO: make this return array, loop appendation? + AppendCache(result, notify); + } + + /// + public void OnChange(DateTime fromTimestamp) + => Rebuild(fromTimestamp); + + /// + public void OnError(Exception exception) + => throw exception; + + /// + public void OnCompleted() + => Unsubscribe(); + + /// + public void Unsubscribe() + { + // Ensure thread-safety for EndTransmission > OnCompleted-type race conditions + // see https://learn.microsoft.com/en-us/dotnet/standard/events/observer-design-pattern-best-practices + + lock (_unsubscribeLock) + { + if (IsSubscribed) + { + Provider.Unsubscribe(this); + } + + Subscription?.Dispose(); + Subscription = null; // ensure the ref is cleared + } + } +} diff --git a/src/_common/Observables/StreamHub.Rebuild.cs b/src/_common/Observables/StreamHub.Rebuild.cs deleted file mode 100644 index 6ff357022..000000000 --- a/src/_common/Observables/StreamHub.Rebuild.cs +++ /dev/null @@ -1,90 +0,0 @@ - -namespace Skender.Stock.Indicators; - -// STREAM HUB (REBUILD CACHE) - -public abstract partial class StreamHub -{ - // full reset - /// - public void Reinitialize() - { - Unsubscribe(); - ResetFault(); - ClearCache(); - Subscription = Provider.Subscribe(this); - RebuildCache(); - } - - // rebuild cache - /// - public void RebuildCache() => RebuildCache(0); - - // rebuild cache from timestamp - /// - public void RebuildCache( - DateTime fromTimestamp) - { - int fromIndex = GetInsertIndex(fromTimestamp); - - // nothing to rebuild - if (fromIndex < 0) - { - return; - } - - int provIndex = Provider.GetInsertIndex(fromTimestamp); - - // nothing to restore - if (provIndex < 0) - { - provIndex = int.MaxValue; - } - - RebuildCache(fromIndex, provIndex); - } - - // rebuild cache from index - /// - public void RebuildCache(int fromIndex) - { - // get equivalent provider index - int provIndex; - - if (fromIndex <= 0) - { - provIndex = 0; - } - else - { - TOut item = Cache[fromIndex]; - - provIndex = Provider.GetInsertIndex(item.Timestamp); - - if (provIndex < 0) - { - // nothing to restore - provIndex = int.MaxValue; - } - } - - RebuildCache(fromIndex, provIndex); - } - - /// - /// Rebuild cache from index and provider index positions. - /// - /// Cache starting position to purge. - /// Provider starting position to add back. - internal void RebuildCache(int thisIndex, int provIndex) - { - // clear outdated cache - ClearCache(thisIndex); - - // rebuild cache from provider - for (int i = provIndex; i < Provider.Results.Count; i++) - { - OnNext((Act.AddNew, Provider.Results[i], i)); - } - } -} diff --git a/src/_common/Observables/StreamHub.Utilities.cs b/src/_common/Observables/StreamHub.Utilities.cs new file mode 100644 index 000000000..041d9e3cf --- /dev/null +++ b/src/_common/Observables/StreamHub.Utilities.cs @@ -0,0 +1,202 @@ +namespace Skender.Stock.Indicators; + +// STREAM HUB (STATIC UTILITIES) + +public static class StreamHub +{ + /// + /// Try to find index position of the provided timestamp + /// + /// + /// Timestamp to seek + /// + /// Index of timestamp or -1 when not found + /// + /// True if found + internal static bool TryFindIndex( + this IReadOnlyList cache, + DateTime timestamp, + out int index) + where T : ISeries + { + index = cache.GetIndex(timestamp, false); + return index != -1; + } + + /// + /// Get the cache index based on item equality. + /// + /// + /// + /// Time-series object to find in cache + /// + /// + /// Throw exception when item is not found + /// + /// Index position + /// + /// When items is not found (should never happen). + /// + internal static int GetIndex( + this IReadOnlyList cache, + T cachedItem, + bool throwOnFail) + where T : ISeries + { + int low = 0; + int high = cache.Count - 1; + int firstMatchIndex = -1; + + while (low <= high) + { + int mid = low + ((high - low) / 2); + int comparison = cache[mid].Timestamp.CompareTo(cachedItem.Timestamp); + + if (comparison == 0) + { + // Found a match by Timestamp, + // store the index of the first match + if (firstMatchIndex == -1) + { + firstMatchIndex = mid; + } + + // Verify with Equals for an exact match + if (cache[mid].Equals(cachedItem)) + { + return mid; // exact match found + } + + // Continue searching to the left for + // the first occurrence + high = mid - 1; + } + else if (comparison < 0) + { + low = mid + 1; + } + else + { + high = mid - 1; + } + } + + // If a timestamp match was found but no exact + // match, try to find an exact match in the range + // of duplicate timestamps (e.g. Renko bricks), + // biased towards later duplicates. + if (firstMatchIndex != -1) + { + // Find the last occurrence of the matching timestamp + for (int i = cache.Count - 1; i >= firstMatchIndex; i--) + { + if (cache[i].Timestamp == cachedItem.Timestamp + && cache[i].Equals(cachedItem)) + { + return i; // exact match found among duplicates + } + } + } + + // not found + return throwOnFail + ? throw new ArgumentException( + "Matching source history not found.", nameof(cachedItem)) + : -1; + } + + /// + /// Get the cache index based on a timestamp. + /// + /// + /// Only use this when you are looking for a point in time + /// without a matching item for context. In most cases + /// is more appropriate. + /// + /// + /// + /// Timestamp of cached item + /// + /// + /// Throw exception when timestamp is not found + /// + /// Index position + /// + /// When timestamp is not found (should never happen). + /// + internal static int GetIndex( + this IReadOnlyList cache, + DateTime timestamp, + bool throwOnFail) + where T : ISeries + { + int low = 0; + int high = cache.Count - 1; + + while (low <= high) + { + int mid = low + ((high - low) / 2); + DateTime midTimestamp = cache[mid].Timestamp; + + if (midTimestamp == timestamp) + { + return mid; + } + else if (midTimestamp < timestamp) + { + low = mid + 1; + } + else + { + high = mid - 1; + } + } + + // not found + return throwOnFail + ? throw new ArgumentException( + "Matching source history not found.", nameof(timestamp)) + : -1; + } + + /// + /// Get the first cache index on or after a timestamp. + /// + /// + /// Only use this when you are looking for a point in time + /// without a matching item for context. In most cases + /// is more appropriate. + /// + /// + /// + /// Timestamp of cached item + /// + /// First index position or -1 if not found + internal static int GetIndexGte( + this IReadOnlyList cache, + DateTime timestamp) + where T : ISeries + { + int low = 0; + int high = cache.Count; + while (low < high) + { + int mid = low + ((high - low) / 2); + if (cache[mid].Timestamp < timestamp) + { + low = mid + 1; + } + else + { + high = mid; + } + } + + // At this point, low is the index of the first + // element that is greater than or equal to timestamp + // or Cache.Count if all elements are less than timestamp. + // If low is equal to Cache.Count, it means there are + // no elements greater than or equal to timestamp. + return low < cache.Count ? low : -1; + } +} diff --git a/src/_common/Observables/StreamHub.cs b/src/_common/Observables/StreamHub.cs index 5b3d806cf..53c6302f4 100644 --- a/src/_common/Observables/StreamHub.cs +++ b/src/_common/Observables/StreamHub.cs @@ -1,61 +1,408 @@ - namespace Skender.Stock.Indicators; -// STREAM HUB (OBSERVER BASE) - -# region hub observer variants - -public abstract class QuoteObserver( - IQuoteProvider provider -) : StreamHub(provider) - where TIn : IQuote - where TOut : ISeries; - -public abstract class ReusableObserver( - IChainProvider provider -) : StreamHub(provider) - where TIn : IReusable - where TOut : ISeries; -#endregion +// STREAM HUB (BASE/CACHE) -/// -/// Streaming hub (abstract observer/provider) -/// -public abstract partial class StreamHub( - IStreamProvider provider -) : StreamProvider, IStreamHub +/// +public abstract partial class StreamHub : IStreamHub where TIn : ISeries where TOut : ISeries { - public bool IsSubscribed => Provider.HasSubscriber(this); + #region constructor + + /// + /// Streaming data provider + /// + private protected StreamHub(IStreamObservable provider) + { + // store provider reference + Provider = provider; + + // set provider cache reference + ProviderCache = provider.GetCacheRef(); + + // inherit settings (reinstantiate struct on heap) + Properties = Properties.Combine(provider.Properties); + } + + #endregion + + #region PROPERTIES + + /// + public IReadOnlyList Results => Cache; + + /// + public bool IsFaulted { get; private set; } - protected internal IDisposable? Subscription { get; set; } + /// + /// Cache of stored values (base). + /// + internal List Cache { get; } = new(); - protected IStreamProvider Provider => provider; + /// + /// Current count of repeated caching attempts. + /// An overflow condition is triggered after 100. + /// + internal byte OverflowCount { get; private set; } - // observer methods + /// + /// Reference to this hub's provider's cache. + /// + protected IReadOnlyList ProviderCache { get; } - public virtual void OnNext((Act, TIn, int?) value) + /// + /// Most recent item saved to cache. + /// + private TOut? LastItem { get; set; } + + #endregion + + // reset fault flag and condition + /// + public void ResetFault() { - (Act act, TIn item, int? index) = value; + OverflowCount = 0; + IsFaulted = false; + } + + // fetch cache reference + /// + public IReadOnlyList GetCacheRef() => Cache; + + public abstract override string ToString(); + + /// + /// Converts incremental value into + /// an indicator candidate and cache position. + /// + /// New item from provider + /// Provider index hint + /// Cacheable item candidate and index hint + protected abstract (TOut result, int index) + ToIndicator(TIn item, int? indexHint); + + #region ADD & ANALYZE - if (act is Act.Unknown or Act.AddNew) + public void Add(TIn newIn) + => OnAdd(newIn, notify: true, null); + + public void Add(IEnumerable batchIn) + { + foreach (TIn newIn in batchIn.OrderBy(x => x.Timestamp)) + { + OnAdd(newIn, notify: true, null); + } + } + + public void Insert(TIn newIn) + { + // note: should only be used when newer timestamps + // are not impacted by the insertion of an older item + + // generate candidate result + (TOut result, int index) = ToIndicator(newIn, null); + + // insert, then rebuild observers (no self-rebuild) + if (index > 0) + { + // check overflow/duplicates + if (IsOverflowing(result)) + { + return; // duplicate found + } + + Cache.Insert(index, result); + NotifyObserversOnChange(result.Timestamp); + } + + // normal add + else + { + AppendCache(result, notify: true); + } + } + + /// + /// Perform appropriate caching action after analysis. + /// It will add if new, ignore if duplicate, or rebuild if late-arrival. + /// + /// TSeries item to cache. + /// + /// Notify subscribers of change (send to observers). + /// This is disabled for bulk operations like rebuild. + /// + protected void AppendCache(TOut result, bool notify) + { + // check overflow/duplicates + if (IsOverflowing(result)) { - Add(act, item, index); return; } - // TODO: handle revision/recursion differently - // for different indicators; and may also need - // to breakout OnDeleted(TIn deleted), etc. - RebuildCache(item.Timestamp); + bool bypassRebuild = Properties[1]; // forced add/caching w/o rebuild + + // consider timeline + Act act = bypassRebuild || Cache.Count == 0 || result.Timestamp > Cache[^1].Timestamp + ? Act.Add + : Act.Rebuild; + + // fulfill action + switch (act) + { + // add to cache + case Act.Add: + Add(result, notify); + break; + + // rebuild cache + case Act.Rebuild: + Rebuild(result.Timestamp); + break; + + // would never happen + default: + throw new InvalidOperationException(); + } } - public void OnError(Exception error) => throw error; + /// + /// Add item to cache and notify observers. + /// + /// Item to add to end of cache + /// Inherited notification instructions. + private void Add(TOut item, bool notify) + { + // notes: + // 1. Should only be called from AppendCache() + // 2. Notify has to be disabled for bulk operations, like rebuild. + // 3. Forced caching (rebuild analysis bypass) is inherited property. - public void OnCompleted() => Unsubscribe(); + // add to cache + Cache.Add(item); + IsFaulted = false; - public void Unsubscribe() => Subscription?.Dispose(); + // notify subscribers + if (notify) + { + NotifyObserversOnAdd(item, Cache.Count - 1); + } + } - public abstract override string ToString(); + /// + /// Validate outbound item and compare to prior cached item, + /// to gracefully manage and prevent overflow conditions. + /// + /// Cacheable time-series object + /// + /// True if item is repeating and duplicate was suppressed. + /// + /// + /// Too many sequential duplicates were detected. + /// + private bool IsOverflowing(TOut item) + { + // skip first arrival + if (LastItem is null) + { + LastItem = item; + return false; + } + + // track/check for overflow condition + if (item.Timestamp == LastItem.Timestamp && item.Equals(LastItem)) + { + // ^^ using progressive check to avoid Equals() on every item + + OverflowCount++; + + // handle overflow + if (OverflowCount > 100) + { + const string msg = """ + A repeated stream update exceeded the 100 attempt threshold. + Check and remove circular chains or check your stream provider. + Provider terminated. + """; + + IsFaulted = true; + + // emit error + OverflowException exception = new(msg); + NotifyObserversOnError(exception); + throw exception; + } + + // bypass duplicate prevention + // when forced caching is enabled + if (Properties[1]) + { + return false; + + // note: will still overflow + // when the 100 limit is reached + } + + return true; + } + + // not repeating + OverflowCount = 0; + LastItem = item; + return false; + } + #endregion + + #region REMOVE & REMOVE RANGE + + /// remove cached item + /// + public void Remove(TOut cachedItem) + { + Cache.Remove(cachedItem); + NotifyObserversOnChange(cachedItem.Timestamp); + } + + /// remove cached item at index position + /// + public void RemoveAt(int cacheIndex) + { + TOut cachedItem = Cache[cacheIndex]; + Cache.RemoveAt(cacheIndex); + NotifyObserversOnChange(cachedItem.Timestamp); + } + + /// remove cache range from timestamp + /// + public void RemoveRange(DateTime fromTimestamp, bool notify) + { + // rollback internal state + RollbackState(fromTimestamp); + + // remove cache entries + Cache.RemoveAll(c => c.Timestamp >= fromTimestamp); + + // notify observers + if (notify) + { + NotifyObserversOnChange(fromTimestamp); + } + } + + /// remove cache range from index + /// + public void RemoveRange(int fromIndex, bool notify) + { + // nothing to do + if (Cache.Count == 0 || fromIndex >= Cache.Count) + { + return; + } + + // remove cache entries + DateTime fromTimestamp = fromIndex <= 0 + ? DateTime.MinValue + : Cache[fromIndex].Timestamp; + + RemoveRange(fromTimestamp, notify); + } + #endregion + + #region REBUILD & REINITIALIZE + + // full reset + /// + public void Reinitialize() + { + Unsubscribe(); + ResetFault(); + Rebuild(); + Subscription = Provider.Subscribe(this); + + // TODO: make reinitialization abstract, + // and build initial Cache from faster static method + + // TODO: evaluate race condition between rebuild + // and subscribe; will it miss any high frequency data? + } + + // rebuild cache + /// + public void Rebuild() + => Rebuild(DateTime.MinValue); + + // rebuild cache from timestamp + /// + public void Rebuild(DateTime fromTimestamp) + { + // clear cache + RemoveRange(fromTimestamp, notify: false); + + // get provider position + int provIndex = ProviderCache.GetIndexGte(fromTimestamp); + + // rebuild + if (provIndex >= 0) + { + for (int i = provIndex; i < ProviderCache.Count; i++) + { + OnAdd(ProviderCache[i], notify: false, i); + } + } + + // notify observers + NotifyObserversOnChange(fromTimestamp); + } + + // rebuild cache from index + /// + public void Rebuild(int fromIndex) + { + // find timestamp + DateTime fromTimestamp = fromIndex <= 0 || Cache.Count == 0 + ? DateTime.MinValue + : Cache[fromIndex].Timestamp; + + // rebuild & notify + Rebuild(fromTimestamp); + } + + /// + /// Rollback internal state to a point in time. + /// Behavior varies by indicator. + /// + /// + /// Override when indicator needs to rollback state to a + /// point in time (e.g. when rebuilding cache). Example: + /// + /// + /// + /// Point in time to restore. + /// + protected virtual void RollbackState(DateTime timestamp) + { + // note: override when rollback is needed + // default: do nothing + // see AtrStopHub() for example + } + #endregion } + +#region chain and quote variants + +/// +public abstract class QuoteProvider( + IStreamObservable provider +) : StreamHub(provider), IQuoteProvider + where TIn : IReusable + where TOut : IQuote +{ + public IReadOnlyList Quotes => Cache; +}; + +/// +public abstract class ChainProvider( + IStreamObservable provider +) : StreamHub(provider), IChainProvider + where TIn : IReusable + where TOut : IReusable; +#endregion diff --git a/src/_common/Observables/StreamProvider.Motify.cs b/src/_common/Observables/StreamProvider.Motify.cs deleted file mode 100644 index c76f92cfc..000000000 --- a/src/_common/Observables/StreamProvider.Motify.cs +++ /dev/null @@ -1,91 +0,0 @@ -namespace Skender.Stock.Indicators; - -// STREAM PROVIDER: MODIFY CACHE + NOTIFY SUBSCRIBERS (MOTIFY) - -public abstract partial class StreamProvider -{ - /// clear cache without restore, from timestamp - /// - public override void ClearCache(DateTime fromTimestamp) - { - // start of range - int fromIndex = GetInsertIndex(fromTimestamp); - - // something to do - if (fromIndex != -1) - { - ClearCache(fromIndex); - } - } - - /// clear cache without restore, from index - /// - public override void ClearCache(int fromIndex) - => ClearCache(fromIndex, toIndex: Cache.Count - 1); - - /// - /// Modify cache and notify observers. - /// - /// Caching instruction - /// TSeries item to send - /// Cached index position - protected void Motify(Act act, TSeries result, int? index) - { - Act actTaken = Modify(act, result, index); - NotifyObservers(actTaken, result, index); - } - - /// - /// Sends TSeries item to all subscribers - /// - /// Caching instruction - /// TSeries item to send - /// Provider index hint - protected void NotifyObservers(Act act, TSeries? item, int? index) - { - // do not propogate "do nothing" acts - if (act == Act.DoNothing || item is null) - { - return; - } - - // send to subscribers - foreach (IObserver<(Act, TSeries, int?)> obs - in _subscribers.ToArray()) - { - obs.OnNext((act, item, index)); - } - } - - /// - /// Deletes cache entries between index range values. - /// - /// - /// This is implemented in inheriting (provider) class - /// due to unique requirement to notify subscribers. - /// - /// First element to delete - /// Last element to delete - /// clears cache segment - /// - private void ClearCache( - int fromIndex, int toIndex) - { - // nothing to do - if (Cache.Count is 0) - { - return; - } - - // determine in-range start/end indices - int fr = Math.Max(0, Math.Min(fromIndex, toIndex)); - int to = Math.Min(Cache.Count - 1, Math.Max(fromIndex, toIndex)); - - // delete and deliver instruction in reverse - // order to prevent recursive recompositions - for (int i = to; i >= fr; i--) - { - Motify(Act.Delete, Cache[i], i); - } - } -} diff --git a/src/_common/Observables/StreamProvider.cs b/src/_common/Observables/StreamProvider.cs deleted file mode 100644 index aa3598906..000000000 --- a/src/_common/Observables/StreamProvider.cs +++ /dev/null @@ -1,64 +0,0 @@ -namespace Skender.Stock.Indicators; - -// STREAM PROVIDER (OBSERVABLE BASE) - -/// -public abstract partial class StreamProvider - : StreamCache, IStreamProvider - where TSeries : ISeries -{ - private readonly HashSet> _subscribers = []; - - public bool HasSubscribers => _subscribers.Count > 0; - - public int SubscriberCount => _subscribers.Count; - - public IReadOnlyList ReadCache => Cache; - - // SUBSCRIPTION SERVICES - - // subscribe observer - public IDisposable Subscribe(IObserver<(Act, TSeries, int?)> observer) - { - _subscribers.Add(observer); - return new Subscription(_subscribers, observer); - } - - // check if observer is subscribed - public bool HasSubscriber( - IObserver<(Act, TSeries, int?)> observer) - => _subscribers.Contains(observer); - - /// - /// A disposable subscription to the stream provider. - /// Unsubscribed with - /// - /// - /// Registry of all subscribers (by ref) - /// - /// - /// Your unique subscription as provided. - /// - private class Subscription( - ISet> subscribers, - IObserver<(Act, TSeries, int?)> subscriber) : IDisposable - { - // remove single observer - public void Dispose() => subscribers.Remove(subscriber); - } - - // unsubscribe all observers - public void EndTransmission() - { - foreach (IObserver<(Act, TSeries, int?)> subscriber - in _subscribers.ToArray()) - { - if (_subscribers.Contains(subscriber)) - { - subscriber.OnCompleted(); - } - } - - _subscribers.Clear(); - } -} diff --git a/src/_common/Quotes/Quote.StreamHub.cs b/src/_common/Quotes/Quote.StreamHub.cs index b73fe4745..08cedbed3 100644 --- a/src/_common/Quotes/Quote.StreamHub.cs +++ b/src/_common/Quotes/Quote.StreamHub.cs @@ -3,11 +3,11 @@ namespace Skender.Stock.Indicators; /// /// Quote provider (abstract base) /// -public class QuoteHub : QuoteObserver, - IQuoteHub +public class QuoteHub + : QuoteProvider where TQuote : IQuote { - public QuoteHub() : base(new QuoteProvider()) { } + public QuoteHub() : base(new EmptyQuoteProvider()) { } public QuoteHub( IQuoteProvider provider) @@ -16,22 +16,15 @@ public QuoteHub( Reinitialize(); } - public IReadOnlyList Quotes => Cache; - // METHODS - internal override void Add(Act act, TQuote newIn, int? index) + protected override (TQuote result, int index) + ToIndicator(TQuote item, int? indexHint) { - try - { - // save and send - Motify(act, newIn, index); - } - catch (OverflowException) - { - EndTransmission(); - throw; - } + int index = indexHint + ?? Cache.GetIndexGte(item.Timestamp); + + return (item, index == -1 ? Cache.Count : index); } public override string ToString() @@ -39,9 +32,31 @@ public override string ToString() } /// -/// Empty quote provider for parent-less QuoteHub +/// Empty quote provider for base Quote Hub initialization. /// +/// Internal use only. Do not use directly. /// -internal class QuoteProvider - : StreamProvider, IQuoteProvider - where TQuote : IQuote; +public class EmptyQuoteProvider + : IQuoteProvider + where TQuote : IQuote +{ + /// + /// Default quote provider is parent-less Quote Hub. + /// It does not transfer its setting to its children. + /// + public BinarySettings Properties { get; } = new(0b00000001, 0b11111110); + public int ObserverCount => 0; + public bool HasObservers => false; + public IReadOnlyList Quotes { get; } = Array.Empty(); + public IReadOnlyList GetCacheRef() => Array.Empty(); + public bool HasSubscriber(IStreamObserver observer) => false; + + public IDisposable Subscribe(IStreamObserver observer) + => throw new InvalidOperationException(); + + public bool Unsubscribe(IStreamObserver observer) + => throw new InvalidOperationException(); + + public void EndTransmission() + => throw new InvalidOperationException(); +} diff --git a/src/_common/Use (QuotePart)/Use.StreamHub.cs b/src/_common/Use (QuotePart)/Use.StreamHub.cs index 0a044fe53..c57db8906 100644 --- a/src/_common/Use (QuotePart)/Use.StreamHub.cs +++ b/src/_common/Use (QuotePart)/Use.StreamHub.cs @@ -11,8 +11,8 @@ public interface IQuotePartHub } #endregion -public class QuotePartHub : QuoteObserver, - IReusableHub, IQuotePartHub +public class QuotePartHub + : ChainProvider, IQuotePartHub where TQuote : IQuote { #region constructors @@ -32,14 +32,14 @@ internal QuotePartHub( // METHODS - internal override void Add(Act act, TQuote newIn, int? index) + protected override (QuotePart result, int index) + ToIndicator(TQuote item, int? indexHint) { // candidate result QuotePart r - = newIn.ToQuotePart(CandlePartSelection); + = item.ToQuotePart(CandlePartSelection); - // save and send - Motify(act, r, index); + return (r, indexHint ?? Cache.Count); } public override string ToString() diff --git a/src/a-d/Adl/Adl.StreamHub.cs b/src/a-d/Adl/Adl.StreamHub.cs index 50870273a..e2c17c144 100644 --- a/src/a-d/Adl/Adl.StreamHub.cs +++ b/src/a-d/Adl/Adl.StreamHub.cs @@ -2,8 +2,8 @@ namespace Skender.Stock.Indicators; // ACCUMULATION/DISTRIBUTION LINE (STREAM HUB) -public class AdlHub : QuoteObserver, - IReusableHub +public class AdlHub + : ChainProvider where TIn : IQuote { #region constructors @@ -17,21 +17,21 @@ internal AdlHub(IQuoteProvider provider) // METHODS - internal override void Add(Act act, TIn newIn, int? index) + protected override (AdlResult result, int index) + ToIndicator(TIn item, int? indexHint) { - int i = index ?? Provider.GetIndex(newIn, false); + int i = indexHint ?? ProviderCache.GetIndex(item, true); // candidate result AdlResult r = Adl.Increment( - newIn.Timestamp, - newIn.High, - newIn.Low, - newIn.Close, - newIn.Volume, + item.Timestamp, + item.High, + item.Low, + item.Close, + item.Volume, i > 0 ? Cache[i - 1].Value : 0); - // save and send - Motify(act, r, i); + return (r, i); } public override string ToString() diff --git a/src/a-d/Adl/Adl.Utilities.cs b/src/a-d/Adl/Adl.Utilities.cs index f54bf9c4a..5b22b3946 100644 --- a/src/a-d/Adl/Adl.Utilities.cs +++ b/src/a-d/Adl/Adl.Utilities.cs @@ -13,7 +13,7 @@ public static partial class Adl /// See documentation /// for more information. /// - /// Timestamp + /// timestamp /// High price, current period /// Low price, current period /// Close price, current period diff --git a/src/a-d/Adx/Adx.StaticSeries.cs b/src/a-d/Adx/Adx.StaticSeries.cs index 13b89108a..3996d71fa 100644 --- a/src/a-d/Adx/Adx.StaticSeries.cs +++ b/src/a-d/Adx/Adx.StaticSeries.cs @@ -96,7 +96,7 @@ private static List CalcAdx( prevPdm = pdm; prevMdm = mdm; - if (trs is 0) + if (trs == 0) { results.Add(new(Timestamp: q.Timestamp)); continue; diff --git a/src/a-d/Alligator/Alligator.StreamHub.cs b/src/a-d/Alligator/Alligator.StreamHub.cs index 813fccb49..e7af60e4c 100644 --- a/src/a-d/Alligator/Alligator.StreamHub.cs +++ b/src/a-d/Alligator/Alligator.StreamHub.cs @@ -15,8 +15,8 @@ public interface IAlligatorHub } #endregion -public class AlligatorHub : ReusableObserver, - IResultHub, IAlligatorHub +public class AlligatorHub + : StreamHub, IAlligatorHub where TIn : IReusable { #region constructors @@ -59,13 +59,14 @@ internal AlligatorHub( public override string ToString() => hubName; - internal override void Add(Act act, TIn newIn, int? index) + protected override (AlligatorResult result, int index) + ToIndicator(TIn item, int? indexHint) { double jaw = double.NaN; double lips = double.NaN; double teeth = double.NaN; - int i = index ?? Provider.GetIndex(newIn, false); + int i = indexHint ?? ProviderCache.GetIndex(item, true); // calculate alligator's jaw, when in range if (i >= JawPeriods + JawOffset - 1) @@ -76,7 +77,7 @@ internal override void Add(Act act, TIn newIn, int? index) double sum = 0; for (int p = i - JawPeriods - JawOffset + 1; p <= i - JawOffset; p++) { - sum += Provider.Results[p].Hl2OrValue(); + sum += ProviderCache[p].Hl2OrValue(); } jaw = sum / JawPeriods; @@ -86,7 +87,7 @@ internal override void Add(Act act, TIn newIn, int? index) else { double prevJaw = Cache[i - 1].Jaw.Null2NaN(); - double newVal = Provider.Results[i - JawOffset].Hl2OrValue(); + double newVal = ProviderCache[i - JawOffset].Hl2OrValue(); jaw = ((prevJaw * (JawPeriods - 1)) + newVal) / JawPeriods; } @@ -101,7 +102,7 @@ internal override void Add(Act act, TIn newIn, int? index) double sum = 0; for (int p = i - TeethPeriods - TeethOffset + 1; p <= i - TeethOffset; p++) { - sum += Provider.Results[p].Hl2OrValue(); + sum += ProviderCache[p].Hl2OrValue(); } teeth = sum / TeethPeriods; @@ -111,7 +112,7 @@ internal override void Add(Act act, TIn newIn, int? index) else { double prevTooth = Cache[i - 1].Teeth.Null2NaN(); - double newVal = Provider.Results[i - TeethOffset].Hl2OrValue(); + double newVal = ProviderCache[i - TeethOffset].Hl2OrValue(); teeth = ((prevTooth * (TeethPeriods - 1)) + newVal) / TeethPeriods; } @@ -126,7 +127,7 @@ internal override void Add(Act act, TIn newIn, int? index) double sum = 0; for (int p = i - LipsPeriods - LipsOffset + 1; p <= i - LipsOffset; p++) { - sum += Provider.Results[p].Hl2OrValue(); + sum += ProviderCache[p].Hl2OrValue(); } lips = sum / LipsPeriods; @@ -136,7 +137,7 @@ internal override void Add(Act act, TIn newIn, int? index) else { double prevLips = Cache[i - 1].Lips.Null2NaN(); - double newVal = Provider.Results[i - LipsOffset].Hl2OrValue(); + double newVal = ProviderCache[i - LipsOffset].Hl2OrValue(); lips = ((prevLips * (LipsPeriods - 1)) + newVal) / LipsPeriods; } @@ -144,12 +145,11 @@ internal override void Add(Act act, TIn newIn, int? index) // candidate result AlligatorResult r = new( - newIn.Timestamp, + item.Timestamp, jaw.NaN2Null(), teeth.NaN2Null(), lips.NaN2Null()); - // save and send - Motify(act, r, i); + return (r, i); } } diff --git a/src/a-d/Atr/Atr.StreamHub.cs b/src/a-d/Atr/Atr.StreamHub.cs index 09660d74c..5aba0234f 100644 --- a/src/a-d/Atr/Atr.StreamHub.cs +++ b/src/a-d/Atr/Atr.StreamHub.cs @@ -10,8 +10,8 @@ public interface IAtrHub } #endregion -public class AtrHub : QuoteObserver, - IReusableHub, IAtrHub +public class AtrHub + : ChainProvider, IAtrHub where TIn : IQuote { #region constructors @@ -36,15 +36,15 @@ internal AtrHub(IQuoteProvider provider, public override string ToString() => hubName; - internal override void Add(Act act, TIn newIn, int? index) + protected override (AtrResult result, int index) + ToIndicator(TIn item, int? indexHint) { - int i = index ?? Provider.GetIndex(newIn, false); + int i = indexHint ?? ProviderCache.GetIndex(item, true); // skip incalculable periods if (i == 0) { - Motify(act, new AtrResult(newIn.Timestamp), i); - return; + return (new AtrResult(item.Timestamp), i); } AtrResult r; @@ -58,9 +58,9 @@ internal override void Add(Act act, TIn newIn, int? index) for (int p = i - LookbackPeriods + 1; p <= i; p++) { tr = Tr.Increment( - (double)Provider.Results[p].High, - (double)Provider.Results[p].Low, - (double)Provider.Results[p - 1].Close); + (double)ProviderCache[p].High, + (double)ProviderCache[p].Low, + (double)ProviderCache[p - 1].Close); sumTr += tr; } @@ -68,10 +68,10 @@ internal override void Add(Act act, TIn newIn, int? index) double atr = sumTr / LookbackPeriods; r = new AtrResult( - newIn.Timestamp, + item.Timestamp, tr, atr, - atr / (double)newIn.Close * 100); + atr / (double)item.Close * 100); } // calculate ATR (normally) @@ -79,12 +79,11 @@ internal override void Add(Act act, TIn newIn, int? index) { r = Atr.Increment( LookbackPeriods, - newIn, - (double)Provider.Results[i - 1].Close, + item, + (double)ProviderCache[i - 1].Close, Cache[i - 1].Atr); } - // save and send - Motify(act, r, i); + return (r, i); } } diff --git a/src/a-d/AtrStop/AtrStop.StreamHub.cs b/src/a-d/AtrStop/AtrStop.StreamHub.cs index 0b35442cf..0b658d29e 100644 --- a/src/a-d/AtrStop/AtrStop.StreamHub.cs +++ b/src/a-d/AtrStop/AtrStop.StreamHub.cs @@ -12,8 +12,8 @@ public interface IAtrStopHub } #endregion -public class AtrStopHub : QuoteObserver, - IResultHub, IAtrStopHub +public class AtrStopHub + : StreamHub, IAtrStopHub where TIn : IQuote { #region constructors @@ -50,59 +50,21 @@ internal AtrStopHub( public override string ToString() => hubName; - // overridden to handle non-standard arrival scenarios - public override void OnNext((Act, TIn, int?) value) + protected override (AtrStopResult result, int index) + ToIndicator(TIn item, int? indexHint) { - (Act act, TIn item, int? index) = value; + // reminder: should only process "new" instructions - // add next value - if (act is Act.AddNew) - { - Add(act, item, index); - return; - } - - int i = index ?? Provider.GetIndex(item, false); - - // reset to the prior stop points - if (i > LookbackPeriods) - { - AtrStopResult resetStop = Cache[i - 1]; - - // reset prevailing direction and bands - IsBullish = resetStop.AtrStop >= resetStop.SellStop; - UpperBand = resetStop.BuyStop ?? default; - LowerBand = resetStop.SellStop ?? default; - - // rebuild cache AFTER last sync point - RebuildCache(i, i); - } - - // full rebuild if no prior reversal - else - { - IsBullish = default; - UpperBand = default; - LowerBand = default; - RebuildCache(); - } - } - - internal override void Add(Act act, TIn newIn, int? index) - { - // reminder: should only processes "new" instructions - - int i = index ?? Provider.GetIndex(newIn, false); + int i = indexHint ?? ProviderCache.GetIndex(item, true); // handle warmup periods if (i < LookbackPeriods) { - Motify(act, new(newIn.Timestamp), null); - return; + return (new AtrStopResult(item.Timestamp), i); } - QuoteD newQ = newIn.ToQuoteD(); - double prevClose = (double)Provider.Results[i - 1].Close; + QuoteD newQ = item.ToQuoteD(); + double prevClose = (double)ProviderCache[i - 1].Close; // initialize direction on first evaluation if (i == LookbackPeriods) @@ -131,9 +93,9 @@ internal override void Add(Act act, TIn newIn, int? index) for (int p = i - LookbackPeriods + 1; p <= i; p++) { sumTr += Tr.Increment( - (double)Provider.Results[p].High, - (double)Provider.Results[p].Low, - (double)Provider.Results[p - 1].Close); + (double)ProviderCache[p].High, + (double)ProviderCache[p].Low, + (double)ProviderCache[p - 1].Close); } atr = sumTr / LookbackPeriods; @@ -178,7 +140,7 @@ internal override void Add(Act act, TIn newIn, int? index) { IsBullish = false; - r = new( + r = new AtrStopResult( Timestamp: newQ.Timestamp, AtrStop: UpperBand, BuyStop: UpperBand, @@ -191,7 +153,7 @@ internal override void Add(Act act, TIn newIn, int? index) { IsBullish = true; - r = new( + r = new AtrStopResult( Timestamp: newQ.Timestamp, AtrStop: LowerBand, BuyStop: null, @@ -199,7 +161,34 @@ internal override void Add(Act act, TIn newIn, int? index) Atr: atr); } - // save and send - Motify(act, r, null); + return (r, i); + } + + /// + /// Restore prior ATR Stop + /// + /// + protected override void RollbackState(DateTime timestamp) + { + int i = ProviderCache.GetIndexGte(timestamp); + + // restore prior stop point + if (i > LookbackPeriods) + { + AtrStopResult resetStop = Cache[i - 1]; + + // prevailing direction and bands + IsBullish = resetStop.AtrStop >= resetStop.SellStop; + UpperBand = resetStop.BuyStop ?? default; + LowerBand = resetStop.SellStop ?? default; + } + + // or reset if no prior stop found + else + { + IsBullish = default; + UpperBand = default; + LowerBand = default; + } } } diff --git a/src/a-d/Cmo/Cmo.StaticSeries.cs b/src/a-d/Cmo/Cmo.StaticSeries.cs index 747042133..43640cf2a 100644 --- a/src/a-d/Cmo/Cmo.StaticSeries.cs +++ b/src/a-d/Cmo/Cmo.StaticSeries.cs @@ -41,7 +41,7 @@ private static List CalcCmo( tick.isUp = double.IsNaN(tick.value) || s.Value == prevValue ? null : s.Value > prevValue; - + ticks.Add(tick); // calculate CMO diff --git a/src/a-d/Correlation/Correlation.StaticSeries.cs b/src/a-d/Correlation/Correlation.StaticSeries.cs index 5a3677c3a..a07a0092e 100644 --- a/src/a-d/Correlation/Correlation.StaticSeries.cs +++ b/src/a-d/Correlation/Correlation.StaticSeries.cs @@ -25,8 +25,10 @@ private static List CalcCorrelation( if (a.Timestamp != b.Timestamp) { - throw new InvalidQuotesException(nameof(sourceA), a.Timestamp, - "Timestamp sequence does not match. Correlation requires matching dates in provided histories."); + throw new InvalidQuotesException( + nameof(sourceA), a.Timestamp, + "Timestamp sequence does not match. " + + "Correlation requires matching dates in provided histories."); } CorrResult r; diff --git a/src/e-k/Ema/Ema.Api.cs b/src/e-k/Ema/Ema.Api.cs index 0facae954..4958e959d 100644 --- a/src/e-k/Ema/Ema.Api.cs +++ b/src/e-k/Ema/Ema.Api.cs @@ -6,6 +6,9 @@ public static partial class Api { //SERIES, from CHAIN public static IReadOnlyList ToEma( + // FIX: "GetEma" or "ToEma"? + // No longer works as extension method. + // Related to "Api" vs "Ema" namespace. this IEnumerable results, int lookbackPeriods) where T : IReusable diff --git a/src/e-k/Ema/Ema.Increments.cs b/src/e-k/Ema/Ema.Increments.cs index e39bc0782..4f077b6a8 100644 --- a/src/e-k/Ema/Ema.Increments.cs +++ b/src/e-k/Ema/Ema.Increments.cs @@ -6,12 +6,12 @@ namespace Skender.Stock.Indicators; /// Exponential Moving Average (EMA) /// from incremental reusable values. /// -public class EmaInc : List, IEma, IIncrementQuote, IIncrementReusable +public class EmaList : List, IEma, IIncrementQuote, IIncrementReusable { private readonly Queue _buffer; private double _bufferSum; - public EmaInc(int lookbackPeriods) + public EmaList(int lookbackPeriods) { Ema.Validate(lookbackPeriods); LookbackPeriods = lookbackPeriods; diff --git a/src/e-k/Ema/Ema.StaticSeries.cs b/src/e-k/Ema/Ema.StaticSeries.cs index 89ea3ed14..081784321 100644 --- a/src/e-k/Ema/Ema.StaticSeries.cs +++ b/src/e-k/Ema/Ema.StaticSeries.cs @@ -14,7 +14,7 @@ internal static List CalcEma( // initialize int length = source.Count; - List results = new(length); + EmaResult[] results = new EmaResult[length]; double lastEma = double.NaN; double k = 2d / (lookbackPeriods + 1); @@ -27,7 +27,7 @@ internal static List CalcEma( // skip incalculable periods if (i < lookbackPeriods - 1) { - results.Add(new(Timestamp: s.Timestamp)); + results[i] = new(Timestamp: s.Timestamp); continue; } @@ -39,15 +39,13 @@ internal static List CalcEma( // when no prior EMA, reset as SMA : Sma.Increment(source, lookbackPeriods, i); - EmaResult r = new( + results[i] = new EmaResult( Timestamp: s.Timestamp, Ema: ema.NaN2Null()); - results.Add(r); - lastEma = ema; } - return results; + return results.ToList(); } } diff --git a/src/e-k/Ema/Ema.StreamHub.cs b/src/e-k/Ema/Ema.StreamHub.cs index 02cd5f1e4..80996e16c 100644 --- a/src/e-k/Ema/Ema.StreamHub.cs +++ b/src/e-k/Ema/Ema.StreamHub.cs @@ -2,14 +2,14 @@ namespace Skender.Stock.Indicators; // EXPONENTIAL MOVING AVERAGE (STREAM HUB) -public class EmaHub : ReusableObserver, - IReusableHub, IEma +public class EmaHub + : ChainProvider, IEma where TIn : IReusable { #region constructors private readonly string hubName; - + internal EmaHub( IChainProvider provider, int lookbackPeriods) : base(provider) @@ -30,35 +30,28 @@ internal EmaHub( public override string ToString() => hubName; - internal override void Add(Act act, TIn newIn, int? index) + protected override (EmaResult result, int index) + ToIndicator(TIn item, int? indexHint) { - double ema; - - int i = index ?? Provider.GetIndex(newIn, false); + int i = indexHint ?? ProviderCache.GetIndex(item, true); - if (i >= LookbackPeriods - 1) - { - ema = Cache[i - 1].Ema is not null + double ema = i >= LookbackPeriods - 1 + ? Cache[i - 1].Ema is not null // normal - ? Ema.Increment(K, Cache[i - 1].Value, newIn.Value) + ? Ema.Increment(K, Cache[i - 1].Value, item.Value) // re/initialize as SMA - : Sma.Increment(Provider.Results, LookbackPeriods, i); - } + : Sma.Increment(ProviderCache, LookbackPeriods, i) - // warmup periods are never calculable - else - { - ema = double.NaN; - } + // warmup periods are never calculable + : double.NaN; // candidate result EmaResult r = new( - Timestamp: newIn.Timestamp, + Timestamp: item.Timestamp, Ema: ema.NaN2Null()); - // save and send - Motify(act, r, i); + return (r, i); } } diff --git a/src/m-r/Renko/Renko.StreamHub.cs b/src/m-r/Renko/Renko.StreamHub.cs index 53f061a54..0ffc4e3b2 100644 --- a/src/m-r/Renko/Renko.StreamHub.cs +++ b/src/m-r/Renko/Renko.StreamHub.cs @@ -11,14 +11,18 @@ public interface IRenkoHub } #endregion -public class RenkoHub : QuoteObserver, - IQuoteHub, IRenkoHub +public class RenkoHub + : QuoteProvider, IRenkoHub where TIn : IQuote { #region constructors private readonly string hubName; + private RenkoResult lastBrick + = new(default, default, default, + default, default, default, default); + internal RenkoHub( IQuoteProvider provider, decimal brickSize, @@ -33,50 +37,105 @@ internal RenkoHub( } #endregion + /// + /// Renko hub settings. Since it can produce 0 or many bricks per quote, + /// the default 1:1 in/out is not used and must be skipped to prevent + /// same-date triggerred rebuilds when caching. + /// + public override BinarySettings Properties { get; init; } = new(0b00000010); // custom + + /// + /// Standard brick size for Renko chart. + /// public decimal BrickSize { get; } + + /// + /// Close or High/Low price used to determine when threshold + /// is met to generate new bricks. + /// public EndType EndType { get; } // METHODS - + public override string ToString() => hubName; - - internal override void Add(Act act, TIn newIn, int? index) - { - // get last brick - RenkoResult lastBrick; + public override void OnAdd(TIn item, bool notify, int? indexHint) + => ToIndicator(item, notify, indexHint); + + protected override (RenkoResult result, int index) + ToIndicator(TIn item, int? indexHint) + => throw new InvalidOperationException(); // not used + + // TODO: see if returning array of results is possible ^^ + // for all indicators, so we don't have to do this goofy override + + /// + /// Restore last brick marker. + /// + /// + protected override void RollbackState(DateTime timestamp) + { + // restore last brick marker if (Cache.Count != 0) { lastBrick = Cache - .Where(c => c.Timestamp <= newIn.Timestamp) - .Last(); + .Last(c => c.Timestamp <= timestamp); + + return; } - else // no bricks yet + + // skip first quote + if (ProviderCache.Count <= 1) { - // skip first quote - if (Provider.Results.Count <= 1) - { - return; - } + return; + } + + SetBaselineBrick(); + } - int decimals = BrickSize.GetDecimalPlaces(); + // re/initialize last brick marker + private void SetBaselineBrick() + { + int decimals = BrickSize.GetDecimalPlaces(); + + TIn q0 = ProviderCache[0]; + + decimal baseline + = Math.Round(q0.Close, + Math.Max(decimals - 1, 0)); + + lastBrick = new( + q0.Timestamp, + Open: baseline, + High: 0, + Low: 0, + Close: baseline, + Volume: 0, + IsUp: false); + } - TIn q0 = Provider.Results[0]; + // custom: build 0 to many bricks per quote + private void ToIndicator(TIn item, bool notify, int? indexHint) + { + int providerIndex = indexHint + ?? throw new InvalidOperationException($"{nameof(indexHint)} cannot be empty"); - decimal baseline - = Math.Round(q0.Close, - Math.Max(decimals - 1, 0)); + // nothing to do + if (providerIndex <= 0) + { + return; + } - lastBrick = new( - q0.Timestamp, - Open: baseline, 0, 0, - Close: baseline, 0, false); + // establish baseline brick + if (providerIndex == 1) + { + SetBaselineBrick(); } // determine new brick quantity int newBrickQty = Renko.GetNewBrickQuantity( - newIn, lastBrick, BrickSize, EndType); + item, lastBrick, BrickSize, EndType); int absBrickQty = Math.Abs(newBrickQty); bool isUp = newBrickQty >= 0; @@ -90,12 +149,11 @@ int newBrickQty decimal sumV = 0; // cumulative // by aggregating provider cache range - int inboundIndex = index ?? Provider.GetIndex(newIn, false); - int lastBrickIndex = Provider.GetIndex(lastBrick.Timestamp, false); + int lastBrickIndex = ProviderCache.GetIndex(lastBrick.Timestamp, true); - for (int w = lastBrickIndex + 1; w <= inboundIndex; w++) + for (int w = lastBrickIndex + 1; w <= providerIndex; w++) { - TIn pq = Provider.Results[w]; + TIn pq = ProviderCache[w]; h = Math.Max(h, pq.High); l = Math.Min(l, pq.Low); @@ -106,28 +164,26 @@ int newBrickQty for (int b = 0; b < absBrickQty; b++) { - decimal o; - decimal c; - - if (isUp) - { - o = Math.Max(lastBrick.Open, lastBrick.Close); - c = o + BrickSize; - } - else - { - o = Math.Min(lastBrick.Open, lastBrick.Close); - c = o - BrickSize; - } + decimal o = isUp + ? Math.Max(lastBrick.Open, lastBrick.Close) + : Math.Min(lastBrick.Open, lastBrick.Close); + + decimal c = isUp + ? o + BrickSize + : o - BrickSize; // candidate result RenkoResult r - = new(newIn.Timestamp, o, h, l, c, v, isUp); + = new(item.Timestamp, o, h, l, c, v, isUp); lastBrick = r; // save and send - Motify(act, r, null); + AppendCache(r, notify); + + // note: bypass rebuild bit set in Properties to allow + // sequential bricks with duplicate dates that would + // normally trigger rebuild, causing stack overflow. } } } diff --git a/src/m-r/RenkoAtr/RenkoAtr.StaticSeries.cs b/src/m-r/RenkoAtr/RenkoAtr.StaticSeries.cs index 21729ad36..142191b05 100644 --- a/src/m-r/RenkoAtr/RenkoAtr.StaticSeries.cs +++ b/src/m-r/RenkoAtr/RenkoAtr.StaticSeries.cs @@ -18,7 +18,7 @@ private static List CalcRenkoAtr( AtrResult? last = atrResults.LastOrDefault(); decimal brickSize = (decimal?)last?.Atr ?? 0; - return brickSize is 0 + return brickSize == 0 ? [] : quotesList.CalcRenko(brickSize, endType); } diff --git a/src/s-z/Sma/Sma.Incremental.cs b/src/s-z/Sma/Sma.Incremental.cs new file mode 100644 index 000000000..3f7c1807d --- /dev/null +++ b/src/s-z/Sma/Sma.Incremental.cs @@ -0,0 +1,36 @@ +using System.Numerics; + +namespace Skender.Stock.Indicators; + +public static partial class Sma +{ + internal static double[] CalcSma(this double[] prices, int period) + { + int count = prices.Length - period + 1; + double[] sma = new double[count]; + + int simdWidth = Vector.Count; + for (int i = 0; i < count; i++) + { + Vector sumVector = Vector.Zero; + + int j; + for (j = 0; j <= period - simdWidth; j += simdWidth) + { + Vector priceVector = new(prices, i + j); + sumVector += priceVector; + } + + double sum = 0; + for (; j < period; j++) // remainder loop + { + sum += prices[i + j]; + } + sum += Vector.Dot(sumVector, Vector.One); + + sma[i] = sum / period; + } + + return sma; + } +} diff --git a/src/s-z/Sma/Sma.StaticSeries.cs b/src/s-z/Sma/Sma.StaticSeries.cs index f06a39124..417fc27c7 100644 --- a/src/s-z/Sma/Sma.StaticSeries.cs +++ b/src/s-z/Sma/Sma.StaticSeries.cs @@ -14,7 +14,13 @@ internal static List CalcSma( // initialize int length = source.Count; - List results = new(length); + SmaResult[] results = new SmaResult[length]; + double[] values = new double[length]; + + for (int i = 0; i < length; i++) + { + values[i] = source[i].Value; + } // roll through source values for (int i = 0; i < length; i++) @@ -25,27 +31,27 @@ internal static List CalcSma( if (i >= lookbackPeriods - 1) { - double sumSma = 0; - for (int p = i - lookbackPeriods + 1; p <= i; p++) + double sum = 0; + int end = i + 1; + int start = end - lookbackPeriods; + + for (int p = start; p < end; p++) { - T ps = source[p]; - sumSma += ps.Value; + sum += source[p].Value; } - sma = sumSma / lookbackPeriods; + sma = sum / lookbackPeriods; } else { sma = double.NaN; } - SmaResult result = new( + results[i] = new SmaResult( Timestamp: s.Timestamp, Sma: sma.NaN2Null()); - - results.Add(result); } - return results; + return results.ToList(); } } diff --git a/src/s-z/Sma/Sma.StreamHub.cs b/src/s-z/Sma/Sma.StreamHub.cs index 32476793c..7cc4636b4 100644 --- a/src/s-z/Sma/Sma.StreamHub.cs +++ b/src/s-z/Sma/Sma.StreamHub.cs @@ -9,14 +9,14 @@ public interface ISmaHub } #endregion -public class SmaHub : ReusableObserver, - IReusableHub, ISmaHub +public class SmaHub + : ChainProvider, ISmaHub where TIn : IReusable { #region constructors private readonly string hubName; - + internal SmaHub( IChainProvider provider, int lookbackPeriods) : base(provider) @@ -35,16 +35,16 @@ internal SmaHub( public override string ToString() => hubName; - internal override void Add(Act act, TIn newIn, int? index) + protected override (SmaResult result, int index) + ToIndicator(TIn item, int? indexHint) { - int i = index ?? Provider.GetIndex(newIn, false); + int i = indexHint ?? ProviderCache.GetIndex(item, true); // candidate result SmaResult r = new( - Timestamp: newIn.Timestamp, - Sma: Sma.Increment(Provider.Results, LookbackPeriods, i).NaN2Null()); + Timestamp: item.Timestamp, + Sma: Sma.Increment(ProviderCache, LookbackPeriods, i).NaN2Null()); - // save and send - Motify(act, r, i); + return (r, i); } } diff --git a/src/s-z/Tr/Tr.StreamHub.cs b/src/s-z/Tr/Tr.StreamHub.cs index f1f768405..3d10f2e61 100644 --- a/src/s-z/Tr/Tr.StreamHub.cs +++ b/src/s-z/Tr/Tr.StreamHub.cs @@ -2,8 +2,8 @@ namespace Skender.Stock.Indicators; // TRUE RANGE (STREAM HUB) -public class TrHub : QuoteObserver, - IReusableHub +public class TrHub + : ChainProvider where TIn : IQuote { #region constructors @@ -21,28 +21,27 @@ internal TrHub(IQuoteProvider provider) public override string ToString() => hubName; - internal override void Add(Act act, TIn newIn, int? index) + protected override (TrResult result, int index) + ToIndicator(TIn item, int? indexHint) { - int i = index ?? Provider.GetIndex(newIn, false); + int i = indexHint ?? ProviderCache.GetIndex(item, true); // skip first period if (i == 0) { - Motify(act, new TrResult(newIn.Timestamp, null), i); - return; + return (new TrResult(item.Timestamp, null), i); } - TIn prev = Provider.Results[i - 1]; + TIn prev = ProviderCache[i - 1]; // candidate result TrResult r = new( - newIn.Timestamp, + item.Timestamp, Tr.Increment( - (double)newIn.High, - (double)newIn.Low, + (double)item.High, + (double)item.Low, (double)prev.Close)); - // save and send - Motify(act, r, i); + return (r, i); } } diff --git a/tests/application/Program.cs b/tests/application/Program.cs index 2b126c4ba..620267b46 100644 --- a/tests/application/Program.cs +++ b/tests/application/Program.cs @@ -206,7 +206,7 @@ private static void SendToConsole( /// private static void Timewarp(int quotesPerMinute = 0) { - if (quotesPerMinute is 0) + if (quotesPerMinute == 0) { return; } diff --git a/tests/indicators/TestBase.cs b/tests/indicators/TestBase.cs index 9a13fe65e..d0d11019f 100644 --- a/tests/indicators/TestBase.cs +++ b/tests/indicators/TestBase.cs @@ -6,9 +6,10 @@ [assembly: CLSCompliant(true)] [assembly: InternalsVisibleTo("Tests.Other")] // these use test data [assembly: InternalsVisibleTo("Tests.Performance")] +[assembly: Parallelize(Scope = ExecutionScope.MethodLevel)] + namespace Test.Data; -[TestClass] public abstract class TestBase // base for all tests { internal static readonly CultureInfo englishCulture = new("en-US", false); @@ -34,42 +35,32 @@ protected static readonly DateTime EvalDate /// /// Base tests that all series indicators should have. /// -[TestClass] public abstract class StaticSeriesTestBase : TestBase { - [TestMethod] public abstract void Standard(); - [TestMethod] public abstract void BadData(); - [TestMethod] public abstract void NoQuotes(); } /// /// Base tests that all static indicators (series) should have. /// -[TestClass] public abstract class IncrementsTestBase : TestBase { - [TestMethod] public abstract void FromQuote(); - [TestMethod] public abstract void FromQuoteBatch(); } /// /// Base tests that all streamed indicators should have. /// -[TestClass] public abstract class StreamHubTestBase : TestBase // default: quote observer { - [TestMethod] public abstract void QuoteObserver(); - [TestMethod] public abstract void CustomToString(); } @@ -78,7 +69,6 @@ public abstract class StreamHubTestBase : TestBase // default: quote observer /// public interface ITestChainObserver { - [TestMethod] void ChainObserver(); } @@ -87,6 +77,5 @@ public interface ITestChainObserver /// public interface ITestChainProvider { - [TestMethod] void ChainProvider(); } diff --git a/tests/indicators/Tests.Indicators.csproj b/tests/indicators/Tests.Indicators.csproj index 848adb9e2..7f6a08c48 100644 --- a/tests/indicators/Tests.Indicators.csproj +++ b/tests/indicators/Tests.Indicators.csproj @@ -14,11 +14,11 @@ - + - + all runtime; build; native; contentfiles; analyzers @@ -33,6 +33,7 @@ + Always diff --git a/tests/indicators/_common/Candles/Candles.StaticSeries.Tests.cs b/tests/indicators/_common/Candles/Candles.Tests.cs similarity index 100% rename from tests/indicators/_common/Candles/Candles.StaticSeries.Tests.cs rename to tests/indicators/_common/Candles/Candles.Tests.cs diff --git a/tests/indicators/_common/Generics/BinarySettingsTests.cs b/tests/indicators/_common/Generics/BinarySettingsTests.cs new file mode 100644 index 000000000..aa2b01b78 --- /dev/null +++ b/tests/indicators/_common/Generics/BinarySettingsTests.cs @@ -0,0 +1,73 @@ +namespace Utilities; + +[TestClass] +public class BinarySettingsTests : TestBase +{ + // see Renko Hub tests for inheritance + + [TestMethod] + public void InitializationDefault() + { + BinarySettings sut = new(); + sut.Settings.Should().Be(0); + sut.Mask.Should().Be(0b11111111); + } + + [TestMethod] + public void InitializationPartial() + { + BinarySettings sut = new(0); + sut.Settings.Should().Be(0); + sut.Mask.Should().Be(0b11111111); + } + + [TestMethod] + public void InitializationCustom() + { + BinarySettings sut = new(0b10101010, 0b11001100); + sut.Settings.Should().Be(0b10101010); + sut.Mask.Should().Be(0b11001100); + } + + [TestMethod] + public void AccessBit() + { + BinarySettings sut = new(0b00010001); + + // positions: 76543210 + sut[0].Should().BeTrue(); + sut[1].Should().BeFalse(); + sut[2].Should().BeFalse(); + sut[3].Should().BeFalse(); + sut[4].Should().BeTrue(); + sut[5].Should().BeFalse(); + sut[6].Should().BeFalse(); + sut[7].Should().BeFalse(); + } + + [TestMethod] + public void CombineDefaultMask() + { + BinarySettings srcSettings = new(0b01101001); + BinarySettings defSettings = new(0b00000010); + BinarySettings newSettings = defSettings.Combine(srcSettings); + newSettings.Settings.Should().Be(0b01101011); + } + + [TestMethod] + public void CombineCustomMask() + { + BinarySettings srcSettings = new(0b01101001, 0b11111110); + BinarySettings defSettings = new(0b00000010); + BinarySettings newSettings = defSettings.Combine(srcSettings); + newSettings.Settings.Should().Be(0b01101010); + } + + [TestMethod] + public void Equality() + { + BinarySettings sut = new(); + Assert.AreEqual(0b00000000, sut.Settings); + Assert.AreEqual(0b11111111, sut.Mask); + } +} diff --git a/tests/indicators/_common/Generics/RemoveWarmup.StaticSeries.Tests.cs b/tests/indicators/_common/Generics/RemoveWarmup.Tests.cs similarity index 100% rename from tests/indicators/_common/Generics/RemoveWarmup.StaticSeries.Tests.cs rename to tests/indicators/_common/Generics/RemoveWarmup.Tests.cs diff --git a/tests/indicators/_common/Generics/Sorting.StaticSeries.Tests.cs b/tests/indicators/_common/Generics/Sorting.Tests.cs similarity index 100% rename from tests/indicators/_common/Generics/Sorting.StaticSeries.Tests.cs rename to tests/indicators/_common/Generics/Sorting.Tests.cs diff --git a/tests/indicators/_common/Generics/Transforms.StaticSeries.Tests.cs b/tests/indicators/_common/Generics/Transforms.Tests.cs similarity index 89% rename from tests/indicators/_common/Generics/Transforms.StaticSeries.Tests.cs rename to tests/indicators/_common/Generics/Transforms.Tests.cs index f6105ea87..60a8da66b 100644 --- a/tests/indicators/_common/Generics/Transforms.StaticSeries.Tests.cs +++ b/tests/indicators/_common/Generics/Transforms.Tests.cs @@ -14,7 +14,7 @@ public void ToCollection() Assert.IsNotNull(collection); Assert.AreEqual(502, collection.Count); - Assert.AreEqual(collection.LastOrDefault().Close, 245.28m); + Assert.AreEqual(245.28m, collection.LastOrDefault().Close); } // null ToCollection diff --git a/tests/indicators/_common/Math/Numerical.StaticSeries.Tests.cs b/tests/indicators/_common/Math/Numerical.Tests.cs similarity index 75% rename from tests/indicators/_common/Math/Numerical.StaticSeries.Tests.cs rename to tests/indicators/_common/Math/Numerical.Tests.cs index 8863435ae..4f0e1f939 100644 --- a/tests/indicators/_common/Math/Numerical.StaticSeries.Tests.cs +++ b/tests/indicators/_common/Math/Numerical.Tests.cs @@ -7,8 +7,8 @@ public class Numericals : TestBase .Select(x => (double)x.Close) .ToArray(); - private readonly double[] _x = [1, 2, 3, 4, 5]; - private readonly double[] _y = [0, 0, 0, 0]; + private readonly double[] _x = { 1, 2, 3, 4, 5 }; + private readonly double[] _y = { 0, 0, 0, 0 }; [TestMethod] public void StdDev() @@ -19,8 +19,10 @@ public void StdDev() } [TestMethod] - [ExpectedException(typeof(ArgumentNullException), "Null parameter.")] - public void StdDevNull() => Numerical.StdDev(null); + public void StdDevNull() + { + Assert.ThrowsException(() => Numerical.StdDev(null)); + } [TestMethod] public void Slope() @@ -31,16 +33,22 @@ public void Slope() } [TestMethod] - [ExpectedException(typeof(ArgumentNullException), "Null X parameter.")] - public void SlopeXnull() => Numerical.Slope(null, _x); + public void SlopeXnull() + { + Assert.ThrowsException(() => Numerical.Slope(null, _x)); + } [TestMethod] - [ExpectedException(typeof(ArgumentNullException), "Null Y parameter.")] - public void SlopeYnull() => Numerical.Slope(_x, null); + public void SlopeYnull() + { + Assert.ThrowsException(() => Numerical.Slope(_x, null)); + } [TestMethod] - [ExpectedException(typeof(ArgumentException), "X and Y different lengths.")] - public void SlopeMismatch() => Numerical.Slope(_x, _y); + public void SlopeMismatch() + { + Assert.ThrowsException(() => Numerical.Slope(_x, _y)); + } [TestMethod] public void RoundDownDate() diff --git a/tests/indicators/_common/Observables/Cache.Manager.StaticSeries.Tests.cs b/tests/indicators/_common/Observables/StreamHub.CacheMgmt.Tests.cs similarity index 93% rename from tests/indicators/_common/Observables/Cache.Manager.StaticSeries.Tests.cs rename to tests/indicators/_common/Observables/StreamHub.CacheMgmt.Tests.cs index 429172cad..2ebd45acf 100644 --- a/tests/indicators/_common/Observables/Cache.Manager.StaticSeries.Tests.cs +++ b/tests/indicators/_common/Observables/StreamHub.CacheMgmt.Tests.cs @@ -52,7 +52,7 @@ public void ActAddOld() // late arrival } // add late - provider.Add(Quotes[100]); + provider.Insert(Quotes[100]); // assert same as original for (int i = 0; i < length; i++) @@ -62,7 +62,7 @@ public void ActAddOld() // late arrival // compare quote to result cache r.Timestamp.Should().Be(q.Timestamp); - r.Value.Should().Be((double)q.Close); + r.Value.Should().Be(q.Value); } // close observations @@ -98,7 +98,7 @@ public void Overflowing() observer.Results.Should().HaveCount(1); provider.IsFaulted.Should().BeFalse(); provider.OverflowCount.Should().Be(100); - provider.HasSubscribers.Should().BeTrue(); + provider.HasObservers.Should().BeTrue(); provider.EndTransmission(); } @@ -135,7 +135,7 @@ public void OverflowedAndReset() observer.Results.Should().HaveCount(1); provider.IsFaulted.Should().BeTrue(); provider.OverflowCount.Should().Be(101); - provider.HasSubscribers.Should().BeFalse(); + provider.HasObservers.Should().BeTrue(); // act: reset @@ -152,7 +152,7 @@ public void OverflowedAndReset() observer.Results.Should().HaveCount(1); provider.IsFaulted.Should().BeFalse(); provider.OverflowCount.Should().Be(100); - provider.HasSubscribers.Should().BeFalse(); // expected + provider.HasObservers.Should().BeTrue(); // not lost provider.EndTransmission(); } diff --git a/tests/indicators/_common/Observables/StreamProvider.StaticSeries.Tests.cs b/tests/indicators/_common/Observables/StreamHub.Observable.Tests.cs similarity index 84% rename from tests/indicators/_common/Observables/StreamProvider.StaticSeries.Tests.cs rename to tests/indicators/_common/Observables/StreamHub.Observable.Tests.cs index af8fedb6c..8dcb6f73c 100644 --- a/tests/indicators/_common/Observables/StreamProvider.StaticSeries.Tests.cs +++ b/tests/indicators/_common/Observables/StreamHub.Observable.Tests.cs @@ -1,7 +1,7 @@ namespace Observables; [TestClass] -public class StreamProviders : TestBase, ITestChainProvider +public class StreamObservables : TestBase, ITestChainProvider { [TestMethod] public void Prefill() @@ -49,32 +49,32 @@ QuotePartHub observer = provider.ToQuotePart(CandlePart.OHLC4); // assert: subscribed - provider.SubscriberCount.Should().Be(1); - provider.HasSubscribers.Should().BeTrue(); + provider.ObserverCount.Should().Be(1); + provider.HasObservers.Should().BeTrue(); observer.IsSubscribed.Should().BeTrue(); // act: unsubscribe observer.Unsubscribe(); // assert: not subscribed - provider.SubscriberCount.Should().Be(0); - provider.HasSubscribers.Should().BeFalse(); + provider.ObserverCount.Should().Be(0); + provider.HasObservers.Should().BeFalse(); observer.IsSubscribed.Should().BeFalse(); // act: resubscribe provider.Subscribe(observer); // assert: subscribed - provider.SubscriberCount.Should().Be(1); - provider.HasSubscribers.Should().BeTrue(); + provider.ObserverCount.Should().Be(1); + provider.HasObservers.Should().BeTrue(); observer.IsSubscribed.Should().BeTrue(); // act: end all subscriptions provider.EndTransmission(); // assert: not subscribed - provider.SubscriberCount.Should().Be(0); - provider.HasSubscribers.Should().BeFalse(); + provider.ObserverCount.Should().Be(0); + provider.HasObservers.Should().BeFalse(); observer.IsSubscribed.Should().BeFalse(); } diff --git a/tests/indicators/_common/Observables/StreamObserver.StaticSeries.Tests.cs b/tests/indicators/_common/Observables/StreamHub.Observer.Tests.cs similarity index 91% rename from tests/indicators/_common/Observables/StreamObserver.StaticSeries.Tests.cs rename to tests/indicators/_common/Observables/StreamHub.Observer.Tests.cs index d0a914a18..794749b3b 100644 --- a/tests/indicators/_common/Observables/StreamObserver.StaticSeries.Tests.cs +++ b/tests/indicators/_common/Observables/StreamHub.Observer.Tests.cs @@ -37,20 +37,20 @@ IReadOnlyList quotesList Quote q1000modified = quotesList[1000] with { Close = 12345m }; QuotePart r1000modified = q1000modified.ToQuotePart(CandlePart.Close); - observer.Modify(r1000modified); // add directly to observer + observer.Cache.Insert(1000, r1000modified); // add directly to cache IReadOnlyList modified = observer.Results.ToList(); // precondition: prefilled, modified provider.Cache.Should().HaveCount(length); - observer.Cache.Should().HaveCount(length); + observer.Cache.Should().HaveCount(length + 1); observer.Cache[1000].Value.Should().Be(12345); observer.Cache.Should().NotBeEquivalentTo(original); observer.Cache.Should().BeEquivalentTo(modified); // act: Rebuild() - observer.RebuildCache(); + observer.Rebuild(); // assert: restored to original observer.Results.Should().HaveCount(length); diff --git a/tests/indicators/_common/Observables/Stackoverflow.StaticSeries.Tests.cs b/tests/indicators/_common/Observables/StreamHub.Stackoverflow.Tests.cs similarity index 79% rename from tests/indicators/_common/Observables/Stackoverflow.StaticSeries.Tests.cs rename to tests/indicators/_common/Observables/StreamHub.Stackoverflow.Tests.cs index 8409d1b32..0452f5f96 100644 --- a/tests/indicators/_common/Observables/Stackoverflow.StaticSeries.Tests.cs +++ b/tests/indicators/_common/Observables/StreamHub.Stackoverflow.Tests.cs @@ -12,16 +12,16 @@ public void FatLongStack() int qtyQuotes = 20000; // setup: many random quotes (massive) - IReadOnlyList quotesList - = Data.GetRandom(qtyQuotes); + IReadOnlyList quotesList = Data.GetRandom(qtyQuotes); QuoteHub provider = new(); // setup: define ~10 subscribers (flat) - List<(string label, IEnumerable results, bool irregular)> subscribers - = new() { - HubRef(provider.ToAdl()), - HubRef(provider.ToEma(14)) }; + List<(string label, IEnumerable results, bool irregular)> subscribers = new() + { + HubRef(provider.ToAdl()), + HubRef(provider.ToEma(14)) + }; // all USEs foreach (CandlePart candlePart in Enum.GetValues()) @@ -35,9 +35,7 @@ IReadOnlyList quotesList provider.Add(quotesList[i]); } - subscribers.Insert(0, new( - provider.ToString(), - provider.Quotes.Cast(), false)); + subscribers.Insert(0, new(provider.ToString(), provider.Quotes.Cast(), false)); // assert: this just has to not fail, really @@ -45,49 +43,37 @@ IReadOnlyList quotesList Console.WriteLine("--------------------"); // assert: all non-irregular subscribers have the same count - foreach ((string label, IEnumerable results, bool irregular) - in subscribers) + foreach ((string label, IEnumerable results, bool irregular) in subscribers) { int resultQty = results.Count(); - Console.WriteLine($"Hub: {resultQty} - {label}"); - if (irregular) { continue; } - resultQty.Should().Be(qtyQuotes); } // assert: [last subscriber] has the same dates - - IReadOnlyList lastSubscriber - = subscribers[^1].results.ToList(); - + IReadOnlyList lastSubscriber = subscribers[^1].results.ToList(); for (int i = 0; i < qtyQuotes; i++) { Quote q = quotesList[i]; ISeries r = lastSubscriber[i]; - r.Timestamp.Should().Be(q.Timestamp); } // act: clear provider cache (cascades to subscribers) int cutoff = qtyQuotes / 2; - provider.ClearCache(cutoff); + provider.RemoveRange(cutoff, notify: true); provider.Quotes.Count.Should().Be(cutoff); Console.WriteLine("--------------------"); // assert: all have same count - foreach ((string label, IEnumerable results, bool irregular) - in subscribers) + foreach ((string label, IEnumerable results, bool irregular) in subscribers) { int resultQty = results.Count(); - Console.WriteLine($"Cut: {resultQty} - {label}"); - if (irregular) { continue; } - resultQty.Should().Be(cutoff); } } @@ -103,14 +89,12 @@ public void ManyChainDepths() int chainDepth = 500; // setup: many random quotes (massive) - IReadOnlyList quotesList - = Data.GetRandom(qtyQuotes); + IReadOnlyList quotesList = Data.GetRandom(qtyQuotes); QuoteHub provider = new(); // setup: subscribe a large chain depth - List<(string label, IEnumerable results, bool irregular)> subscribers - = new(chainDepth + 2); + List<(string label, IEnumerable results, bool irregular)> subscribers = new(chainDepth + 2); SmaHub init = provider.ToSma(1); SmaHub sma = init.ToSma(2); @@ -135,9 +119,7 @@ IReadOnlyList quotesList provider.Add(quotesList[i]); } - subscribers.Insert(0, - new(provider.ToString(), - provider.Quotes.Cast(), false)); + subscribers.Insert(0, new(provider.ToString(), provider.Quotes.Cast(), false)); Console.WriteLine($"Subscribers: {subscribers.Count}"); Console.WriteLine("--------------------"); @@ -145,8 +127,7 @@ IReadOnlyList quotesList // assert: this just has to not fail, really // assert: all non-irregular subscribers have the same count - foreach ((string label, IEnumerable results, bool irregular) - in subscribers) + foreach ((string label, IEnumerable results, bool irregular) in subscribers) { int resultQty = results.Count(); Console.WriteLine($"Hub: {resultQty} - {label}"); @@ -155,37 +136,26 @@ IReadOnlyList quotesList } // assert: [last subscriber] has the same dates - - IReadOnlyList lastSubscriber - = subscribers[^1].results.ToList(); - + IReadOnlyList lastSubscriber = subscribers[^1].results.ToList(); for (int i = 0; i < qtyQuotes; i++) { Quote q = quotesList[i]; ISeries r = lastSubscriber[i]; - r.Timestamp.Should().Be(q.Timestamp); } // act: clear provider cache (cascades to subscribers) int cutoff = qtyQuotes / 2; - provider.ClearCache(cutoff); + provider.RemoveRange(cutoff, notify: true); provider.Quotes.Count.Should().Be(cutoff); // assert: all have same count - foreach ((string label, IEnumerable results, bool irregular) - in subscribers) + foreach ((string label, IEnumerable results, bool irregular) in subscribers) { int resultQty = results.Count(); - Console.WriteLine($"Cut: {resultQty} - {label}"); - - if (irregular) - { - continue; - } - + if (irregular) { continue; } resultQty.Should().Be(cutoff); } } @@ -200,21 +170,20 @@ public void ManySubscribers() int qtyQuotes = 5000; // setup: many random quotes - IReadOnlyList quotesList - = Data.GetRandom(qtyQuotes); + IReadOnlyList quotesList = Data.GetRandom(qtyQuotes); QuoteHub provider = new(); // setup: define all possible subscribers // TODO: add to this as more Hubs come online - List<(string label, IEnumerable results, bool irregular)> subscribers - = new() { - HubRef(provider.ToAdl()), - HubRef(provider.ToAlligator()), - HubRef(provider.ToEma(14)), - HubRef(provider.ToRenko(2.1m), irregular: true), - HubRef(provider.ToQuote()) - }; + List<(string label, IEnumerable results, bool irregular)> subscribers = new() + { + HubRef(provider.ToAdl()), + HubRef(provider.ToAlligator()), + HubRef(provider.ToEma(14)), + //HubRef(provider.ToRenko(2.1m), irregular: true), + HubRef(provider.ToQuote()) + }; // all QuoteParts foreach (CandlePart candlePart in Enum.GetValues()) @@ -234,9 +203,7 @@ IReadOnlyList quotesList provider.Add(quotesList[i]); } - subscribers.Insert(0, new( - provider.ToString(), - provider.Quotes.Cast(), false)); + subscribers.Insert(0, new(provider.ToString(), provider.Quotes.Cast(), false)); // assert: this just has to not fail, really @@ -244,49 +211,37 @@ IReadOnlyList quotesList Console.WriteLine("--------------------"); // assert: all non-irregular subscribers have the same count - foreach ((string label, IEnumerable results, bool irregular) - in subscribers) + foreach ((string label, IEnumerable results, bool irregular) in subscribers) { int resultQty = results.Count(); - Console.WriteLine($"Hub: {resultQty} - {label}"); - if (irregular) { continue; } - resultQty.Should().Be(qtyQuotes); } // assert: [last subscriber] has the same dates - - IReadOnlyList lastSubscriber - = subscribers[^1].results.ToList(); - + IReadOnlyList lastSubscriber = subscribers[^1].results.ToList(); for (int i = 0; i < qtyQuotes; i++) { Quote q = quotesList[i]; ISeries r = lastSubscriber[i]; - r.Timestamp.Should().Be(q.Timestamp); } // act: clear provider cache (cascades to subscribers) int cutoff = qtyQuotes / 2; - provider.ClearCache(cutoff); + provider.RemoveRange(cutoff, notify: true); provider.Quotes.Count.Should().Be(cutoff); Console.WriteLine("--------------------"); // assert: all have same count - foreach ((string label, IEnumerable results, bool irregular) - in subscribers) + foreach ((string label, IEnumerable results, bool irregular) in subscribers) { int resultQty = results.Count(); - Console.WriteLine($"Cut: {resultQty} - {label}"); - if (irregular) { continue; } - resultQty.Should().Be(cutoff); } } @@ -303,4 +258,3 @@ private static (string, IEnumerable, bool) HubRef( return (hub.ToString(), results, irregular); } } - diff --git a/tests/indicators/_common/Observables/Cache.Utilities.StaticSeries.Tests.cs b/tests/indicators/_common/Observables/StreamHub.Utilities.StaticSeries.Tests.cs similarity index 74% rename from tests/indicators/_common/Observables/Cache.Utilities.StaticSeries.Tests.cs rename to tests/indicators/_common/Observables/StreamHub.Utilities.StaticSeries.Tests.cs index 3030607a3..17e87a1dd 100644 --- a/tests/indicators/_common/Observables/Cache.Utilities.StaticSeries.Tests.cs +++ b/tests/indicators/_common/Observables/StreamHub.Utilities.StaticSeries.Tests.cs @@ -3,36 +3,6 @@ namespace Observables; [TestClass] public class CacheUtilities : TestBase { - [TestMethod] - public void ClearCache() - { - // setup quote provider - - List quotesList = Quotes - .ToSortedList() - .Take(10) - .ToList(); - - int length = quotesList.Count; - - QuoteHub provider = new(); - - QuotePartHub observer = provider - .ToQuotePart(CandlePart.Close); - - for (int i = 0; i < length; i++) - { - provider.Add(quotesList[i]); - } - - // act: clear cache - observer.ClearCache(); - - // assert: cache is empty - observer.Cache.Should().BeEmpty(); - provider.Cache.Should().HaveCount(10); - } - [TestMethod] public void ClearCacheByTimestamp() { @@ -58,7 +28,7 @@ public void ClearCacheByTimestamp() Quote q3 = quotesList[3]; // act: clear cache - observer.ClearCache(q3.Timestamp); + observer.RemoveRange(q3.Timestamp, notify: false); // assert: cache is empty observer.Cache.Should().HaveCount(3); @@ -79,7 +49,6 @@ List cacheUndr [TestMethod] public void ClearCacheByIndex() { - // setup quote provider List quotesList = Quotes @@ -102,7 +71,7 @@ public void ClearCacheByIndex() Quote q3 = quotesList[3]; // act: clear cache - observer.ClearCache(3); + observer.RemoveRange(3, notify: true); // assert: cache is empty observer.Cache.Should().HaveCount(3); @@ -141,8 +110,8 @@ public void GetIndex() // find position of quote Quote q = quotesList[4]; - int itemIndexEx = provider.GetIndex(q, false); - int timeIndexEx = provider.GetIndex(q.Timestamp, false); + int itemIndexEx = provider.Cache.GetIndex(q, true); + int timeIndexEx = provider.Cache.GetIndex(q.Timestamp, true); // assert: same index itemIndexEx.Should().Be(4); @@ -152,22 +121,22 @@ public void GetIndex() Quote o = Quotes[10]; Assert.ThrowsException(() => { - provider.GetIndex(o, false); + provider.Cache.GetIndex(o, true); }); Assert.ThrowsException(() => { - provider.GetIndex(o.Timestamp, false); + provider.Cache.GetIndex(o.Timestamp, true); }); // out of range (no exceptions) - int itemIndexNo = provider.GetIndex(o, true); - int timeIndexNo = provider.GetIndex(o.Timestamp, true); + int itemIndexNo = provider.Cache.GetIndex(o, false); + int timeIndexNo = provider.Cache.GetIndex(o.Timestamp, false); itemIndexNo.Should().Be(-1); timeIndexNo.Should().Be(-1); - int timeInsertOut = provider.GetInsertIndex(o.Timestamp); - int timeInsertIn = provider.GetInsertIndex(quotesList[2].Timestamp); + int timeInsertOut = provider.Cache.GetIndexGte(o.Timestamp); + int timeInsertIn = provider.Cache.GetIndexGte(quotesList[2].Timestamp); timeInsertOut.Should().Be(-1); timeInsertIn.Should().Be(2); @@ -198,7 +167,7 @@ public void TryFindIndex() // act: find index of quote // assert: correct index - if (provider.TryFindIndex(q.Timestamp, out int goodIndex)) + if (provider.Cache.TryFindIndex(q.Timestamp, out int goodIndex)) { goodIndex.Should().Be(4); } @@ -208,7 +177,7 @@ public void TryFindIndex() } // assert: out of range - if (provider.TryFindIndex(DateTime.MaxValue, out int badIndex)) + if (provider.Cache.TryFindIndex(DateTime.MaxValue, out int badIndex)) { Assert.Fail("unexpected index found"); } diff --git a/tests/indicators/_common/Quotes/Quote.Aggregates.Tests.cs b/tests/indicators/_common/Quotes/Quote.Aggregates.Tests.cs index 23df6d46f..0f9a4b449 100644 --- a/tests/indicators/_common/Quotes/Quote.Aggregates.Tests.cs +++ b/tests/indicators/_common/Quotes/Quote.Aggregates.Tests.cs @@ -126,10 +126,8 @@ public void AggregateMonth() Assert.AreEqual(3173255968m, r23.Volume); } - [TestMethod] - [ExpectedException(typeof(ArgumentOutOfRangeException), "Bad aggregation size.")] - public void AggregateBadSize() => - - // bad period size - Quotes.Aggregate(TimeSpan.Zero); + [TestMethod] // bad period size + public void AggregateBadSize() + => Assert.ThrowsException(() + => Quotes.Aggregate(TimeSpan.Zero)); } diff --git a/tests/indicators/_common/Quotes/Quote.Exceptions.Tests.cs b/tests/indicators/_common/Quotes/Quote.Exceptions.Tests.cs index 986ff7d5b..48ba52573 100644 --- a/tests/indicators/_common/Quotes/Quote.Exceptions.Tests.cs +++ b/tests/indicators/_common/Quotes/Quote.Exceptions.Tests.cs @@ -5,17 +5,17 @@ namespace Utilities; public partial class Quotes : TestBase { [TestMethod] - [ExpectedException(typeof(InvalidQuotesException), "Bad quotes without message.")] public void InvalidQuotesExceptionThrow() - => throw new InvalidQuotesException(); + => Assert.ThrowsException(() + => throw new InvalidQuotesException()); [TestMethod] - [ExpectedException(typeof(InvalidQuotesException), "Bad quotes with message.")] public void InvalidQuotesExceptionThrowWithMessage() - => throw new InvalidQuotesException("This is a quotes exception."); + => Assert.ThrowsException(() + => throw new InvalidQuotesException("This is a quotes exception.")); [TestMethod] - [ExpectedException(typeof(InvalidQuotesException), "Bad quotes with inner Exception.")] public void InvalidQuotesExceptionThrowWithInner() - => throw new InvalidQuotesException("This has an inner Exception.", new ArgumentException()); + => Assert.ThrowsException(() + => throw new InvalidQuotesException("This has an inner Exception.", new ArgumentException())); } diff --git a/tests/indicators/_common/Quotes/Quote.Validation.Tests.cs b/tests/indicators/_common/Quotes/Quote.Validation.Tests.cs index a704ed382..2dcc1d0aa 100644 --- a/tests/indicators/_common/Quotes/Quote.Validation.Tests.cs +++ b/tests/indicators/_common/Quotes/Quote.Validation.Tests.cs @@ -76,18 +76,17 @@ public void ValidateCut() /* BAD QUOTES EXCEPTIONS */ [TestMethod] - [ExpectedException(typeof(InvalidQuotesException), "Duplicate date found.")] public void ValidateDuplicates() { - IReadOnlyList badHistory = - [ + IReadOnlyList badHistory = new List + { new(Timestamp: DateTime.ParseExact("2017-01-03", "yyyy-MM-dd", englishCulture), Open: 214.86m, High: 220.33m, Low: 210.96m, Close: 216.99m, Volume: 5923254), new(Timestamp: DateTime.ParseExact("2017-01-04", "yyyy-MM-dd", englishCulture), Open: 214.75m, High: 228.00m, Low: 214.31m, Close: 226.99m, Volume: 11213471), new(Timestamp: DateTime.ParseExact("2017-01-05", "yyyy-MM-dd", englishCulture), Open: 226.42m, High: 227.48m, Low: 221.95m, Close: 226.75m, Volume: 5911695), new(Timestamp: DateTime.ParseExact("2017-01-06", "yyyy-MM-dd", englishCulture), Open: 226.93m, High: 230.31m, Low: 225.45m, Close: 229.01m, Volume: 5527893), new(Timestamp: DateTime.ParseExact("2017-01-06", "yyyy-MM-dd", englishCulture), Open: 228.97m, High: 231.92m, Low: 228.00m, Close: 231.28m, Volume: 3979484) - ]; + }; - badHistory.Validate(); + Assert.ThrowsException(() => badHistory.Validate()); } } diff --git a/tests/indicators/_common/Reusable/Reusable.Utilities.StaticSeries.Tests.cs b/tests/indicators/_common/Reusable/Reusable.Utilities.Tests.cs similarity index 98% rename from tests/indicators/_common/Reusable/Reusable.Utilities.StaticSeries.Tests.cs rename to tests/indicators/_common/Reusable/Reusable.Utilities.Tests.cs index c209a5871..14bda1648 100644 --- a/tests/indicators/_common/Reusable/Reusable.Utilities.StaticSeries.Tests.cs +++ b/tests/indicators/_common/Reusable/Reusable.Utilities.Tests.cs @@ -35,7 +35,7 @@ public void ToReusableList() Assert.IsNotNull(reusableList); Assert.AreEqual(502, reusableList.Count); - Assert.AreEqual(reusableList[^1].Value, 245.28d); + Assert.AreEqual(245.28d, reusableList[^1].Value); } [TestMethod] diff --git a/tests/indicators/_common/Use (QuotePart)/Use.StaticSeries.Tests.cs b/tests/indicators/_common/Use (QuotePart)/QuotePart.StaticSeries.Tests.cs similarity index 98% rename from tests/indicators/_common/Use (QuotePart)/Use.StaticSeries.Tests.cs rename to tests/indicators/_common/Use (QuotePart)/QuotePart.StaticSeries.Tests.cs index 8acf42ac5..3f879cd3c 100644 --- a/tests/indicators/_common/Use (QuotePart)/Use.StaticSeries.Tests.cs +++ b/tests/indicators/_common/Use (QuotePart)/QuotePart.StaticSeries.Tests.cs @@ -1,7 +1,7 @@ namespace StaticSeries; [TestClass] -public class Use : StaticSeriesTestBase +public class QuoteParts : StaticSeriesTestBase { [TestMethod] public override void Standard() diff --git a/tests/indicators/_common/Use (QuotePart)/QuotePart.StreamHub.Tests.cs b/tests/indicators/_common/Use (QuotePart)/QuotePart.StreamHub.Tests.cs index 4dc2ac8a1..f5b8a1405 100644 --- a/tests/indicators/_common/Use (QuotePart)/QuotePart.StreamHub.Tests.cs +++ b/tests/indicators/_common/Use (QuotePart)/QuotePart.StreamHub.Tests.cs @@ -50,7 +50,7 @@ IReadOnlyList streamList } // late arrival - provider.Add(quotesList[80]); + provider.Insert(quotesList[80]); // delete provider.Remove(quotesList[400]); diff --git a/tests/indicators/_common/Use (QuotePart)/QuotePart.Utilities.StaticSeries.Tests.cs b/tests/indicators/_common/Use (QuotePart)/QuotePart.Utilities.Tests.cs similarity index 100% rename from tests/indicators/_common/Use (QuotePart)/QuotePart.Utilities.StaticSeries.Tests.cs rename to tests/indicators/_common/Use (QuotePart)/QuotePart.Utilities.Tests.cs diff --git a/tests/indicators/a-d/Adl/Adl.StreamHub.Tests.cs b/tests/indicators/a-d/Adl/Adl.StreamHub.Tests.cs index 2714bae73..4554a8b83 100644 --- a/tests/indicators/a-d/Adl/Adl.StreamHub.Tests.cs +++ b/tests/indicators/a-d/Adl/Adl.StreamHub.Tests.cs @@ -48,7 +48,7 @@ IReadOnlyList streamList } // late arrival - provider.Add(quotesList[80]); + provider.Insert(quotesList[80]); // delete provider.Remove(quotesList[400]); @@ -69,7 +69,7 @@ IReadOnlyList streamList [TestMethod] public void ChainProvider() { - int smaPeriods = 8; + const int smaPeriods = 8; List quotesList = Quotes .ToSortedList(); @@ -80,7 +80,7 @@ public void ChainProvider() QuoteHub provider = new(); // initialize observer - IChainProvider adlHub = provider + AdlHub adlHub = provider .ToAdl(); SmaHub observer = adlHub diff --git a/tests/indicators/a-d/Alligator/Alligator.StreamHub.Tests.cs b/tests/indicators/a-d/Alligator/Alligator.StreamHub.Tests.cs index f88c3b7ef..5d9ce4f3a 100644 --- a/tests/indicators/a-d/Alligator/Alligator.StreamHub.Tests.cs +++ b/tests/indicators/a-d/Alligator/Alligator.StreamHub.Tests.cs @@ -48,7 +48,7 @@ IReadOnlyList streamList } // late arrival - provider.Add(quotesList[80]); + provider.Insert(quotesList[80]); // delete provider.Remove(quotesList[400]); @@ -104,7 +104,7 @@ public void ChainObserver() } // late arrival - provider.Add(quotesList[80]); + provider.Insert(quotesList[80]); // delete provider.Remove(quotesList[400]); diff --git a/tests/indicators/a-d/Atr/Atr.StreamHub.Tests.cs b/tests/indicators/a-d/Atr/Atr.StreamHub.Tests.cs index 43374ed83..f05843c9a 100644 --- a/tests/indicators/a-d/Atr/Atr.StreamHub.Tests.cs +++ b/tests/indicators/a-d/Atr/Atr.StreamHub.Tests.cs @@ -48,7 +48,7 @@ IReadOnlyList streamList } // late arrival - provider.Add(quotesList[80]); + provider.Insert(quotesList[80]); // delete provider.Remove(quotesList[400]); diff --git a/tests/indicators/a-d/AtrStop/AtrStop.StreamHub.Tests.cs b/tests/indicators/a-d/AtrStop/AtrStop.StreamHub.Tests.cs index 404a402b7..8beda6360 100644 --- a/tests/indicators/a-d/AtrStop/AtrStop.StreamHub.Tests.cs +++ b/tests/indicators/a-d/AtrStop/AtrStop.StreamHub.Tests.cs @@ -47,8 +47,8 @@ IReadOnlyList streamList } // late arrivals - provider.Add(quotesList[30]); // rebuilds complete series - provider.Add(quotesList[80]); // rebuilds from last reversal + provider.Insert(quotesList[30]); // rebuilds complete series + provider.Insert(quotesList[80]); // rebuilds from last reversal // delete provider.Remove(quotesList[400]); diff --git a/tests/indicators/e-k/Ema/Ema.Increments.Tests.cs b/tests/indicators/e-k/Ema/Ema.Increments.Tests.cs index 275aa31f0..8563b9bb0 100644 --- a/tests/indicators/e-k/Ema/Ema.Increments.Tests.cs +++ b/tests/indicators/e-k/Ema/Ema.Increments.Tests.cs @@ -26,7 +26,7 @@ private static readonly IReadOnlyList series [TestMethod] public void FromReusableSplit() { - EmaInc sut = new(lookbackPeriods); + EmaList sut = new(lookbackPeriods); foreach (IReusable item in reusables) { @@ -40,7 +40,7 @@ public void FromReusableSplit() [TestMethod] public void FromReusableItem() { - EmaInc sut = new(lookbackPeriods); + EmaList sut = new(lookbackPeriods); foreach (IReusable item in reusables) { sut.Add(item); } @@ -51,7 +51,7 @@ public void FromReusableItem() [TestMethod] public void FromReusableBatch() { - EmaInc sut = new(lookbackPeriods) { reusables }; + EmaList sut = new(lookbackPeriods) { reusables }; sut.Should().HaveCount(Quotes.Count); sut.Should().BeEquivalentTo(series); @@ -60,7 +60,7 @@ public void FromReusableBatch() [TestMethod] public override void FromQuote() { - EmaInc sut = new(lookbackPeriods); + EmaList sut = new(lookbackPeriods); foreach (Quote q in Quotes) { sut.Add(q); } @@ -71,7 +71,7 @@ public override void FromQuote() [TestMethod] public override void FromQuoteBatch() { - EmaInc sut = new(lookbackPeriods) { Quotes }; + EmaList sut = new(lookbackPeriods) { Quotes }; IReadOnlyList series = Quotes.ToEma(lookbackPeriods); diff --git a/tests/indicators/e-k/Ema/Ema.StreamHub.Tests.cs b/tests/indicators/e-k/Ema/Ema.StreamHub.Tests.cs index 552b2f2e7..c0216ef6b 100644 --- a/tests/indicators/e-k/Ema/Ema.StreamHub.Tests.cs +++ b/tests/indicators/e-k/Ema/Ema.StreamHub.Tests.cs @@ -48,7 +48,7 @@ IReadOnlyList streamList } // late arrival - provider.Add(quotesList[80]); + provider.Insert(quotesList[80]); // delete provider.Remove(quotesList[400]); @@ -148,7 +148,7 @@ public void ChainProvider() } // late arrival - provider.Add(quotesList[80]); + provider.Insert(quotesList[80]); // delete provider.Remove(quotesList[400]); diff --git a/tests/indicators/m-r/Renko/Renko.StreamHub.Tests.cs b/tests/indicators/m-r/Renko/Renko.StreamHub.Tests.cs index 287cc469e..b0e7832b8 100644 --- a/tests/indicators/m-r/Renko/Renko.StreamHub.Tests.cs +++ b/tests/indicators/m-r/Renko/Renko.StreamHub.Tests.cs @@ -7,7 +7,7 @@ public class RenkoHub : StreamHubTestBase, ITestChainProvider public override void QuoteObserver() { decimal brickSize = 2.5m; - EndType endType = EndType.Close; + EndType endType = EndType.HighLow; List quotesList = Quotes .ToSortedList(); @@ -51,7 +51,7 @@ IReadOnlyList streamList } // late arrival - provider.Add(quotesList[80]); + provider.Insert(quotesList[80]); // delete provider.Remove(quotesList[400]); @@ -62,8 +62,8 @@ IReadOnlyList streamList .GetRenko(brickSize, endType); // assert, should equal series - streamList.Should().HaveCount(112); streamList.Should().BeEquivalentTo(seriesList); + streamList.Should().HaveCount(159); observer.Unsubscribe(); provider.EndTransmission(); @@ -74,7 +74,7 @@ public void ChainProvider() { decimal brickSize = 2.5m; EndType endType = EndType.Close; - int smaPeriods = 8; + int smaPeriods = 50; List quotesList = Quotes .ToSortedList(); @@ -109,8 +109,8 @@ IReadOnlyList streamList .GetSma(smaPeriods); // assert, should equal series - streamList.Should().HaveCount(112); streamList.Should().BeEquivalentTo(seriesList); + streamList.Should().HaveCount(112); observer.Unsubscribe(); provider.EndTransmission(); @@ -122,4 +122,28 @@ public override void CustomToString() RenkoHub hub = new(new QuoteHub(), 2.5m, EndType.Close); hub.ToString().Should().Be("RENKO(2.5,CLOSE)"); } + + [TestMethod] + public void SettingsInheritance() + { + // setup quote hub (1st level) + QuoteHub quoteHub = new(); + + // setup renko hub (2nd level) + RenkoHub renkoHub = quoteHub + .ToRenko(brickSize: 2.5m, endType: EndType.Close); + + // setup child hub (3rd level) + SmaHub childHub = renkoHub + .ToSma(lookbackPeriods: 5); + + // note: dispite `quoteHub` being parentless, + // it has default properties; it should not + // inherit its own empty provider settings + + // assert + quoteHub.Properties.Settings.Should().Be(0b00000000, "is has default settings, not inherited"); + renkoHub.Properties.Settings.Should().Be(0b00000010, "it has custom Renko properties"); + childHub.Properties.Settings.Should().Be(0b00000010, "it inherits Renko properties"); + } } diff --git a/tests/indicators/s-z/Sma/Sma.StreamHub.Tests.cs b/tests/indicators/s-z/Sma/Sma.StreamHub.Tests.cs index 939d3ee52..1934a0f4c 100644 --- a/tests/indicators/s-z/Sma/Sma.StreamHub.Tests.cs +++ b/tests/indicators/s-z/Sma/Sma.StreamHub.Tests.cs @@ -48,7 +48,7 @@ IReadOnlyList streamList } // late arrival - provider.Add(quotesList[80]); + provider.Insert(quotesList[80]); // delete provider.Remove(quotesList[400]); diff --git a/tests/indicators/s-z/Tr/Tr.StreamHub.Tests.cs b/tests/indicators/s-z/Tr/Tr.StreamHub.Tests.cs index 86ac56307..82c802a19 100644 --- a/tests/indicators/s-z/Tr/Tr.StreamHub.Tests.cs +++ b/tests/indicators/s-z/Tr/Tr.StreamHub.Tests.cs @@ -48,7 +48,7 @@ IReadOnlyList streamList } // late arrival - provider.Add(quotesList[80]); + provider.Insert(quotesList[80]); // delete provider.Remove(quotesList[400]); diff --git a/tests/other/PublicApi.Interface.Tests.cs b/tests/other/PublicApi.Interface.Tests.cs index 0ec736e34..d623cef08 100644 --- a/tests/other/PublicApi.Interface.Tests.cs +++ b/tests/other/PublicApi.Interface.Tests.cs @@ -1,4 +1,6 @@ [assembly: CLSCompliant(true)] +[assembly: Parallelize(Scope = ExecutionScope.MethodLevel)] + namespace PublicApi; // PUBLIC API (INTERFACES) @@ -78,7 +80,7 @@ public void StreamMany() // from quote provider } // late arrival - provider.Add(quotes[80]); + provider.Insert(quotes[80]); // end all observations provider.EndTransmission(); diff --git a/tests/other/Tests.Other.csproj b/tests/other/Tests.Other.csproj index 16b67ebc4..7d31c15e1 100644 --- a/tests/other/Tests.Other.csproj +++ b/tests/other/Tests.Other.csproj @@ -14,9 +14,9 @@ - + - + all runtime; build; native; contentfiles; analyzers diff --git a/tests/performance/Perf.Increments.cs b/tests/performance/Perf.Increments.cs index 51c83e466..a4917ea40 100644 --- a/tests/performance/Perf.Increments.cs +++ b/tests/performance/Perf.Increments.cs @@ -12,7 +12,7 @@ private static readonly List quotesList = quotes .ToSortedList(); - private static readonly double[] primatives + private static readonly double[] primitives = quotes .Select(x => x.Value) .ToArray(); @@ -31,20 +31,20 @@ private static readonly IReadOnlyList reusables public void Cleanup() { provider.EndTransmission(); - provider.ClearCache(); + provider.Cache.Clear(); } [Benchmark] public object EmaIncRusBatch() { - EmaInc sut = new(14) { reusables }; + EmaList sut = new(14) { reusables }; return sut; } [Benchmark] public object EmaIncRusItem() { - EmaInc sut = new(14); + EmaList sut = new(14); for (int i = 0; i < reusables.Count; i++) { @@ -57,7 +57,7 @@ public object EmaIncRusItem() [Benchmark] public object EmaIncRusSplit() { - EmaInc sut = new(14); + EmaList sut = new(14); for (int i = 0; i < reusables.Count; i++) { @@ -70,14 +70,14 @@ public object EmaIncRusSplit() [Benchmark] public object EmaIncQotBatch() { - EmaInc sut = new(14) { quotes }; + EmaList sut = new(14) { quotes }; return sut; } [Benchmark] public object EmaIncQot() { - EmaInc sut = new(14); + EmaList sut = new(14); for (int i = 0; i < quotes.Count; i++) { @@ -90,7 +90,7 @@ public object EmaIncQot() [Benchmark] public object EmaIncPrmBatch() { - EmaIncPrimitive sut = new(14) { primatives }; + EmaIncPrimitive sut = new(14) { primitives }; return sut; } @@ -99,9 +99,9 @@ public object EmaIncPrm() { EmaIncPrimitive sut = new(14); - for (int i = 0; i < primatives.Length; i++) + for (int i = 0; i < primitives.Length; i++) { - sut.Add(primatives[i]); + sut.Add(primitives[i]); } return sut; @@ -109,7 +109,7 @@ public object EmaIncPrm() // TIME-SERIES EQUIVALENTS - [Benchmark(Baseline = true)] + [Benchmark] public object EmaSeriesEqiv() => quotesList.CalcEma(14); [Benchmark] @@ -118,10 +118,37 @@ public object EmaIncPrm() [Benchmark] public object EmaIncremEqiv() { - EmaInc ema = new(14) { quotes.ToSortedList() }; + EmaList ema = new(14) { quotes.ToSortedList() }; return ema; } [Benchmark] public object EmaStreamEqiv() => provider.ToEma(14).Results; + + [Benchmark] + public object SmaArrOrig() + { + int periods = 20; + double[] results = new double[primitives.Length]; + + for (int i = 0; i < primitives.Length; i++) + { + if (i < periods - 1) + { + results[i] = double.NaN; + continue; + } + + double sum = 0; + for (int w = i - periods + 1; w <= i; w++) + { + sum += primitives[i]; + } + results[i] = sum / periods; + } + return results; + } + + [Benchmark] + public object SmaArrSimd() => primitives.CalcSma(20); } diff --git a/tests/performance/Perf.StreamHub.Externals.cs b/tests/performance/Perf.StreamHub.Externals.cs index befa94676..3a2dd4eb0 100644 --- a/tests/performance/Perf.StreamHub.Externals.cs +++ b/tests/performance/Perf.StreamHub.Externals.cs @@ -27,7 +27,7 @@ private static readonly IReadOnlyList quotes public void Cleanup() { provider.EndTransmission(); - provider.ClearCache(); + provider.Cache.Clear(); } // BENCHMARKS diff --git a/tests/performance/Perf.StreamHub.cs b/tests/performance/Perf.StreamHub.cs index e0892cc03..6ad618641 100644 --- a/tests/performance/Perf.StreamHub.cs +++ b/tests/performance/Perf.StreamHub.cs @@ -8,7 +8,8 @@ public class StreamIndicators private static readonly IReadOnlyList quotes = Data.GetDefault(); - private readonly QuoteHub provider = new(); + private readonly QuoteHub provider = new(); // prepopulated + private readonly QuoteHub supplier = new(); // empty /* SETUP/CLEANUP - runs before and after each. * @@ -27,7 +28,7 @@ private static readonly IReadOnlyList quotes public void Cleanup() { provider.EndTransmission(); - provider.ClearCache(); + provider.Cache.Clear(); } // BENCHMARKS @@ -47,6 +48,19 @@ public void Cleanup() [Benchmark] public object EmaHub() => provider.ToEma(14).Results; + [Benchmark] + public object EmaHub2() + { + EmaHub observer = supplier.ToEma(14); + + for (int i = 0; i < quotes.Count; i++) + { + observer.OnAdd(quotes[i], notify: false, i); + } + + return observer.Results; + } + [Benchmark] public object QuoteHub() => provider.ToQuote().Results; diff --git a/tests/performance/Tests.Performance.csproj b/tests/performance/Tests.Performance.csproj index a610fde50..43bc26589 100644 --- a/tests/performance/Tests.Performance.csproj +++ b/tests/performance/Tests.Performance.csproj @@ -5,6 +5,10 @@ Exe Performance.Program + false + None + true + enable true From 8b02491a5a874c0fbb8962cc618a51467e1b93fa Mon Sep 17 00:00:00 2001 From: Dave Skender <8432125+DaveSkender@users.noreply.github.com> Date: Wed, 9 Oct 2024 20:18:27 -0400 Subject: [PATCH 19/38] minor static EMA edits --- src/e-k/Ema/Ema.Api.cs | 6 +++--- src/e-k/Ema/Ema.StaticSeries.cs | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/e-k/Ema/Ema.Api.cs b/src/e-k/Ema/Ema.Api.cs index 4958e959d..d579e3375 100644 --- a/src/e-k/Ema/Ema.Api.cs +++ b/src/e-k/Ema/Ema.Api.cs @@ -6,9 +6,9 @@ public static partial class Api { //SERIES, from CHAIN public static IReadOnlyList ToEma( - // FIX: "GetEma" or "ToEma"? - // No longer works as extension method. - // Related to "Api" vs "Ema" namespace. + + // FIX: Use "Ema" instead of "Api" class name (fails). + this IEnumerable results, int lookbackPeriods) where T : IReusable diff --git a/src/e-k/Ema/Ema.StaticSeries.cs b/src/e-k/Ema/Ema.StaticSeries.cs index 081784321..0db8863db 100644 --- a/src/e-k/Ema/Ema.StaticSeries.cs +++ b/src/e-k/Ema/Ema.StaticSeries.cs @@ -27,11 +27,11 @@ internal static List CalcEma( // skip incalculable periods if (i < lookbackPeriods - 1) { - results[i] = new(Timestamp: s.Timestamp); + results[i] = new EmaResult(Timestamp: s.Timestamp); continue; } - double ema = results[i - 1].Ema is not null + double ema = !double.IsNaN(lastEma) // calculate EMA (normally) ? Ema.Increment(k, lastEma, s.Value) From c0cd0ec3cdf817762b784ae67a80e5a1937bdf4a Mon Sep 17 00:00:00 2001 From: Dave Skender <8432125+DaveSkender@users.noreply.github.com> Date: Fri, 11 Oct 2024 18:36:19 -0400 Subject: [PATCH 20/38] revert: rename of GetEma to ToEma (for now) --- src/_common/ObsoleteV3.cs | 2 +- src/e-k/Ema/Ema.Api.cs | 5 +-- src/e-k/Ema/Ema.StaticSeries.cs | 2 +- src/s-z/Sma/Sma.StaticSeries.cs | 2 +- .../Observables/StreamHub.Observable.Tests.cs | 2 +- .../e-k/Ema/Ema.Increments.Tests.cs | 6 ++-- .../e-k/Ema/Ema.StaticSeries.Tests.cs | 34 +++++++++---------- .../indicators/e-k/Ema/Ema.StreamHub.Tests.cs | 10 +++--- .../s-z/Sma/Sma.StaticSeries.Tests.cs | 2 +- .../indicators/s-z/Sma/Sma.StreamHub.Tests.cs | 2 +- .../SmaAnalysis.StaticSeries.Tests.cs | 2 +- tests/other/Convergence.Tests.cs | 2 +- tests/other/Custom.Indicator.Tests.cs | 2 +- tests/other/Custom.Quotes.Tests.cs | 8 ++--- tests/other/Custom.Results.Tests.cs | 4 +-- tests/other/PublicApi.Interface.Tests.cs | 4 +-- tests/performance/Perf.Increments.cs | 2 +- tests/performance/Perf.StaticSeries.cs | 2 +- tests/performance/Perf.StreamHub.Externals.cs | 2 +- 19 files changed, 48 insertions(+), 47 deletions(-) diff --git a/src/_common/ObsoleteV3.cs b/src/_common/ObsoleteV3.cs index df7368e01..e5fed2b73 100644 --- a/src/_common/ObsoleteV3.cs +++ b/src/_common/ObsoleteV3.cs @@ -33,7 +33,7 @@ public static IEnumerable GetAlligator( public static IEnumerable GetEma( this IEnumerable quotes, int lookbackPeriods) where TQuote : IQuote - => Api.ToEma(quotes, lookbackPeriods); + => Api.GetEma(quotes, lookbackPeriods); // REMOVAL OF INTEGRATED SMAs (evaluates to ERRORs) diff --git a/src/e-k/Ema/Ema.Api.cs b/src/e-k/Ema/Ema.Api.cs index d579e3375..10bac357f 100644 --- a/src/e-k/Ema/Ema.Api.cs +++ b/src/e-k/Ema/Ema.Api.cs @@ -5,9 +5,10 @@ namespace Skender.Stock.Indicators; public static partial class Api { //SERIES, from CHAIN - public static IReadOnlyList ToEma( + public static IReadOnlyList GetEma( - // FIX: Use "Ema" instead of "Api" class name (fails). + // FIX: Use "Ema" instead of "Api" class name + // It fails when renaming this to ToEma() this IEnumerable results, int lookbackPeriods) diff --git a/src/e-k/Ema/Ema.StaticSeries.cs b/src/e-k/Ema/Ema.StaticSeries.cs index 0db8863db..ae46fa361 100644 --- a/src/e-k/Ema/Ema.StaticSeries.cs +++ b/src/e-k/Ema/Ema.StaticSeries.cs @@ -46,6 +46,6 @@ internal static List CalcEma( lastEma = ema; } - return results.ToList(); + return new List(results); } } diff --git a/src/s-z/Sma/Sma.StaticSeries.cs b/src/s-z/Sma/Sma.StaticSeries.cs index 417fc27c7..06de8a4f1 100644 --- a/src/s-z/Sma/Sma.StaticSeries.cs +++ b/src/s-z/Sma/Sma.StaticSeries.cs @@ -52,6 +52,6 @@ internal static List CalcSma( Sma: sma.NaN2Null()); } - return results.ToList(); + return new List(results); } } diff --git a/tests/indicators/_common/Observables/StreamHub.Observable.Tests.cs b/tests/indicators/_common/Observables/StreamHub.Observable.Tests.cs index 8dcb6f73c..def163d9f 100644 --- a/tests/indicators/_common/Observables/StreamHub.Observable.Tests.cs +++ b/tests/indicators/_common/Observables/StreamHub.Observable.Tests.cs @@ -100,7 +100,7 @@ IReadOnlyList streamList // time-series, for comparison IReadOnlyList seriesList = Quotes .Use(CandlePart.HL2) - .ToEma(11); + .GetEma(11); // assert, should equal series streamList.Should().HaveCount(Quotes.Count); diff --git a/tests/indicators/e-k/Ema/Ema.Increments.Tests.cs b/tests/indicators/e-k/Ema/Ema.Increments.Tests.cs index 8563b9bb0..02bd30aa6 100644 --- a/tests/indicators/e-k/Ema/Ema.Increments.Tests.cs +++ b/tests/indicators/e-k/Ema/Ema.Increments.Tests.cs @@ -16,8 +16,8 @@ private static readonly IReadOnlyList reusables .ToList(); private static readonly IReadOnlyList series - = Quotes - .ToEma(lookbackPeriods); + = Api.GetEma(Quotes +, lookbackPeriods); private static readonly List seriesArray = series .Select(x => x.Ema) @@ -74,7 +74,7 @@ public override void FromQuoteBatch() EmaList sut = new(lookbackPeriods) { Quotes }; IReadOnlyList series - = Quotes.ToEma(lookbackPeriods); + = Api.GetEma(Quotes, lookbackPeriods); sut.Should().HaveCount(Quotes.Count); sut.Should().BeEquivalentTo(series); diff --git a/tests/indicators/e-k/Ema/Ema.StaticSeries.Tests.cs b/tests/indicators/e-k/Ema/Ema.StaticSeries.Tests.cs index 6136b75d2..d17760174 100644 --- a/tests/indicators/e-k/Ema/Ema.StaticSeries.Tests.cs +++ b/tests/indicators/e-k/Ema/Ema.StaticSeries.Tests.cs @@ -14,8 +14,8 @@ public void Increment() [TestMethod] public override void Standard() { - IReadOnlyList results = Quotes - .ToEma(20); + IReadOnlyList results = Api.GetEma(Quotes +, 20); // proper quantities Assert.AreEqual(502, results.Count); @@ -37,7 +37,7 @@ public void UsePart() { IReadOnlyList results = Quotes .Use(CandlePart.Open) - .ToEma(20); + .GetEma(20); // assertions @@ -62,7 +62,7 @@ public void UseReusable() { IReadOnlyList results = Quotes .Use(CandlePart.Close) - .ToEma(20); + .GetEma(20); Assert.AreEqual(502, results.Count); Assert.AreEqual(483, results.Count(x => x.Ema != null)); @@ -74,7 +74,7 @@ public void Chainee() { IReadOnlyList results = Quotes .GetSma(2) - .ToEma(20); + .GetEma(20); Assert.AreEqual(502, results.Count); Assert.AreEqual(482, results.Count(x => x.Ema != null)); @@ -84,8 +84,8 @@ public void Chainee() [TestMethod] public void Chainor() { - IReadOnlyList results = Quotes - .ToEma(20) + IReadOnlyList results = Api.GetEma(Quotes +, 20) .GetSma(10); Assert.AreEqual(502, results.Count); @@ -98,7 +98,7 @@ public void ChaineeMore() { IReadOnlyList results = Quotes .GetRsi() - .ToEma(20); + .GetEma(20); // assertions Assert.AreEqual(502, results.Count); @@ -122,8 +122,8 @@ public void ChaineeMore() [TestMethod] public override void BadData() { - IReadOnlyList r = BadQuotes - .ToEma(15); + IReadOnlyList r = Api.GetEma(BadQuotes +, 15); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Ema is double.NaN)); @@ -132,13 +132,13 @@ public override void BadData() [TestMethod] public override void NoQuotes() { - IReadOnlyList r0 = Noquotes - .ToEma(10); + IReadOnlyList r0 = Api.GetEma(Noquotes +, 10); Assert.AreEqual(0, r0.Count); - IReadOnlyList r1 = Onequote - .ToEma(10); + IReadOnlyList r1 = Api.GetEma(Onequote +, 10); Assert.AreEqual(1, r1.Count); } @@ -146,8 +146,8 @@ public override void NoQuotes() [TestMethod] public void Removed() { - IReadOnlyList results = Quotes - .ToEma(20) + IReadOnlyList results = Api.GetEma(Quotes +, 20) .RemoveWarmupPeriods(); // assertions @@ -161,5 +161,5 @@ public void Removed() [TestMethod] public void Exceptions() => Assert.ThrowsException(() - => Quotes.ToEma(0)); + => Api.GetEma(Quotes, 0)); } diff --git a/tests/indicators/e-k/Ema/Ema.StreamHub.Tests.cs b/tests/indicators/e-k/Ema/Ema.StreamHub.Tests.cs index c0216ef6b..71f29b64f 100644 --- a/tests/indicators/e-k/Ema/Ema.StreamHub.Tests.cs +++ b/tests/indicators/e-k/Ema/Ema.StreamHub.Tests.cs @@ -55,8 +55,8 @@ IReadOnlyList streamList quotesList.RemoveAt(400); // time-series, for comparison - IReadOnlyList seriesList = quotesList - .ToEma(5); + IReadOnlyList seriesList = Api.GetEma(quotesList +, 5); // assert, should equal series streamList.Should().HaveCount(length - 1); @@ -99,7 +99,7 @@ IReadOnlyList streamList IReadOnlyList seriesList = quotesList .GetSma(smaPeriods) - .ToEma(emaPeriods); + .GetEma(emaPeriods); // assert, should equal series streamList.Should().HaveCount(length); @@ -160,8 +160,8 @@ IReadOnlyList streamList // time-series, for comparison IReadOnlyList seriesList - = quotesList - .ToEma(emaPeriods) + = Api.GetEma(quotesList +, emaPeriods) .GetSma(smaPeriods); // assert, should equal series diff --git a/tests/indicators/s-z/Sma/Sma.StaticSeries.Tests.cs b/tests/indicators/s-z/Sma/Sma.StaticSeries.Tests.cs index f811a88c6..526eea09b 100644 --- a/tests/indicators/s-z/Sma/Sma.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/Sma/Sma.StaticSeries.Tests.cs @@ -68,7 +68,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetSma(10) - .ToEma(10); + .GetEma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(484, results.Count(x => x.Ema != null)); diff --git a/tests/indicators/s-z/Sma/Sma.StreamHub.Tests.cs b/tests/indicators/s-z/Sma/Sma.StreamHub.Tests.cs index 1934a0f4c..8580bbbc4 100644 --- a/tests/indicators/s-z/Sma/Sma.StreamHub.Tests.cs +++ b/tests/indicators/s-z/Sma/Sma.StreamHub.Tests.cs @@ -150,7 +150,7 @@ IReadOnlyList streamList IReadOnlyList seriesList = quotesList .GetSma(smaPeriods) - .ToEma(emaPeriods); + .GetEma(emaPeriods); // assert, should equal series streamList.Should().HaveCount(length - 1); diff --git a/tests/indicators/s-z/SmaAnalysis/SmaAnalysis.StaticSeries.Tests.cs b/tests/indicators/s-z/SmaAnalysis/SmaAnalysis.StaticSeries.Tests.cs index 0c483fe5f..9da59b2e9 100644 --- a/tests/indicators/s-z/SmaAnalysis/SmaAnalysis.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/SmaAnalysis/SmaAnalysis.StaticSeries.Tests.cs @@ -48,7 +48,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetSmaAnalysis(10) - .ToEma(10); + .GetEma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(484, results.Count(x => x.Ema != null)); diff --git a/tests/other/Convergence.Tests.cs b/tests/other/Convergence.Tests.cs index 232a52a47..2b709899e 100644 --- a/tests/other/Convergence.Tests.cs +++ b/tests/other/Convergence.Tests.cs @@ -105,7 +105,7 @@ public void Ema() foreach (int qty in QuotesQuantities) { IReadOnlyList qts = Data.GetLongish(qty); - IReadOnlyList r = qts.ToEma(15); + IReadOnlyList r = Api.GetEma(qts, 15); EmaResult l = r[^1]; Console.WriteLine($"EMA(15) on {l.Timestamp:d} with {qts.Count,4} periods: {l.Ema:N8}"); diff --git a/tests/other/Custom.Indicator.Tests.cs b/tests/other/Custom.Indicator.Tests.cs index 261064fe7..352e740dd 100644 --- a/tests/other/Custom.Indicator.Tests.cs +++ b/tests/other/Custom.Indicator.Tests.cs @@ -81,7 +81,7 @@ public void Chainor() { IReadOnlyList results = quotes .GetIndicator(10) - .ToEma(10); + .GetEma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(484, results.Count(x => x.Ema != null)); diff --git a/tests/other/Custom.Quotes.Tests.cs b/tests/other/Custom.Quotes.Tests.cs index 4a2aeaa06..1db53373a 100644 --- a/tests/other/Custom.Quotes.Tests.cs +++ b/tests/other/Custom.Quotes.Tests.cs @@ -33,8 +33,8 @@ public void CustomQuoteSeries() }) .ToList(); - IReadOnlyList results = myGenericHistory - .ToEma(20); + IReadOnlyList results = Api.GetEma(myGenericHistory +, 20); // proper quantities Assert.AreEqual(502, results.Count); @@ -160,8 +160,8 @@ public void CustomQuoteInheritedSeries() MyOtherProperty: 123456)) .ToList(); - IReadOnlyList results = myGenericHistory - .ToEma(20); + IReadOnlyList results = Api.GetEma(myGenericHistory +, 20); // proper quantities Assert.AreEqual(502, results.Count); diff --git a/tests/other/Custom.Results.Tests.cs b/tests/other/Custom.Results.Tests.cs index a45bd6264..f2204ef88 100644 --- a/tests/other/Custom.Results.Tests.cs +++ b/tests/other/Custom.Results.Tests.cs @@ -29,7 +29,7 @@ public void CustomSeriesClass() [TestMethod] public void CustomSeriesClassLinq() { - IEnumerable emaResults = quotes.ToEma(14); + IEnumerable emaResults = Api.GetEma(quotes, 14); // can use a derive Indicator class using Linq @@ -48,7 +48,7 @@ public void CustomSeriesClassLinq() public void CustomSeriesClassFind() { List emaResults - = quotes.ToEma(20).ToList(); + = Api.GetEma(quotes, 20).ToList(); // can use a derive Indicator class using Linq diff --git a/tests/other/PublicApi.Interface.Tests.cs b/tests/other/PublicApi.Interface.Tests.cs index d623cef08..a1111684a 100644 --- a/tests/other/PublicApi.Interface.Tests.cs +++ b/tests/other/PublicApi.Interface.Tests.cs @@ -17,7 +17,7 @@ public void QuoteValidation() enumerable.Validate(); enumerable.GetSma(6); - enumerable.ToEma(5); + Api.GetEma(enumerable, 5); } [TestMethod] @@ -90,7 +90,7 @@ public void StreamMany() // from quote provider IReadOnlyList staticAtr = quotes.GetAtr(); IReadOnlyList staticAtrStop = quotes.GetAtrStop(); IEnumerable staticAlligator = quotes.GetAlligator(); - IEnumerable staticEma = quotes.ToEma(20); + IEnumerable staticEma = Api.GetEma(quotes, 20); IEnumerable staticQuotePart = quotes.Use(CandlePart.OHL3); IEnumerable staticSma = quotes.GetSma(20); IReadOnlyList staticTr = quotes.GetTr(); diff --git a/tests/performance/Perf.Increments.cs b/tests/performance/Perf.Increments.cs index a4917ea40..9188e17b9 100644 --- a/tests/performance/Perf.Increments.cs +++ b/tests/performance/Perf.Increments.cs @@ -113,7 +113,7 @@ public object EmaIncPrm() public object EmaSeriesEqiv() => quotesList.CalcEma(14); [Benchmark] - public object EmaSeriesOrig() => quotes.ToEma(14); + public object EmaSeriesOrig() => Api.GetEma(quotes, 14); [Benchmark] public object EmaIncremEqiv() diff --git a/tests/performance/Perf.StaticSeries.cs b/tests/performance/Perf.StaticSeries.cs index ac86db83a..b3a8aff78 100644 --- a/tests/performance/Perf.StaticSeries.cs +++ b/tests/performance/Perf.StaticSeries.cs @@ -93,7 +93,7 @@ public class SeriesIndicators public object GetElderRay() => q.GetElderRay(); [Benchmark] - public object GetEma() => q.ToEma(14); + public object GetEma() => Api.GetEma(q, 14); [Benchmark] public object GetEpma() => q.GetEpma(14); diff --git a/tests/performance/Perf.StreamHub.Externals.cs b/tests/performance/Perf.StreamHub.Externals.cs index 3a2dd4eb0..c3f258a0c 100644 --- a/tests/performance/Perf.StreamHub.Externals.cs +++ b/tests/performance/Perf.StreamHub.Externals.cs @@ -35,7 +35,7 @@ public void Cleanup() // TODO: replace with external data cache model, when available [Benchmark(Baseline = true)] - public object EmaSeries() => quotes.ToEma(14); + public object EmaSeries() => Api.GetEma(quotes, 14); [Benchmark] public object EmaStream() => provider.ToEma(14).Results; From a027f30272fe6a814ab92ab8542c30863d3ed9a0 Mon Sep 17 00:00:00 2001 From: Dave Skender <8432125+DaveSkender@users.noreply.github.com> Date: Fri, 11 Oct 2024 18:42:37 -0400 Subject: [PATCH 21/38] array-ize static TR --- src/s-z/Tr/Tr.StaticSeries.cs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/s-z/Tr/Tr.StaticSeries.cs b/src/s-z/Tr/Tr.StaticSeries.cs index 2ab91b4fd..54100a88e 100644 --- a/src/s-z/Tr/Tr.StaticSeries.cs +++ b/src/s-z/Tr/Tr.StaticSeries.cs @@ -10,13 +10,12 @@ private static List CalcTr( { // initialize int length = source.Count; - List results = new(length); + TrResult[] results = new TrResult[length]; // skip first period if (length > 0) { - results.Add( - new(source[0].Timestamp, null)); + results[0] = new TrResult(source[0].Timestamp, null); } // roll through source values @@ -24,11 +23,11 @@ private static List CalcTr( { QuoteD q = source[i]; - results.Add(new TrResult( + results[i] = new TrResult( Timestamp: q.Timestamp, - Tr: Increment(q.High, q.Low, source[i - 1].Close))); + Tr: Increment(q.High, q.Low, source[i - 1].Close)); } - return results; + return new List(results); } } From d24a41f512ba11fe7eed9ce27e7c11c67e3110ca Mon Sep 17 00:00:00 2001 From: Dave Skender <8432125+DaveSkender@users.noreply.github.com> Date: Sun, 13 Oct 2024 18:57:27 -0400 Subject: [PATCH 22/38] refactor static alligator --- src/a-d/Alligator/Alligator.StaticSeries.cs | 90 ++------------------- src/a-d/Alligator/Alligator.Utilities.cs | 34 ++++++++ 2 files changed, 41 insertions(+), 83 deletions(-) diff --git a/src/a-d/Alligator/Alligator.StaticSeries.cs b/src/a-d/Alligator/Alligator.StaticSeries.cs index 887a98b9e..0c3a4e696 100644 --- a/src/a-d/Alligator/Alligator.StaticSeries.cs +++ b/src/a-d/Alligator/Alligator.StaticSeries.cs @@ -25,95 +25,19 @@ internal static List CalcAlligator( // initialize int length = source.Count; - List results = new(length); + AlligatorResult[] results = new AlligatorResult[length]; // roll through source values for (int i = 0; i < length; i++) { - double jaw = double.NaN; - double lips = double.NaN; - double teeth = double.NaN; - - // calculate alligator's jaw, when in range - if (i >= jawPeriods + jawOffset - 1) - { - // first/reset value: calculate SMA - if (results[i - 1].Jaw is null) - { - double sum = 0; - for (int p = i - jawPeriods - jawOffset + 1; p <= i - jawOffset; p++) - { - sum += source[p].Value; - } - - jaw = sum / jawPeriods; - } - - // remaining values: SMMA - else - { - double prevJaw = results[i - 1].Jaw.Null2NaN(); - - jaw = ((prevJaw * (jawPeriods - 1)) + source[i - jawOffset].Value) / jawPeriods; - } - } - - // calculate alligator's teeth, when in range - if (i >= teethPeriods + teethOffset - 1) - { - // first/reset value: calculate SMA - if (results[i - 1].Teeth is null) - { - double sum = 0; - for (int p = i - teethPeriods - teethOffset + 1; p <= i - teethOffset; p++) - { - sum += source[p].Value; - } - - teeth = sum / teethPeriods; - } - - // remaining values: SMMA - else - { - double prevTooth = results[i - 1].Teeth.Null2NaN(); - - teeth = ((prevTooth * (teethPeriods - 1)) + source[i - teethOffset].Value) / teethPeriods; - } - } - - // calculate alligator's lips, when in range - if (i >= lipsPeriods + lipsOffset - 1) - { - // first/reset value: calculate SMA - if (results[i - 1].Lips is null) - { - double sum = 0; - for (int p = i - lipsPeriods - lipsOffset + 1; p <= i - lipsOffset; p++) - { - sum += source[p].Value; - } - - lips = sum / lipsPeriods; - } - - // remaining values: SMMA - else - { - double prevLips = results[i - 1].Lips.Null2NaN(); - - lips = ((prevLips * (lipsPeriods - 1)) + source[i - lipsOffset].Value) / lipsPeriods; - } - } - - // result - results.Add(new AlligatorResult( + results[i] = new AlligatorResult( source[i].Timestamp, - jaw.NaN2Null(), - teeth.NaN2Null(), - lips.NaN2Null())); + Jaw: SmoothValue(source, results, i, jawPeriods, jawOffset, r => r.Jaw).NaN2Null(), + Teeth: SmoothValue(source, results, i, teethPeriods, teethOffset, r => r.Teeth).NaN2Null(), + Lips: SmoothValue(source, results, i, lipsPeriods, lipsOffset, r => r.Lips).NaN2Null()); } - return results; + return new List(results); } + } diff --git a/src/a-d/Alligator/Alligator.Utilities.cs b/src/a-d/Alligator/Alligator.Utilities.cs index 59cae1a79..2d7acf61e 100644 --- a/src/a-d/Alligator/Alligator.Utilities.cs +++ b/src/a-d/Alligator/Alligator.Utilities.cs @@ -2,6 +2,40 @@ namespace Skender.Stock.Indicators; public static partial class Alligator { + private static double SmoothValue( + List source, + AlligatorResult[] results, + int i, + int periods, + int offset, + Func selector) + where T : IReusable + { + // skip warmup periods + if (i < periods + offset - 1) + { + return double.NaN; + } + + // re/initialize + if (results[i - 1] is null || selector(results[i - 1]) is null) + { + double sum = 0; + for (int p = i - periods - offset + 1; p <= i - offset; p++) + { + sum += source[p].Value; + } + return sum / periods; + } + + // normal smoothing + else + { + double prevValue = selector(results[i - 1]).Null2NaN(); + return ((prevValue * (periods - 1)) + source[i - offset].Value) / periods; + } + } + // CONDENSE (REMOVE null results) public static IReadOnlyList Condense( this IEnumerable results) From 7e5a213ddc71f474968619a30663f603f03355eb Mon Sep 17 00:00:00 2001 From: Dave Skender <8432125+DaveSkender@users.noreply.github.com> Date: Sun, 13 Oct 2024 18:58:14 -0400 Subject: [PATCH 23/38] revert: last commit (slower) --- src/a-d/Alligator/Alligator.StaticSeries.cs | 90 +++++++++++++++++++-- src/a-d/Alligator/Alligator.Utilities.cs | 34 -------- 2 files changed, 83 insertions(+), 41 deletions(-) diff --git a/src/a-d/Alligator/Alligator.StaticSeries.cs b/src/a-d/Alligator/Alligator.StaticSeries.cs index 0c3a4e696..887a98b9e 100644 --- a/src/a-d/Alligator/Alligator.StaticSeries.cs +++ b/src/a-d/Alligator/Alligator.StaticSeries.cs @@ -25,19 +25,95 @@ internal static List CalcAlligator( // initialize int length = source.Count; - AlligatorResult[] results = new AlligatorResult[length]; + List results = new(length); // roll through source values for (int i = 0; i < length; i++) { - results[i] = new AlligatorResult( + double jaw = double.NaN; + double lips = double.NaN; + double teeth = double.NaN; + + // calculate alligator's jaw, when in range + if (i >= jawPeriods + jawOffset - 1) + { + // first/reset value: calculate SMA + if (results[i - 1].Jaw is null) + { + double sum = 0; + for (int p = i - jawPeriods - jawOffset + 1; p <= i - jawOffset; p++) + { + sum += source[p].Value; + } + + jaw = sum / jawPeriods; + } + + // remaining values: SMMA + else + { + double prevJaw = results[i - 1].Jaw.Null2NaN(); + + jaw = ((prevJaw * (jawPeriods - 1)) + source[i - jawOffset].Value) / jawPeriods; + } + } + + // calculate alligator's teeth, when in range + if (i >= teethPeriods + teethOffset - 1) + { + // first/reset value: calculate SMA + if (results[i - 1].Teeth is null) + { + double sum = 0; + for (int p = i - teethPeriods - teethOffset + 1; p <= i - teethOffset; p++) + { + sum += source[p].Value; + } + + teeth = sum / teethPeriods; + } + + // remaining values: SMMA + else + { + double prevTooth = results[i - 1].Teeth.Null2NaN(); + + teeth = ((prevTooth * (teethPeriods - 1)) + source[i - teethOffset].Value) / teethPeriods; + } + } + + // calculate alligator's lips, when in range + if (i >= lipsPeriods + lipsOffset - 1) + { + // first/reset value: calculate SMA + if (results[i - 1].Lips is null) + { + double sum = 0; + for (int p = i - lipsPeriods - lipsOffset + 1; p <= i - lipsOffset; p++) + { + sum += source[p].Value; + } + + lips = sum / lipsPeriods; + } + + // remaining values: SMMA + else + { + double prevLips = results[i - 1].Lips.Null2NaN(); + + lips = ((prevLips * (lipsPeriods - 1)) + source[i - lipsOffset].Value) / lipsPeriods; + } + } + + // result + results.Add(new AlligatorResult( source[i].Timestamp, - Jaw: SmoothValue(source, results, i, jawPeriods, jawOffset, r => r.Jaw).NaN2Null(), - Teeth: SmoothValue(source, results, i, teethPeriods, teethOffset, r => r.Teeth).NaN2Null(), - Lips: SmoothValue(source, results, i, lipsPeriods, lipsOffset, r => r.Lips).NaN2Null()); + jaw.NaN2Null(), + teeth.NaN2Null(), + lips.NaN2Null())); } - return new List(results); + return results; } - } diff --git a/src/a-d/Alligator/Alligator.Utilities.cs b/src/a-d/Alligator/Alligator.Utilities.cs index 2d7acf61e..59cae1a79 100644 --- a/src/a-d/Alligator/Alligator.Utilities.cs +++ b/src/a-d/Alligator/Alligator.Utilities.cs @@ -2,40 +2,6 @@ namespace Skender.Stock.Indicators; public static partial class Alligator { - private static double SmoothValue( - List source, - AlligatorResult[] results, - int i, - int periods, - int offset, - Func selector) - where T : IReusable - { - // skip warmup periods - if (i < periods + offset - 1) - { - return double.NaN; - } - - // re/initialize - if (results[i - 1] is null || selector(results[i - 1]) is null) - { - double sum = 0; - for (int p = i - periods - offset + 1; p <= i - offset; p++) - { - sum += source[p].Value; - } - return sum / periods; - } - - // normal smoothing - else - { - double prevValue = selector(results[i - 1]).Null2NaN(); - return ((prevValue * (periods - 1)) + source[i - offset].Value) / periods; - } - } - // CONDENSE (REMOVE null results) public static IReadOnlyList Condense( this IEnumerable results) From 9e64796163c8090a14d5bc3a95f9889211ccb11c Mon Sep 17 00:00:00 2001 From: Dave Skender <8432125+DaveSkender@users.noreply.github.com> Date: Sun, 13 Oct 2024 19:13:39 -0400 Subject: [PATCH 24/38] revert concrete Reusable abstract --- src/_common/Quotes/Quote.Models.cs | 14 ++++---------- src/_common/Reusable/Reusable.Models.cs | 17 ----------------- src/_common/Use (QuotePart)/QuotePart.Models.cs | 4 ++-- src/a-d/Adl/Adl.Models.cs | 4 ++-- src/a-d/Adx/Adx.Models.cs | 4 ++-- src/a-d/Alma/Alma.Models.cs | 4 ++-- src/a-d/Aroon/Aroon.Models.cs | 4 ++-- src/a-d/Atr/Atr.Models.cs | 4 ++-- src/a-d/Awesome/Awesome.Models.cs | 4 ++-- src/a-d/Beta/Beta.Models.cs | 4 ++-- src/a-d/BollingerBands/BollingerBands.Models.cs | 4 ++-- src/a-d/Bop/Bop.Models.cs | 4 ++-- src/a-d/Cci/Cci.Models.cs | 4 ++-- src/a-d/ChaikinOsc/ChaikinOsc.Models.cs | 4 ++-- src/a-d/Chandelier/Chandelier.Models.cs | 4 ++-- src/a-d/Chop/Chop.Models.cs | 4 ++-- src/a-d/Cmf/Cmf.Models.cs | 4 ++-- src/a-d/Cmo/Cmo.Models.cs | 4 ++-- src/a-d/ConnorsRsi/ConnorsRsi.Models.cs | 4 ++-- src/a-d/Correlation/Correlation.Models.cs | 4 ++-- src/a-d/Dema/Dema.Models.cs | 4 ++-- src/a-d/Dpo/Dpo.Models.cs | 4 ++-- src/a-d/Dynamic/Dynamic.Models.cs | 4 ++-- src/e-k/ElderRay/ElderRay.Models.cs | 4 ++-- src/e-k/Ema/Ema.Models.cs | 4 ++-- src/e-k/Epma/Epma.Models.cs | 4 ++-- .../FisherTransform/FisherTransform.Models.cs | 4 ++-- src/e-k/ForceIndex/ForceIndex.Models.cs | 4 ++-- src/e-k/Hma/Hma.Models.cs | 4 ++-- src/e-k/HtTrendline/HtTrendline.Models.cs | 4 ++-- src/e-k/Hurst/Hurst.Models.cs | 4 ++-- src/e-k/Kama/Kama.Models.cs | 4 ++-- src/e-k/Kvo/Kvo.Models.cs | 4 ++-- src/m-r/Macd/Macd.Models.cs | 4 ++-- src/m-r/Mama/Mama.Models.cs | 4 ++-- src/m-r/Mfi/Mfi.Models.cs | 4 ++-- src/m-r/Obv/Obv.Models.cs | 4 ++-- src/m-r/ParabolicSar/ParabolicSar.Models.cs | 4 ++-- src/m-r/Pmo/Pmo.Models.cs | 4 ++-- src/m-r/Prs/Prs.Models.cs | 4 ++-- src/m-r/Pvo/Pvo.Models.cs | 4 ++-- src/m-r/Roc/Roc.Models.cs | 4 ++-- src/m-r/RocWb/RocWb.Models.cs | 4 ++-- src/m-r/Rsi/Rsi.Models.cs | 4 ++-- src/s-z/Slope/Slope.Models.cs | 4 ++-- src/s-z/Sma/Sma.Models.cs | 4 ++-- src/s-z/Smi/Smi.Models.cs | 4 ++-- src/s-z/Smma/Smma.Models.cs | 4 ++-- src/s-z/Stc/Stc.Models.cs | 4 ++-- src/s-z/StdDev/StdDev.Models.cs | 4 ++-- src/s-z/Stoch/Stoch.Models.cs | 4 ++-- src/s-z/StochRsi/StochRsi.Models.cs | 4 ++-- src/s-z/T3/T3.Models.cs | 4 ++-- src/s-z/Tema/Tema.Models.cs | 4 ++-- src/s-z/Tr/Tr.Models.cs | 4 ++-- src/s-z/Trix/Trix.Models.cs | 4 ++-- src/s-z/Tsi/Tsi.Models.cs | 4 ++-- src/s-z/UlcerIndex/UlcerIndex.Models.cs | 4 ++-- src/s-z/Ultimate/Ultimate.Models.cs | 4 ++-- src/s-z/VolatilityStop/VolatilityStop.Models.cs | 4 ++-- src/s-z/Vwap/Vwap.Models.cs | 4 ++-- src/s-z/Vwma/Vwma.Models.cs | 4 ++-- src/s-z/WilliamsR/WilliamsR.Models.cs | 4 ++-- src/s-z/Wma/Wma.Models.cs | 4 ++-- src/s-z/ZigZag/ZigZag.Models.cs | 4 ++-- tests/other/Sut.CustomItems.cs | 4 ++-- 66 files changed, 132 insertions(+), 155 deletions(-) delete mode 100644 src/_common/Reusable/Reusable.Models.cs diff --git a/src/_common/Quotes/Quote.Models.cs b/src/_common/Quotes/Quote.Models.cs index d8bbdea23..28074d717 100644 --- a/src/_common/Quotes/Quote.Models.cs +++ b/src/_common/Quotes/Quote.Models.cs @@ -16,12 +16,6 @@ namespace Skender.Stock.Indicators; /// /// double IReusable.Value => (double)Close; /// -/// or inherit the record class -/// -/// public record MyQuote(DateTime MyTimestamp, decimal MyClosePrice, ...) -/// : Reusable(MyTimestamp, (double)MyClosePrice), IQuote -/// { ... } -/// /// /// /// TIP: If you do not need a custom quote type, @@ -86,9 +80,9 @@ public record Quote decimal Low, decimal Close, decimal Volume -) : Reusable(Timestamp), IQuote +) : IReusable, IQuote { - public override double Value => (double)Close; + public double Value => (double)Close; // TODO: add [Obsolete] auto-getter/setter for 'Date' property // but only for a short transition period. See if there can be @@ -108,7 +102,7 @@ internal record QuoteD double Low, double Close, double Volume -) : Reusable(Timestamp) +) : IReusable { - public override double Value => Close; + public double Value => Close; } diff --git a/src/_common/Reusable/Reusable.Models.cs b/src/_common/Reusable/Reusable.Models.cs deleted file mode 100644 index 201f94a32..000000000 --- a/src/_common/Reusable/Reusable.Models.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace Skender.Stock.Indicators; - -/// -/// Reusable base result model for chainable indicators. -/// -/// -public abstract record Reusable( - DateTime Timestamp -) : IReusable -{ - // we've done it this way to avoid - // having to seal the inherited classes - // to enable inheritance, but without - // instantiating the Value property - - public abstract double Value { get; } -} diff --git a/src/_common/Use (QuotePart)/QuotePart.Models.cs b/src/_common/Use (QuotePart)/QuotePart.Models.cs index ff857c126..60627a28a 100644 --- a/src/_common/Use (QuotePart)/QuotePart.Models.cs +++ b/src/_common/Use (QuotePart)/QuotePart.Models.cs @@ -7,12 +7,12 @@ public record QuotePart ( DateTime Timestamp, double Value -) : Reusable(Timestamp) +) : IReusable { public QuotePart(IReusable reusable) : this(reusable?.Timestamp ?? default, reusable?.Value ?? default) { } - public override double Value { get; } = Value; + public double Value { get; } = Value; } diff --git a/src/a-d/Adl/Adl.Models.cs b/src/a-d/Adl/Adl.Models.cs index d17d41031..a5fd38014 100644 --- a/src/a-d/Adl/Adl.Models.cs +++ b/src/a-d/Adl/Adl.Models.cs @@ -6,7 +6,7 @@ public record AdlResult double Adl, double? MoneyFlowMultiplier = null, double? MoneyFlowVolume = null -) : Reusable(Timestamp) +) : IReusable { - public override double Value => Adl; + public double Value => Adl; } diff --git a/src/a-d/Adx/Adx.Models.cs b/src/a-d/Adx/Adx.Models.cs index 3673d8acc..609131564 100644 --- a/src/a-d/Adx/Adx.Models.cs +++ b/src/a-d/Adx/Adx.Models.cs @@ -7,7 +7,7 @@ public record AdxResult double? Mdi = null, double? Adx = null, double? Adxr = null -) : Reusable(Timestamp) +) : IReusable { - public override double Value => Adx.Null2NaN(); + public double Value => Adx.Null2NaN(); } diff --git a/src/a-d/Alma/Alma.Models.cs b/src/a-d/Alma/Alma.Models.cs index e14e5b8df..c245ac967 100644 --- a/src/a-d/Alma/Alma.Models.cs +++ b/src/a-d/Alma/Alma.Models.cs @@ -4,7 +4,7 @@ public record AlmaResult ( DateTime Timestamp, double? Alma -) : Reusable(Timestamp) +) : IReusable { - public override double Value => Alma.Null2NaN(); + public double Value => Alma.Null2NaN(); } diff --git a/src/a-d/Aroon/Aroon.Models.cs b/src/a-d/Aroon/Aroon.Models.cs index 7413d6cfd..1e4712be0 100644 --- a/src/a-d/Aroon/Aroon.Models.cs +++ b/src/a-d/Aroon/Aroon.Models.cs @@ -6,7 +6,7 @@ public record AroonResult double? AroonUp, double? AroonDown, double? Oscillator -) : Reusable(Timestamp) +) : IReusable { - public override double Value => Oscillator.Null2NaN(); + public double Value => Oscillator.Null2NaN(); } diff --git a/src/a-d/Atr/Atr.Models.cs b/src/a-d/Atr/Atr.Models.cs index bee607e79..900a749f6 100644 --- a/src/a-d/Atr/Atr.Models.cs +++ b/src/a-d/Atr/Atr.Models.cs @@ -6,7 +6,7 @@ public record AtrResult double? Tr = null, double? Atr = null, double? Atrp = null -) : Reusable(Timestamp) +) : IReusable { - public override double Value => Atrp.Null2NaN(); + public double Value => Atrp.Null2NaN(); } diff --git a/src/a-d/Awesome/Awesome.Models.cs b/src/a-d/Awesome/Awesome.Models.cs index 7101206ae..007a14e6c 100644 --- a/src/a-d/Awesome/Awesome.Models.cs +++ b/src/a-d/Awesome/Awesome.Models.cs @@ -5,7 +5,7 @@ public record AwesomeResult DateTime Timestamp, double? Oscillator, double? Normalized -) : Reusable(Timestamp) +) : IReusable { - public override double Value => Oscillator.Null2NaN(); + public double Value => Oscillator.Null2NaN(); } diff --git a/src/a-d/Beta/Beta.Models.cs b/src/a-d/Beta/Beta.Models.cs index cd020fa54..49339ebf9 100644 --- a/src/a-d/Beta/Beta.Models.cs +++ b/src/a-d/Beta/Beta.Models.cs @@ -9,9 +9,9 @@ public record BetaResult( double? Convexity = null, double? ReturnsEval = null, double? ReturnsMrkt = null -) : Reusable(Timestamp) +) : IReusable { - public override double Value => Beta.Null2NaN(); + public double Value => Beta.Null2NaN(); } public enum BetaType diff --git a/src/a-d/BollingerBands/BollingerBands.Models.cs b/src/a-d/BollingerBands/BollingerBands.Models.cs index 49b42b90c..a3c6f1d0a 100644 --- a/src/a-d/BollingerBands/BollingerBands.Models.cs +++ b/src/a-d/BollingerBands/BollingerBands.Models.cs @@ -9,7 +9,7 @@ public record BollingerBandsResult double? PercentB = null, double? ZScore = null, double? Width = null -) : Reusable(Timestamp) +) : IReusable { - public override double Value => PercentB.Null2NaN(); + public double Value => PercentB.Null2NaN(); } diff --git a/src/a-d/Bop/Bop.Models.cs b/src/a-d/Bop/Bop.Models.cs index 5283a18c2..11d564184 100644 --- a/src/a-d/Bop/Bop.Models.cs +++ b/src/a-d/Bop/Bop.Models.cs @@ -4,7 +4,7 @@ public record BopResult ( DateTime Timestamp, double? Bop -) : Reusable(Timestamp) +) : IReusable { - public override double Value => Bop.Null2NaN(); + public double Value => Bop.Null2NaN(); } diff --git a/src/a-d/Cci/Cci.Models.cs b/src/a-d/Cci/Cci.Models.cs index 3e3d2d046..1b448e730 100644 --- a/src/a-d/Cci/Cci.Models.cs +++ b/src/a-d/Cci/Cci.Models.cs @@ -4,7 +4,7 @@ public record CciResult ( DateTime Timestamp, double? Cci -) : Reusable(Timestamp) +) : IReusable { - public override double Value => Cci.Null2NaN(); + public double Value => Cci.Null2NaN(); } diff --git a/src/a-d/ChaikinOsc/ChaikinOsc.Models.cs b/src/a-d/ChaikinOsc/ChaikinOsc.Models.cs index fa5adf0db..62a508717 100644 --- a/src/a-d/ChaikinOsc/ChaikinOsc.Models.cs +++ b/src/a-d/ChaikinOsc/ChaikinOsc.Models.cs @@ -7,7 +7,7 @@ public record ChaikinOscResult double? MoneyFlowVolume, double? Adl, double? Oscillator -) : Reusable(Timestamp) +) : IReusable { - public override double Value => Oscillator.Null2NaN(); + public double Value => Oscillator.Null2NaN(); } diff --git a/src/a-d/Chandelier/Chandelier.Models.cs b/src/a-d/Chandelier/Chandelier.Models.cs index 7d90ea11f..b6bd6af2b 100644 --- a/src/a-d/Chandelier/Chandelier.Models.cs +++ b/src/a-d/Chandelier/Chandelier.Models.cs @@ -4,9 +4,9 @@ public record ChandelierResult ( DateTime Timestamp, double? ChandelierExit -) : Reusable(Timestamp) +) : IReusable { - public override double Value => ChandelierExit.Null2NaN(); + public double Value => ChandelierExit.Null2NaN(); } public enum ChandelierType diff --git a/src/a-d/Chop/Chop.Models.cs b/src/a-d/Chop/Chop.Models.cs index 51ef88f86..d5a3cbc66 100644 --- a/src/a-d/Chop/Chop.Models.cs +++ b/src/a-d/Chop/Chop.Models.cs @@ -4,7 +4,7 @@ public record ChopResult ( DateTime Timestamp, double? Chop -) : Reusable(Timestamp) +) : IReusable { - public override double Value => Chop.Null2NaN(); + public double Value => Chop.Null2NaN(); } diff --git a/src/a-d/Cmf/Cmf.Models.cs b/src/a-d/Cmf/Cmf.Models.cs index 35e5700db..f8de46088 100644 --- a/src/a-d/Cmf/Cmf.Models.cs +++ b/src/a-d/Cmf/Cmf.Models.cs @@ -6,7 +6,7 @@ public record CmfResult double? MoneyFlowMultiplier, double? MoneyFlowVolume, double? Cmf -) : Reusable(Timestamp) +) : IReusable { - public override double Value => Cmf.Null2NaN(); + public double Value => Cmf.Null2NaN(); } diff --git a/src/a-d/Cmo/Cmo.Models.cs b/src/a-d/Cmo/Cmo.Models.cs index 87e2ce136..708bbe262 100644 --- a/src/a-d/Cmo/Cmo.Models.cs +++ b/src/a-d/Cmo/Cmo.Models.cs @@ -4,7 +4,7 @@ public record CmoResult ( DateTime Timestamp, double? Cmo = null -) : Reusable(Timestamp) +) : IReusable { - public override double Value => Cmo.Null2NaN(); + public double Value => Cmo.Null2NaN(); } diff --git a/src/a-d/ConnorsRsi/ConnorsRsi.Models.cs b/src/a-d/ConnorsRsi/ConnorsRsi.Models.cs index dae912427..b7b9b31fc 100644 --- a/src/a-d/ConnorsRsi/ConnorsRsi.Models.cs +++ b/src/a-d/ConnorsRsi/ConnorsRsi.Models.cs @@ -8,7 +8,7 @@ public record ConnorsRsiResult double? RsiStreak = null, double? PercentRank = null, double? ConnorsRsi = null -) : Reusable(Timestamp) +) : IReusable { - public override double Value => ConnorsRsi.Null2NaN(); + public double Value => ConnorsRsi.Null2NaN(); } diff --git a/src/a-d/Correlation/Correlation.Models.cs b/src/a-d/Correlation/Correlation.Models.cs index 559972c6c..33a1a4f51 100644 --- a/src/a-d/Correlation/Correlation.Models.cs +++ b/src/a-d/Correlation/Correlation.Models.cs @@ -8,7 +8,7 @@ public record CorrResult double? Covariance = null, double? Correlation = null, double? RSquared = null -) : Reusable(Timestamp) +) : IReusable { - public override double Value => Correlation.Null2NaN(); + public double Value => Correlation.Null2NaN(); } diff --git a/src/a-d/Dema/Dema.Models.cs b/src/a-d/Dema/Dema.Models.cs index 5dde861e7..41d5a330e 100644 --- a/src/a-d/Dema/Dema.Models.cs +++ b/src/a-d/Dema/Dema.Models.cs @@ -4,7 +4,7 @@ public record DemaResult ( DateTime Timestamp, double? Dema = null -) : Reusable(Timestamp) +) : IReusable { - public override double Value => Dema.Null2NaN(); + public double Value => Dema.Null2NaN(); } diff --git a/src/a-d/Dpo/Dpo.Models.cs b/src/a-d/Dpo/Dpo.Models.cs index 8a9d3bfeb..ff0ded498 100644 --- a/src/a-d/Dpo/Dpo.Models.cs +++ b/src/a-d/Dpo/Dpo.Models.cs @@ -5,7 +5,7 @@ public record DpoResult DateTime Timestamp, double? Dpo = null, double? Sma = null - ) : Reusable(Timestamp) + ) : IReusable { - public override double Value => Dpo.Null2NaN(); + public double Value => Dpo.Null2NaN(); } diff --git a/src/a-d/Dynamic/Dynamic.Models.cs b/src/a-d/Dynamic/Dynamic.Models.cs index d6707e31b..83d73b23f 100644 --- a/src/a-d/Dynamic/Dynamic.Models.cs +++ b/src/a-d/Dynamic/Dynamic.Models.cs @@ -4,7 +4,7 @@ public record DynamicResult ( DateTime Timestamp, double? Dynamic -) : Reusable(Timestamp) +) : IReusable { - public override double Value => Dynamic.Null2NaN(); + public double Value => Dynamic.Null2NaN(); } diff --git a/src/e-k/ElderRay/ElderRay.Models.cs b/src/e-k/ElderRay/ElderRay.Models.cs index 06cde6fc9..7fb38fb86 100644 --- a/src/e-k/ElderRay/ElderRay.Models.cs +++ b/src/e-k/ElderRay/ElderRay.Models.cs @@ -6,7 +6,7 @@ public record ElderRayResult double? Ema, double? BullPower, double? BearPower -) : Reusable(Timestamp) +) : IReusable { - public override double Value => (BullPower + BearPower).Null2NaN(); + public double Value => (BullPower + BearPower).Null2NaN(); } diff --git a/src/e-k/Ema/Ema.Models.cs b/src/e-k/Ema/Ema.Models.cs index f66860fc4..c999dbaad 100644 --- a/src/e-k/Ema/Ema.Models.cs +++ b/src/e-k/Ema/Ema.Models.cs @@ -4,7 +4,7 @@ public record EmaResult ( DateTime Timestamp, double? Ema = null -) : Reusable(Timestamp) +) : IReusable { - public override double Value => Ema.Null2NaN(); + public double Value => Ema.Null2NaN(); } diff --git a/src/e-k/Epma/Epma.Models.cs b/src/e-k/Epma/Epma.Models.cs index 9e5fb96d8..9392c5e26 100644 --- a/src/e-k/Epma/Epma.Models.cs +++ b/src/e-k/Epma/Epma.Models.cs @@ -4,7 +4,7 @@ public record EpmaResult ( DateTime Timestamp, double? Epma -) : Reusable(Timestamp) +) : IReusable { - public override double Value => Epma.Null2NaN(); + public double Value => Epma.Null2NaN(); } diff --git a/src/e-k/FisherTransform/FisherTransform.Models.cs b/src/e-k/FisherTransform/FisherTransform.Models.cs index 17ec99011..0f983ffe0 100644 --- a/src/e-k/FisherTransform/FisherTransform.Models.cs +++ b/src/e-k/FisherTransform/FisherTransform.Models.cs @@ -5,7 +5,7 @@ public record FisherTransformResult DateTime Timestamp, double? Fisher, double? Trigger -) : Reusable(Timestamp) +) : IReusable { - public override double Value => Fisher.Null2NaN(); + public double Value => Fisher.Null2NaN(); } diff --git a/src/e-k/ForceIndex/ForceIndex.Models.cs b/src/e-k/ForceIndex/ForceIndex.Models.cs index 9724707ea..08a51bdb3 100644 --- a/src/e-k/ForceIndex/ForceIndex.Models.cs +++ b/src/e-k/ForceIndex/ForceIndex.Models.cs @@ -4,7 +4,7 @@ public record ForceIndexResult ( DateTime Timestamp, double? ForceIndex = null -) : Reusable(Timestamp) +) : IReusable { - public override double Value => ForceIndex.Null2NaN(); + public double Value => ForceIndex.Null2NaN(); } diff --git a/src/e-k/Hma/Hma.Models.cs b/src/e-k/Hma/Hma.Models.cs index 3f908c113..af738a356 100644 --- a/src/e-k/Hma/Hma.Models.cs +++ b/src/e-k/Hma/Hma.Models.cs @@ -4,7 +4,7 @@ public record HmaResult ( DateTime Timestamp, double? Hma = null -) : Reusable(Timestamp) +) : IReusable { - public override double Value => Hma.Null2NaN(); + public double Value => Hma.Null2NaN(); } diff --git a/src/e-k/HtTrendline/HtTrendline.Models.cs b/src/e-k/HtTrendline/HtTrendline.Models.cs index 5e2d7a88a..42bd3aaee 100644 --- a/src/e-k/HtTrendline/HtTrendline.Models.cs +++ b/src/e-k/HtTrendline/HtTrendline.Models.cs @@ -6,7 +6,7 @@ public record HtlResult int? DcPeriods, double? Trendline, double? SmoothPrice -) : Reusable(Timestamp) +) : IReusable { - public override double Value => Trendline.Null2NaN(); + public double Value => Trendline.Null2NaN(); } diff --git a/src/e-k/Hurst/Hurst.Models.cs b/src/e-k/Hurst/Hurst.Models.cs index 42064930d..bb5cb2aec 100644 --- a/src/e-k/Hurst/Hurst.Models.cs +++ b/src/e-k/Hurst/Hurst.Models.cs @@ -4,7 +4,7 @@ public record HurstResult ( DateTime Timestamp, double? HurstExponent -) : Reusable(Timestamp) +) : IReusable { - public override double Value => HurstExponent.Null2NaN(); + public double Value => HurstExponent.Null2NaN(); } diff --git a/src/e-k/Kama/Kama.Models.cs b/src/e-k/Kama/Kama.Models.cs index 23789bfda..74a7509ec 100644 --- a/src/e-k/Kama/Kama.Models.cs +++ b/src/e-k/Kama/Kama.Models.cs @@ -5,7 +5,7 @@ public record KamaResult DateTime Timestamp, double? Er = null, double? Kama = null -) : Reusable(Timestamp) +) : IReusable { - public override double Value => Kama.Null2NaN(); + public double Value => Kama.Null2NaN(); } diff --git a/src/e-k/Kvo/Kvo.Models.cs b/src/e-k/Kvo/Kvo.Models.cs index 2a9bdeed1..259119208 100644 --- a/src/e-k/Kvo/Kvo.Models.cs +++ b/src/e-k/Kvo/Kvo.Models.cs @@ -5,7 +5,7 @@ public record KvoResult DateTime Timestamp, double? Oscillator = null, double? Signal = null -) : Reusable(Timestamp) +) : IReusable { - public override double Value => Oscillator.Null2NaN(); + public double Value => Oscillator.Null2NaN(); } diff --git a/src/m-r/Macd/Macd.Models.cs b/src/m-r/Macd/Macd.Models.cs index ca62b0997..343ec3ec4 100644 --- a/src/m-r/Macd/Macd.Models.cs +++ b/src/m-r/Macd/Macd.Models.cs @@ -11,7 +11,7 @@ public record MacdResult double? FastEma, double? SlowEma -) : Reusable(Timestamp) +) : IReusable { - public override double Value => Macd.Null2NaN(); + public double Value => Macd.Null2NaN(); } diff --git a/src/m-r/Mama/Mama.Models.cs b/src/m-r/Mama/Mama.Models.cs index 44ef0bb24..789019c78 100644 --- a/src/m-r/Mama/Mama.Models.cs +++ b/src/m-r/Mama/Mama.Models.cs @@ -5,7 +5,7 @@ public record MamaResult DateTime Timestamp, double? Mama = null, double? Fama = null -) : Reusable(Timestamp) +) : IReusable { - public override double Value => Mama.Null2NaN(); + public double Value => Mama.Null2NaN(); } diff --git a/src/m-r/Mfi/Mfi.Models.cs b/src/m-r/Mfi/Mfi.Models.cs index 601598009..3fed3c72d 100644 --- a/src/m-r/Mfi/Mfi.Models.cs +++ b/src/m-r/Mfi/Mfi.Models.cs @@ -4,7 +4,7 @@ public record MfiResult ( DateTime Timestamp, double? Mfi -) : Reusable(Timestamp) +) : IReusable { - public override double Value => Mfi.Null2NaN(); + public double Value => Mfi.Null2NaN(); } diff --git a/src/m-r/Obv/Obv.Models.cs b/src/m-r/Obv/Obv.Models.cs index 74f25129f..fdb191089 100644 --- a/src/m-r/Obv/Obv.Models.cs +++ b/src/m-r/Obv/Obv.Models.cs @@ -4,7 +4,7 @@ public record ObvResult ( DateTime Timestamp, double Obv -) : Reusable(Timestamp) +) : IReusable { - public override double Value => Obv; + public double Value => Obv; } diff --git a/src/m-r/ParabolicSar/ParabolicSar.Models.cs b/src/m-r/ParabolicSar/ParabolicSar.Models.cs index 12dadd669..1c49a0538 100644 --- a/src/m-r/ParabolicSar/ParabolicSar.Models.cs +++ b/src/m-r/ParabolicSar/ParabolicSar.Models.cs @@ -5,7 +5,7 @@ public record ParabolicSarResult DateTime Timestamp, double? Sar = null, bool? IsReversal = null -) : Reusable(Timestamp) +) : IReusable { - public override double Value => Sar.Null2NaN(); + public double Value => Sar.Null2NaN(); } diff --git a/src/m-r/Pmo/Pmo.Models.cs b/src/m-r/Pmo/Pmo.Models.cs index f4807d81f..3bf28a820 100644 --- a/src/m-r/Pmo/Pmo.Models.cs +++ b/src/m-r/Pmo/Pmo.Models.cs @@ -5,7 +5,7 @@ public record PmoResult DateTime Timestamp, double? Pmo, double? Signal -) : Reusable(Timestamp) +) : IReusable { - public override double Value => Pmo.Null2NaN(); + public double Value => Pmo.Null2NaN(); } diff --git a/src/m-r/Prs/Prs.Models.cs b/src/m-r/Prs/Prs.Models.cs index bcb721a71..8170f040b 100644 --- a/src/m-r/Prs/Prs.Models.cs +++ b/src/m-r/Prs/Prs.Models.cs @@ -5,7 +5,7 @@ public record PrsResult DateTime Timestamp, double? Prs, double? PrsPercent -) : Reusable(Timestamp) +) : IReusable { - public override double Value => Prs.Null2NaN(); + public double Value => Prs.Null2NaN(); } diff --git a/src/m-r/Pvo/Pvo.Models.cs b/src/m-r/Pvo/Pvo.Models.cs index 49e18ec66..7d6c0828c 100644 --- a/src/m-r/Pvo/Pvo.Models.cs +++ b/src/m-r/Pvo/Pvo.Models.cs @@ -6,7 +6,7 @@ public record PvoResult double? Pvo, double? Signal, double? Histogram -) : Reusable(Timestamp) +) : IReusable { - public override double Value => Pvo.Null2NaN(); + public double Value => Pvo.Null2NaN(); } diff --git a/src/m-r/Roc/Roc.Models.cs b/src/m-r/Roc/Roc.Models.cs index d6bb41bcc..78837b215 100644 --- a/src/m-r/Roc/Roc.Models.cs +++ b/src/m-r/Roc/Roc.Models.cs @@ -5,7 +5,7 @@ public record RocResult DateTime Timestamp, double? Momentum, double? Roc -) : Reusable(Timestamp) +) : IReusable { - public override double Value => Roc.Null2NaN(); + public double Value => Roc.Null2NaN(); } diff --git a/src/m-r/RocWb/RocWb.Models.cs b/src/m-r/RocWb/RocWb.Models.cs index e00443252..f6856c952 100644 --- a/src/m-r/RocWb/RocWb.Models.cs +++ b/src/m-r/RocWb/RocWb.Models.cs @@ -7,7 +7,7 @@ public record RocWbResult double? RocEma, double? UpperBand, double? LowerBand -) : Reusable(Timestamp) +) : IReusable { - public override double Value => Roc.Null2NaN(); + public double Value => Roc.Null2NaN(); } diff --git a/src/m-r/Rsi/Rsi.Models.cs b/src/m-r/Rsi/Rsi.Models.cs index 1cdd40ded..de6d97113 100644 --- a/src/m-r/Rsi/Rsi.Models.cs +++ b/src/m-r/Rsi/Rsi.Models.cs @@ -4,7 +4,7 @@ public record RsiResult ( DateTime Timestamp, double? Rsi = null -) : Reusable(Timestamp) +) : IReusable { - public override double Value => Rsi.Null2NaN(); + public double Value => Rsi.Null2NaN(); } diff --git a/src/s-z/Slope/Slope.Models.cs b/src/s-z/Slope/Slope.Models.cs index f0c6c91a1..b2ea358a0 100644 --- a/src/s-z/Slope/Slope.Models.cs +++ b/src/s-z/Slope/Slope.Models.cs @@ -8,7 +8,7 @@ public record SlopeResult double? StdDev = null, double? RSquared = null, decimal? Line = null // last line segment only -) : Reusable(Timestamp) +) : IReusable { - public override double Value => Slope.Null2NaN(); + public double Value => Slope.Null2NaN(); } diff --git a/src/s-z/Sma/Sma.Models.cs b/src/s-z/Sma/Sma.Models.cs index ffdb800bf..44a8885c4 100644 --- a/src/s-z/Sma/Sma.Models.cs +++ b/src/s-z/Sma/Sma.Models.cs @@ -3,7 +3,7 @@ namespace Skender.Stock.Indicators; public record SmaResult( DateTime Timestamp, double? Sma -) : Reusable(Timestamp) +) : IReusable { - public override double Value => Sma.Null2NaN(); + public double Value => Sma.Null2NaN(); } diff --git a/src/s-z/Smi/Smi.Models.cs b/src/s-z/Smi/Smi.Models.cs index 8291a51ac..406f4af07 100644 --- a/src/s-z/Smi/Smi.Models.cs +++ b/src/s-z/Smi/Smi.Models.cs @@ -5,7 +5,7 @@ public record SmiResult DateTime Timestamp, double? Smi, double? Signal -) : Reusable(Timestamp) +) : IReusable { - public override double Value => Smi.Null2NaN(); + public double Value => Smi.Null2NaN(); } diff --git a/src/s-z/Smma/Smma.Models.cs b/src/s-z/Smma/Smma.Models.cs index c4e926828..882392ea4 100644 --- a/src/s-z/Smma/Smma.Models.cs +++ b/src/s-z/Smma/Smma.Models.cs @@ -4,7 +4,7 @@ public record SmmaResult ( DateTime Timestamp, double? Smma = null -) : Reusable(Timestamp) +) : IReusable { - public override double Value => Smma.Null2NaN(); + public double Value => Smma.Null2NaN(); } diff --git a/src/s-z/Stc/Stc.Models.cs b/src/s-z/Stc/Stc.Models.cs index b9d8a4577..3a3b78ee8 100644 --- a/src/s-z/Stc/Stc.Models.cs +++ b/src/s-z/Stc/Stc.Models.cs @@ -4,7 +4,7 @@ public record StcResult ( DateTime Timestamp, double? Stc -) : Reusable(Timestamp) +) : IReusable { - public override double Value => Stc.Null2NaN(); + public double Value => Stc.Null2NaN(); } diff --git a/src/s-z/StdDev/StdDev.Models.cs b/src/s-z/StdDev/StdDev.Models.cs index 4258f9777..3cd6e455c 100644 --- a/src/s-z/StdDev/StdDev.Models.cs +++ b/src/s-z/StdDev/StdDev.Models.cs @@ -6,7 +6,7 @@ public record StdDevResult double? StdDev, double? Mean, double? ZScore -) : Reusable(Timestamp) +) : IReusable { - public override double Value => StdDev.Null2NaN(); + public double Value => StdDev.Null2NaN(); } diff --git a/src/s-z/Stoch/Stoch.Models.cs b/src/s-z/Stoch/Stoch.Models.cs index 41e20f00a..11798b267 100644 --- a/src/s-z/Stoch/Stoch.Models.cs +++ b/src/s-z/Stoch/Stoch.Models.cs @@ -8,9 +8,9 @@ public record StochResult double? Oscillator, double? Signal, double? PercentJ -) : Reusable(Timestamp) +) : IReusable { - public override double Value => Oscillator.Null2NaN(); + public double Value => Oscillator.Null2NaN(); // aliases public double? K => Oscillator; diff --git a/src/s-z/StochRsi/StochRsi.Models.cs b/src/s-z/StochRsi/StochRsi.Models.cs index ec2670859..cad4f480a 100644 --- a/src/s-z/StochRsi/StochRsi.Models.cs +++ b/src/s-z/StochRsi/StochRsi.Models.cs @@ -5,7 +5,7 @@ public record StochRsiResult DateTime Timestamp, double? StochRsi = null, double? Signal = null -) : Reusable(Timestamp) +) : IReusable { - public override double Value => StochRsi.Null2NaN(); + public double Value => StochRsi.Null2NaN(); } diff --git a/src/s-z/T3/T3.Models.cs b/src/s-z/T3/T3.Models.cs index b65c223ff..b1aebebb8 100644 --- a/src/s-z/T3/T3.Models.cs +++ b/src/s-z/T3/T3.Models.cs @@ -4,7 +4,7 @@ public record T3Result ( DateTime Timestamp, double? T3 -) : Reusable(Timestamp) +) : IReusable { - public override double Value => T3.Null2NaN(); + public double Value => T3.Null2NaN(); } diff --git a/src/s-z/Tema/Tema.Models.cs b/src/s-z/Tema/Tema.Models.cs index f5c01e949..36293757c 100644 --- a/src/s-z/Tema/Tema.Models.cs +++ b/src/s-z/Tema/Tema.Models.cs @@ -4,7 +4,7 @@ public record TemaResult ( DateTime Timestamp, double? Tema = null -) : Reusable(Timestamp) +) : IReusable { - public override double Value => Tema.Null2NaN(); + public double Value => Tema.Null2NaN(); } diff --git a/src/s-z/Tr/Tr.Models.cs b/src/s-z/Tr/Tr.Models.cs index bd88886d1..c6cbd373a 100644 --- a/src/s-z/Tr/Tr.Models.cs +++ b/src/s-z/Tr/Tr.Models.cs @@ -3,7 +3,7 @@ namespace Skender.Stock.Indicators; public record TrResult( DateTime Timestamp, double? Tr -) : Reusable(Timestamp) +) : IReusable { - public override double Value => Tr.Null2NaN(); + public double Value => Tr.Null2NaN(); } diff --git a/src/s-z/Trix/Trix.Models.cs b/src/s-z/Trix/Trix.Models.cs index 46479f029..9f7cf0114 100644 --- a/src/s-z/Trix/Trix.Models.cs +++ b/src/s-z/Trix/Trix.Models.cs @@ -5,7 +5,7 @@ public record TrixResult DateTime Timestamp, double? Ema3 = null, double? Trix = null -) : Reusable(Timestamp) +) : IReusable { - public override double Value => Trix.Null2NaN(); + public double Value => Trix.Null2NaN(); } diff --git a/src/s-z/Tsi/Tsi.Models.cs b/src/s-z/Tsi/Tsi.Models.cs index b19317c7f..68804399f 100644 --- a/src/s-z/Tsi/Tsi.Models.cs +++ b/src/s-z/Tsi/Tsi.Models.cs @@ -5,7 +5,7 @@ public record TsiResult DateTime Timestamp, double? Tsi = null, double? Signal = null -) : Reusable(Timestamp) +) : IReusable { - public override double Value => Tsi.Null2NaN(); + public double Value => Tsi.Null2NaN(); } diff --git a/src/s-z/UlcerIndex/UlcerIndex.Models.cs b/src/s-z/UlcerIndex/UlcerIndex.Models.cs index e14aa2a01..33be09d19 100644 --- a/src/s-z/UlcerIndex/UlcerIndex.Models.cs +++ b/src/s-z/UlcerIndex/UlcerIndex.Models.cs @@ -4,9 +4,9 @@ public record UlcerIndexResult ( DateTime Timestamp, double? UlcerIndex -) : Reusable(Timestamp) +) : IReusable { - public override double Value => UlcerIndex.Null2NaN(); + public double Value => UlcerIndex.Null2NaN(); [Obsolete("Rename UI to UlcerIndex")] // v3.0.0 public double? UI => UlcerIndex; diff --git a/src/s-z/Ultimate/Ultimate.Models.cs b/src/s-z/Ultimate/Ultimate.Models.cs index 575919d1f..0286a6ab4 100644 --- a/src/s-z/Ultimate/Ultimate.Models.cs +++ b/src/s-z/Ultimate/Ultimate.Models.cs @@ -4,7 +4,7 @@ public record UltimateResult ( DateTime Timestamp, double? Ultimate -) : Reusable(Timestamp) +) : IReusable { - public override double Value => Ultimate.Null2NaN(); + public double Value => Ultimate.Null2NaN(); } diff --git a/src/s-z/VolatilityStop/VolatilityStop.Models.cs b/src/s-z/VolatilityStop/VolatilityStop.Models.cs index 101c876a9..19467860f 100644 --- a/src/s-z/VolatilityStop/VolatilityStop.Models.cs +++ b/src/s-z/VolatilityStop/VolatilityStop.Models.cs @@ -10,7 +10,7 @@ public record VolatilityStopResult double? UpperBand = null, double? LowerBand = null -) : Reusable(Timestamp) +) : IReusable { - public override double Value => Sar.Null2NaN(); + public double Value => Sar.Null2NaN(); } diff --git a/src/s-z/Vwap/Vwap.Models.cs b/src/s-z/Vwap/Vwap.Models.cs index c7b24df2e..168f55103 100644 --- a/src/s-z/Vwap/Vwap.Models.cs +++ b/src/s-z/Vwap/Vwap.Models.cs @@ -4,7 +4,7 @@ public record VwapResult ( DateTime Timestamp, double? Vwap -) : Reusable(Timestamp) +) : IReusable { - public override double Value => Vwap.Null2NaN(); + public double Value => Vwap.Null2NaN(); } diff --git a/src/s-z/Vwma/Vwma.Models.cs b/src/s-z/Vwma/Vwma.Models.cs index 1de241f44..a145b314c 100644 --- a/src/s-z/Vwma/Vwma.Models.cs +++ b/src/s-z/Vwma/Vwma.Models.cs @@ -4,7 +4,7 @@ public record VwmaResult ( DateTime Timestamp, double? Vwma -) : Reusable(Timestamp) +) : IReusable { - public override double Value => Vwma.Null2NaN(); + public double Value => Vwma.Null2NaN(); } diff --git a/src/s-z/WilliamsR/WilliamsR.Models.cs b/src/s-z/WilliamsR/WilliamsR.Models.cs index a260ae42e..7eacca043 100644 --- a/src/s-z/WilliamsR/WilliamsR.Models.cs +++ b/src/s-z/WilliamsR/WilliamsR.Models.cs @@ -4,7 +4,7 @@ public record WilliamsResult ( DateTime Timestamp, double? WilliamsR -) : Reusable(Timestamp) +) : IReusable { - public override double Value => WilliamsR.Null2NaN(); + public double Value => WilliamsR.Null2NaN(); } diff --git a/src/s-z/Wma/Wma.Models.cs b/src/s-z/Wma/Wma.Models.cs index 9231177fa..ae37a2bc6 100644 --- a/src/s-z/Wma/Wma.Models.cs +++ b/src/s-z/Wma/Wma.Models.cs @@ -4,7 +4,7 @@ public record WmaResult ( DateTime Timestamp, double? Wma -) : Reusable(Timestamp) +) : IReusable { - public override double Value => Wma.Null2NaN(); + public double Value => Wma.Null2NaN(); } diff --git a/src/s-z/ZigZag/ZigZag.Models.cs b/src/s-z/ZigZag/ZigZag.Models.cs index 6ebd5db44..de7fce44f 100644 --- a/src/s-z/ZigZag/ZigZag.Models.cs +++ b/src/s-z/ZigZag/ZigZag.Models.cs @@ -7,9 +7,9 @@ public record ZigZagResult string? PointType = null, // indicates a specific point and type e.g. H or L decimal? RetraceHigh = null, // zig zag retrace high line decimal? RetraceLow = null // zig zag retrace low line -) : Reusable(Timestamp) +) : IReusable { - public override double Value => ZigZag.Null2NaN(); + public double Value => ZigZag.Null2NaN(); } internal class ZigZagEval diff --git a/tests/other/Sut.CustomItems.cs b/tests/other/Sut.CustomItems.cs index 2761f64db..4b051c35a 100644 --- a/tests/other/Sut.CustomItems.cs +++ b/tests/other/Sut.CustomItems.cs @@ -51,9 +51,9 @@ double IReusable.Value public sealed record CustomReusableInherited( DateTime Timestamp, double? Sma - ) : Reusable(Timestamp) + ) : IReusable { - public override double Value + public double Value => Sma.Null2NaN(); } From d18ea376165202d1aae2ae5f4301296cde859e23 Mon Sep 17 00:00:00 2001 From: Dave Skender <8432125+DaveSkender@users.noreply.github.com> Date: Sun, 13 Oct 2024 19:20:58 -0400 Subject: [PATCH 25/38] remove experimental EMA primitive buffer --- src/_common/Incrementals/IIncremental.cs | 16 ----- src/e-k/Ema/Ema.Increments.cs | 62 ------------------- .../e-k/Ema/Ema.Increments.Tests.cs | 29 --------- tests/performance/Perf.Increments.cs | 52 ---------------- 4 files changed, 159 deletions(-) diff --git a/src/_common/Incrementals/IIncremental.cs b/src/_common/Incrementals/IIncremental.cs index 611613f74..5014c1f53 100644 --- a/src/_common/Incrementals/IIncremental.cs +++ b/src/_common/Incrementals/IIncremental.cs @@ -50,19 +50,3 @@ public interface IIncrementQuote /// void Add(IReadOnlyList quotes); } - -/// -/// This produces the same results as the equivalent -/// time-series indicator, but is optimized for primitive type operations. -/// Since it does not retain a date context, -/// all new values provided to the -/// method are expected to be in chronological order. -/// -public interface IIncrementPrimitive -{ - /// - void Add(double value); - - /// - void Add(double[] values); -} diff --git a/src/e-k/Ema/Ema.Increments.cs b/src/e-k/Ema/Ema.Increments.cs index 4f077b6a8..59d4a4c7d 100644 --- a/src/e-k/Ema/Ema.Increments.cs +++ b/src/e-k/Ema/Ema.Increments.cs @@ -88,65 +88,3 @@ public void Add(IReadOnlyList quotes) } } } - -/// -/// Exponential Moving Average (EMA) -/// from incremental primitives, without date context. -/// -/// -public class EmaIncPrimitive : List, IEma, IIncrementPrimitive -{ - private readonly Queue _buffer; - private double _bufferSum; - - public EmaIncPrimitive(int lookbackPeriods) - { - Ema.Validate(lookbackPeriods); - LookbackPeriods = lookbackPeriods; - K = 2d / (lookbackPeriods + 1); - - _buffer = new(lookbackPeriods); - _bufferSum = 0; - } - - public int LookbackPeriods { get; init; } - public double K { get; init; } - - public void Add(double value) - { - // update buffer - if (_buffer.Count == LookbackPeriods) - { - _bufferSum -= _buffer.Dequeue(); - } - _buffer.Enqueue(value); - _bufferSum += value; - - // add nulls for incalculable periods - if (Count < LookbackPeriods - 1) - { - base.Add(null); - return; - } - - // re/initialize as SMA - if (this[^1] is null) - { - base.Add(_bufferSum / LookbackPeriods); - return; - } - - // calculate EMA normally - base.Add(Ema.Increment(K, this[^1], value)); - } - - public void Add(double[] values) - { - ArgumentNullException.ThrowIfNull(values); - - for (int i = 0; i < values.Length; i++) - { - Add(values[i]); - } - } -} diff --git a/tests/indicators/e-k/Ema/Ema.Increments.Tests.cs b/tests/indicators/e-k/Ema/Ema.Increments.Tests.cs index 02bd30aa6..5e6b5bc4e 100644 --- a/tests/indicators/e-k/Ema/Ema.Increments.Tests.cs +++ b/tests/indicators/e-k/Ema/Ema.Increments.Tests.cs @@ -5,11 +5,6 @@ public class Ema : IncrementsTestBase { private const int lookbackPeriods = 14; - private static readonly double[] primatives - = Quotes - .Select(x => (double)x.Close) - .ToArray(); - private static readonly IReadOnlyList reusables = Quotes .Cast() @@ -19,10 +14,6 @@ private static readonly IReadOnlyList series = Api.GetEma(Quotes , lookbackPeriods); - private static readonly List seriesArray = series - .Select(x => x.Ema) - .ToList(); - [TestMethod] public void FromReusableSplit() { @@ -79,24 +70,4 @@ IReadOnlyList series sut.Should().HaveCount(Quotes.Count); sut.Should().BeEquivalentTo(series); } - - [TestMethod] - public void FromPrimitive() - { - EmaIncPrimitive sut = new(lookbackPeriods); - - foreach (double p in primatives) { sut.Add(p); } - - sut.Should().HaveCount(Quotes.Count); - sut.Should().BeEquivalentTo(seriesArray); - } - - [TestMethod] - public void FromPrimitiveBatch() - { - EmaIncPrimitive sut = new(lookbackPeriods) { primatives }; - - sut.Should().HaveCount(Quotes.Count); - sut.Should().BeEquivalentTo(seriesArray); - } } diff --git a/tests/performance/Perf.Increments.cs b/tests/performance/Perf.Increments.cs index 9188e17b9..348c9c74c 100644 --- a/tests/performance/Perf.Increments.cs +++ b/tests/performance/Perf.Increments.cs @@ -12,11 +12,6 @@ private static readonly List quotesList = quotes .ToSortedList(); - private static readonly double[] primitives - = quotes - .Select(x => x.Value) - .ToArray(); - private static readonly IReadOnlyList reusables = quotes .Cast() @@ -87,26 +82,6 @@ public object EmaIncQot() return sut; } - [Benchmark] - public object EmaIncPrmBatch() - { - EmaIncPrimitive sut = new(14) { primitives }; - return sut; - } - - [Benchmark] - public object EmaIncPrm() - { - EmaIncPrimitive sut = new(14); - - for (int i = 0; i < primitives.Length; i++) - { - sut.Add(primitives[i]); - } - - return sut; - } - // TIME-SERIES EQUIVALENTS [Benchmark] @@ -124,31 +99,4 @@ public object EmaIncremEqiv() [Benchmark] public object EmaStreamEqiv() => provider.ToEma(14).Results; - - [Benchmark] - public object SmaArrOrig() - { - int periods = 20; - double[] results = new double[primitives.Length]; - - for (int i = 0; i < primitives.Length; i++) - { - if (i < periods - 1) - { - results[i] = double.NaN; - continue; - } - - double sum = 0; - for (int w = i - periods + 1; w <= i; w++) - { - sum += primitives[i]; - } - results[i] = sum / periods; - } - return results; - } - - [Benchmark] - public object SmaArrSimd() => primitives.CalcSma(20); } From e5c4a4cd52475eae09c87fd193c20d9a2dcd02f7 Mon Sep 17 00:00:00 2001 From: Dave Skender <8432125+DaveSkender@users.noreply.github.com> Date: Sun, 13 Oct 2024 19:44:08 -0400 Subject: [PATCH 26/38] add readonly quotes validation + tests --- src/_common/Quotes/Quote.Validation.cs | 50 ++++++++++++++++++++++++ tests/other/PublicApi.Interface.Tests.cs | 23 ++++++++++- 2 files changed, 72 insertions(+), 1 deletion(-) diff --git a/src/_common/Quotes/Quote.Validation.cs b/src/_common/Quotes/Quote.Validation.cs index 2a75e5235..b0197e78b 100644 --- a/src/_common/Quotes/Quote.Validation.cs +++ b/src/_common/Quotes/Quote.Validation.cs @@ -1,3 +1,5 @@ +using System.Globalization; + namespace Skender.Stock.Indicators; // QUOTE UTILITIES @@ -19,6 +21,7 @@ public static IReadOnlyList Validate( DateTime lastDate = DateTime.MinValue; foreach (TQuote q in quotesList) { + // check for duplicates if (lastDate == q.Timestamp) { throw new InvalidQuotesException( @@ -30,4 +33,51 @@ public static IReadOnlyList Validate( return quotesList; } + + /// + /// Check that quotes are valid and in ascending order. + /// + /// IQuote type + /// List of quotes + /// Valid list of quotes + /// + /// List of quotes cannot be a null reference. + /// + /// + /// Duplicate or out of sequence quotes found. + /// + public static IReadOnlyList Validate( + this IReadOnlyList quotes) + where TQuote : IQuote + { + // assumes already sorted + if (quotes is null) + { + throw new ArgumentNullException(nameof(quotes)); + } + + // check for duplicates/sequence + DateTime lastDate = DateTime.MinValue; + foreach (TQuote q in quotes) + { + // check for duplicates + if (lastDate == q.Timestamp) + { + throw new InvalidQuotesException( + string.Format(CultureInfo.InvariantCulture, "Duplicate date found on {0}.", q.Timestamp)); + } + + // check for sequence + if (lastDate > q.Timestamp) + { + throw new InvalidQuotesException( + string.Format(NativeCulture, "Quotes are out of sequence on {0}.", q.Timestamp)); + } + + lastDate = q.Timestamp; + } + + return quotes; + } + } diff --git a/tests/other/PublicApi.Interface.Tests.cs b/tests/other/PublicApi.Interface.Tests.cs index a1111684a..ae9a96cc0 100644 --- a/tests/other/PublicApi.Interface.Tests.cs +++ b/tests/other/PublicApi.Interface.Tests.cs @@ -9,15 +9,36 @@ namespace PublicApi; public class UserInterface { private static readonly IReadOnlyList quotes = Data.GetDefault(); + private static readonly IReadOnlyList quotesBad = Data.GetBad(); [TestMethod] - public void QuoteValidation() + public void QuoteValidationEnumerable() { IEnumerable enumerable = quotes; enumerable.Validate(); enumerable.GetSma(6); Api.GetEma(enumerable, 5); + + Assert.ThrowsException( + () => quotesBad.Validate()); + } + + [TestMethod] + public void QuoteValidationReadOnlyList() + { + IReadOnlyList clean = quotes; + + clean.Validate(); + clean.GetSma(6); + Api.GetEma(clean, 5); + + IReadOnlyList reverse = quotes + .OrderByDescending(x => x.Timestamp) + .ToList(); + + Assert.ThrowsException( + () => reverse.Validate()); } [TestMethod] From 5df1ffdb56983ccccf55fe8133d789f9d3fa18e0 Mon Sep 17 00:00:00 2001 From: Dave Skender <8432125+DaveSkender@users.noreply.github.com> Date: Sun, 13 Oct 2024 22:34:51 -0400 Subject: [PATCH 27/38] use IReadOnly result inputs --- src/_common/Generics/Pruning.cs | 4 +- src/_common/Generics/Transforms.cs | 5 +- src/_common/Math/Numerical.cs | 22 ++----- src/_common/ObsoleteV3.cs | 2 +- src/_common/Quotes/Quote.Converters.cs | 2 - src/_common/Quotes/Quote.Validation.cs | 57 +++++-------------- src/_common/Quotes/info.xml | 17 +----- src/_common/Reusable/Reusable.Utilities.cs | 7 +-- src/a-d/Adx/Adx.Utilities.cs | 4 +- src/a-d/Alligator/Alligator.Utilities.cs | 2 +- src/a-d/Alma/Alma.Api.cs | 2 +- src/a-d/Alma/Alma.Utilities.cs | 4 +- src/a-d/Aroon/Aroon.Utilities.cs | 4 +- src/a-d/Atr/Atr.Utilities.cs | 2 +- src/a-d/AtrStop/AtrStop.Utilities.cs | 8 +-- src/a-d/Awesome/Awesome.Utilities.cs | 4 +- src/a-d/Beta/Beta.Utilities.cs | 4 +- src/a-d/BollingerBands/BollingerBands.Api.cs | 2 +- .../BollingerBands.Utilities.cs | 4 +- src/a-d/Bop/Bop.Utilities.cs | 4 +- src/a-d/Cci/Cci.Utilities.cs | 4 +- src/a-d/ChaikinOsc/ChaikinOsc.StaticSeries.cs | 4 +- src/a-d/ChaikinOsc/ChaikinOsc.Utilities.cs | 4 +- src/a-d/Chandelier/Chandelier.Utilities.cs | 4 +- src/a-d/Chop/Chop.Utilities.cs | 4 +- src/a-d/Cmf/Cmf.Utilities.cs | 4 +- src/a-d/Cmo/Cmo.Utilities.cs | 4 +- src/a-d/ConnorsRsi/ConnorsRsi.Api.cs | 2 +- src/a-d/ConnorsRsi/ConnorsRsi.Utilities.cs | 4 +- src/a-d/Correlation/Correlation.Utilities.cs | 4 +- src/a-d/Dema/Dema.Api.cs | 2 +- src/a-d/Dema/Dema.Utilities.cs | 4 +- src/a-d/Donchian/Donchian.Utilities.cs | 8 +-- src/a-d/Dpo/Dpo.Api.cs | 2 +- src/a-d/Dpo/Dpo.StaticSeries.cs | 2 +- src/a-d/Dynamic/Dynamic.Api.cs | 2 +- src/e-k/ElderRay/ElderRay.StaticSeries.cs | 4 +- src/e-k/ElderRay/ElderRay.Utilities.cs | 4 +- src/e-k/Ema/Ema.Api.cs | 15 +---- src/e-k/Ema/Ema.StaticSeries.cs | 5 +- src/e-k/Ema/Ema.Utilities.cs | 2 +- src/e-k/Epma/Epma.Api.cs | 2 +- src/e-k/Epma/Epma.Utilities.cs | 4 +- src/e-k/Fcb/Fcb.Utilities.cs | 8 +-- .../FisherTransform/FisherTransform.Api.cs | 2 +- src/e-k/ForceIndex/ForceIndex.Utilities.cs | 4 +- src/e-k/Fractal/Fractal.Utilities.cs | 4 +- src/e-k/Gator/Gator.Utilities.cs | 8 +-- src/e-k/Hma/Hma.Api.cs | 2 +- src/e-k/Hma/Hma.Utilities.cs | 4 +- src/e-k/HtTrendline/HtTrendline.Utilities.cs | 4 +- src/e-k/Hurst/Hurst.Api.cs | 2 +- src/e-k/Hurst/Hurst.Utilities.cs | 4 +- src/e-k/Ichimoku/Ichimoku.Utilities.cs | 4 +- src/e-k/Kama/Kama.Utilities.cs | 4 +- src/e-k/Keltner/Keltner.StaticSeries.cs | 2 +- src/e-k/Keltner/Keltner.Utilities.cs | 8 +-- src/e-k/Kvo/Kvo.Utilities.cs | 4 +- src/m-r/MaEnvelopes/MaEnvelopes.Api.cs | 2 +- .../MaEnvelopes/MaEnvelopes.StaticSeries.cs | 4 +- src/m-r/MaEnvelopes/MaEnvelopes.Utilities.cs | 4 +- src/m-r/Macd/Macd.Utilities.cs | 4 +- src/m-r/Macd/MacdApi.cs | 2 +- src/m-r/Mama/Mama.Api.cs | 2 +- src/m-r/Mama/Mama.Utilities.cs | 4 +- src/m-r/Mfi/Mfi.Utilities.cs | 4 +- .../ParabolicSar/ParabolicSar.Utilities.cs | 4 +- src/m-r/PivotPoints/PivotPoints.Utilities.cs | 4 +- src/m-r/Pivots/Pivots.Utilities.cs | 4 +- src/m-r/Pmo/Pmo.Api.cs | 2 +- src/m-r/Pmo/Pmo.Utilities.cs | 4 +- src/m-r/Pvo/Pvo.Utilities.cs | 4 +- src/m-r/Roc/Roc.Api.cs | 2 +- src/m-r/Roc/Roc.Utilities.cs | 4 +- src/m-r/RocWb/RocWb.Api.cs | 2 +- src/m-r/RocWb/RocWb.Utilities.cs | 4 +- .../RollingPivots/RollingPivots.Utilities.cs | 4 +- src/m-r/Rsi/Rsi.Api.cs | 2 +- src/m-r/Rsi/Rsi.Utilities.cs | 4 +- src/s-z/Slope/Slope.Api.cs | 2 +- src/s-z/Slope/Slope.Utilities.cs | 4 +- src/s-z/Sma/Sma.Api.cs | 9 --- src/s-z/Sma/Sma.StaticSeries.cs | 7 ++- .../SmaAnalysis/SmaAnalysis.StaticSeries.cs | 2 +- src/s-z/Smi/Smi.Utilities.cs | 4 +- src/s-z/Smma/Smma.Api.cs | 2 +- src/s-z/Smma/Smma.Utilities.cs | 4 +- src/s-z/StarcBands/StarcBands.StaticSeries.cs | 6 +- src/s-z/StarcBands/StarcBands.Utilities.cs | 8 +-- src/s-z/Stc/Stc.Api.cs | 2 +- src/s-z/Stc/Stc.Utilities.cs | 4 +- src/s-z/StdDev/StdDev.Api.cs | 2 +- src/s-z/StdDev/StdDev.Utilities.cs | 4 +- src/s-z/StdDevChannels/StdDevChannels.Api.cs | 2 +- .../StdDevChannels.Utilities.cs | 8 +-- src/s-z/Stoch/Stoch.Utilities.cs | 4 +- src/s-z/StochRsi/StochRsi.Api.cs | 2 +- src/s-z/StochRsi/StochRsi.Utilities.cs | 4 +- src/s-z/SuperTrend/SuperTrend.Utilities.cs | 8 +-- src/s-z/T3/T3.Api.cs | 2 +- src/s-z/Tema/Tema.Api.cs | 2 +- src/s-z/Tema/Tema.Utilities.cs | 4 +- src/s-z/Trix/Trix.Api.cs | 2 +- src/s-z/Trix/Trix.Utilities.cs | 4 +- src/s-z/Tsi/Tsi.Api.cs | 2 +- src/s-z/Tsi/Tsi.Utilities.cs | 4 +- src/s-z/UlcerIndex/UlcerIndex.Api.cs | 2 +- src/s-z/UlcerIndex/UlcerIndex.Utilities.cs | 4 +- src/s-z/Ultimate/Ultimate.Utilities.cs | 4 +- .../VolatilityStop.Utilities.cs | 4 +- src/s-z/Vortex/Vortex.Utilities.cs | 8 +-- src/s-z/Vwap/Vwap.Utilities.cs | 4 +- src/s-z/Vwma/Vwma.Utilities.cs | 4 +- src/s-z/WilliamsR/WilliamsR.Utilities.cs | 4 +- src/s-z/Wma/Wma.Api.cs | 2 +- src/s-z/Wma/Wma.Utilities.cs | 4 +- src/s-z/ZigZag/ZigZag.Utilities.cs | 4 +- .../Observables/StreamHub.Observable.Tests.cs | 2 +- .../_common/Quotes/Quote.StreamHub.Tests.cs | 2 +- .../_common/Quotes/Quote.Validation.Tests.cs | 4 +- .../QuotePart.StaticSeries.Tests.cs | 2 +- .../QuotePart.StreamHub.Tests.cs | 2 +- .../a-d/Adl/Adl.StaticSeries.Tests.cs | 2 +- .../indicators/a-d/Adl/Adl.StreamHub.Tests.cs | 2 +- .../a-d/Adx/Adx.StaticSeries.Tests.cs | 2 +- .../Alligator/Alligator.StaticSeries.Tests.cs | 2 +- .../Alligator/Alligator.StreamHub.Tests.cs | 2 +- .../a-d/Alma/Alma.StaticSeries.Tests.cs | 4 +- .../a-d/Aroon/Aroon.StaticSeries.Tests.cs | 2 +- .../a-d/Atr/Atr.StaticSeries.Tests.cs | 2 +- .../indicators/a-d/Atr/Atr.StreamHub.Tests.cs | 2 +- .../a-d/Awesome/Awesome.StaticSeries.Tests.cs | 4 +- .../a-d/Beta/Beta.StaticSeries.Tests.cs | 6 +- .../BollingerBands.StaticSeries.Tests.cs | 4 +- .../a-d/Bop/Bop.StaticSeries.Tests.cs | 2 +- .../a-d/Cci/Cci.StaticSeries.Tests.cs | 2 +- .../ChaikinOsc.StaticSeries.Tests.cs | 2 +- .../Chandelier.StaticSeries.Tests.cs | 2 +- .../a-d/Chop/Chop.StaticSeries.Tests.cs | 2 +- .../a-d/Cmf/Cmf.StaticSeries.Tests.cs | 2 +- .../a-d/Cmo/Cmo.StaticSeries.Tests.cs | 4 +- .../ConnorsRsi.StaticSeries.Tests.cs | 4 +- .../Correlation.StaticSeries.Tests.cs | 6 +- .../a-d/Dema/Dema.StaticSeries.Tests.cs | 4 +- .../a-d/Dpo/Dpo.StaticSeries.Tests.cs | 4 +- .../a-d/Dynamic/Dynamic.StaticSeries.Tests.cs | 4 +- .../ElderRay/ElderRay.StaticSeries.Tests.cs | 2 +- .../e-k/Ema/Ema.Increments.Tests.cs | 5 +- .../e-k/Ema/Ema.StaticSeries.Tests.cs | 33 +++++------ .../indicators/e-k/Ema/Ema.StreamHub.Tests.cs | 12 ++-- .../e-k/Epma/Epma.StaticSeries.Tests.cs | 4 +- .../FisherTransform.StaticSeries.Tests.cs | 4 +- .../ForceIndex.StaticSeries.Tests.cs | 2 +- .../e-k/Gator/Gator.StaticSeries.Tests.cs | 2 +- .../HeikinAshi.StaticSeries.Tests.cs | 4 +- .../e-k/Hma/Hma.StaticSeries.Tests.cs | 4 +- .../HtTrendline.StaticSeries.Tests.cs | 4 +- .../e-k/Hurst/Hurst.StaticSeries.Tests.cs | 4 +- .../e-k/Kama/Kama.StaticSeries.Tests.cs | 4 +- .../e-k/Kvo/Kvo.StaticSeries.Tests.cs | 2 +- .../MaEnvelopes.StaticSeries.Tests.cs | 2 +- .../m-r/Macd/Macd.StaticSeries.Tests.cs | 4 +- .../m-r/Mama/Mama.StaticSeries.Tests.cs | 4 +- .../m-r/Mfi/Mfi.StaticSeries.Tests.cs | 2 +- .../m-r/Obv/Obv.StaticSeries.Tests.cs | 2 +- .../ParabolicSar.StaticSeries.Tests.cs | 2 +- .../m-r/Pmo/Pmo.StaticSeries.Tests.cs | 4 +- .../m-r/Prs/Prs.StaticSeries.Tests.cs | 6 +- .../m-r/Pvo/Pvo.StaticSeries.Tests.cs | 2 +- .../m-r/Renko/Renko.StaticSeries.Tests.cs | 4 +- .../m-r/Renko/Renko.StreamHub.Tests.cs | 2 +- .../m-r/Roc/Roc.StaticSeries.Tests.cs | 4 +- .../m-r/RocWb/RocWb.StaticSeries.Tests.cs | 4 +- .../m-r/Rsi/Rsi.StaticSeries.Tests.cs | 8 +-- .../s-z/Slope/Slope.StaticSeries.Tests.cs | 4 +- .../s-z/Sma/Sma.StaticSeries.Tests.cs | 22 +++---- .../indicators/s-z/Sma/Sma.StreamHub.Tests.cs | 8 +-- .../SmaAnalysis.StaticSeries.Tests.cs | 4 +- .../s-z/Smi/Smi.StaticSeries.Tests.cs | 2 +- .../s-z/Smma/Smma.StaticSeries.Tests.cs | 4 +- .../s-z/Stc/Stc.StaticSeries.Tests.cs | 4 +- .../s-z/StdDev/StdDev.StaticSeries.Tests.cs | 4 +- .../StdDevChannels.StaticSeries.Tests.cs | 2 +- .../s-z/Stoch/Stoch.StaticSeries.Tests.cs | 2 +- .../StochRsi/StochRsi.StaticSeries.Tests.cs | 4 +- .../s-z/T3/T3.StaticSeries.Tests.cs | 4 +- .../s-z/Tema/Tema.StaticSeries.Tests.cs | 4 +- tests/indicators/s-z/Tr/Tr.StreamHub.Tests.cs | 2 +- .../s-z/Trix/Trix.StaticSeries.Tests.cs | 4 +- .../s-z/Tsi/Tsi.StaticSeries.Tests.cs | 4 +- .../UlcerIndex.StaticSeries.Tests.cs | 4 +- .../Ultimate/Ultimate.StaticSeries.Tests.cs | 2 +- .../VolatilityStop.StaticSeries.Tests.cs | 2 +- .../s-z/Vwap/Vwap.StaticSeries.Tests.cs | 2 +- .../s-z/Vwma/Vwma.StaticSeries.Tests.cs | 2 +- .../WilliamsR/WilliamsR.StaticSeries.Tests.cs | 2 +- .../s-z/Wma/Wma.StaticSeries.Tests.cs | 4 +- .../s-z/ZigZag/ZigZag.StaticSeries.Tests.cs | 2 +- tests/other/Convergence.Tests.cs | 2 +- tests/other/Custom.Indicator.Tests.cs | 2 +- tests/other/Custom.Quotes.Tests.cs | 6 +- tests/other/Custom.Results.Tests.cs | 4 +- tests/other/PublicApi.Interface.Tests.cs | 28 ++++----- tests/other/Sut.CustomItems.cs | 2 +- tests/performance/Perf.Increments.cs | 15 ++--- tests/performance/Perf.StaticSeries.cs | 4 +- tests/performance/Perf.StreamHub.Externals.cs | 2 +- 207 files changed, 406 insertions(+), 517 deletions(-) diff --git a/src/_common/Generics/Pruning.cs b/src/_common/Generics/Pruning.cs index c6d58f089..997957a91 100644 --- a/src/_common/Generics/Pruning.cs +++ b/src/_common/Generics/Pruning.cs @@ -6,7 +6,7 @@ public static partial class Utility { // REMOVE SPECIFIC PERIODS public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable series, + this IReadOnlyList series, int removePeriods) => removePeriods < 0 ? throw new ArgumentOutOfRangeException(nameof(removePeriods), removePeriods, @@ -15,7 +15,7 @@ public static IReadOnlyList RemoveWarmupPeriods( // REMOVE PERIODS internal static List Remove( - this IEnumerable series, + this IReadOnlyList series, int removePeriods) { List seriesList = series.ToList(); diff --git a/src/_common/Generics/Transforms.cs b/src/_common/Generics/Transforms.cs index eb2f63415..11e6b3ffd 100644 --- a/src/_common/Generics/Transforms.cs +++ b/src/_common/Generics/Transforms.cs @@ -9,10 +9,7 @@ public static partial class Utility // TO COLLECTION internal static Collection ToCollection(this IEnumerable source) { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + ArgumentNullException.ThrowIfNull(source); Collection collection = [.. source]; diff --git a/src/_common/Math/Numerical.cs b/src/_common/Math/Numerical.cs index b9e68e69b..bba184344 100644 --- a/src/_common/Math/Numerical.cs +++ b/src/_common/Math/Numerical.cs @@ -5,13 +5,8 @@ public static class Numerical // STANDARD DEVIATION public static double StdDev(this double[] values) { - // validate parameters - if (values is null) - { - throw new ArgumentNullException( - nameof(values), - "StdDev values cannot be null."); - } + ArgumentNullException.ThrowIfNull( + values, "StdDev values cannot be null."); int n = values.Length; @@ -43,17 +38,8 @@ public static double StdDev(this double[] values) public static double Slope(double[] x, double[] y) { // validate parameters - if (x is null) - { - throw new ArgumentNullException( - nameof(x), "Slope X values cannot be null."); - } - - if (y is null) - { - throw new ArgumentNullException( - nameof(y), "Slope Y values cannot be null."); - } + ArgumentNullException.ThrowIfNull(x, "Slope X values cannot be null."); + ArgumentNullException.ThrowIfNull(y, "Slope Y values cannot be null."); if (x.Length != y.Length) { diff --git a/src/_common/ObsoleteV3.cs b/src/_common/ObsoleteV3.cs index e5fed2b73..a9f881db2 100644 --- a/src/_common/ObsoleteV3.cs +++ b/src/_common/ObsoleteV3.cs @@ -33,7 +33,7 @@ public static IEnumerable GetAlligator( public static IEnumerable GetEma( this IEnumerable quotes, int lookbackPeriods) where TQuote : IQuote - => Api.GetEma(quotes, lookbackPeriods); + => quotes.ToSortedList().ToEma(lookbackPeriods); // REMOVAL OF INTEGRATED SMAs (evaluates to ERRORs) diff --git a/src/_common/Quotes/Quote.Converters.cs b/src/_common/Quotes/Quote.Converters.cs index d78bbdd97..3aa55d0c1 100644 --- a/src/_common/Quotes/Quote.Converters.cs +++ b/src/_common/Quotes/Quote.Converters.cs @@ -6,8 +6,6 @@ namespace Skender.Stock.Indicators; public static partial class Utility { - private static readonly CultureInfo NativeCulture = Thread.CurrentThread.CurrentUICulture; - /* LISTS */ // convert TQuote type list to built-in Quote type list diff --git a/src/_common/Quotes/Quote.Validation.cs b/src/_common/Quotes/Quote.Validation.cs index b0197e78b..8063da563 100644 --- a/src/_common/Quotes/Quote.Validation.cs +++ b/src/_common/Quotes/Quote.Validation.cs @@ -2,38 +2,10 @@ namespace Skender.Stock.Indicators; -// QUOTE UTILITIES +// QUOTE UTILITIES: VALIDATION public static partial class Utility { - // VALIDATION - /// - /// - public static IReadOnlyList Validate( - this IEnumerable quotes) - where TQuote : IQuote - { - // we cannot rely on date consistency when looking back, so we force sort - - List quotesList = quotes.ToSortedList(); - - // check for duplicates - DateTime lastDate = DateTime.MinValue; - foreach (TQuote q in quotesList) - { - // check for duplicates - if (lastDate == q.Timestamp) - { - throw new InvalidQuotesException( - string.Format(NativeCulture, "Duplicate date found on {0}.", q.Timestamp)); - } - - lastDate = q.Timestamp; - } - - return quotesList; - } - /// /// Check that quotes are valid and in ascending order. /// @@ -50,34 +22,33 @@ public static IReadOnlyList Validate( this IReadOnlyList quotes) where TQuote : IQuote { - // assumes already sorted - if (quotes is null) + ArgumentNullException.ThrowIfNull(quotes); + + if (quotes.Count == 0) { - throw new ArgumentNullException(nameof(quotes)); + return quotes; } - // check for duplicates/sequence - DateTime lastDate = DateTime.MinValue; - foreach (TQuote q in quotes) + DateTime lastDate = quotes[0].Timestamp; + for (int i = 1; i < quotes.Count; i++) { - // check for duplicates - if (lastDate == q.Timestamp) + DateTime currentDate = quotes[i].Timestamp; + + if (lastDate == currentDate) { throw new InvalidQuotesException( - string.Format(CultureInfo.InvariantCulture, "Duplicate date found on {0}.", q.Timestamp)); + string.Format(CultureInfo.InvariantCulture, "Duplicate date found on {0}.", currentDate)); } - // check for sequence - if (lastDate > q.Timestamp) + if (lastDate > currentDate) { throw new InvalidQuotesException( - string.Format(NativeCulture, "Quotes are out of sequence on {0}.", q.Timestamp)); + string.Format(CultureInfo.InvariantCulture, "Quotes are out of sequence on {0}.", currentDate)); } - lastDate = q.Timestamp; + lastDate = currentDate; } return quotes; } - } diff --git a/src/_common/Quotes/info.xml b/src/_common/Quotes/info.xml index d172a60d0..721479e5b 100644 --- a/src/_common/Quotes/info.xml +++ b/src/_common/Quotes/info.xml @@ -2,21 +2,6 @@ - - - Validate historical quotes. - - See - documentation - for more information. - - - Configurable Quote type. See Guide for more information. - Historical price quotes. - Time series of historical quote values. - Validation check failed. - - Converts historical quotes into larger bar sizes. @@ -49,4 +34,4 @@ Invalid parameter value provided. - \ No newline at end of file + diff --git a/src/_common/Reusable/Reusable.Utilities.cs b/src/_common/Reusable/Reusable.Utilities.cs index d49655a27..00a729560 100644 --- a/src/_common/Reusable/Reusable.Utilities.cs +++ b/src/_common/Reusable/Reusable.Utilities.cs @@ -26,7 +26,7 @@ public static IReadOnlyList ToReusableList( /// Indicator results to evaluate. /// Time series of indicator results, condensed. public static IReadOnlyList Condense( - this IEnumerable results) + this IReadOnlyList results) where T : IReusable { List resultsList = results @@ -37,9 +37,6 @@ public static IReadOnlyList Condense( x => double.IsNaN(x.Value)); return resultsList; - - // TODO: remove specific indicator 'Condense()' methods - // that are now redundant to this generic method (not all are) } /// @@ -54,7 +51,7 @@ public static IReadOnlyList Condense( /// Indicator results to evaluate. /// Time series of results, pruned. internal static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) where T : IReusable { // this is the default implementation, it will diff --git a/src/a-d/Adx/Adx.Utilities.cs b/src/a-d/Adx/Adx.Utilities.cs index 67e984948..ff9a1d40f 100644 --- a/src/a-d/Adx/Adx.Utilities.cs +++ b/src/a-d/Adx/Adx.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int n = results .ToList() diff --git a/src/a-d/Alligator/Alligator.Utilities.cs b/src/a-d/Alligator/Alligator.Utilities.cs index 59cae1a79..b0a1fd257 100644 --- a/src/a-d/Alligator/Alligator.Utilities.cs +++ b/src/a-d/Alligator/Alligator.Utilities.cs @@ -18,7 +18,7 @@ public static IReadOnlyList Condense( // remove recommended periods public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int removePeriods = results .ToList() diff --git a/src/a-d/Alma/Alma.Api.cs b/src/a-d/Alma/Alma.Api.cs index 64b49785a..ffb1e3555 100644 --- a/src/a-d/Alma/Alma.Api.cs +++ b/src/a-d/Alma/Alma.Api.cs @@ -5,7 +5,7 @@ public static partial class Indicator { // SERIES, from CHAIN public static IReadOnlyList GetAlma( - this IEnumerable results, + this IReadOnlyList results, int lookbackPeriods = 9, double offset = 0.85, double sigma = 6) diff --git a/src/a-d/Alma/Alma.Utilities.cs b/src/a-d/Alma/Alma.Utilities.cs index bdf32d6ab..13542b0e0 100644 --- a/src/a-d/Alma/Alma.Utilities.cs +++ b/src/a-d/Alma/Alma.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int removePeriods = results .ToList() diff --git a/src/a-d/Aroon/Aroon.Utilities.cs b/src/a-d/Aroon/Aroon.Utilities.cs index d9819d84f..66eb9d036 100644 --- a/src/a-d/Aroon/Aroon.Utilities.cs +++ b/src/a-d/Aroon/Aroon.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int removePeriods = results .ToList() diff --git a/src/a-d/Atr/Atr.Utilities.cs b/src/a-d/Atr/Atr.Utilities.cs index 14239d69a..3b5790747 100644 --- a/src/a-d/Atr/Atr.Utilities.cs +++ b/src/a-d/Atr/Atr.Utilities.cs @@ -41,7 +41,7 @@ public static AtrResult Increment( // remove recommended periods public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int removePeriods = results .ToList() diff --git a/src/a-d/AtrStop/AtrStop.Utilities.cs b/src/a-d/AtrStop/AtrStop.Utilities.cs index a96b27fd5..8f2bd1c5f 100644 --- a/src/a-d/AtrStop/AtrStop.Utilities.cs +++ b/src/a-d/AtrStop/AtrStop.Utilities.cs @@ -5,9 +5,9 @@ namespace Skender.Stock.Indicators; public static partial class AtrStop { // CONDENSE (REMOVE null results) - /// + /// public static IReadOnlyList Condense( - this IEnumerable results) + this IReadOnlyList results) { List resultsList = results .ToList(); @@ -18,9 +18,9 @@ public static IReadOnlyList Condense( } // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int removePeriods = results .ToList() diff --git a/src/a-d/Awesome/Awesome.Utilities.cs b/src/a-d/Awesome/Awesome.Utilities.cs index 63333ebeb..cd8ec64ee 100644 --- a/src/a-d/Awesome/Awesome.Utilities.cs +++ b/src/a-d/Awesome/Awesome.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int removePeriods = results .ToList() diff --git a/src/a-d/Beta/Beta.Utilities.cs b/src/a-d/Beta/Beta.Utilities.cs index ac1a1434c..9cb071a21 100644 --- a/src/a-d/Beta/Beta.Utilities.cs +++ b/src/a-d/Beta/Beta.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int removePeriods = results .ToList() diff --git a/src/a-d/BollingerBands/BollingerBands.Api.cs b/src/a-d/BollingerBands/BollingerBands.Api.cs index 28fa8dda8..aa4c0a99d 100644 --- a/src/a-d/BollingerBands/BollingerBands.Api.cs +++ b/src/a-d/BollingerBands/BollingerBands.Api.cs @@ -5,7 +5,7 @@ public static partial class Indicator { // SERIES, from CHAIN public static IReadOnlyList GetBollingerBands( - this IEnumerable results, + this IReadOnlyList results, int lookbackPeriods = 20, double standardDeviations = 2) where T : IReusable diff --git a/src/a-d/BollingerBands/BollingerBands.Utilities.cs b/src/a-d/BollingerBands/BollingerBands.Utilities.cs index 167fee2b7..b8d3906cb 100644 --- a/src/a-d/BollingerBands/BollingerBands.Utilities.cs +++ b/src/a-d/BollingerBands/BollingerBands.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int removePeriods = results .ToList() diff --git a/src/a-d/Bop/Bop.Utilities.cs b/src/a-d/Bop/Bop.Utilities.cs index 08a059ba9..cb36acf08 100644 --- a/src/a-d/Bop/Bop.Utilities.cs +++ b/src/a-d/Bop/Bop.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int removePeriods = results .ToList() diff --git a/src/a-d/Cci/Cci.Utilities.cs b/src/a-d/Cci/Cci.Utilities.cs index e71456947..fee230bb7 100644 --- a/src/a-d/Cci/Cci.Utilities.cs +++ b/src/a-d/Cci/Cci.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int removePeriods = results .ToList() diff --git a/src/a-d/ChaikinOsc/ChaikinOsc.StaticSeries.cs b/src/a-d/ChaikinOsc/ChaikinOsc.StaticSeries.cs index 00b2ea54a..0cc49d026 100644 --- a/src/a-d/ChaikinOsc/ChaikinOsc.StaticSeries.cs +++ b/src/a-d/ChaikinOsc/ChaikinOsc.StaticSeries.cs @@ -21,8 +21,8 @@ private static List CalcChaikinOsc( List adlResults = source.CalcAdl(); // fast/slow EMA of ADL - List adlEmaSlow = adlResults.CalcEma(slowPeriods); - List adlEmaFast = adlResults.CalcEma(fastPeriods); + IReadOnlyList adlEmaSlow = adlResults.ToEma(slowPeriods); + IReadOnlyList adlEmaFast = adlResults.ToEma(fastPeriods); // roll through source values for (int i = 0; i < length; i++) diff --git a/src/a-d/ChaikinOsc/ChaikinOsc.Utilities.cs b/src/a-d/ChaikinOsc/ChaikinOsc.Utilities.cs index 6f11abc34..edfeb413e 100644 --- a/src/a-d/ChaikinOsc/ChaikinOsc.Utilities.cs +++ b/src/a-d/ChaikinOsc/ChaikinOsc.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int s = results .ToList() diff --git a/src/a-d/Chandelier/Chandelier.Utilities.cs b/src/a-d/Chandelier/Chandelier.Utilities.cs index a7ff84bcb..5ac5dc0b9 100644 --- a/src/a-d/Chandelier/Chandelier.Utilities.cs +++ b/src/a-d/Chandelier/Chandelier.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int removePeriods = results .ToList() diff --git a/src/a-d/Chop/Chop.Utilities.cs b/src/a-d/Chop/Chop.Utilities.cs index 7b93a5d31..bc05a29ba 100644 --- a/src/a-d/Chop/Chop.Utilities.cs +++ b/src/a-d/Chop/Chop.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int removePeriods = results .ToList() diff --git a/src/a-d/Cmf/Cmf.Utilities.cs b/src/a-d/Cmf/Cmf.Utilities.cs index 02954b3d6..2fd812d8e 100644 --- a/src/a-d/Cmf/Cmf.Utilities.cs +++ b/src/a-d/Cmf/Cmf.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int removePeriods = results .ToList() diff --git a/src/a-d/Cmo/Cmo.Utilities.cs b/src/a-d/Cmo/Cmo.Utilities.cs index 3c9b23628..715694baf 100644 --- a/src/a-d/Cmo/Cmo.Utilities.cs +++ b/src/a-d/Cmo/Cmo.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int removePeriods = results .ToList() diff --git a/src/a-d/ConnorsRsi/ConnorsRsi.Api.cs b/src/a-d/ConnorsRsi/ConnorsRsi.Api.cs index 5cb943377..949647b72 100644 --- a/src/a-d/ConnorsRsi/ConnorsRsi.Api.cs +++ b/src/a-d/ConnorsRsi/ConnorsRsi.Api.cs @@ -5,7 +5,7 @@ public static partial class Indicator { // SERIES, from CHAIN public static IReadOnlyList GetConnorsRsi( - this IEnumerable results, + this IReadOnlyList results, int rsiPeriods = 3, int streakPeriods = 2, int rankPeriods = 100) diff --git a/src/a-d/ConnorsRsi/ConnorsRsi.Utilities.cs b/src/a-d/ConnorsRsi/ConnorsRsi.Utilities.cs index b4d79d2d1..313953e5b 100644 --- a/src/a-d/ConnorsRsi/ConnorsRsi.Utilities.cs +++ b/src/a-d/ConnorsRsi/ConnorsRsi.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int n = results .ToList() diff --git a/src/a-d/Correlation/Correlation.Utilities.cs b/src/a-d/Correlation/Correlation.Utilities.cs index a6be6eb7e..dafbf54fa 100644 --- a/src/a-d/Correlation/Correlation.Utilities.cs +++ b/src/a-d/Correlation/Correlation.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int removePeriods = results .ToList() diff --git a/src/a-d/Dema/Dema.Api.cs b/src/a-d/Dema/Dema.Api.cs index fdbfca629..bbabc1acb 100644 --- a/src/a-d/Dema/Dema.Api.cs +++ b/src/a-d/Dema/Dema.Api.cs @@ -5,7 +5,7 @@ public static partial class Indicator { // SERIES, from CHAIN public static IReadOnlyList GetDema( - this IEnumerable results, + this IReadOnlyList results, int lookbackPeriods) where T : IReusable => results diff --git a/src/a-d/Dema/Dema.Utilities.cs b/src/a-d/Dema/Dema.Utilities.cs index 60f63a390..c31646de2 100644 --- a/src/a-d/Dema/Dema.Utilities.cs +++ b/src/a-d/Dema/Dema.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int n = results .ToList() diff --git a/src/a-d/Donchian/Donchian.Utilities.cs b/src/a-d/Donchian/Donchian.Utilities.cs index bc74a5da2..4c7b45533 100644 --- a/src/a-d/Donchian/Donchian.Utilities.cs +++ b/src/a-d/Donchian/Donchian.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // CONDENSE (REMOVE null results) - /// + /// public static IReadOnlyList Condense( - this IEnumerable results) + this IReadOnlyList results) { List resultsList = results .ToList(); @@ -18,9 +18,9 @@ public static IReadOnlyList Condense( } // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int removePeriods = results .ToList() diff --git a/src/a-d/Dpo/Dpo.Api.cs b/src/a-d/Dpo/Dpo.Api.cs index 38a81aea1..740f3b503 100644 --- a/src/a-d/Dpo/Dpo.Api.cs +++ b/src/a-d/Dpo/Dpo.Api.cs @@ -5,7 +5,7 @@ public static partial class Indicator { // SERIES, from CHAIN public static IReadOnlyList GetDpo( - this IEnumerable results, + this IReadOnlyList results, int lookbackPeriods) where T : IReusable => results diff --git a/src/a-d/Dpo/Dpo.StaticSeries.cs b/src/a-d/Dpo/Dpo.StaticSeries.cs index 6f55dd35a..2c79a189d 100644 --- a/src/a-d/Dpo/Dpo.StaticSeries.cs +++ b/src/a-d/Dpo/Dpo.StaticSeries.cs @@ -20,7 +20,7 @@ private static List CalcDpo( int offset = (lookbackPeriods / 2) + 1; IReadOnlyList sma - = source.CalcSma(lookbackPeriods); + = source.ToSma(lookbackPeriods); // roll through source values for (int i = 0; i < length; i++) diff --git a/src/a-d/Dynamic/Dynamic.Api.cs b/src/a-d/Dynamic/Dynamic.Api.cs index 55f47ec05..9a953f59f 100644 --- a/src/a-d/Dynamic/Dynamic.Api.cs +++ b/src/a-d/Dynamic/Dynamic.Api.cs @@ -6,7 +6,7 @@ public static partial class MgDynamic { // SERIES, from CHAIN public static IReadOnlyList GetDynamic( - this IEnumerable results, + this IReadOnlyList results, int lookbackPeriods, double kFactor = 0.6) where T : IReusable diff --git a/src/e-k/ElderRay/ElderRay.StaticSeries.cs b/src/e-k/ElderRay/ElderRay.StaticSeries.cs index 0400056bb..3935caa6a 100644 --- a/src/e-k/ElderRay/ElderRay.StaticSeries.cs +++ b/src/e-k/ElderRay/ElderRay.StaticSeries.cs @@ -16,8 +16,8 @@ private static List CalcElderRay( List results = new(length); // EMA - List emaResults - = source.CalcEma(lookbackPeriods); + IReadOnlyList emaResults + = source.ToEma(lookbackPeriods); // roll through source values for (int i = 0; i < length; i++) diff --git a/src/e-k/ElderRay/ElderRay.Utilities.cs b/src/e-k/ElderRay/ElderRay.Utilities.cs index e38e79590..052844eea 100644 --- a/src/e-k/ElderRay/ElderRay.Utilities.cs +++ b/src/e-k/ElderRay/ElderRay.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int n = results .ToList() diff --git a/src/e-k/Ema/Ema.Api.cs b/src/e-k/Ema/Ema.Api.cs index 10bac357f..bf9d82f37 100644 --- a/src/e-k/Ema/Ema.Api.cs +++ b/src/e-k/Ema/Ema.Api.cs @@ -2,21 +2,8 @@ namespace Skender.Stock.Indicators; // EXPONENTIAL MOVING AVERAGE (API) -public static partial class Api +public static partial class Ema { - //SERIES, from CHAIN - public static IReadOnlyList GetEma( - - // FIX: Use "Ema" instead of "Api" class name - // It fails when renaming this to ToEma() - - this IEnumerable results, - int lookbackPeriods) - where T : IReusable - => results - .ToSortedList() - .CalcEma(lookbackPeriods); - // HUB, from Chain Provider public static EmaHub ToEma( this IChainProvider chainProvider, diff --git a/src/e-k/Ema/Ema.StaticSeries.cs b/src/e-k/Ema/Ema.StaticSeries.cs index ae46fa361..49ad66637 100644 --- a/src/e-k/Ema/Ema.StaticSeries.cs +++ b/src/e-k/Ema/Ema.StaticSeries.cs @@ -4,12 +4,13 @@ namespace Skender.Stock.Indicators; public static partial class Ema { - internal static List CalcEma( - this List source, + public static IReadOnlyList ToEma( + this IReadOnlyList source, int lookbackPeriods) where T : IReusable { // check parameter arguments + ArgumentNullException.ThrowIfNull(source); Validate(lookbackPeriods); // initialize diff --git a/src/e-k/Ema/Ema.Utilities.cs b/src/e-k/Ema/Ema.Utilities.cs index eb922d370..6a8f8f1f0 100644 --- a/src/e-k/Ema/Ema.Utilities.cs +++ b/src/e-k/Ema/Ema.Utilities.cs @@ -27,7 +27,7 @@ public static double Increment( // remove recommended periods public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int n = results .ToList() diff --git a/src/e-k/Epma/Epma.Api.cs b/src/e-k/Epma/Epma.Api.cs index 932ccea70..0937ac444 100644 --- a/src/e-k/Epma/Epma.Api.cs +++ b/src/e-k/Epma/Epma.Api.cs @@ -5,7 +5,7 @@ public static partial class Indicator { // SERIES, from CHAIN public static IReadOnlyList GetEpma( - this IEnumerable results, + this IReadOnlyList results, int lookbackPeriods) where T : IReusable => results diff --git a/src/e-k/Epma/Epma.Utilities.cs b/src/e-k/Epma/Epma.Utilities.cs index 1376bb215..b0e7bbdf1 100644 --- a/src/e-k/Epma/Epma.Utilities.cs +++ b/src/e-k/Epma/Epma.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int removePeriods = results .ToList() diff --git a/src/e-k/Fcb/Fcb.Utilities.cs b/src/e-k/Fcb/Fcb.Utilities.cs index 989961b6d..b1ac461a7 100644 --- a/src/e-k/Fcb/Fcb.Utilities.cs +++ b/src/e-k/Fcb/Fcb.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // CONDENSE (REMOVE null results) - /// + /// public static IReadOnlyList Condense( - this IEnumerable results) + this IReadOnlyList results) { List resultsList = results .ToList(); @@ -18,9 +18,9 @@ public static IReadOnlyList Condense( } // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int removePeriods = results .ToList() diff --git a/src/e-k/FisherTransform/FisherTransform.Api.cs b/src/e-k/FisherTransform/FisherTransform.Api.cs index 0a8ba4f0c..51cec1dc9 100644 --- a/src/e-k/FisherTransform/FisherTransform.Api.cs +++ b/src/e-k/FisherTransform/FisherTransform.Api.cs @@ -5,7 +5,7 @@ public static partial class Indicator { // SERIES, from CHAIN public static IReadOnlyList GetFisherTransform( - this IEnumerable results, + this IReadOnlyList results, int lookbackPeriods = 10) where T : IReusable => results diff --git a/src/e-k/ForceIndex/ForceIndex.Utilities.cs b/src/e-k/ForceIndex/ForceIndex.Utilities.cs index 428b8dcfc..9c8ce8899 100644 --- a/src/e-k/ForceIndex/ForceIndex.Utilities.cs +++ b/src/e-k/ForceIndex/ForceIndex.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int n = results .ToList() diff --git a/src/e-k/Fractal/Fractal.Utilities.cs b/src/e-k/Fractal/Fractal.Utilities.cs index 5926ae46a..be6e56385 100644 --- a/src/e-k/Fractal/Fractal.Utilities.cs +++ b/src/e-k/Fractal/Fractal.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // CONDENSE (REMOVE null results) - /// + /// public static IReadOnlyList Condense( - this IEnumerable results) + this IReadOnlyList results) { List resultsList = results .ToList(); diff --git a/src/e-k/Gator/Gator.Utilities.cs b/src/e-k/Gator/Gator.Utilities.cs index e8be0f046..d2ce6e2a6 100644 --- a/src/e-k/Gator/Gator.Utilities.cs +++ b/src/e-k/Gator/Gator.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // CONDENSE (REMOVE null results) - /// + /// public static IReadOnlyList Condense( - this IEnumerable results) + this IReadOnlyList results) { List resultsList = results .ToList(); @@ -18,7 +18,7 @@ public static IReadOnlyList Condense( } // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) => results.Remove(150); + this IReadOnlyList results) => results.Remove(150); } diff --git a/src/e-k/Hma/Hma.Api.cs b/src/e-k/Hma/Hma.Api.cs index 2ea9d317d..8d11e4041 100644 --- a/src/e-k/Hma/Hma.Api.cs +++ b/src/e-k/Hma/Hma.Api.cs @@ -5,7 +5,7 @@ public static partial class Indicator { // SERIES, from CHAIN public static IReadOnlyList GetHma( - this IEnumerable results, + this IReadOnlyList results, int lookbackPeriods) where T : IReusable => results diff --git a/src/e-k/Hma/Hma.Utilities.cs b/src/e-k/Hma/Hma.Utilities.cs index d22ef9ffe..bbed74d40 100644 --- a/src/e-k/Hma/Hma.Utilities.cs +++ b/src/e-k/Hma/Hma.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int removePeriods = results .ToList() diff --git a/src/e-k/HtTrendline/HtTrendline.Utilities.cs b/src/e-k/HtTrendline/HtTrendline.Utilities.cs index b4fe28e15..ad7ef3c75 100644 --- a/src/e-k/HtTrendline/HtTrendline.Utilities.cs +++ b/src/e-k/HtTrendline/HtTrendline.Utilities.cs @@ -3,7 +3,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) => results.Remove(100); + this IReadOnlyList results) => results.Remove(100); } diff --git a/src/e-k/Hurst/Hurst.Api.cs b/src/e-k/Hurst/Hurst.Api.cs index 18789abed..ae882f69c 100644 --- a/src/e-k/Hurst/Hurst.Api.cs +++ b/src/e-k/Hurst/Hurst.Api.cs @@ -5,7 +5,7 @@ public static partial class Indicator { // SERIES, from CHAIN public static IReadOnlyList GetHurst( - this IEnumerable results, + this IReadOnlyList results, int lookbackPeriods = 100) where T : IReusable => results diff --git a/src/e-k/Hurst/Hurst.Utilities.cs b/src/e-k/Hurst/Hurst.Utilities.cs index 827f95467..bbce8e52a 100644 --- a/src/e-k/Hurst/Hurst.Utilities.cs +++ b/src/e-k/Hurst/Hurst.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int removePeriods = results .ToList() diff --git a/src/e-k/Ichimoku/Ichimoku.Utilities.cs b/src/e-k/Ichimoku/Ichimoku.Utilities.cs index 0e5f7891e..b09b048f0 100644 --- a/src/e-k/Ichimoku/Ichimoku.Utilities.cs +++ b/src/e-k/Ichimoku/Ichimoku.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // CONDENSE (REMOVE null results) - /// + /// public static IReadOnlyList Condense( - this IEnumerable results) + this IReadOnlyList results) { List resultsList = results .ToList(); diff --git a/src/e-k/Kama/Kama.Utilities.cs b/src/e-k/Kama/Kama.Utilities.cs index 3f844acab..ec2dada62 100644 --- a/src/e-k/Kama/Kama.Utilities.cs +++ b/src/e-k/Kama/Kama.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Kama { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int erPeriods = results .ToList() diff --git a/src/e-k/Keltner/Keltner.StaticSeries.cs b/src/e-k/Keltner/Keltner.StaticSeries.cs index 922d44401..f9fabdee9 100644 --- a/src/e-k/Keltner/Keltner.StaticSeries.cs +++ b/src/e-k/Keltner/Keltner.StaticSeries.cs @@ -18,7 +18,7 @@ private static List CalcKeltner( List results = new(length); IReadOnlyList emaResults - = source.CalcEma(emaPeriods); + = source.ToEma(emaPeriods); IReadOnlyList atrResults = source.CalcAtr(atrPeriods); diff --git a/src/e-k/Keltner/Keltner.Utilities.cs b/src/e-k/Keltner/Keltner.Utilities.cs index b97b5e68e..450152548 100644 --- a/src/e-k/Keltner/Keltner.Utilities.cs +++ b/src/e-k/Keltner/Keltner.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // CONDENSE (REMOVE null results) - /// + /// public static IReadOnlyList Condense( - this IEnumerable results) + this IReadOnlyList results) { List resultsList = results .ToList(); @@ -18,9 +18,9 @@ public static IReadOnlyList Condense( } // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int n = results .ToList() diff --git a/src/e-k/Kvo/Kvo.Utilities.cs b/src/e-k/Kvo/Kvo.Utilities.cs index b57303ac8..35d18ee9b 100644 --- a/src/e-k/Kvo/Kvo.Utilities.cs +++ b/src/e-k/Kvo/Kvo.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int l = results .ToList() diff --git a/src/m-r/MaEnvelopes/MaEnvelopes.Api.cs b/src/m-r/MaEnvelopes/MaEnvelopes.Api.cs index 477c7006c..d83d0b2f8 100644 --- a/src/m-r/MaEnvelopes/MaEnvelopes.Api.cs +++ b/src/m-r/MaEnvelopes/MaEnvelopes.Api.cs @@ -5,7 +5,7 @@ public static partial class Indicator { // SERIES, from CHAIN public static IReadOnlyList GetMaEnvelopes( - this IEnumerable results, + this IReadOnlyList results, int lookbackPeriods, double percentOffset = 2.5, MaType movingAverageType = MaType.SMA) diff --git a/src/m-r/MaEnvelopes/MaEnvelopes.StaticSeries.cs b/src/m-r/MaEnvelopes/MaEnvelopes.StaticSeries.cs index c2c065a0e..41736bb0e 100644 --- a/src/m-r/MaEnvelopes/MaEnvelopes.StaticSeries.cs +++ b/src/m-r/MaEnvelopes/MaEnvelopes.StaticSeries.cs @@ -72,7 +72,7 @@ private static IEnumerable MaEnvEma( int lookbackPeriods, double offsetRatio) where T : IReusable - => source.CalcEma(lookbackPeriods) + => source.ToEma(lookbackPeriods) .Select(x => new MaEnvelopeResult( Timestamp: x.Timestamp, Centerline: x.Ema, @@ -108,7 +108,7 @@ private static IEnumerable MaEnvSma( int lookbackPeriods, double offsetRatio) where T : IReusable - => source.CalcSma(lookbackPeriods) + => source.ToSma(lookbackPeriods) .Select(x => new MaEnvelopeResult( Timestamp: x.Timestamp, Centerline: x.Sma, diff --git a/src/m-r/MaEnvelopes/MaEnvelopes.Utilities.cs b/src/m-r/MaEnvelopes/MaEnvelopes.Utilities.cs index 55937c355..e2f6bdca5 100644 --- a/src/m-r/MaEnvelopes/MaEnvelopes.Utilities.cs +++ b/src/m-r/MaEnvelopes/MaEnvelopes.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // CONDENSE (REMOVE null results) - /// + /// public static IReadOnlyList Condense( - this IEnumerable results) + this IReadOnlyList results) { List resultsList = results .ToList(); diff --git a/src/m-r/Macd/Macd.Utilities.cs b/src/m-r/Macd/Macd.Utilities.cs index 53c0a5227..981a844a7 100644 --- a/src/m-r/Macd/Macd.Utilities.cs +++ b/src/m-r/Macd/Macd.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int n = results .ToList() diff --git a/src/m-r/Macd/MacdApi.cs b/src/m-r/Macd/MacdApi.cs index db9759211..a5d342aea 100644 --- a/src/m-r/Macd/MacdApi.cs +++ b/src/m-r/Macd/MacdApi.cs @@ -5,7 +5,7 @@ public static partial class Indicator { // SERIES, from CHAIN public static IReadOnlyList GetMacd( - this IEnumerable results, + this IReadOnlyList results, int fastPeriods = 12, int slowPeriods = 26, int signalPeriods = 9) diff --git a/src/m-r/Mama/Mama.Api.cs b/src/m-r/Mama/Mama.Api.cs index 5b4d98e0a..34264484d 100644 --- a/src/m-r/Mama/Mama.Api.cs +++ b/src/m-r/Mama/Mama.Api.cs @@ -5,7 +5,7 @@ public static partial class Indicator { // SERIES, from CHAIN public static IReadOnlyList GetMama( - this IEnumerable results, + this IReadOnlyList results, double fastLimit = 0.5, double slowLimit = 0.05) where T : IReusable diff --git a/src/m-r/Mama/Mama.Utilities.cs b/src/m-r/Mama/Mama.Utilities.cs index 3789e8d72..6ccb00e26 100644 --- a/src/m-r/Mama/Mama.Utilities.cs +++ b/src/m-r/Mama/Mama.Utilities.cs @@ -3,7 +3,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) => results.Remove(50); + this IReadOnlyList results) => results.Remove(50); } diff --git a/src/m-r/Mfi/Mfi.Utilities.cs b/src/m-r/Mfi/Mfi.Utilities.cs index 07a1ba3c9..a3e420448 100644 --- a/src/m-r/Mfi/Mfi.Utilities.cs +++ b/src/m-r/Mfi/Mfi.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int removePeriods = results .ToList() diff --git a/src/m-r/ParabolicSar/ParabolicSar.Utilities.cs b/src/m-r/ParabolicSar/ParabolicSar.Utilities.cs index 4c9db1b4b..e08d805dd 100644 --- a/src/m-r/ParabolicSar/ParabolicSar.Utilities.cs +++ b/src/m-r/ParabolicSar/ParabolicSar.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int removePeriods = results .ToList() diff --git a/src/m-r/PivotPoints/PivotPoints.Utilities.cs b/src/m-r/PivotPoints/PivotPoints.Utilities.cs index 0de695e83..56ef7fd2e 100644 --- a/src/m-r/PivotPoints/PivotPoints.Utilities.cs +++ b/src/m-r/PivotPoints/PivotPoints.Utilities.cs @@ -4,9 +4,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int removePeriods = results .ToList() diff --git a/src/m-r/Pivots/Pivots.Utilities.cs b/src/m-r/Pivots/Pivots.Utilities.cs index 65417f95a..620d15622 100644 --- a/src/m-r/Pivots/Pivots.Utilities.cs +++ b/src/m-r/Pivots/Pivots.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // CONDENSE (REMOVE null results) - /// + /// public static IReadOnlyList Condense( - this IEnumerable results) + this IReadOnlyList results) { List resultsList = results .ToList(); diff --git a/src/m-r/Pmo/Pmo.Api.cs b/src/m-r/Pmo/Pmo.Api.cs index 6dd0e9481..99801c5d0 100644 --- a/src/m-r/Pmo/Pmo.Api.cs +++ b/src/m-r/Pmo/Pmo.Api.cs @@ -5,7 +5,7 @@ public static partial class Indicator { // SERIES, from CHAIN public static IReadOnlyList GetPmo( - this IEnumerable results, + this IReadOnlyList results, int timePeriods = 35, int smoothPeriods = 20, int signalPeriods = 10) diff --git a/src/m-r/Pmo/Pmo.Utilities.cs b/src/m-r/Pmo/Pmo.Utilities.cs index 388388b4c..02e0e10c0 100644 --- a/src/m-r/Pmo/Pmo.Utilities.cs +++ b/src/m-r/Pmo/Pmo.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int ts = results .ToList() diff --git a/src/m-r/Pvo/Pvo.Utilities.cs b/src/m-r/Pvo/Pvo.Utilities.cs index 05729ea59..efd19f3ee 100644 --- a/src/m-r/Pvo/Pvo.Utilities.cs +++ b/src/m-r/Pvo/Pvo.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int n = results .ToList() diff --git a/src/m-r/Roc/Roc.Api.cs b/src/m-r/Roc/Roc.Api.cs index f087095af..a6759f4e5 100644 --- a/src/m-r/Roc/Roc.Api.cs +++ b/src/m-r/Roc/Roc.Api.cs @@ -5,7 +5,7 @@ public static partial class Indicator { // SERIES, from CHAIN public static IReadOnlyList GetRoc( - this IEnumerable results, + this IReadOnlyList results, int lookbackPeriods) where T : IReusable => results diff --git a/src/m-r/Roc/Roc.Utilities.cs b/src/m-r/Roc/Roc.Utilities.cs index 132642fe7..a16969444 100644 --- a/src/m-r/Roc/Roc.Utilities.cs +++ b/src/m-r/Roc/Roc.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int removePeriods = results .ToList() diff --git a/src/m-r/RocWb/RocWb.Api.cs b/src/m-r/RocWb/RocWb.Api.cs index a32ec46f0..ed5f5bed1 100644 --- a/src/m-r/RocWb/RocWb.Api.cs +++ b/src/m-r/RocWb/RocWb.Api.cs @@ -5,7 +5,7 @@ public static partial class Indicator { // SERIES, from CHAIN public static IReadOnlyList GetRocWb( - this IEnumerable results, + this IReadOnlyList results, int lookbackPeriods, int emaPeriods, int stdDevPeriods) diff --git a/src/m-r/RocWb/RocWb.Utilities.cs b/src/m-r/RocWb/RocWb.Utilities.cs index 60cbc8c64..c2f0321bc 100644 --- a/src/m-r/RocWb/RocWb.Utilities.cs +++ b/src/m-r/RocWb/RocWb.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int n = results .ToList() diff --git a/src/m-r/RollingPivots/RollingPivots.Utilities.cs b/src/m-r/RollingPivots/RollingPivots.Utilities.cs index 420fdd5c7..43ad0a3d7 100644 --- a/src/m-r/RollingPivots/RollingPivots.Utilities.cs +++ b/src/m-r/RollingPivots/RollingPivots.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int removePeriods = results .ToList() diff --git a/src/m-r/Rsi/Rsi.Api.cs b/src/m-r/Rsi/Rsi.Api.cs index a12cfeea7..85f27accd 100644 --- a/src/m-r/Rsi/Rsi.Api.cs +++ b/src/m-r/Rsi/Rsi.Api.cs @@ -5,7 +5,7 @@ public static partial class Indicator { // SERIES, from CHAIN public static IReadOnlyList GetRsi( - this IEnumerable results, + this IReadOnlyList results, int lookbackPeriods = 14) where T : IReusable => results diff --git a/src/m-r/Rsi/Rsi.Utilities.cs b/src/m-r/Rsi/Rsi.Utilities.cs index ed81fd4a4..25ecc15ca 100644 --- a/src/m-r/Rsi/Rsi.Utilities.cs +++ b/src/m-r/Rsi/Rsi.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int n = results .ToList() diff --git a/src/s-z/Slope/Slope.Api.cs b/src/s-z/Slope/Slope.Api.cs index 5b3a7ec7e..1760f9ae2 100644 --- a/src/s-z/Slope/Slope.Api.cs +++ b/src/s-z/Slope/Slope.Api.cs @@ -5,7 +5,7 @@ public static partial class Indicator { // SERIES, from CHAIN public static IReadOnlyList GetSlope( - this IEnumerable results, + this IReadOnlyList results, int lookbackPeriods) where T : IReusable => results diff --git a/src/s-z/Slope/Slope.Utilities.cs b/src/s-z/Slope/Slope.Utilities.cs index bbe498ed9..99ce32fd9 100644 --- a/src/s-z/Slope/Slope.Utilities.cs +++ b/src/s-z/Slope/Slope.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int removePeriods = results .ToList() diff --git a/src/s-z/Sma/Sma.Api.cs b/src/s-z/Sma/Sma.Api.cs index d8b39b6fc..e1eaf6712 100644 --- a/src/s-z/Sma/Sma.Api.cs +++ b/src/s-z/Sma/Sma.Api.cs @@ -4,15 +4,6 @@ namespace Skender.Stock.Indicators; public static partial class Sma { - // SERIES, from CHAIN - public static IReadOnlyList GetSma( - this IEnumerable source, - int lookbackPeriods) - where T : IReusable - => source - .ToSortedList() - .CalcSma(lookbackPeriods); - // OBSERVER, from Chain Provider public static SmaHub ToSma( this IChainProvider chainProvider, diff --git a/src/s-z/Sma/Sma.StaticSeries.cs b/src/s-z/Sma/Sma.StaticSeries.cs index 06de8a4f1..a0b7a5c39 100644 --- a/src/s-z/Sma/Sma.StaticSeries.cs +++ b/src/s-z/Sma/Sma.StaticSeries.cs @@ -4,13 +4,14 @@ namespace Skender.Stock.Indicators; public static partial class Sma { - internal static List CalcSma( - this List source, + public static IReadOnlyList ToSma( + this IReadOnlyList source, int lookbackPeriods) where T : IReusable { // check parameter arguments - Sma.Validate(lookbackPeriods); + ArgumentNullException.ThrowIfNull(source); + Validate(lookbackPeriods); // initialize int length = source.Count; diff --git a/src/s-z/SmaAnalysis/SmaAnalysis.StaticSeries.cs b/src/s-z/SmaAnalysis/SmaAnalysis.StaticSeries.cs index cf9486374..b52cc6c08 100644 --- a/src/s-z/SmaAnalysis/SmaAnalysis.StaticSeries.cs +++ b/src/s-z/SmaAnalysis/SmaAnalysis.StaticSeries.cs @@ -10,7 +10,7 @@ private static List CalcSmaAnalysis( { // initialize List results = source - .CalcSma(lookbackPeriods) + .ToSma(lookbackPeriods) .Select(s => new SmaAnalysis(s.Timestamp, s.Sma)) .ToList(); diff --git a/src/s-z/Smi/Smi.Utilities.cs b/src/s-z/Smi/Smi.Utilities.cs index 77b41759e..3b4b3a5af 100644 --- a/src/s-z/Smi/Smi.Utilities.cs +++ b/src/s-z/Smi/Smi.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int removePeriods = results .ToList() diff --git a/src/s-z/Smma/Smma.Api.cs b/src/s-z/Smma/Smma.Api.cs index d614d06f9..b792078a9 100644 --- a/src/s-z/Smma/Smma.Api.cs +++ b/src/s-z/Smma/Smma.Api.cs @@ -5,7 +5,7 @@ public static partial class Indicator { // SERIES, from CHAIN public static IReadOnlyList GetSmma( - this IEnumerable results, + this IReadOnlyList results, int lookbackPeriods) where T : IReusable => results diff --git a/src/s-z/Smma/Smma.Utilities.cs b/src/s-z/Smma/Smma.Utilities.cs index 5681a3e18..f77205627 100644 --- a/src/s-z/Smma/Smma.Utilities.cs +++ b/src/s-z/Smma/Smma.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int n = results .ToList() diff --git a/src/s-z/StarcBands/StarcBands.StaticSeries.cs b/src/s-z/StarcBands/StarcBands.StaticSeries.cs index 92bb409f2..106f5f753 100644 --- a/src/s-z/StarcBands/StarcBands.StaticSeries.cs +++ b/src/s-z/StarcBands/StarcBands.StaticSeries.cs @@ -17,7 +17,7 @@ private static List CalcStarcBands( int length = source.Count; List results = new(length); List atrResults = source.CalcAtr(atrPeriods); - List smaResults = source.CalcSma(smaPeriods); + IReadOnlyList smaResults = source.ToSma(smaPeriods); // roll through source values for (int i = 0; i < length; i++) @@ -28,8 +28,8 @@ private static List CalcStarcBands( results.Add(new( Timestamp: s.Timestamp, Centerline: s.Sma, - UpperBand: s.Sma + multiplier * a.Atr, - LowerBand: s.Sma - multiplier * a.Atr)); + UpperBand: s.Sma + (multiplier * a.Atr), + LowerBand: s.Sma - (multiplier * a.Atr))); } return results; diff --git a/src/s-z/StarcBands/StarcBands.Utilities.cs b/src/s-z/StarcBands/StarcBands.Utilities.cs index 8eb9c85c1..92e05adc5 100644 --- a/src/s-z/StarcBands/StarcBands.Utilities.cs +++ b/src/s-z/StarcBands/StarcBands.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // CONDENSE (REMOVE null results) - /// + /// public static IReadOnlyList Condense( - this IEnumerable results) + this IReadOnlyList results) { List resultsList = results .ToList(); @@ -18,9 +18,9 @@ public static IReadOnlyList Condense( } // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int n = results .ToList() diff --git a/src/s-z/Stc/Stc.Api.cs b/src/s-z/Stc/Stc.Api.cs index 199a5c519..aa8b638b5 100644 --- a/src/s-z/Stc/Stc.Api.cs +++ b/src/s-z/Stc/Stc.Api.cs @@ -5,7 +5,7 @@ public static partial class Indicator { // SERIES, from CHAIN public static IReadOnlyList GetStc( - this IEnumerable results, + this IReadOnlyList results, int cyclePeriods = 10, int fastPeriods = 23, int slowPeriods = 50) diff --git a/src/s-z/Stc/Stc.Utilities.cs b/src/s-z/Stc/Stc.Utilities.cs index 96763e7a9..390492324 100644 --- a/src/s-z/Stc/Stc.Utilities.cs +++ b/src/s-z/Stc/Stc.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int n = results .ToList() diff --git a/src/s-z/StdDev/StdDev.Api.cs b/src/s-z/StdDev/StdDev.Api.cs index 3488c082a..6bc98569e 100644 --- a/src/s-z/StdDev/StdDev.Api.cs +++ b/src/s-z/StdDev/StdDev.Api.cs @@ -5,7 +5,7 @@ public static partial class Indicator { // SERIES, from CHAIN public static IReadOnlyList GetStdDev( - this IEnumerable results, + this IReadOnlyList results, int lookbackPeriods) where T : IReusable => results diff --git a/src/s-z/StdDev/StdDev.Utilities.cs b/src/s-z/StdDev/StdDev.Utilities.cs index 90648f99b..7f519e639 100644 --- a/src/s-z/StdDev/StdDev.Utilities.cs +++ b/src/s-z/StdDev/StdDev.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int removePeriods = results .ToList() diff --git a/src/s-z/StdDevChannels/StdDevChannels.Api.cs b/src/s-z/StdDevChannels/StdDevChannels.Api.cs index d063b151b..5557f4274 100644 --- a/src/s-z/StdDevChannels/StdDevChannels.Api.cs +++ b/src/s-z/StdDevChannels/StdDevChannels.Api.cs @@ -5,7 +5,7 @@ public static partial class Indicator { // SERIES, from CHAIN public static IReadOnlyList GetStdDevChannels( - this IEnumerable results, + this IReadOnlyList results, int? lookbackPeriods = 20, double stdDeviations = 2) where T : IReusable diff --git a/src/s-z/StdDevChannels/StdDevChannels.Utilities.cs b/src/s-z/StdDevChannels/StdDevChannels.Utilities.cs index 881f7381c..228ff78d4 100644 --- a/src/s-z/StdDevChannels/StdDevChannels.Utilities.cs +++ b/src/s-z/StdDevChannels/StdDevChannels.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // CONDENSE (REMOVE null results) - /// + /// public static IReadOnlyList Condense( - this IEnumerable results) + this IReadOnlyList results) { List resultsList = results .ToList(); @@ -21,9 +21,9 @@ x.UpperChannel is null } // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int removePeriods = results .ToList() diff --git a/src/s-z/Stoch/Stoch.Utilities.cs b/src/s-z/Stoch/Stoch.Utilities.cs index 61df7f848..5b3eb2806 100644 --- a/src/s-z/Stoch/Stoch.Utilities.cs +++ b/src/s-z/Stoch/Stoch.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int removePeriods = results .ToList() diff --git a/src/s-z/StochRsi/StochRsi.Api.cs b/src/s-z/StochRsi/StochRsi.Api.cs index 83c3985ae..cb0c41945 100644 --- a/src/s-z/StochRsi/StochRsi.Api.cs +++ b/src/s-z/StochRsi/StochRsi.Api.cs @@ -5,7 +5,7 @@ public static partial class Indicator { // SERIES, from CHAIN public static IReadOnlyList GetStochRsi( - this IEnumerable results, + this IReadOnlyList results, int rsiPeriods, int stochPeriods, int signalPeriods, diff --git a/src/s-z/StochRsi/StochRsi.Utilities.cs b/src/s-z/StochRsi/StochRsi.Utilities.cs index 03ace36c6..00dd324b4 100644 --- a/src/s-z/StochRsi/StochRsi.Utilities.cs +++ b/src/s-z/StochRsi/StochRsi.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int n = results .ToList() diff --git a/src/s-z/SuperTrend/SuperTrend.Utilities.cs b/src/s-z/SuperTrend/SuperTrend.Utilities.cs index 749f35339..d5bf857dc 100644 --- a/src/s-z/SuperTrend/SuperTrend.Utilities.cs +++ b/src/s-z/SuperTrend/SuperTrend.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // CONDENSE (REMOVE null results) - /// + /// public static IReadOnlyList Condense( - this IEnumerable results) + this IReadOnlyList results) { List resultsList = results .ToList(); @@ -18,9 +18,9 @@ public static IReadOnlyList Condense( } // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int removePeriods = results .ToList() diff --git a/src/s-z/T3/T3.Api.cs b/src/s-z/T3/T3.Api.cs index 610f3008b..fbfb6794d 100644 --- a/src/s-z/T3/T3.Api.cs +++ b/src/s-z/T3/T3.Api.cs @@ -5,7 +5,7 @@ public static partial class Indicator { // SERIES, from CHAIN public static IReadOnlyList GetT3( - this IEnumerable results, + this IReadOnlyList results, int lookbackPeriods = 5, double volumeFactor = 0.7) where T : IReusable diff --git a/src/s-z/Tema/Tema.Api.cs b/src/s-z/Tema/Tema.Api.cs index 5cbb96ad7..b3b6f0107 100644 --- a/src/s-z/Tema/Tema.Api.cs +++ b/src/s-z/Tema/Tema.Api.cs @@ -5,7 +5,7 @@ public static partial class Indicator { // SERIES, from CHAIN public static IReadOnlyList GetTema( - this IEnumerable results, + this IReadOnlyList results, int lookbackPeriods) where T : IReusable => results diff --git a/src/s-z/Tema/Tema.Utilities.cs b/src/s-z/Tema/Tema.Utilities.cs index 594228578..e0a559dc3 100644 --- a/src/s-z/Tema/Tema.Utilities.cs +++ b/src/s-z/Tema/Tema.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int n = results .ToList() diff --git a/src/s-z/Trix/Trix.Api.cs b/src/s-z/Trix/Trix.Api.cs index a08e53bb5..3b114888d 100644 --- a/src/s-z/Trix/Trix.Api.cs +++ b/src/s-z/Trix/Trix.Api.cs @@ -5,7 +5,7 @@ public static partial class Indicator { // SERIES, from CHAIN public static IReadOnlyList GetTrix( - this IEnumerable results, + this IReadOnlyList results, int lookbackPeriods) where T : IReusable => results diff --git a/src/s-z/Trix/Trix.Utilities.cs b/src/s-z/Trix/Trix.Utilities.cs index 97f041a6d..8aeaac921 100644 --- a/src/s-z/Trix/Trix.Utilities.cs +++ b/src/s-z/Trix/Trix.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int n = results .ToList() diff --git a/src/s-z/Tsi/Tsi.Api.cs b/src/s-z/Tsi/Tsi.Api.cs index 029928648..4d688f345 100644 --- a/src/s-z/Tsi/Tsi.Api.cs +++ b/src/s-z/Tsi/Tsi.Api.cs @@ -5,7 +5,7 @@ public static partial class Indicator { // SERIES, from CHAIN public static IReadOnlyList GetTsi( - this IEnumerable results, + this IReadOnlyList results, int lookbackPeriods = 25, int smoothPeriods = 13, int signalPeriods = 7) diff --git a/src/s-z/Tsi/Tsi.Utilities.cs b/src/s-z/Tsi/Tsi.Utilities.cs index 04d622781..1d8921bd2 100644 --- a/src/s-z/Tsi/Tsi.Utilities.cs +++ b/src/s-z/Tsi/Tsi.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int nm = results .ToList() diff --git a/src/s-z/UlcerIndex/UlcerIndex.Api.cs b/src/s-z/UlcerIndex/UlcerIndex.Api.cs index ed6fab72a..bb5322f22 100644 --- a/src/s-z/UlcerIndex/UlcerIndex.Api.cs +++ b/src/s-z/UlcerIndex/UlcerIndex.Api.cs @@ -5,7 +5,7 @@ public static partial class Indicator { // SERIES, from CHAIN public static IReadOnlyList GetUlcerIndex( - this IEnumerable results, + this IReadOnlyList results, int lookbackPeriods = 14) where T : IReusable => results diff --git a/src/s-z/UlcerIndex/UlcerIndex.Utilities.cs b/src/s-z/UlcerIndex/UlcerIndex.Utilities.cs index da03ac1a7..eb66129de 100644 --- a/src/s-z/UlcerIndex/UlcerIndex.Utilities.cs +++ b/src/s-z/UlcerIndex/UlcerIndex.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int removePeriods = results .ToList() diff --git a/src/s-z/Ultimate/Ultimate.Utilities.cs b/src/s-z/Ultimate/Ultimate.Utilities.cs index bb1ce4389..187318b1f 100644 --- a/src/s-z/Ultimate/Ultimate.Utilities.cs +++ b/src/s-z/Ultimate/Ultimate.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int removePeriods = results .ToList() diff --git a/src/s-z/VolatilityStop/VolatilityStop.Utilities.cs b/src/s-z/VolatilityStop/VolatilityStop.Utilities.cs index 6713b93ee..203926f57 100644 --- a/src/s-z/VolatilityStop/VolatilityStop.Utilities.cs +++ b/src/s-z/VolatilityStop/VolatilityStop.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int removePeriods = results .ToList() diff --git a/src/s-z/Vortex/Vortex.Utilities.cs b/src/s-z/Vortex/Vortex.Utilities.cs index 0b49878f1..db723ca83 100644 --- a/src/s-z/Vortex/Vortex.Utilities.cs +++ b/src/s-z/Vortex/Vortex.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // CONDENSE (REMOVE null results) - /// + /// public static IReadOnlyList Condense( - this IEnumerable results) + this IReadOnlyList results) { List resultsList = results .ToList(); @@ -18,9 +18,9 @@ public static IReadOnlyList Condense( } // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int removePeriods = results .ToList() diff --git a/src/s-z/Vwap/Vwap.Utilities.cs b/src/s-z/Vwap/Vwap.Utilities.cs index 10c8cc564..1b2de2b61 100644 --- a/src/s-z/Vwap/Vwap.Utilities.cs +++ b/src/s-z/Vwap/Vwap.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int removePeriods = results .ToList() diff --git a/src/s-z/Vwma/Vwma.Utilities.cs b/src/s-z/Vwma/Vwma.Utilities.cs index aeee25851..dcb253ac3 100644 --- a/src/s-z/Vwma/Vwma.Utilities.cs +++ b/src/s-z/Vwma/Vwma.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int removePeriods = results .ToList() diff --git a/src/s-z/WilliamsR/WilliamsR.Utilities.cs b/src/s-z/WilliamsR/WilliamsR.Utilities.cs index a7cdaab47..ab1d51037 100644 --- a/src/s-z/WilliamsR/WilliamsR.Utilities.cs +++ b/src/s-z/WilliamsR/WilliamsR.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int removePeriods = results .ToList() diff --git a/src/s-z/Wma/Wma.Api.cs b/src/s-z/Wma/Wma.Api.cs index f3af400ea..f6d77132d 100644 --- a/src/s-z/Wma/Wma.Api.cs +++ b/src/s-z/Wma/Wma.Api.cs @@ -5,7 +5,7 @@ public static partial class Indicator { // SERIES, from CHAIN public static IReadOnlyList GetWma( - this IEnumerable results, + this IReadOnlyList results, int lookbackPeriods) where T : IReusable => results diff --git a/src/s-z/Wma/Wma.Utilities.cs b/src/s-z/Wma/Wma.Utilities.cs index d9225ffde..44c72b402 100644 --- a/src/s-z/Wma/Wma.Utilities.cs +++ b/src/s-z/Wma/Wma.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IEnumerable results) + this IReadOnlyList results) { int removePeriods = results .ToList() diff --git a/src/s-z/ZigZag/ZigZag.Utilities.cs b/src/s-z/ZigZag/ZigZag.Utilities.cs index c35be15d0..5bd39608a 100644 --- a/src/s-z/ZigZag/ZigZag.Utilities.cs +++ b/src/s-z/ZigZag/ZigZag.Utilities.cs @@ -3,9 +3,9 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // CONDENSE (REMOVE null results) - /// + /// public static IReadOnlyList Condense( - this IEnumerable results) + this IReadOnlyList results) { List resultsList = results .ToList(); diff --git a/tests/indicators/_common/Observables/StreamHub.Observable.Tests.cs b/tests/indicators/_common/Observables/StreamHub.Observable.Tests.cs index def163d9f..8dcb6f73c 100644 --- a/tests/indicators/_common/Observables/StreamHub.Observable.Tests.cs +++ b/tests/indicators/_common/Observables/StreamHub.Observable.Tests.cs @@ -100,7 +100,7 @@ IReadOnlyList streamList // time-series, for comparison IReadOnlyList seriesList = Quotes .Use(CandlePart.HL2) - .GetEma(11); + .ToEma(11); // assert, should equal series streamList.Should().HaveCount(Quotes.Count); diff --git a/tests/indicators/_common/Quotes/Quote.StreamHub.Tests.cs b/tests/indicators/_common/Quotes/Quote.StreamHub.Tests.cs index c9871b9cc..36dd4ef05 100644 --- a/tests/indicators/_common/Quotes/Quote.StreamHub.Tests.cs +++ b/tests/indicators/_common/Quotes/Quote.StreamHub.Tests.cs @@ -73,7 +73,7 @@ IReadOnlyList streamList // time-series, for comparison IReadOnlyList seriesList = quotesList - .GetSma(smaPeriods); + .ToSma(smaPeriods); // assert, should equal series streamList.Should().HaveCount(length - 1); diff --git a/tests/indicators/_common/Quotes/Quote.Validation.Tests.cs b/tests/indicators/_common/Quotes/Quote.Validation.Tests.cs index 2dcc1d0aa..a4f27eb64 100644 --- a/tests/indicators/_common/Quotes/Quote.Validation.Tests.cs +++ b/tests/indicators/_common/Quotes/Quote.Validation.Tests.cs @@ -48,7 +48,7 @@ public void ValidateCut() Assert.AreEqual(200, h.Count); // should be 20 results and no index corruption - IReadOnlyList r1 = h.TakeLast(20).GetSma(14).ToList(); + IReadOnlyList r1 = h.TakeLast(20).ToList().ToSma(14).ToList(); Assert.AreEqual(20, r1.Count); for (int i = 1; i < r1.Count; i++) @@ -57,7 +57,7 @@ public void ValidateCut() } // should be 50 results and no index corruption - IReadOnlyList r2 = h.TakeLast(50).GetSma(14).ToList(); + IReadOnlyList r2 = h.TakeLast(50).ToList().ToSma(14).ToList(); Assert.AreEqual(50, r2.Count); for (int i = 1; i < r2.Count; i++) diff --git a/tests/indicators/_common/Use (QuotePart)/QuotePart.StaticSeries.Tests.cs b/tests/indicators/_common/Use (QuotePart)/QuotePart.StaticSeries.Tests.cs index 3f879cd3c..720328894 100644 --- a/tests/indicators/_common/Use (QuotePart)/QuotePart.StaticSeries.Tests.cs +++ b/tests/indicators/_common/Use (QuotePart)/QuotePart.StaticSeries.Tests.cs @@ -56,7 +56,7 @@ public void Chainor() { IReadOnlyList results = Quotes .Use(CandlePart.Close) - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(493, results.Count(x => x.Sma != null)); diff --git a/tests/indicators/_common/Use (QuotePart)/QuotePart.StreamHub.Tests.cs b/tests/indicators/_common/Use (QuotePart)/QuotePart.StreamHub.Tests.cs index f5b8a1405..4aa893bdb 100644 --- a/tests/indicators/_common/Use (QuotePart)/QuotePart.StreamHub.Tests.cs +++ b/tests/indicators/_common/Use (QuotePart)/QuotePart.StreamHub.Tests.cs @@ -116,7 +116,7 @@ IReadOnlyList streamList IReadOnlyList seriesList = quotesList .Use(candlePart) - .GetSma(smaPeriods); + .ToSma(smaPeriods); // assert, should equal series for (int i = 0; i < length - 1; i++) diff --git a/tests/indicators/a-d/Adl/Adl.StaticSeries.Tests.cs b/tests/indicators/a-d/Adl/Adl.StaticSeries.Tests.cs index 94f245bc7..d336216fa 100644 --- a/tests/indicators/a-d/Adl/Adl.StaticSeries.Tests.cs +++ b/tests/indicators/a-d/Adl/Adl.StaticSeries.Tests.cs @@ -29,7 +29,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetAdl() - .GetSma(10); + .ToSma(10); // assertions diff --git a/tests/indicators/a-d/Adl/Adl.StreamHub.Tests.cs b/tests/indicators/a-d/Adl/Adl.StreamHub.Tests.cs index 4554a8b83..db3ba55b1 100644 --- a/tests/indicators/a-d/Adl/Adl.StreamHub.Tests.cs +++ b/tests/indicators/a-d/Adl/Adl.StreamHub.Tests.cs @@ -103,7 +103,7 @@ IReadOnlyList streamList // time-series, for comparison IReadOnlyList seriesList = quotesList .GetAdl() - .GetSma(smaPeriods); + .ToSma(smaPeriods); // assert, should equal series streamList.Should().HaveCount(length - 1); diff --git a/tests/indicators/a-d/Adx/Adx.StaticSeries.Tests.cs b/tests/indicators/a-d/Adx/Adx.StaticSeries.Tests.cs index fdd6e89c1..fbf8b2a65 100644 --- a/tests/indicators/a-d/Adx/Adx.StaticSeries.Tests.cs +++ b/tests/indicators/a-d/Adx/Adx.StaticSeries.Tests.cs @@ -47,7 +47,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetAdx() - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(466, results.Count(x => x.Sma != null)); diff --git a/tests/indicators/a-d/Alligator/Alligator.StaticSeries.Tests.cs b/tests/indicators/a-d/Alligator/Alligator.StaticSeries.Tests.cs index ab84e4578..50399eeb0 100644 --- a/tests/indicators/a-d/Alligator/Alligator.StaticSeries.Tests.cs +++ b/tests/indicators/a-d/Alligator/Alligator.StaticSeries.Tests.cs @@ -46,7 +46,7 @@ public override void Standard() public void Chainee() { IReadOnlyList results = Quotes - .GetSma(2) + .ToSma(2) .GetAlligator(); Assert.AreEqual(502, results.Count); diff --git a/tests/indicators/a-d/Alligator/Alligator.StreamHub.Tests.cs b/tests/indicators/a-d/Alligator/Alligator.StreamHub.Tests.cs index 5d9ce4f3a..bfe92a4e1 100644 --- a/tests/indicators/a-d/Alligator/Alligator.StreamHub.Tests.cs +++ b/tests/indicators/a-d/Alligator/Alligator.StreamHub.Tests.cs @@ -117,7 +117,7 @@ IReadOnlyList streamList // time-series, for comparison IReadOnlyList seriesList = quotesList - .GetSma(10) + .ToSma(10) .GetAlligator(); // assert, should equal series diff --git a/tests/indicators/a-d/Alma/Alma.StaticSeries.Tests.cs b/tests/indicators/a-d/Alma/Alma.StaticSeries.Tests.cs index 75a77bb66..de8e61331 100644 --- a/tests/indicators/a-d/Alma/Alma.StaticSeries.Tests.cs +++ b/tests/indicators/a-d/Alma/Alma.StaticSeries.Tests.cs @@ -55,7 +55,7 @@ public void UseReusable() public void Chainee() { IReadOnlyList results = Quotes - .GetSma(2) + .ToSma(2) .GetAlma(10); Assert.AreEqual(502, results.Count); @@ -71,7 +71,7 @@ public void Chainor() IReadOnlyList results = Quotes .GetAlma(lookbackPeriods, offset, sigma) - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(484, results.Count(x => x.Sma != null)); diff --git a/tests/indicators/a-d/Aroon/Aroon.StaticSeries.Tests.cs b/tests/indicators/a-d/Aroon/Aroon.StaticSeries.Tests.cs index 4a193d5c6..79e77cc5b 100644 --- a/tests/indicators/a-d/Aroon/Aroon.StaticSeries.Tests.cs +++ b/tests/indicators/a-d/Aroon/Aroon.StaticSeries.Tests.cs @@ -47,7 +47,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetAroon() - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(468, results.Count(x => x.Sma != null)); diff --git a/tests/indicators/a-d/Atr/Atr.StaticSeries.Tests.cs b/tests/indicators/a-d/Atr/Atr.StaticSeries.Tests.cs index 1fe4b8944..8e7fbab50 100644 --- a/tests/indicators/a-d/Atr/Atr.StaticSeries.Tests.cs +++ b/tests/indicators/a-d/Atr/Atr.StaticSeries.Tests.cs @@ -66,7 +66,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetAtr(10) - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(502 - 19, results.Count(x => x.Sma != null)); diff --git a/tests/indicators/a-d/Atr/Atr.StreamHub.Tests.cs b/tests/indicators/a-d/Atr/Atr.StreamHub.Tests.cs index f05843c9a..ba3ca5f7c 100644 --- a/tests/indicators/a-d/Atr/Atr.StreamHub.Tests.cs +++ b/tests/indicators/a-d/Atr/Atr.StreamHub.Tests.cs @@ -103,7 +103,7 @@ IReadOnlyList streamList // time-series, for comparison IReadOnlyList seriesList = quotesList .GetAtr(14) - .GetSma(smaPeriods); + .ToSma(smaPeriods); // assert, should equal series streamList.Should().HaveCount(length - 1); diff --git a/tests/indicators/a-d/Awesome/Awesome.StaticSeries.Tests.cs b/tests/indicators/a-d/Awesome/Awesome.StaticSeries.Tests.cs index e08f291d9..49eab3994 100644 --- a/tests/indicators/a-d/Awesome/Awesome.StaticSeries.Tests.cs +++ b/tests/indicators/a-d/Awesome/Awesome.StaticSeries.Tests.cs @@ -46,7 +46,7 @@ public void UseReusable() public void Chainee() { IReadOnlyList results = Quotes - .GetSma(2) + .ToSma(2) .GetAwesome(); Assert.AreEqual(502, results.Count); @@ -58,7 +58,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetAwesome() - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(460, results.Count(x => x.Sma != null)); diff --git a/tests/indicators/a-d/Beta/Beta.StaticSeries.Tests.cs b/tests/indicators/a-d/Beta/Beta.StaticSeries.Tests.cs index 49a660630..cfced403d 100644 --- a/tests/indicators/a-d/Beta/Beta.StaticSeries.Tests.cs +++ b/tests/indicators/a-d/Beta/Beta.StaticSeries.Tests.cs @@ -108,7 +108,7 @@ public void Chainor() { IReadOnlyList results = OtherQuotes .GetBeta(Quotes, 20) - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(473, results.Count(x => x.Sma != null)); @@ -118,8 +118,8 @@ public void Chainor() public void Chainee() { IReadOnlyList results = Quotes - .GetSma(2) - .GetBeta(OtherQuotes.GetSma(2), 20); + .ToSma(2) + .GetBeta(OtherQuotes.ToSma(2), 20); Assert.AreEqual(502, results.Count); Assert.AreEqual(481, results.Count(x => x.Beta != null)); diff --git a/tests/indicators/a-d/BollingerBands/BollingerBands.StaticSeries.Tests.cs b/tests/indicators/a-d/BollingerBands/BollingerBands.StaticSeries.Tests.cs index dac11b87c..b8e028e06 100644 --- a/tests/indicators/a-d/BollingerBands/BollingerBands.StaticSeries.Tests.cs +++ b/tests/indicators/a-d/BollingerBands/BollingerBands.StaticSeries.Tests.cs @@ -51,7 +51,7 @@ public void UseReusable() public void Chainee() { IReadOnlyList results = Quotes - .GetSma(2) + .ToSma(2) .GetBollingerBands(); Assert.AreEqual(502, results.Count); @@ -63,7 +63,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetBollingerBands() - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(474, results.Count(x => x.Sma != null)); diff --git a/tests/indicators/a-d/Bop/Bop.StaticSeries.Tests.cs b/tests/indicators/a-d/Bop/Bop.StaticSeries.Tests.cs index b9e1dd932..10ea4d8e9 100644 --- a/tests/indicators/a-d/Bop/Bop.StaticSeries.Tests.cs +++ b/tests/indicators/a-d/Bop/Bop.StaticSeries.Tests.cs @@ -35,7 +35,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetBop() - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(480, results.Count(x => x.Sma != null)); diff --git a/tests/indicators/a-d/Cci/Cci.StaticSeries.Tests.cs b/tests/indicators/a-d/Cci/Cci.StaticSeries.Tests.cs index afcacf1fe..2807b47c7 100644 --- a/tests/indicators/a-d/Cci/Cci.StaticSeries.Tests.cs +++ b/tests/indicators/a-d/Cci/Cci.StaticSeries.Tests.cs @@ -23,7 +23,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetCci() - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(474, results.Count(x => x.Sma != null)); diff --git a/tests/indicators/a-d/ChaikinOsc/ChaikinOsc.StaticSeries.Tests.cs b/tests/indicators/a-d/ChaikinOsc/ChaikinOsc.StaticSeries.Tests.cs index c55f4df4a..a9cc6474f 100644 --- a/tests/indicators/a-d/ChaikinOsc/ChaikinOsc.StaticSeries.Tests.cs +++ b/tests/indicators/a-d/ChaikinOsc/ChaikinOsc.StaticSeries.Tests.cs @@ -29,7 +29,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetChaikinOsc() - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(484, results.Count(x => x.Sma != null)); diff --git a/tests/indicators/a-d/Chandelier/Chandelier.StaticSeries.Tests.cs b/tests/indicators/a-d/Chandelier/Chandelier.StaticSeries.Tests.cs index 8c3de54ec..727f00fdb 100644 --- a/tests/indicators/a-d/Chandelier/Chandelier.StaticSeries.Tests.cs +++ b/tests/indicators/a-d/Chandelier/Chandelier.StaticSeries.Tests.cs @@ -35,7 +35,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetChandelier() - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(471, results.Count(x => x.Sma != null)); diff --git a/tests/indicators/a-d/Chop/Chop.StaticSeries.Tests.cs b/tests/indicators/a-d/Chop/Chop.StaticSeries.Tests.cs index 871e0f5d5..5610f776f 100644 --- a/tests/indicators/a-d/Chop/Chop.StaticSeries.Tests.cs +++ b/tests/indicators/a-d/Chop/Chop.StaticSeries.Tests.cs @@ -32,7 +32,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetChop() - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(479, results.Count(x => x.Sma != null)); diff --git a/tests/indicators/a-d/Cmf/Cmf.StaticSeries.Tests.cs b/tests/indicators/a-d/Cmf/Cmf.StaticSeries.Tests.cs index e8f3b80b7..30120cfcb 100644 --- a/tests/indicators/a-d/Cmf/Cmf.StaticSeries.Tests.cs +++ b/tests/indicators/a-d/Cmf/Cmf.StaticSeries.Tests.cs @@ -35,7 +35,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetCmf() - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(474, results.Count(x => x.Sma != null)); diff --git a/tests/indicators/a-d/Cmo/Cmo.StaticSeries.Tests.cs b/tests/indicators/a-d/Cmo/Cmo.StaticSeries.Tests.cs index cbbef590a..ad5aa350a 100644 --- a/tests/indicators/a-d/Cmo/Cmo.StaticSeries.Tests.cs +++ b/tests/indicators/a-d/Cmo/Cmo.StaticSeries.Tests.cs @@ -42,7 +42,7 @@ public void UseReusable() public void Chainee() { IReadOnlyList results = Quotes - .GetSma(2) + .ToSma(2) .GetCmo(20); Assert.AreEqual(502, results.Count); @@ -54,7 +54,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetCmo(20) - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(473, results.Count(x => x.Sma != null)); diff --git a/tests/indicators/a-d/ConnorsRsi/ConnorsRsi.StaticSeries.Tests.cs b/tests/indicators/a-d/ConnorsRsi/ConnorsRsi.StaticSeries.Tests.cs index 6839702c4..5d8bd2bd3 100644 --- a/tests/indicators/a-d/ConnorsRsi/ConnorsRsi.StaticSeries.Tests.cs +++ b/tests/indicators/a-d/ConnorsRsi/ConnorsRsi.StaticSeries.Tests.cs @@ -49,7 +49,7 @@ public void UseReusable() public void Chainee() { IReadOnlyList results = Quotes - .GetSma(2) + .ToSma(2) .GetConnorsRsi(); Assert.AreEqual(502, results.Count); @@ -61,7 +61,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetConnorsRsi() - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(392, results.Count(x => x.Sma != null)); diff --git a/tests/indicators/a-d/Correlation/Correlation.StaticSeries.Tests.cs b/tests/indicators/a-d/Correlation/Correlation.StaticSeries.Tests.cs index 7c97e4d1a..3a203c39b 100644 --- a/tests/indicators/a-d/Correlation/Correlation.StaticSeries.Tests.cs +++ b/tests/indicators/a-d/Correlation/Correlation.StaticSeries.Tests.cs @@ -48,7 +48,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetCorrelation(OtherQuotes, 20) - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(474, results.Count(x => x.Sma != null)); @@ -58,8 +58,8 @@ public void Chainor() public void Chainee() { IReadOnlyList results = Quotes - .GetSma(2) - .GetCorrelation(OtherQuotes.GetSma(2), 20); + .ToSma(2) + .GetCorrelation(OtherQuotes.ToSma(2), 20); Assert.AreEqual(502, results.Count); Assert.AreEqual(482, results.Count(x => x.Correlation != null)); diff --git a/tests/indicators/a-d/Dema/Dema.StaticSeries.Tests.cs b/tests/indicators/a-d/Dema/Dema.StaticSeries.Tests.cs index 683f8531f..2ec06a281 100644 --- a/tests/indicators/a-d/Dema/Dema.StaticSeries.Tests.cs +++ b/tests/indicators/a-d/Dema/Dema.StaticSeries.Tests.cs @@ -42,7 +42,7 @@ public void UseReusable() public void Chainee() { IReadOnlyList results = Quotes - .GetSma(2) + .ToSma(2) .GetDema(20); Assert.AreEqual(502, results.Count); @@ -54,7 +54,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetDema(20) - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(474, results.Count(x => x.Sma != null)); diff --git a/tests/indicators/a-d/Dpo/Dpo.StaticSeries.Tests.cs b/tests/indicators/a-d/Dpo/Dpo.StaticSeries.Tests.cs index f279d237b..5694b4f84 100644 --- a/tests/indicators/a-d/Dpo/Dpo.StaticSeries.Tests.cs +++ b/tests/indicators/a-d/Dpo/Dpo.StaticSeries.Tests.cs @@ -56,7 +56,7 @@ public void UseReusable() public void Chainee() { IReadOnlyList results = Quotes - .GetSma(2) + .ToSma(2) .GetDpo(14); Assert.AreEqual(502, results.Count); @@ -68,7 +68,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetDpo(14) - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(480, results.Count(x => x.Sma is not null and not double.NaN)); diff --git a/tests/indicators/a-d/Dynamic/Dynamic.StaticSeries.Tests.cs b/tests/indicators/a-d/Dynamic/Dynamic.StaticSeries.Tests.cs index 5fbd7b8b6..5baf359bf 100644 --- a/tests/indicators/a-d/Dynamic/Dynamic.StaticSeries.Tests.cs +++ b/tests/indicators/a-d/Dynamic/Dynamic.StaticSeries.Tests.cs @@ -43,7 +43,7 @@ public void UseReusable() public void Chainee() { IReadOnlyList results = Quotes - .GetSma(10) + .ToSma(10) .GetDynamic(14); Assert.AreEqual(502, results.Count); @@ -55,7 +55,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetDynamic(14) - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(492, results.Count(x => x.Sma != null)); diff --git a/tests/indicators/e-k/ElderRay/ElderRay.StaticSeries.Tests.cs b/tests/indicators/e-k/ElderRay/ElderRay.StaticSeries.Tests.cs index 8bef0f2d7..5f3d300eb 100644 --- a/tests/indicators/e-k/ElderRay/ElderRay.StaticSeries.Tests.cs +++ b/tests/indicators/e-k/ElderRay/ElderRay.StaticSeries.Tests.cs @@ -51,7 +51,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetElderRay() - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(481, results.Count(x => x.Sma != null)); diff --git a/tests/indicators/e-k/Ema/Ema.Increments.Tests.cs b/tests/indicators/e-k/Ema/Ema.Increments.Tests.cs index 5e6b5bc4e..b19ce4c69 100644 --- a/tests/indicators/e-k/Ema/Ema.Increments.Tests.cs +++ b/tests/indicators/e-k/Ema/Ema.Increments.Tests.cs @@ -11,8 +11,7 @@ private static readonly IReadOnlyList reusables .ToList(); private static readonly IReadOnlyList series - = Api.GetEma(Quotes -, lookbackPeriods); + = Quotes.ToEma(lookbackPeriods); [TestMethod] public void FromReusableSplit() @@ -65,7 +64,7 @@ public override void FromQuoteBatch() EmaList sut = new(lookbackPeriods) { Quotes }; IReadOnlyList series - = Api.GetEma(Quotes, lookbackPeriods); + = Quotes.ToEma(lookbackPeriods); sut.Should().HaveCount(Quotes.Count); sut.Should().BeEquivalentTo(series); diff --git a/tests/indicators/e-k/Ema/Ema.StaticSeries.Tests.cs b/tests/indicators/e-k/Ema/Ema.StaticSeries.Tests.cs index d17760174..71b1a5d69 100644 --- a/tests/indicators/e-k/Ema/Ema.StaticSeries.Tests.cs +++ b/tests/indicators/e-k/Ema/Ema.StaticSeries.Tests.cs @@ -14,8 +14,7 @@ public void Increment() [TestMethod] public override void Standard() { - IReadOnlyList results = Api.GetEma(Quotes -, 20); + IReadOnlyList results = Quotes.ToEma(20); // proper quantities Assert.AreEqual(502, results.Count); @@ -37,7 +36,7 @@ public void UsePart() { IReadOnlyList results = Quotes .Use(CandlePart.Open) - .GetEma(20); + .ToEma(20); // assertions @@ -62,7 +61,7 @@ public void UseReusable() { IReadOnlyList results = Quotes .Use(CandlePart.Close) - .GetEma(20); + .ToEma(20); Assert.AreEqual(502, results.Count); Assert.AreEqual(483, results.Count(x => x.Ema != null)); @@ -73,8 +72,8 @@ public void UseReusable() public void Chainee() { IReadOnlyList results = Quotes - .GetSma(2) - .GetEma(20); + .ToSma(2) + .ToEma(20); Assert.AreEqual(502, results.Count); Assert.AreEqual(482, results.Count(x => x.Ema != null)); @@ -84,9 +83,9 @@ public void Chainee() [TestMethod] public void Chainor() { - IReadOnlyList results = Api.GetEma(Quotes -, 20) - .GetSma(10); + IReadOnlyList results = Quotes + .ToEma(20) + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(474, results.Count(x => x.Sma != null)); @@ -98,7 +97,7 @@ public void ChaineeMore() { IReadOnlyList results = Quotes .GetRsi() - .GetEma(20); + .ToEma(20); // assertions Assert.AreEqual(502, results.Count); @@ -122,8 +121,7 @@ public void ChaineeMore() [TestMethod] public override void BadData() { - IReadOnlyList r = Api.GetEma(BadQuotes -, 15); + IReadOnlyList r = BadQuotes.ToEma(15); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Ema is double.NaN)); @@ -132,13 +130,11 @@ public override void BadData() [TestMethod] public override void NoQuotes() { - IReadOnlyList r0 = Api.GetEma(Noquotes -, 10); + IReadOnlyList r0 = Noquotes.ToEma(10); Assert.AreEqual(0, r0.Count); - IReadOnlyList r1 = Api.GetEma(Onequote -, 10); + IReadOnlyList r1 = Onequote.ToEma(10); Assert.AreEqual(1, r1.Count); } @@ -146,8 +142,7 @@ public override void NoQuotes() [TestMethod] public void Removed() { - IReadOnlyList results = Api.GetEma(Quotes -, 20) + IReadOnlyList results = Quotes.ToEma(20) .RemoveWarmupPeriods(); // assertions @@ -161,5 +156,5 @@ public void Removed() [TestMethod] public void Exceptions() => Assert.ThrowsException(() - => Api.GetEma(Quotes, 0)); + => Quotes.ToEma(0)); } diff --git a/tests/indicators/e-k/Ema/Ema.StreamHub.Tests.cs b/tests/indicators/e-k/Ema/Ema.StreamHub.Tests.cs index 71f29b64f..5e4e1f2c4 100644 --- a/tests/indicators/e-k/Ema/Ema.StreamHub.Tests.cs +++ b/tests/indicators/e-k/Ema/Ema.StreamHub.Tests.cs @@ -55,8 +55,7 @@ IReadOnlyList streamList quotesList.RemoveAt(400); // time-series, for comparison - IReadOnlyList seriesList = Api.GetEma(quotesList -, 5); + IReadOnlyList seriesList = quotesList.ToEma(5); // assert, should equal series streamList.Should().HaveCount(length - 1); @@ -98,8 +97,8 @@ IReadOnlyList streamList // time-series, for comparison IReadOnlyList seriesList = quotesList - .GetSma(smaPeriods) - .GetEma(emaPeriods); + .ToSma(smaPeriods) + .ToEma(emaPeriods); // assert, should equal series streamList.Should().HaveCount(length); @@ -160,9 +159,8 @@ IReadOnlyList streamList // time-series, for comparison IReadOnlyList seriesList - = Api.GetEma(quotesList -, emaPeriods) - .GetSma(smaPeriods); + = quotesList.ToEma(emaPeriods) + .ToSma(smaPeriods); // assert, should equal series streamList.Should().HaveCount(length - 1); diff --git a/tests/indicators/e-k/Epma/Epma.StaticSeries.Tests.cs b/tests/indicators/e-k/Epma/Epma.StaticSeries.Tests.cs index 98be869cd..d1d8fc1f0 100644 --- a/tests/indicators/e-k/Epma/Epma.StaticSeries.Tests.cs +++ b/tests/indicators/e-k/Epma/Epma.StaticSeries.Tests.cs @@ -45,7 +45,7 @@ public void UseReusable() public void Chainee() { IReadOnlyList results = Quotes - .GetSma(2) + .ToSma(2) .GetEpma(20); Assert.AreEqual(502, results.Count); @@ -57,7 +57,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetEpma(20) - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(474, results.Count(x => x.Sma != null)); diff --git a/tests/indicators/e-k/FisherTransform/FisherTransform.StaticSeries.Tests.cs b/tests/indicators/e-k/FisherTransform/FisherTransform.StaticSeries.Tests.cs index 8ed431cb4..c0649936e 100644 --- a/tests/indicators/e-k/FisherTransform/FisherTransform.StaticSeries.Tests.cs +++ b/tests/indicators/e-k/FisherTransform/FisherTransform.StaticSeries.Tests.cs @@ -60,7 +60,7 @@ public void UseReusable() public void Chainee() { IReadOnlyList results = Quotes - .GetSma(2) + .ToSma(2) .GetFisherTransform(); Assert.AreEqual(502, results.Count); @@ -72,7 +72,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetFisherTransform() - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(493, results.Count(x => x.Sma != null)); diff --git a/tests/indicators/e-k/ForceIndex/ForceIndex.StaticSeries.Tests.cs b/tests/indicators/e-k/ForceIndex/ForceIndex.StaticSeries.Tests.cs index 48ef7077d..a5d6d6e64 100644 --- a/tests/indicators/e-k/ForceIndex/ForceIndex.StaticSeries.Tests.cs +++ b/tests/indicators/e-k/ForceIndex/ForceIndex.StaticSeries.Tests.cs @@ -27,7 +27,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetForceIndex(13) - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(480, results.Count(x => x.Sma != null)); diff --git a/tests/indicators/e-k/Gator/Gator.StaticSeries.Tests.cs b/tests/indicators/e-k/Gator/Gator.StaticSeries.Tests.cs index 7f433e3ab..fff0d1027 100644 --- a/tests/indicators/e-k/Gator/Gator.StaticSeries.Tests.cs +++ b/tests/indicators/e-k/Gator/Gator.StaticSeries.Tests.cs @@ -157,7 +157,7 @@ public void UseReusable() public void Chainee() { IReadOnlyList results = Quotes - .GetSma(2) + .ToSma(2) .GetGator(); Assert.AreEqual(502, results.Count); diff --git a/tests/indicators/e-k/HeikinAshi/HeikinAshi.StaticSeries.Tests.cs b/tests/indicators/e-k/HeikinAshi/HeikinAshi.StaticSeries.Tests.cs index 26e3816dc..0c6e0e1e3 100644 --- a/tests/indicators/e-k/HeikinAshi/HeikinAshi.StaticSeries.Tests.cs +++ b/tests/indicators/e-k/HeikinAshi/HeikinAshi.StaticSeries.Tests.cs @@ -24,8 +24,8 @@ public override void Standard() [TestMethod] public void UseAsQuotes() { - IEnumerable haQuotes = Quotes.GetHeikinAshi(); - IEnumerable haSma = haQuotes.GetSma(5); + IReadOnlyList haQuotes = Quotes.GetHeikinAshi(); + IReadOnlyList haSma = haQuotes.ToSma(5); Assert.AreEqual(498, haSma.Count(x => x.Sma != null)); } diff --git a/tests/indicators/e-k/Hma/Hma.StaticSeries.Tests.cs b/tests/indicators/e-k/Hma/Hma.StaticSeries.Tests.cs index 9bceb5d16..6e196317c 100644 --- a/tests/indicators/e-k/Hma/Hma.StaticSeries.Tests.cs +++ b/tests/indicators/e-k/Hma/Hma.StaticSeries.Tests.cs @@ -36,7 +36,7 @@ public void UseReusable() public void Chainee() { IReadOnlyList results = Quotes - .GetSma(2) + .ToSma(2) .GetHma(19); Assert.AreEqual(502, results.Count); @@ -48,7 +48,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetHma(20) - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(471, results.Count(x => x.Sma != null)); diff --git a/tests/indicators/e-k/HtTrendline/HtTrendline.StaticSeries.Tests.cs b/tests/indicators/e-k/HtTrendline/HtTrendline.StaticSeries.Tests.cs index 463b781f3..0e0572559 100644 --- a/tests/indicators/e-k/HtTrendline/HtTrendline.StaticSeries.Tests.cs +++ b/tests/indicators/e-k/HtTrendline/HtTrendline.StaticSeries.Tests.cs @@ -71,7 +71,7 @@ public void UseReusable() public void Chainee() { IReadOnlyList results = Quotes - .GetSma(2) + .ToSma(2) .GetHtTrendline(); Assert.AreEqual(502, results.Count); @@ -83,7 +83,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetHtTrendline() - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(493, results.Count(x => x.Sma != null)); diff --git a/tests/indicators/e-k/Hurst/Hurst.StaticSeries.Tests.cs b/tests/indicators/e-k/Hurst/Hurst.StaticSeries.Tests.cs index db69cc2b5..e44dc3060 100644 --- a/tests/indicators/e-k/Hurst/Hurst.StaticSeries.Tests.cs +++ b/tests/indicators/e-k/Hurst/Hurst.StaticSeries.Tests.cs @@ -36,7 +36,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetHurst() - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(393, results.Count(x => x.Sma != null)); @@ -46,7 +46,7 @@ public void Chainor() public void Chainee() { IReadOnlyList results = Quotes - .GetSma(10) + .ToSma(10) .GetHurst(); Assert.AreEqual(502, results.Count); diff --git a/tests/indicators/e-k/Kama/Kama.StaticSeries.Tests.cs b/tests/indicators/e-k/Kama/Kama.StaticSeries.Tests.cs index 1a03ba4fd..82f5ba206 100644 --- a/tests/indicators/e-k/Kama/Kama.StaticSeries.Tests.cs +++ b/tests/indicators/e-k/Kama/Kama.StaticSeries.Tests.cs @@ -63,7 +63,7 @@ public void UseReusable() public void Chainee() { IReadOnlyList results = Quotes - .GetSma(2) + .ToSma(2) .GetKama(); Assert.AreEqual(502, results.Count); @@ -75,7 +75,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetKama() - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(484, results.Count(x => x.Sma != null)); diff --git a/tests/indicators/e-k/Kvo/Kvo.StaticSeries.Tests.cs b/tests/indicators/e-k/Kvo/Kvo.StaticSeries.Tests.cs index 2f9f24172..d68cce515 100644 --- a/tests/indicators/e-k/Kvo/Kvo.StaticSeries.Tests.cs +++ b/tests/indicators/e-k/Kvo/Kvo.StaticSeries.Tests.cs @@ -49,7 +49,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetKvo() - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(437, results.Count(x => x.Sma != null)); diff --git a/tests/indicators/m-r/MaEnvelopes/MaEnvelopes.StaticSeries.Tests.cs b/tests/indicators/m-r/MaEnvelopes/MaEnvelopes.StaticSeries.Tests.cs index de453ae75..5a24b70f5 100644 --- a/tests/indicators/m-r/MaEnvelopes/MaEnvelopes.StaticSeries.Tests.cs +++ b/tests/indicators/m-r/MaEnvelopes/MaEnvelopes.StaticSeries.Tests.cs @@ -251,7 +251,7 @@ public void UseReusable() public void Chainee() { IReadOnlyList results = Quotes - .GetSma(2) + .ToSma(2) .GetMaEnvelopes(10); Assert.AreEqual(502, results.Count); diff --git a/tests/indicators/m-r/Macd/Macd.StaticSeries.Tests.cs b/tests/indicators/m-r/Macd/Macd.StaticSeries.Tests.cs index 1cdcbcfdf..dbceb87eb 100644 --- a/tests/indicators/m-r/Macd/Macd.StaticSeries.Tests.cs +++ b/tests/indicators/m-r/Macd/Macd.StaticSeries.Tests.cs @@ -57,7 +57,7 @@ public void UseReusable() public void Chainee() { IReadOnlyList results = Quotes - .GetSma(2) + .ToSma(2) .GetMacd(); Assert.AreEqual(502, results.Count); @@ -69,7 +69,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetMacd() - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(468, results.Count(x => x.Sma != null)); diff --git a/tests/indicators/m-r/Mama/Mama.StaticSeries.Tests.cs b/tests/indicators/m-r/Mama/Mama.StaticSeries.Tests.cs index 2866f9b7d..747029e66 100644 --- a/tests/indicators/m-r/Mama/Mama.StaticSeries.Tests.cs +++ b/tests/indicators/m-r/Mama/Mama.StaticSeries.Tests.cs @@ -61,7 +61,7 @@ public void UseReusable() public void Chainee() { IReadOnlyList results = Quotes - .GetSma(2) + .ToSma(2) .GetMama(); Assert.AreEqual(502, results.Count); @@ -73,7 +73,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetMama() - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(488, results.Count(x => x.Sma != null)); diff --git a/tests/indicators/m-r/Mfi/Mfi.StaticSeries.Tests.cs b/tests/indicators/m-r/Mfi/Mfi.StaticSeries.Tests.cs index 34fec7d95..f79332ed8 100644 --- a/tests/indicators/m-r/Mfi/Mfi.StaticSeries.Tests.cs +++ b/tests/indicators/m-r/Mfi/Mfi.StaticSeries.Tests.cs @@ -26,7 +26,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetMfi() - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(479, results.Count(x => x.Sma != null)); diff --git a/tests/indicators/m-r/Obv/Obv.StaticSeries.Tests.cs b/tests/indicators/m-r/Obv/Obv.StaticSeries.Tests.cs index b919ed5af..ae62e85c4 100644 --- a/tests/indicators/m-r/Obv/Obv.StaticSeries.Tests.cs +++ b/tests/indicators/m-r/Obv/Obv.StaticSeries.Tests.cs @@ -25,7 +25,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetObv() - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(493, results.Count(x => x.Sma != null)); diff --git a/tests/indicators/m-r/ParabolicSar/ParabolicSar.StaticSeries.Tests.cs b/tests/indicators/m-r/ParabolicSar/ParabolicSar.StaticSeries.Tests.cs index b5ed0025d..a5510c360 100644 --- a/tests/indicators/m-r/ParabolicSar/ParabolicSar.StaticSeries.Tests.cs +++ b/tests/indicators/m-r/ParabolicSar/ParabolicSar.StaticSeries.Tests.cs @@ -78,7 +78,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetParabolicSar() - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(479, results.Count(x => x.Sma != null)); diff --git a/tests/indicators/m-r/Pmo/Pmo.StaticSeries.Tests.cs b/tests/indicators/m-r/Pmo/Pmo.StaticSeries.Tests.cs index 5b30416d7..0f1d971ac 100644 --- a/tests/indicators/m-r/Pmo/Pmo.StaticSeries.Tests.cs +++ b/tests/indicators/m-r/Pmo/Pmo.StaticSeries.Tests.cs @@ -39,7 +39,7 @@ public void UseReusable() public void Chainee() { IReadOnlyList results = Quotes - .GetSma(2) + .ToSma(2) .GetPmo(); Assert.AreEqual(502, results.Count); @@ -51,7 +51,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetPmo() - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(439, results.Count(x => x.Sma != null)); diff --git a/tests/indicators/m-r/Prs/Prs.StaticSeries.Tests.cs b/tests/indicators/m-r/Prs/Prs.StaticSeries.Tests.cs index 3e15b23f6..14a6b43ad 100644 --- a/tests/indicators/m-r/Prs/Prs.StaticSeries.Tests.cs +++ b/tests/indicators/m-r/Prs/Prs.StaticSeries.Tests.cs @@ -45,7 +45,7 @@ public void Chainor() { IReadOnlyList results = OtherQuotes .GetPrs(Quotes, 20) - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(493, results.Count(x => x.Sma != null)); @@ -55,8 +55,8 @@ public void Chainor() public void Chainee() { IReadOnlyList results = Quotes - .GetSma(2) - .GetPrs(OtherQuotes.GetSma(2), 20); + .ToSma(2) + .GetPrs(OtherQuotes.ToSma(2), 20); Assert.AreEqual(502, results.Count); Assert.AreEqual(501, results.Count(x => x.Prs != null)); diff --git a/tests/indicators/m-r/Pvo/Pvo.StaticSeries.Tests.cs b/tests/indicators/m-r/Pvo/Pvo.StaticSeries.Tests.cs index a871a561e..866c40d04 100644 --- a/tests/indicators/m-r/Pvo/Pvo.StaticSeries.Tests.cs +++ b/tests/indicators/m-r/Pvo/Pvo.StaticSeries.Tests.cs @@ -51,7 +51,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetPvo() - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(468, results.Count(x => x.Sma != null)); diff --git a/tests/indicators/m-r/Renko/Renko.StaticSeries.Tests.cs b/tests/indicators/m-r/Renko/Renko.StaticSeries.Tests.cs index a0d4c9f52..df8046942 100644 --- a/tests/indicators/m-r/Renko/Renko.StaticSeries.Tests.cs +++ b/tests/indicators/m-r/Renko/Renko.StaticSeries.Tests.cs @@ -107,8 +107,8 @@ public void Atr() [TestMethod] public void UseAsQuotes() { - IEnumerable renkoQuotes = Quotes.GetRenko(2.5m); - IEnumerable renkoSma = renkoQuotes.GetSma(5); + IReadOnlyList renkoQuotes = Quotes.GetRenko(2.5m); + IReadOnlyList renkoSma = renkoQuotes.ToSma(5); Assert.AreEqual(108, renkoSma.Count(x => x.Sma != null)); } diff --git a/tests/indicators/m-r/Renko/Renko.StreamHub.Tests.cs b/tests/indicators/m-r/Renko/Renko.StreamHub.Tests.cs index b0e7832b8..8899267f2 100644 --- a/tests/indicators/m-r/Renko/Renko.StreamHub.Tests.cs +++ b/tests/indicators/m-r/Renko/Renko.StreamHub.Tests.cs @@ -106,7 +106,7 @@ IReadOnlyList streamList // time-series, for comparison IReadOnlyList seriesList = quotesList .GetRenko(brickSize, endType) - .GetSma(smaPeriods); + .ToSma(smaPeriods); // assert, should equal series streamList.Should().BeEquivalentTo(seriesList); diff --git a/tests/indicators/m-r/Roc/Roc.StaticSeries.Tests.cs b/tests/indicators/m-r/Roc/Roc.StaticSeries.Tests.cs index dd8179ad8..a246ab33d 100644 --- a/tests/indicators/m-r/Roc/Roc.StaticSeries.Tests.cs +++ b/tests/indicators/m-r/Roc/Roc.StaticSeries.Tests.cs @@ -43,7 +43,7 @@ public void UseReusable() public void Chainee() { IReadOnlyList results = Quotes - .GetSma(2) + .ToSma(2) .GetRoc(20); Assert.AreEqual(502, results.Count); @@ -55,7 +55,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetRoc(20) - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(473, results.Count(x => x.Sma != null)); diff --git a/tests/indicators/m-r/RocWb/RocWb.StaticSeries.Tests.cs b/tests/indicators/m-r/RocWb/RocWb.StaticSeries.Tests.cs index d4838b8bd..584af10ae 100644 --- a/tests/indicators/m-r/RocWb/RocWb.StaticSeries.Tests.cs +++ b/tests/indicators/m-r/RocWb/RocWb.StaticSeries.Tests.cs @@ -81,7 +81,7 @@ public void UseReusable() public void Chainee() { IReadOnlyList results = Quotes - .GetSma(2) + .ToSma(2) .GetRocWb(20, 3, 20); Assert.AreEqual(502, results.Count); @@ -93,7 +93,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetRocWb(20, 3, 20) - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(473, results.Count(x => x.Sma != null)); diff --git a/tests/indicators/m-r/Rsi/Rsi.StaticSeries.Tests.cs b/tests/indicators/m-r/Rsi/Rsi.StaticSeries.Tests.cs index 416bf9f88..de79ccff7 100644 --- a/tests/indicators/m-r/Rsi/Rsi.StaticSeries.Tests.cs +++ b/tests/indicators/m-r/Rsi/Rsi.StaticSeries.Tests.cs @@ -49,7 +49,7 @@ public void SmallLookback() [TestMethod] public void CryptoData() { - IEnumerable btc = Data.GetBitcoin(); + IReadOnlyList btc = Data.GetBitcoin(); IReadOnlyList r = btc .GetRsi(1); @@ -72,7 +72,7 @@ public void UseReusable() public void Chainee() { IReadOnlyList results = Quotes - .GetSma(2) + .ToSma(2) .GetRsi(); Assert.AreEqual(502, results.Count); @@ -84,7 +84,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetRsi() - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(479, results.Count(x => x.Sma != null)); @@ -131,7 +131,7 @@ public void Removed() .RemoveWarmupPeriods(); // assertions - Assert.AreEqual(502 - 10 * 14, results.Count); + Assert.AreEqual(502 - (10 * 14), results.Count); RsiResult last = results[^1]; Assert.AreEqual(42.0773, last.Rsi.Round(4)); diff --git a/tests/indicators/s-z/Slope/Slope.StaticSeries.Tests.cs b/tests/indicators/s-z/Slope/Slope.StaticSeries.Tests.cs index 60e32f9ab..168aed275 100644 --- a/tests/indicators/s-z/Slope/Slope.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/Slope/Slope.StaticSeries.Tests.cs @@ -53,7 +53,7 @@ public void UseReusable() public void Chainee() { IReadOnlyList results = Quotes - .GetSma(2) + .ToSma(2) .GetSlope(20); Assert.AreEqual(502, results.Count); @@ -65,7 +65,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetSlope(20) - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(474, results.Count(x => x.Sma != null)); diff --git a/tests/indicators/s-z/Sma/Sma.StaticSeries.Tests.cs b/tests/indicators/s-z/Sma/Sma.StaticSeries.Tests.cs index 526eea09b..beb01d021 100644 --- a/tests/indicators/s-z/Sma/Sma.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/Sma/Sma.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class Sma : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = Quotes - .GetSma(20); + .ToSma(20); // proper quantities Assert.AreEqual(502, results.Count); @@ -27,7 +27,7 @@ public void CandlePartOpen() { IReadOnlyList results = Quotes .Use(CandlePart.Open) - .GetSma(20); + .ToSma(20); Assert.AreEqual(502, results.Count); Assert.AreEqual(483, results.Count(x => x.Sma != null)); @@ -46,7 +46,7 @@ public void CandlePartVolume() { IReadOnlyList results = Quotes .Use(CandlePart.Volume) - .GetSma(20); + .ToSma(20); Assert.AreEqual(502, results.Count); Assert.AreEqual(483, results.Count(x => x.Sma != null)); @@ -67,8 +67,8 @@ public void CandlePartVolume() public void Chainor() { IReadOnlyList results = Quotes - .GetSma(10) - .GetEma(10); + .ToSma(10) + .ToEma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(484, results.Count(x => x.Ema != null)); @@ -78,7 +78,7 @@ public void Chainor() public void NaN() { IReadOnlyList r = Data.GetBtcUsdNan() - .GetSma(50); + .ToSma(50); Assert.AreEqual(0, r.Count(x => x.Sma is double.NaN)); } @@ -87,7 +87,7 @@ public void NaN() public override void BadData() { IReadOnlyList r = BadQuotes - .GetSma(15); + .ToSma(15); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Sma is double.NaN)); @@ -97,12 +97,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetSma(5); + .ToSma(5); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetSma(5); + .ToSma(5); Assert.AreEqual(1, r1.Count); } @@ -111,7 +111,7 @@ public override void NoQuotes() public void Removed() { IReadOnlyList results = Quotes - .GetSma(20) + .ToSma(20) .RemoveWarmupPeriods(); // assertions @@ -145,5 +145,5 @@ public void Equality() [TestMethod] public void Exceptions() => Assert.ThrowsException(() - => Quotes.GetSma(0)); + => Quotes.ToSma(0)); } diff --git a/tests/indicators/s-z/Sma/Sma.StreamHub.Tests.cs b/tests/indicators/s-z/Sma/Sma.StreamHub.Tests.cs index 8580bbbc4..ff1efc058 100644 --- a/tests/indicators/s-z/Sma/Sma.StreamHub.Tests.cs +++ b/tests/indicators/s-z/Sma/Sma.StreamHub.Tests.cs @@ -57,7 +57,7 @@ IReadOnlyList streamList // time-series, for comparison IReadOnlyList seriesList = quotesList - .GetSma(5); + .ToSma(5); // assert, should equal series streamList.Should().HaveCount(length - 1); @@ -102,7 +102,7 @@ public void ChainObserver() IReadOnlyList seriesList = quotesList .Use(CandlePart.OC2) - .GetSma(11); + .ToSma(11); // assert, should equal series streamList.Should().HaveCount(length); @@ -149,8 +149,8 @@ IReadOnlyList streamList // time-series, for comparison IReadOnlyList seriesList = quotesList - .GetSma(smaPeriods) - .GetEma(emaPeriods); + .ToSma(smaPeriods) + .ToEma(emaPeriods); // assert, should equal series streamList.Should().HaveCount(length - 1); diff --git a/tests/indicators/s-z/SmaAnalysis/SmaAnalysis.StaticSeries.Tests.cs b/tests/indicators/s-z/SmaAnalysis/SmaAnalysis.StaticSeries.Tests.cs index 9da59b2e9..31452ea82 100644 --- a/tests/indicators/s-z/SmaAnalysis/SmaAnalysis.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/SmaAnalysis/SmaAnalysis.StaticSeries.Tests.cs @@ -36,7 +36,7 @@ public void UseReusable() public void Chainee() { IReadOnlyList results = Quotes - .GetSma(2) + .ToSma(2) .GetSmaAnalysis(20); Assert.AreEqual(502, results.Count); @@ -48,7 +48,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetSmaAnalysis(10) - .GetEma(10); + .ToEma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(484, results.Count(x => x.Ema != null)); diff --git a/tests/indicators/s-z/Smi/Smi.StaticSeries.Tests.cs b/tests/indicators/s-z/Smi/Smi.StaticSeries.Tests.cs index c9955776d..46ea3bc3e 100644 --- a/tests/indicators/s-z/Smi/Smi.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/Smi/Smi.StaticSeries.Tests.cs @@ -49,7 +49,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetSmi(14, 20, 5) - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(480, results.Count(x => x.Sma != null)); diff --git a/tests/indicators/s-z/Smma/Smma.StaticSeries.Tests.cs b/tests/indicators/s-z/Smma/Smma.StaticSeries.Tests.cs index 49a25790e..aad46502e 100644 --- a/tests/indicators/s-z/Smma/Smma.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/Smma/Smma.StaticSeries.Tests.cs @@ -40,7 +40,7 @@ public void UseReusable() public void Chainee() { IReadOnlyList results = Quotes - .GetSma(2) + .ToSma(2) .GetSmma(20); Assert.AreEqual(502, results.Count); @@ -52,7 +52,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetSmma(20) - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(474, results.Count(x => x.Sma != null)); diff --git a/tests/indicators/s-z/Stc/Stc.StaticSeries.Tests.cs b/tests/indicators/s-z/Stc/Stc.StaticSeries.Tests.cs index 287e5d03d..37480617f 100644 --- a/tests/indicators/s-z/Stc/Stc.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/Stc/Stc.StaticSeries.Tests.cs @@ -49,7 +49,7 @@ public void UseReusable() public void Chainee() { IReadOnlyList results = Quotes - .GetSma(2) + .ToSma(2) .GetStc(9, 12, 26); Assert.AreEqual(502, results.Count); @@ -61,7 +61,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetStc(9, 12, 26) - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(458, results.Count(x => x.Sma != null)); diff --git a/tests/indicators/s-z/StdDev/StdDev.StaticSeries.Tests.cs b/tests/indicators/s-z/StdDev/StdDev.StaticSeries.Tests.cs index fe2a399e6..ab4eb254e 100644 --- a/tests/indicators/s-z/StdDev/StdDev.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/StdDev/StdDev.StaticSeries.Tests.cs @@ -51,7 +51,7 @@ public void UseReusable() public void Chainee() { IReadOnlyList results = Quotes - .GetSma(2) + .ToSma(2) .GetStdDev(10); Assert.AreEqual(502, results.Count); @@ -63,7 +63,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetStdDev(10) - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(484, results.Count(x => x.Sma != null)); diff --git a/tests/indicators/s-z/StdDevChannels/StdDevChannels.StaticSeries.Tests.cs b/tests/indicators/s-z/StdDevChannels/StdDevChannels.StaticSeries.Tests.cs index 26e4f21fc..14b5e5af3 100644 --- a/tests/indicators/s-z/StdDevChannels/StdDevChannels.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/StdDevChannels/StdDevChannels.StaticSeries.Tests.cs @@ -110,7 +110,7 @@ public void UseReusable() public void Chainee() { IReadOnlyList results = Quotes - .GetSma(2) + .ToSma(2) .GetStdDevChannels(); Assert.AreEqual(502, results.Count); diff --git a/tests/indicators/s-z/Stoch/Stoch.StaticSeries.Tests.cs b/tests/indicators/s-z/Stoch/Stoch.StaticSeries.Tests.cs index f871e1a7e..bb5f2cf90 100644 --- a/tests/indicators/s-z/Stoch/Stoch.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/Stoch/Stoch.StaticSeries.Tests.cs @@ -116,7 +116,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetStoch() - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(478, results.Count(x => x.Sma != null)); diff --git a/tests/indicators/s-z/StochRsi/StochRsi.StaticSeries.Tests.cs b/tests/indicators/s-z/StochRsi/StochRsi.StaticSeries.Tests.cs index 856009de1..71cdf7289 100644 --- a/tests/indicators/s-z/StochRsi/StochRsi.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/StochRsi/StochRsi.StaticSeries.Tests.cs @@ -91,7 +91,7 @@ public void UseReusable() public void Chainee() { IReadOnlyList results = Quotes - .GetSma(2) + .ToSma(2) .GetStochRsi(14, 14, 3); Assert.AreEqual(502, results.Count); @@ -103,7 +103,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetStochRsi(14, 14, 3, 3) - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(464, results.Count(x => x.Sma != null)); diff --git a/tests/indicators/s-z/T3/T3.StaticSeries.Tests.cs b/tests/indicators/s-z/T3/T3.StaticSeries.Tests.cs index 6b90394fc..5b10b3763 100644 --- a/tests/indicators/s-z/T3/T3.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/T3/T3.StaticSeries.Tests.cs @@ -48,7 +48,7 @@ public void UseReusable() public void Chainee() { IReadOnlyList results = Quotes - .GetSma(2) + .ToSma(2) .GetT3(); Assert.AreEqual(502, results.Count); @@ -60,7 +60,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetT3() - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); } diff --git a/tests/indicators/s-z/Tema/Tema.StaticSeries.Tests.cs b/tests/indicators/s-z/Tema/Tema.StaticSeries.Tests.cs index a2e2f483c..2878835ae 100644 --- a/tests/indicators/s-z/Tema/Tema.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/Tema/Tema.StaticSeries.Tests.cs @@ -42,7 +42,7 @@ public void UseReusable() public void Chainee() { IReadOnlyList results = Quotes - .GetSma(2) + .ToSma(2) .GetTema(20); Assert.AreEqual(502, results.Count); @@ -54,7 +54,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetTema(20) - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(474, results.Count(x => x.Sma != null)); diff --git a/tests/indicators/s-z/Tr/Tr.StreamHub.Tests.cs b/tests/indicators/s-z/Tr/Tr.StreamHub.Tests.cs index 82c802a19..3b94e3cd0 100644 --- a/tests/indicators/s-z/Tr/Tr.StreamHub.Tests.cs +++ b/tests/indicators/s-z/Tr/Tr.StreamHub.Tests.cs @@ -103,7 +103,7 @@ IReadOnlyList streamList // time-series, for comparison IReadOnlyList seriesList = quotesList .GetTr() - .GetSma(smaPeriods); + .ToSma(smaPeriods); // assert, should equal series streamList.Should().HaveCount(length - 1); diff --git a/tests/indicators/s-z/Trix/Trix.StaticSeries.Tests.cs b/tests/indicators/s-z/Trix/Trix.StaticSeries.Tests.cs index da1623b0d..88b041932 100644 --- a/tests/indicators/s-z/Trix/Trix.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/Trix/Trix.StaticSeries.Tests.cs @@ -47,7 +47,7 @@ public void UseReusable() public void Chainee() { IReadOnlyList results = Quotes - .GetSma(2) + .ToSma(2) .GetTrix(20); Assert.AreEqual(502, results.Count); @@ -59,7 +59,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetTrix(20) - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(473, results.Count(x => x.Sma != null)); diff --git a/tests/indicators/s-z/Tsi/Tsi.StaticSeries.Tests.cs b/tests/indicators/s-z/Tsi/Tsi.StaticSeries.Tests.cs index 4b13e4f66..1557345d0 100644 --- a/tests/indicators/s-z/Tsi/Tsi.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/Tsi/Tsi.StaticSeries.Tests.cs @@ -55,7 +55,7 @@ public void UseReusable() public void Chainee() { IReadOnlyList results = Quotes - .GetSma(2) + .ToSma(2) .GetTsi(); Assert.AreEqual(502, results.Count); @@ -67,7 +67,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetTsi() - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(456, results.Count(x => x.Sma != null)); diff --git a/tests/indicators/s-z/UlcerIndex/UlcerIndex.StaticSeries.Tests.cs b/tests/indicators/s-z/UlcerIndex/UlcerIndex.StaticSeries.Tests.cs index bd37fb6d6..d38b6646b 100644 --- a/tests/indicators/s-z/UlcerIndex/UlcerIndex.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/UlcerIndex/UlcerIndex.StaticSeries.Tests.cs @@ -33,7 +33,7 @@ public void UseReusable() public void Chainee() { IReadOnlyList results = Quotes - .GetSma(2) + .ToSma(2) .GetUlcerIndex(); Assert.AreEqual(502, results.Count); @@ -45,7 +45,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetUlcerIndex() - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(480, results.Count(x => x.Sma != null)); diff --git a/tests/indicators/s-z/Ultimate/Ultimate.StaticSeries.Tests.cs b/tests/indicators/s-z/Ultimate/Ultimate.StaticSeries.Tests.cs index 4d1e5532b..e2ab1a19a 100644 --- a/tests/indicators/s-z/Ultimate/Ultimate.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/Ultimate/Ultimate.StaticSeries.Tests.cs @@ -29,7 +29,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetUltimate() - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(465, results.Count(x => x.Sma != null)); diff --git a/tests/indicators/s-z/VolatilityStop/VolatilityStop.StaticSeries.Tests.cs b/tests/indicators/s-z/VolatilityStop/VolatilityStop.StaticSeries.Tests.cs index 7cb17f5be..5e5198956 100644 --- a/tests/indicators/s-z/VolatilityStop/VolatilityStop.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/VolatilityStop/VolatilityStop.StaticSeries.Tests.cs @@ -65,7 +65,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetVolatilityStop() - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(439, results.Count(x => x.Sma != null)); diff --git a/tests/indicators/s-z/Vwap/Vwap.StaticSeries.Tests.cs b/tests/indicators/s-z/Vwap/Vwap.StaticSeries.Tests.cs index aa31fe8d5..041b4ea1c 100644 --- a/tests/indicators/s-z/Vwap/Vwap.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/Vwap/Vwap.StaticSeries.Tests.cs @@ -62,7 +62,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetVwap() - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(493, results.Count(x => x.Sma != null)); diff --git a/tests/indicators/s-z/Vwma/Vwma.StaticSeries.Tests.cs b/tests/indicators/s-z/Vwma/Vwma.StaticSeries.Tests.cs index c3fed2674..8b3e75ec0 100644 --- a/tests/indicators/s-z/Vwma/Vwma.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/Vwma/Vwma.StaticSeries.Tests.cs @@ -29,7 +29,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetVwma(10) - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(484, results.Count(x => x.Sma != null)); diff --git a/tests/indicators/s-z/WilliamsR/WilliamsR.StaticSeries.Tests.cs b/tests/indicators/s-z/WilliamsR/WilliamsR.StaticSeries.Tests.cs index 36c855f79..cee2ffdea 100644 --- a/tests/indicators/s-z/WilliamsR/WilliamsR.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/WilliamsR/WilliamsR.StaticSeries.Tests.cs @@ -38,7 +38,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetWilliamsR() - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(480, results.Count(x => x.Sma != null)); diff --git a/tests/indicators/s-z/Wma/Wma.StaticSeries.Tests.cs b/tests/indicators/s-z/Wma/Wma.StaticSeries.Tests.cs index 014820658..adaa328d7 100644 --- a/tests/indicators/s-z/Wma/Wma.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/Wma/Wma.StaticSeries.Tests.cs @@ -36,7 +36,7 @@ public void UseReusable() public void Chainee() { IReadOnlyList results = Quotes - .GetSma(2) + .ToSma(2) .GetWma(20); Assert.AreEqual(502, results.Count); @@ -48,7 +48,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetWma(20) - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(474, results.Count(x => x.Sma != null)); diff --git a/tests/indicators/s-z/ZigZag/ZigZag.StaticSeries.Tests.cs b/tests/indicators/s-z/ZigZag/ZigZag.StaticSeries.Tests.cs index abdedebde..0a57b7b76 100644 --- a/tests/indicators/s-z/ZigZag/ZigZag.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/ZigZag/ZigZag.StaticSeries.Tests.cs @@ -112,7 +112,7 @@ public void Chainor() { IReadOnlyList results = Quotes .GetZigZag(EndType.Close, 3) - .GetSma(10); + .ToSma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(225, results.Count(x => x.Sma != null)); diff --git a/tests/other/Convergence.Tests.cs b/tests/other/Convergence.Tests.cs index 2b709899e..232a52a47 100644 --- a/tests/other/Convergence.Tests.cs +++ b/tests/other/Convergence.Tests.cs @@ -105,7 +105,7 @@ public void Ema() foreach (int qty in QuotesQuantities) { IReadOnlyList qts = Data.GetLongish(qty); - IReadOnlyList r = Api.GetEma(qts, 15); + IReadOnlyList r = qts.ToEma(15); EmaResult l = r[^1]; Console.WriteLine($"EMA(15) on {l.Timestamp:d} with {qts.Count,4} periods: {l.Ema:N8}"); diff --git a/tests/other/Custom.Indicator.Tests.cs b/tests/other/Custom.Indicator.Tests.cs index 352e740dd..261064fe7 100644 --- a/tests/other/Custom.Indicator.Tests.cs +++ b/tests/other/Custom.Indicator.Tests.cs @@ -81,7 +81,7 @@ public void Chainor() { IReadOnlyList results = quotes .GetIndicator(10) - .GetEma(10); + .ToEma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(484, results.Count(x => x.Ema != null)); diff --git a/tests/other/Custom.Quotes.Tests.cs b/tests/other/Custom.Quotes.Tests.cs index 1db53373a..3b50b542d 100644 --- a/tests/other/Custom.Quotes.Tests.cs +++ b/tests/other/Custom.Quotes.Tests.cs @@ -33,8 +33,7 @@ public void CustomQuoteSeries() }) .ToList(); - IReadOnlyList results = Api.GetEma(myGenericHistory -, 20); + IReadOnlyList results = Ema.ToEma(myGenericHistory, 20); // proper quantities Assert.AreEqual(502, results.Count); @@ -160,8 +159,7 @@ public void CustomQuoteInheritedSeries() MyOtherProperty: 123456)) .ToList(); - IReadOnlyList results = Api.GetEma(myGenericHistory -, 20); + IReadOnlyList results = myGenericHistory.ToEma(20); // proper quantities Assert.AreEqual(502, results.Count); diff --git a/tests/other/Custom.Results.Tests.cs b/tests/other/Custom.Results.Tests.cs index f2204ef88..a45bd6264 100644 --- a/tests/other/Custom.Results.Tests.cs +++ b/tests/other/Custom.Results.Tests.cs @@ -29,7 +29,7 @@ public void CustomSeriesClass() [TestMethod] public void CustomSeriesClassLinq() { - IEnumerable emaResults = Api.GetEma(quotes, 14); + IEnumerable emaResults = quotes.ToEma(14); // can use a derive Indicator class using Linq @@ -48,7 +48,7 @@ public void CustomSeriesClassLinq() public void CustomSeriesClassFind() { List emaResults - = Api.GetEma(quotes, 20).ToList(); + = quotes.ToEma(20).ToList(); // can use a derive Indicator class using Linq diff --git a/tests/other/PublicApi.Interface.Tests.cs b/tests/other/PublicApi.Interface.Tests.cs index ae9a96cc0..7e66e061e 100644 --- a/tests/other/PublicApi.Interface.Tests.cs +++ b/tests/other/PublicApi.Interface.Tests.cs @@ -12,31 +12,23 @@ public class UserInterface private static readonly IReadOnlyList quotesBad = Data.GetBad(); [TestMethod] - public void QuoteValidationEnumerable() - { - IEnumerable enumerable = quotes; - - enumerable.Validate(); - enumerable.GetSma(6); - Api.GetEma(enumerable, 5); - - Assert.ThrowsException( - () => quotesBad.Validate()); - } - - [TestMethod] - public void QuoteValidationReadOnlyList() + public void QuoteValidation() { IReadOnlyList clean = quotes; clean.Validate(); - clean.GetSma(6); - Api.GetEma(clean, 5); + clean.ToSma(6); + clean.ToEma(5); IReadOnlyList reverse = quotes .OrderByDescending(x => x.Timestamp) .ToList(); + // has duplicates + Assert.ThrowsException( + () => quotesBad.Validate()); + + // out of order Assert.ThrowsException( () => reverse.Validate()); } @@ -111,9 +103,9 @@ public void StreamMany() // from quote provider IReadOnlyList staticAtr = quotes.GetAtr(); IReadOnlyList staticAtrStop = quotes.GetAtrStop(); IEnumerable staticAlligator = quotes.GetAlligator(); - IEnumerable staticEma = Api.GetEma(quotes, 20); + IEnumerable staticEma = quotes.ToEma(20); IEnumerable staticQuotePart = quotes.Use(CandlePart.OHL3); - IEnumerable staticSma = quotes.GetSma(20); + IEnumerable staticSma = quotes.ToSma(20); IReadOnlyList staticTr = quotes.GetTr(); // final results should persist in scope diff --git a/tests/other/Sut.CustomItems.cs b/tests/other/Sut.CustomItems.cs index 4b051c35a..dcc922fd1 100644 --- a/tests/other/Sut.CustomItems.cs +++ b/tests/other/Sut.CustomItems.cs @@ -80,7 +80,7 @@ public static class CustomIndicator { // SERIES, from CHAIN public static IReadOnlyList GetIndicator( - this IEnumerable source, + this IReadOnlyList source, int lookbackPeriods) where T : IReusable => source diff --git a/tests/performance/Perf.Increments.cs b/tests/performance/Perf.Increments.cs index 348c9c74c..cb4ffdef1 100644 --- a/tests/performance/Perf.Increments.cs +++ b/tests/performance/Perf.Increments.cs @@ -8,10 +8,6 @@ public class Incrementals private static readonly IReadOnlyList quotes = Data.GetDefault(); - private static readonly List quotesList - = quotes - .ToSortedList(); - private static readonly IReadOnlyList reusables = quotes .Cast() @@ -85,18 +81,15 @@ public object EmaIncQot() // TIME-SERIES EQUIVALENTS [Benchmark] - public object EmaSeriesEqiv() => quotesList.CalcEma(14); - - [Benchmark] - public object EmaSeriesOrig() => Api.GetEma(quotes, 14); + public object EmaSeries() => quotes.ToEma(14); [Benchmark] - public object EmaIncremEqiv() + public object EmaIncrem() { - EmaList ema = new(14) { quotes.ToSortedList() }; + EmaList ema = new(14) { quotes }; return ema; } [Benchmark] - public object EmaStreamEqiv() => provider.ToEma(14).Results; + public object EmaStream() => provider.ToEma(14).Results; } diff --git a/tests/performance/Perf.StaticSeries.cs b/tests/performance/Perf.StaticSeries.cs index b3a8aff78..cdecc570e 100644 --- a/tests/performance/Perf.StaticSeries.cs +++ b/tests/performance/Perf.StaticSeries.cs @@ -93,7 +93,7 @@ public class SeriesIndicators public object GetElderRay() => q.GetElderRay(); [Benchmark] - public object GetEma() => Api.GetEma(q, 14); + public object GetEma() => q.ToEma(14); [Benchmark] public object GetEpma() => q.GetEpma(14); @@ -198,7 +198,7 @@ public class SeriesIndicators public object GetSlope() => q.GetSlope(20); [Benchmark] - public object GetSma() => q.GetSma(10); + public object GetSma() => q.ToSma(10); [Benchmark] public object GetSmaAnalysis() => q.GetSmaAnalysis(10); diff --git a/tests/performance/Perf.StreamHub.Externals.cs b/tests/performance/Perf.StreamHub.Externals.cs index c3f258a0c..3a2dd4eb0 100644 --- a/tests/performance/Perf.StreamHub.Externals.cs +++ b/tests/performance/Perf.StreamHub.Externals.cs @@ -35,7 +35,7 @@ public void Cleanup() // TODO: replace with external data cache model, when available [Benchmark(Baseline = true)] - public object EmaSeries() => Api.GetEma(quotes, 14); + public object EmaSeries() => quotes.ToEma(14); [Benchmark] public object EmaStream() => provider.ToEma(14).Results; From 70c6d6087a87e90597cac02012e9a3e27104f8f1 Mon Sep 17 00:00:00 2001 From: Dave Skender <8432125+DaveSkender@users.noreply.github.com> Date: Sun, 13 Oct 2024 22:35:27 -0400 Subject: [PATCH 28/38] convert to naming for static series --- src/_common/ObsoleteV3.cs | 8 +- src/a-d/Adl/Adl.Api.cs | 19 -- src/a-d/Adl/Adl.StaticSeries.cs | 6 +- src/a-d/Adx/Adx.Api.cs | 4 +- src/a-d/Adx/Adx.Common.cs | 18 -- src/a-d/Adx/Adx.StaticSeries.cs | 2 +- src/a-d/Adx/Adx.Utilities.cs | 14 +- src/a-d/Alligator/Alligator.Api.cs | 2 +- src/a-d/Alma/Alma.Api.cs | 2 +- src/a-d/Aroon/Aroon.Api.cs | 4 +- src/a-d/Aroon/Aroon.Common.cs | 19 -- src/a-d/Aroon/Aroon.StaticSeries.cs | 4 +- src/a-d/Aroon/Aroon.Utilities.cs | 14 +- src/a-d/Atr/Atr.Api.cs | 2 +- src/a-d/AtrStop/AtrStop.Api.cs | 2 +- src/a-d/Awesome/Awesome.Api.cs | 4 +- src/a-d/Awesome/Awesome.Common.cs | 26 --- src/a-d/Awesome/Awesome.StaticSeries.cs | 2 +- src/a-d/Awesome/Awesome.Utilities.cs | 21 ++- src/a-d/Beta/Beta.Api.cs | 4 +- src/a-d/Beta/Beta.Common.cs | 30 --- src/a-d/Beta/Beta.StaticSeries.cs | 4 +- src/a-d/Beta/Beta.Utilities.cs | 25 ++- src/a-d/BollingerBands/BollingerBands.Api.cs | 2 +- src/a-d/Bop/Bop.Api.cs | 2 +- src/a-d/Cci/Cci.Api.cs | 2 +- src/a-d/ChaikinOsc/ChaikinOsc.Api.cs | 2 +- src/a-d/ChaikinOsc/ChaikinOsc.StaticSeries.cs | 2 +- src/a-d/Chandelier/Chandelier.Api.cs | 2 +- src/a-d/Chop/Chop.Api.cs | 2 +- src/a-d/Cmf/Cmf.Api.cs | 2 +- src/a-d/Cmf/Cmf.StaticSeries.cs | 2 +- src/a-d/Cmo/Cmo.Api.cs | 2 +- src/a-d/ConnorsRsi/ConnorsRsi.Api.cs | 2 +- src/a-d/Correlation/Correlation.Api.cs | 4 +- src/a-d/Correlation/Correlation.Common.cs | 30 --- .../Correlation/Correlation.StaticSeries.cs | 4 +- src/a-d/Correlation/Correlation.Utilities.cs | 25 ++- src/a-d/Dema/Dema.Api.cs | 2 +- src/a-d/Doji/Doji.Api.cs | 2 +- src/a-d/Donchian/Donchian.Api.cs | 2 +- src/a-d/Dpo/Dpo.Api.cs | 2 +- src/a-d/Dynamic/Dynamic.Api.cs | 2 +- src/e-k/ElderRay/ElderRay.Api.cs | 2 +- src/e-k/Epma/Epma.Api.cs | 2 +- src/e-k/Fcb/Fcb.Api.cs | 2 +- .../FisherTransform/FisherTransform.Api.cs | 2 +- src/e-k/ForceIndex/ForceIndex.Api.cs | 2 +- src/e-k/Fractal/Fractal.Api.cs | 2 +- src/e-k/Gator/Gator.Api.cs | 4 +- src/e-k/HeikinAshi/HeikinAshi.Api.cs | 2 +- src/e-k/Hma/Hma.Api.cs | 2 +- src/e-k/HtTrendline/HtTrendline.Api.cs | 2 +- src/e-k/Hurst/Hurst.Api.cs | 2 +- src/e-k/Ichimoku/Ichimoku.Api.cs | 2 +- src/e-k/Kama/Kama.Api.cs | 2 +- src/e-k/Keltner/Keltner.Api.cs | 2 +- src/e-k/Kvo/Kvo.Api.cs | 2 +- src/m-r/MaEnvelopes/MaEnvelopes.Api.cs | 2 +- src/m-r/Macd/MacdApi.cs | 2 +- src/m-r/Mama/Mama.Api.cs | 2 +- src/m-r/Marubozu/Marubozu.Api.cs | 2 +- src/m-r/Mfi/Mfi.Api.cs | 2 +- src/m-r/Obv/Obv.Api.cs | 2 +- src/m-r/ParabolicSar/ParabolicSar.Api.cs | 2 +- src/m-r/PivotPoints/PivotPoints.Api.cs | 2 +- src/m-r/Pivots/Pivots.Api.cs | 2 +- src/m-r/Pmo/Pmo.Api.cs | 2 +- src/m-r/Prs/Prs.Api.cs | 2 +- src/m-r/Pvo/Pvo.Api.cs | 2 +- src/m-r/Renko/Renko.Api.cs | 2 +- src/m-r/Roc/Roc.Api.cs | 2 +- src/m-r/RocWb/RocWb.Api.cs | 2 +- src/m-r/RollingPivots/RollingPivots.Api.cs | 2 +- src/m-r/Rsi/Rsi.Api.cs | 2 +- src/s-z/Slope/Slope.Api.cs | 2 +- src/s-z/SmaAnalysis/SmaAnalysis.Api.cs | 2 +- src/s-z/Smi/Smi.Api.cs | 2 +- src/s-z/Smma/Smma.Api.cs | 2 +- src/s-z/StarcBands/StarcBands.Api.cs | 2 +- src/s-z/Stc/Stc.Api.cs | 2 +- src/s-z/StdDev/StdDev.Api.cs | 2 +- src/s-z/StdDevChannels/StdDevChannels.Api.cs | 2 +- src/s-z/Stoch/Stoch.Api.cs | 4 +- src/s-z/StochRsi/StochRsi.Api.cs | 2 +- src/s-z/SuperTrend/SuperTrend.Api.cs | 2 +- src/s-z/T3/T3.Api.cs | 2 +- src/s-z/Tema/Tema.Api.cs | 2 +- src/s-z/Tr/Tr.Api.cs | 2 +- src/s-z/Trix/Trix.Api.cs | 2 +- src/s-z/Tsi/Tsi.Api.cs | 2 +- src/s-z/UlcerIndex/UlcerIndex.Api.cs | 2 +- src/s-z/Ultimate/Ultimate.Api.cs | 2 +- src/s-z/VolatilityStop/VolatilityStop.Api.cs | 2 +- src/s-z/Vortex/Vortex.Api.cs | 2 +- src/s-z/Vwap/Vwap.Api.cs | 2 +- src/s-z/Vwma/Vwma.Api.cs | 2 +- src/s-z/WilliamsR/WilliamsR.Api.cs | 2 +- src/s-z/Wma/Wma.Api.cs | 2 +- src/s-z/ZigZag/ZigZag.Api.cs | 2 +- .../_common/Generics/RemoveWarmup.Tests.cs | 6 +- .../Reusable/Reusable.Utilities.Tests.cs | 2 +- .../a-d/Adl/Adl.StaticSeries.Tests.cs | 14 +- .../indicators/a-d/Adl/Adl.StreamHub.Tests.cs | 4 +- .../a-d/Adx/Adx.StaticSeries.Tests.cs | 20 +- .../Alligator/Alligator.StaticSeries.Tests.cs | 30 +-- .../Alligator/Alligator.StreamHub.Tests.cs | 4 +- .../a-d/Alma/Alma.StaticSeries.Tests.cs | 26 +-- .../a-d/Aroon/Aroon.StaticSeries.Tests.cs | 14 +- .../a-d/Atr/Atr.StaticSeries.Tests.cs | 18 +- .../indicators/a-d/Atr/Atr.StreamHub.Tests.cs | 4 +- .../a-d/AtrStop/AtrStop.StaticSeries.Tests.cs | 18 +- .../a-d/AtrStop/AtrStop.StreamHub.Tests.cs | 4 +- .../a-d/Awesome/Awesome.StaticSeries.Tests.cs | 20 +- .../a-d/Beta/Beta.StaticSeries.Tests.cs | 38 ++-- .../BollingerBands.StaticSeries.Tests.cs | 20 +- .../a-d/Bop/Bop.StaticSeries.Tests.cs | 16 +- .../a-d/Cci/Cci.StaticSeries.Tests.cs | 14 +- .../ChaikinOsc.StaticSeries.Tests.cs | 16 +- .../Chandelier.StaticSeries.Tests.cs | 20 +- .../a-d/Chop/Chop.StaticSeries.Tests.cs | 16 +- .../a-d/Cmf/Cmf.StaticSeries.Tests.cs | 16 +- .../a-d/Cmo/Cmo.StaticSeries.Tests.cs | 18 +- .../ConnorsRsi.StaticSeries.Tests.cs | 24 +-- .../Correlation.StaticSeries.Tests.cs | 24 +-- .../a-d/Dema/Dema.StaticSeries.Tests.cs | 18 +- .../a-d/Doji/Doji.StaticSeries.Tests.cs | 14 +- .../Donchian/Donchian.StaticSeries.Tests.cs | 14 +- .../a-d/Dpo/Dpo.StaticSeries.Tests.cs | 16 +- .../a-d/Dynamic/Dynamic.StaticSeries.Tests.cs | 18 +- .../ElderRay/ElderRay.StaticSeries.Tests.cs | 14 +- .../e-k/Ema/Ema.StaticSeries.Tests.cs | 2 +- .../e-k/Epma/Epma.StaticSeries.Tests.cs | 18 +- .../e-k/Fcb/Fcb.StaticSeries.Tests.cs | 14 +- .../FisherTransform.StaticSeries.Tests.cs | 16 +- .../ForceIndex.StaticSeries.Tests.cs | 14 +- .../e-k/Fractal/Fractal.StaticSeries.Tests.cs | 12 +- .../e-k/Gator/Gator.StaticSeries.Tests.cs | 18 +- .../HeikinAshi.StaticSeries.Tests.cs | 10 +- .../e-k/Hma/Hma.StaticSeries.Tests.cs | 18 +- .../HtTrendline.StaticSeries.Tests.cs | 18 +- .../e-k/Hurst/Hurst.StaticSeries.Tests.cs | 18 +- .../Ichimoku/Ichimoku.StaticSeries.Tests.cs | 16 +- .../e-k/Kama/Kama.StaticSeries.Tests.cs | 22 +-- .../e-k/Keltner/Keltner.StaticSeries.Tests.cs | 18 +- .../e-k/Kvo/Kvo.StaticSeries.Tests.cs | 18 +- .../MaEnvelopes.StaticSeries.Tests.cs | 48 ++--- .../m-r/Macd/Macd.StaticSeries.Tests.cs | 22 +-- .../m-r/Mama/Mama.StaticSeries.Tests.cs | 22 +-- .../Marubozu/Marubozu.StaticSeries.Tests.cs | 14 +- .../m-r/Mfi/Mfi.StaticSeries.Tests.cs | 16 +- .../m-r/Obv/Obv.StaticSeries.Tests.cs | 12 +- .../ParabolicSar.StaticSeries.Tests.cs | 18 +- .../PivotPoints.StaticSeries.Tests.cs | 22 +-- .../m-r/Pivots/Pivots.StaticSeries.Tests.cs | 16 +- .../m-r/Pmo/Pmo.StaticSeries.Tests.cs | 22 +-- .../m-r/Prs/Prs.StaticSeries.Tests.cs | 22 +-- .../m-r/Pvo/Pvo.StaticSeries.Tests.cs | 18 +- .../m-r/Renko/Renko.StaticSeries.Tests.cs | 14 +- .../m-r/Renko/Renko.StreamHub.Tests.cs | 4 +- .../m-r/Roc/Roc.StaticSeries.Tests.cs | 18 +- .../m-r/RocWb/RocWb.StaticSeries.Tests.cs | 22 +-- .../RollingPivots.StaticSeries.Tests.cs | 22 +-- .../m-r/Rsi/Rsi.StaticSeries.Tests.cs | 24 +-- .../s-z/Slope/Slope.StaticSeries.Tests.cs | 20 +- .../SmaAnalysis.StaticSeries.Tests.cs | 18 +- .../s-z/Smi/Smi.StaticSeries.Tests.cs | 24 +-- .../s-z/Smma/Smma.StaticSeries.Tests.cs | 18 +- .../StarcBands.StaticSeries.Tests.cs | 18 +- .../s-z/Stc/Stc.StaticSeries.Tests.cs | 24 +-- .../s-z/StdDev/StdDev.StaticSeries.Tests.cs | 20 +- .../StdDevChannels.StaticSeries.Tests.cs | 22 +-- .../s-z/Stoch/Stoch.StaticSeries.Tests.cs | 34 ++-- .../StochRsi/StochRsi.StaticSeries.Tests.cs | 26 +-- .../SuperTrend.StaticSeries.Tests.cs | 18 +- .../s-z/T3/T3.StaticSeries.Tests.cs | 18 +- .../s-z/Tema/Tema.StaticSeries.Tests.cs | 18 +- .../s-z/Tr/Tr.StaticSeries.Tests.cs | 14 +- tests/indicators/s-z/Tr/Tr.StreamHub.Tests.cs | 4 +- .../s-z/Trix/Trix.StaticSeries.Tests.cs | 18 +- .../s-z/Tsi/Tsi.StaticSeries.Tests.cs | 24 +-- .../UlcerIndex.StaticSeries.Tests.cs | 18 +- .../Ultimate/Ultimate.StaticSeries.Tests.cs | 18 +- .../VolatilityStop.StaticSeries.Tests.cs | 16 +- .../s-z/Vortex/Vortex.StaticSeries.Tests.cs | 14 +- .../s-z/Vwap/Vwap.StaticSeries.Tests.cs | 18 +- .../s-z/Vwma/Vwma.StaticSeries.Tests.cs | 14 +- .../WilliamsR/WilliamsR.StaticSeries.Tests.cs | 18 +- .../s-z/Wma/Wma.StaticSeries.Tests.cs | 22 +-- .../s-z/ZigZag/ZigZag.StaticSeries.Tests.cs | 28 +-- tests/other/Convergence.Tests.cs | 52 ++--- tests/other/PublicApi.Interface.Tests.cs | 10 +- tests/performance/Perf.StaticSeries.cs | 178 +++++++++--------- 193 files changed, 1115 insertions(+), 1166 deletions(-) delete mode 100644 src/a-d/Adx/Adx.Common.cs delete mode 100644 src/a-d/Aroon/Aroon.Common.cs delete mode 100644 src/a-d/Awesome/Awesome.Common.cs delete mode 100644 src/a-d/Beta/Beta.Common.cs delete mode 100644 src/a-d/Correlation/Correlation.Common.cs diff --git a/src/_common/ObsoleteV3.cs b/src/_common/ObsoleteV3.cs index a9f881db2..1f78baa0f 100644 --- a/src/_common/ObsoleteV3.cs +++ b/src/_common/ObsoleteV3.cs @@ -42,28 +42,28 @@ public static IEnumerable GetEma( public static IEnumerable GetAdl( this IEnumerable quotes, int smaPeriods) where TQuote : IQuote - => quotes.ToSortedList().CalcAdl(); + => quotes.ToSortedList().ToAdl(); [ExcludeFromCodeCoverage] [Obsolete("Use a chained `results.GetSma(smaPeriods)` to generate a moving average.", true)] // v3.0.0 public static IEnumerable GetObv( this IEnumerable quotes, int smaPeriods) where TQuote : IQuote - => quotes.GetObv(); + => quotes.ToObv(); [ExcludeFromCodeCoverage] [Obsolete("Use a chained `results.GetSma(smaPeriods)` to generate a moving average.", true)] // v3.0.0 public static IEnumerable GetPrs( this IEnumerable quotesEval, IEnumerable quotesBase, int lookbackPeriods, int smaPeriods) where TQuote : IQuote - => quotesEval.Use(CandlePart.Close).GetPrs(quotesBase.Use(CandlePart.Close), lookbackPeriods); + => quotesEval.Use(CandlePart.Close).ToPrs(quotesBase.Use(CandlePart.Close), lookbackPeriods); [ExcludeFromCodeCoverage] [Obsolete("Use a chained `results.GetSma(smaPeriods)` to generate a moving average.", true)] // v3.0.0 public static IEnumerable GetRoc( this IEnumerable quotes, int lookbackPeriods, int smaPeriods) where TQuote : IQuote - => quotes.Use(CandlePart.Close).GetRoc(lookbackPeriods); + => quotes.Use(CandlePart.Close).ToRoc(lookbackPeriods); [ExcludeFromCodeCoverage] [Obsolete("Use a chained `results.GetSma(smaPeriods)` to generate a moving average.", true)] // v3.0.0 diff --git a/src/a-d/Adl/Adl.Api.cs b/src/a-d/Adl/Adl.Api.cs index e7a08f051..cb02c9b8f 100644 --- a/src/a-d/Adl/Adl.Api.cs +++ b/src/a-d/Adl/Adl.Api.cs @@ -4,25 +4,6 @@ namespace Skender.Stock.Indicators; public static partial class Adl { - // SERIES, from TQuote - /// - ///Accumulation / Distribution Line(ADL) is a rolling accumulation of Chaikin Money Flow Volume. - /// - ///See - /// documentation - ///for more information. - /// - /// - /// Configurable Quote type. See Guide for more information. - ///Historical price quotes. - ///Time series of ADL values. - public static IReadOnlyList GetAdl( - this IEnumerable quotes) - where TQuote : IQuote - => quotes - .ToSortedList() - .CalcAdl(); - // OBSERVER, from Quote Provider public static AdlHub ToAdl( this IQuoteProvider quoteProvider) diff --git a/src/a-d/Adl/Adl.StaticSeries.cs b/src/a-d/Adl/Adl.StaticSeries.cs index 8b7c17cea..10f833ed4 100644 --- a/src/a-d/Adl/Adl.StaticSeries.cs +++ b/src/a-d/Adl/Adl.StaticSeries.cs @@ -4,10 +4,12 @@ namespace Skender.Stock.Indicators; public static partial class Adl { - internal static List CalcAdl( - this List source) + public static IReadOnlyList ToAdl( + this IReadOnlyList source) where TQuote : IQuote { + ArgumentNullException.ThrowIfNull(source); + // initialize int length = source.Count; List results = new(length); diff --git a/src/a-d/Adx/Adx.Api.cs b/src/a-d/Adx/Adx.Api.cs index c578dad40..7a60a587b 100644 --- a/src/a-d/Adx/Adx.Api.cs +++ b/src/a-d/Adx/Adx.Api.cs @@ -2,12 +2,12 @@ namespace Skender.Stock.Indicators; // AVERAGE DIRECTIONAL INDEX (API) -public static partial class Indicator +public static partial class Adx { // SERIES, from TQuote /// /// - public static IReadOnlyList GetAdx( + public static IReadOnlyList ToAdx( this IEnumerable quotes, int lookbackPeriods = 14) where TQuote : IQuote => quotes diff --git a/src/a-d/Adx/Adx.Common.cs b/src/a-d/Adx/Adx.Common.cs deleted file mode 100644 index deb21a614..000000000 --- a/src/a-d/Adx/Adx.Common.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace Skender.Stock.Indicators; - -// AVERAGE DIRECTIONAL INDEX (COMMON) - -public static class Adx -{ - // parameter validation - internal static void Validate( - int lookbackPeriods) - { - // check parameter arguments - if (lookbackPeriods <= 1) - { - throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, - "Lookback periods must be greater than 1 for ADX."); - } - } -} diff --git a/src/a-d/Adx/Adx.StaticSeries.cs b/src/a-d/Adx/Adx.StaticSeries.cs index 3996d71fa..7944d6bb1 100644 --- a/src/a-d/Adx/Adx.StaticSeries.cs +++ b/src/a-d/Adx/Adx.StaticSeries.cs @@ -2,7 +2,7 @@ namespace Skender.Stock.Indicators; // AVERAGE DIRECTIONAL INDEX (SERIES) -public static partial class Indicator +public static partial class Adx { private static List CalcAdx( this List source, diff --git a/src/a-d/Adx/Adx.Utilities.cs b/src/a-d/Adx/Adx.Utilities.cs index ff9a1d40f..f7e65d5f9 100644 --- a/src/a-d/Adx/Adx.Utilities.cs +++ b/src/a-d/Adx/Adx.Utilities.cs @@ -1,6 +1,6 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +public static partial class Adx { // remove recommended periods /// @@ -13,4 +13,16 @@ public static IReadOnlyList RemoveWarmupPeriods( return results.Remove(2 * n + 100); } + + // parameter validation + internal static void Validate( + int lookbackPeriods) + { + // check parameter arguments + if (lookbackPeriods <= 1) + { + throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, + "Lookback periods must be greater than 1 for ADX."); + } + } } diff --git a/src/a-d/Alligator/Alligator.Api.cs b/src/a-d/Alligator/Alligator.Api.cs index 6d0c047eb..06a613a74 100644 --- a/src/a-d/Alligator/Alligator.Api.cs +++ b/src/a-d/Alligator/Alligator.Api.cs @@ -29,7 +29,7 @@ public static partial class Alligator /// /// Invalid parameter value provided. /// - public static IReadOnlyList GetAlligator( + public static IReadOnlyList ToAlligator( this IEnumerable source, int jawPeriods = 13, int jawOffset = 8, diff --git a/src/a-d/Alma/Alma.Api.cs b/src/a-d/Alma/Alma.Api.cs index ffb1e3555..1eb838afd 100644 --- a/src/a-d/Alma/Alma.Api.cs +++ b/src/a-d/Alma/Alma.Api.cs @@ -4,7 +4,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // SERIES, from CHAIN - public static IReadOnlyList GetAlma( + public static IReadOnlyList ToAlma( this IReadOnlyList results, int lookbackPeriods = 9, double offset = 0.85, diff --git a/src/a-d/Aroon/Aroon.Api.cs b/src/a-d/Aroon/Aroon.Api.cs index 9abeee793..17a2fc1ab 100644 --- a/src/a-d/Aroon/Aroon.Api.cs +++ b/src/a-d/Aroon/Aroon.Api.cs @@ -1,12 +1,12 @@ namespace Skender.Stock.Indicators; // AROON OSCILLATOR (API) -public static partial class Indicator +public static partial class Aroon { // SERIES, from TQuote /// /// - public static IReadOnlyList GetAroon( + public static IReadOnlyList ToAroon( this IEnumerable quotes, int lookbackPeriods = 25) where TQuote : IQuote => quotes diff --git a/src/a-d/Aroon/Aroon.Common.cs b/src/a-d/Aroon/Aroon.Common.cs deleted file mode 100644 index 4c0c30bf8..000000000 --- a/src/a-d/Aroon/Aroon.Common.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Skender.Stock.Indicators; - -// AROON OSCILLATOR (COMMON) - -public static class Aroon -{ - // parameter validation - internal static void Validate( - int lookbackPeriods) - { - // check parameter arguments - if (lookbackPeriods <= 0) - { - throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, - "Lookback periods must be greater than 0 for Aroon."); - } - } - -} diff --git a/src/a-d/Aroon/Aroon.StaticSeries.cs b/src/a-d/Aroon/Aroon.StaticSeries.cs index a8af83f1e..1d60eadad 100644 --- a/src/a-d/Aroon/Aroon.StaticSeries.cs +++ b/src/a-d/Aroon/Aroon.StaticSeries.cs @@ -2,14 +2,14 @@ namespace Skender.Stock.Indicators; // AROON OSCILLATOR (SERIES) -public static partial class Indicator +public static partial class Aroon { private static List CalcAroon( this List source, int lookbackPeriods) { // check parameter arguments - Aroon.Validate(lookbackPeriods); + Validate(lookbackPeriods); // initialize int length = source.Count; diff --git a/src/a-d/Aroon/Aroon.Utilities.cs b/src/a-d/Aroon/Aroon.Utilities.cs index 66eb9d036..9a3fde239 100644 --- a/src/a-d/Aroon/Aroon.Utilities.cs +++ b/src/a-d/Aroon/Aroon.Utilities.cs @@ -1,6 +1,6 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +public static partial class Aroon { // remove recommended periods /// @@ -13,4 +13,16 @@ public static IReadOnlyList RemoveWarmupPeriods( return results.Remove(removePeriods); } + + // parameter validation + internal static void Validate( + int lookbackPeriods) + { + // check parameter arguments + if (lookbackPeriods <= 0) + { + throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, + "Lookback periods must be greater than 0 for Aroon."); + } + } } diff --git a/src/a-d/Atr/Atr.Api.cs b/src/a-d/Atr/Atr.Api.cs index a10d67c21..39f5c7c08 100644 --- a/src/a-d/Atr/Atr.Api.cs +++ b/src/a-d/Atr/Atr.Api.cs @@ -7,7 +7,7 @@ public static partial class Atr // SERIES, from TQuote /// /// - public static IReadOnlyList GetAtr( + public static IReadOnlyList ToAtr( this IEnumerable quotes, int lookbackPeriods = 14) where TQuote : IQuote => quotes diff --git a/src/a-d/AtrStop/AtrStop.Api.cs b/src/a-d/AtrStop/AtrStop.Api.cs index f985cd541..cd4fbebee 100644 --- a/src/a-d/AtrStop/AtrStop.Api.cs +++ b/src/a-d/AtrStop/AtrStop.Api.cs @@ -7,7 +7,7 @@ public static partial class AtrStop // SERIES, from TQuote /// /// - public static IReadOnlyList GetAtrStop( + public static IReadOnlyList ToAtrStop( this IEnumerable quotes, int lookbackPeriods = 21, double multiplier = 3, diff --git a/src/a-d/Awesome/Awesome.Api.cs b/src/a-d/Awesome/Awesome.Api.cs index ccf389b14..918f79bd7 100644 --- a/src/a-d/Awesome/Awesome.Api.cs +++ b/src/a-d/Awesome/Awesome.Api.cs @@ -1,10 +1,10 @@ namespace Skender.Stock.Indicators; // AWESOME OSCILLATOR (API) -public static partial class Indicator +public static partial class Awesome { // SERIES, from CHAIN - public static IReadOnlyList GetAwesome( + public static IReadOnlyList ToAwesome( this IEnumerable source, int fastPeriods = 5, int slowPeriods = 34) diff --git a/src/a-d/Awesome/Awesome.Common.cs b/src/a-d/Awesome/Awesome.Common.cs deleted file mode 100644 index a8c194923..000000000 --- a/src/a-d/Awesome/Awesome.Common.cs +++ /dev/null @@ -1,26 +0,0 @@ -namespace Skender.Stock.Indicators; - -// AWESOME OSCILLATOR (COMMON) - -public static class Awesome -{ - // parameter validation - internal static void Validate( - int fastPeriods, - int slowPeriods) - { - // check parameter arguments - if (fastPeriods <= 0) - { - throw new ArgumentOutOfRangeException(nameof(slowPeriods), slowPeriods, - "Fast periods must be greater than 0 for Awesome Oscillator."); - } - - if (slowPeriods <= fastPeriods) - { - throw new ArgumentOutOfRangeException(nameof(slowPeriods), slowPeriods, - "Slow periods must be larger than Fast Periods for Awesome Oscillator."); - } - } - -} diff --git a/src/a-d/Awesome/Awesome.StaticSeries.cs b/src/a-d/Awesome/Awesome.StaticSeries.cs index a2ca091fc..67d20e027 100644 --- a/src/a-d/Awesome/Awesome.StaticSeries.cs +++ b/src/a-d/Awesome/Awesome.StaticSeries.cs @@ -2,7 +2,7 @@ namespace Skender.Stock.Indicators; // AWESOME OSCILLATOR (SERIES) -public static partial class Indicator +public static partial class Awesome { private static List CalcAwesome( this List source, diff --git a/src/a-d/Awesome/Awesome.Utilities.cs b/src/a-d/Awesome/Awesome.Utilities.cs index cd8ec64ee..5b48dbbaf 100644 --- a/src/a-d/Awesome/Awesome.Utilities.cs +++ b/src/a-d/Awesome/Awesome.Utilities.cs @@ -1,6 +1,6 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +public static partial class Awesome { // remove recommended periods /// @@ -13,4 +13,23 @@ public static IReadOnlyList RemoveWarmupPeriods( return results.Remove(removePeriods); } + + // parameter validation + internal static void Validate( + int fastPeriods, + int slowPeriods) + { + // check parameter arguments + if (fastPeriods <= 0) + { + throw new ArgumentOutOfRangeException(nameof(slowPeriods), slowPeriods, + "Fast periods must be greater than 0 for Awesome Oscillator."); + } + + if (slowPeriods <= fastPeriods) + { + throw new ArgumentOutOfRangeException(nameof(slowPeriods), slowPeriods, + "Slow periods must be larger than Fast Periods for Awesome Oscillator."); + } + } } diff --git a/src/a-d/Beta/Beta.Api.cs b/src/a-d/Beta/Beta.Api.cs index 989c47cac..5b4ef72dc 100644 --- a/src/a-d/Beta/Beta.Api.cs +++ b/src/a-d/Beta/Beta.Api.cs @@ -1,10 +1,10 @@ namespace Skender.Stock.Indicators; // BETA COEFFICIENT (API) -public static partial class Indicator +public static partial class Beta { // SERIES, from CHAINS (both inputs reusable) - public static IReadOnlyList GetBeta( + public static IReadOnlyList ToBeta( this IEnumerable evalSource, IEnumerable mrktSource, int lookbackPeriods, diff --git a/src/a-d/Beta/Beta.Common.cs b/src/a-d/Beta/Beta.Common.cs deleted file mode 100644 index 384b86fc5..000000000 --- a/src/a-d/Beta/Beta.Common.cs +++ /dev/null @@ -1,30 +0,0 @@ -namespace Skender.Stock.Indicators; - -// BETA COEFFICIENT (COMMON) - -public static class Beta -{ - // parameter validation - internal static void Validate( - List sourceEval, - List sourceMrkt, - int lookbackPeriods) - where T : ISeries - { - // check parameter arguments - if (lookbackPeriods <= 0) - { - throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, - "Lookback periods must be greater than 0 for Beta."); - } - - // check quotes - if (sourceEval.Count != sourceMrkt.Count) - { - throw new InvalidQuotesException( - nameof(sourceEval), - "Eval quotes should have the same number of Market quotes for Beta."); - } - } - -} diff --git a/src/a-d/Beta/Beta.StaticSeries.cs b/src/a-d/Beta/Beta.StaticSeries.cs index f584c9f83..48b50c8c0 100644 --- a/src/a-d/Beta/Beta.StaticSeries.cs +++ b/src/a-d/Beta/Beta.StaticSeries.cs @@ -2,7 +2,7 @@ namespace Skender.Stock.Indicators; // BETA COEFFICIENT (SERIES) -public static partial class Indicator +public static partial class Beta { // NOTE: sequence swapped from API private static List CalcBeta( @@ -146,7 +146,7 @@ private static List CalcBeta( } // calculate correlation, covariance, and variance - CorrResult c = PeriodCorrelation( + CorrResult c = Correlation.PeriodCorrelation( default, [.. dataA], [.. dataB]); diff --git a/src/a-d/Beta/Beta.Utilities.cs b/src/a-d/Beta/Beta.Utilities.cs index 9cb071a21..f4f6617a4 100644 --- a/src/a-d/Beta/Beta.Utilities.cs +++ b/src/a-d/Beta/Beta.Utilities.cs @@ -1,6 +1,6 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +public static partial class Beta { // remove recommended periods /// @@ -13,4 +13,27 @@ public static IReadOnlyList RemoveWarmupPeriods( return results.Remove(removePeriods); } + + // parameter validation + internal static void Validate( + List sourceEval, + List sourceMrkt, + int lookbackPeriods) + where T : ISeries + { + // check parameter arguments + if (lookbackPeriods <= 0) + { + throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, + "Lookback periods must be greater than 0 for Beta."); + } + + // check quotes + if (sourceEval.Count != sourceMrkt.Count) + { + throw new InvalidQuotesException( + nameof(sourceEval), + "Eval quotes should have the same number of Market quotes for Beta."); + } + } } diff --git a/src/a-d/BollingerBands/BollingerBands.Api.cs b/src/a-d/BollingerBands/BollingerBands.Api.cs index aa4c0a99d..c79096c79 100644 --- a/src/a-d/BollingerBands/BollingerBands.Api.cs +++ b/src/a-d/BollingerBands/BollingerBands.Api.cs @@ -4,7 +4,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // SERIES, from CHAIN - public static IReadOnlyList GetBollingerBands( + public static IReadOnlyList ToBollingerBands( this IReadOnlyList results, int lookbackPeriods = 20, double standardDeviations = 2) diff --git a/src/a-d/Bop/Bop.Api.cs b/src/a-d/Bop/Bop.Api.cs index 0cc2e8413..9461ecdf2 100644 --- a/src/a-d/Bop/Bop.Api.cs +++ b/src/a-d/Bop/Bop.Api.cs @@ -6,7 +6,7 @@ public static partial class Indicator // SERIES, from TQuote /// /// - public static IReadOnlyList GetBop( + public static IReadOnlyList ToBop( this IEnumerable quotes, int smoothPeriods = 14) where TQuote : IQuote => quotes diff --git a/src/a-d/Cci/Cci.Api.cs b/src/a-d/Cci/Cci.Api.cs index 1d262caac..2ada8940a 100644 --- a/src/a-d/Cci/Cci.Api.cs +++ b/src/a-d/Cci/Cci.Api.cs @@ -6,7 +6,7 @@ public static partial class Indicator // SERIES, from TQuote /// /// - public static IReadOnlyList GetCci( + public static IReadOnlyList ToCci( this IEnumerable quotes, int lookbackPeriods = 20) where TQuote : IQuote => quotes diff --git a/src/a-d/ChaikinOsc/ChaikinOsc.Api.cs b/src/a-d/ChaikinOsc/ChaikinOsc.Api.cs index 8871af1ed..5e5352a4d 100644 --- a/src/a-d/ChaikinOsc/ChaikinOsc.Api.cs +++ b/src/a-d/ChaikinOsc/ChaikinOsc.Api.cs @@ -6,7 +6,7 @@ public static partial class Indicator // SERIES, from TQuote /// /// - public static IReadOnlyList GetChaikinOsc( + public static IReadOnlyList ToChaikinOsc( this IEnumerable quotes, int fastPeriods = 3, int slowPeriods = 10) diff --git a/src/a-d/ChaikinOsc/ChaikinOsc.StaticSeries.cs b/src/a-d/ChaikinOsc/ChaikinOsc.StaticSeries.cs index 0cc49d026..257c8d69a 100644 --- a/src/a-d/ChaikinOsc/ChaikinOsc.StaticSeries.cs +++ b/src/a-d/ChaikinOsc/ChaikinOsc.StaticSeries.cs @@ -18,7 +18,7 @@ private static List CalcChaikinOsc( List results = new(length); // money flow - List adlResults = source.CalcAdl(); + var adlResults = source.ToAdl(); // fast/slow EMA of ADL IReadOnlyList adlEmaSlow = adlResults.ToEma(slowPeriods); diff --git a/src/a-d/Chandelier/Chandelier.Api.cs b/src/a-d/Chandelier/Chandelier.Api.cs index 60f36c875..cd0f6d502 100644 --- a/src/a-d/Chandelier/Chandelier.Api.cs +++ b/src/a-d/Chandelier/Chandelier.Api.cs @@ -6,7 +6,7 @@ public static partial class Indicator // SERIES, from TQuote /// /// - public static IReadOnlyList GetChandelier( + public static IReadOnlyList ToChandelier( this IEnumerable quotes, int lookbackPeriods = 22, double multiplier = 3, diff --git a/src/a-d/Chop/Chop.Api.cs b/src/a-d/Chop/Chop.Api.cs index e834dfec5..7aac59be9 100644 --- a/src/a-d/Chop/Chop.Api.cs +++ b/src/a-d/Chop/Chop.Api.cs @@ -6,7 +6,7 @@ public static partial class Indicator // SERIES, from TQuote /// /// - public static IReadOnlyList GetChop( + public static IReadOnlyList ToChop( this IEnumerable quotes, int lookbackPeriods = 14) where TQuote : IQuote => quotes diff --git a/src/a-d/Cmf/Cmf.Api.cs b/src/a-d/Cmf/Cmf.Api.cs index 96f8c5961..8c3465e69 100644 --- a/src/a-d/Cmf/Cmf.Api.cs +++ b/src/a-d/Cmf/Cmf.Api.cs @@ -6,7 +6,7 @@ public static partial class Indicator // SERIES, from TQuote /// /// - public static IReadOnlyList GetCmf( + public static IReadOnlyList ToCmf( this IEnumerable quotes, int lookbackPeriods = 20) where TQuote : IQuote => quotes diff --git a/src/a-d/Cmf/Cmf.StaticSeries.cs b/src/a-d/Cmf/Cmf.StaticSeries.cs index 6da645c0d..d2b2a79ac 100644 --- a/src/a-d/Cmf/Cmf.StaticSeries.cs +++ b/src/a-d/Cmf/Cmf.StaticSeries.cs @@ -19,7 +19,7 @@ double[] volume // initialize int length = volume.Length; List results = new(length); - List adlResults = source.CalcAdl(); + IReadOnlyList adlResults = source.ToAdl(); // roll through source values for (int i = 0; i < length; i++) diff --git a/src/a-d/Cmo/Cmo.Api.cs b/src/a-d/Cmo/Cmo.Api.cs index cd9e4c85b..db1875b9e 100644 --- a/src/a-d/Cmo/Cmo.Api.cs +++ b/src/a-d/Cmo/Cmo.Api.cs @@ -4,7 +4,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // SERIES, from CHAIN - public static IReadOnlyList GetCmo( + public static IReadOnlyList ToCmo( this IEnumerable source, int lookbackPeriods) where T : IReusable diff --git a/src/a-d/ConnorsRsi/ConnorsRsi.Api.cs b/src/a-d/ConnorsRsi/ConnorsRsi.Api.cs index 949647b72..dfa5e4f7f 100644 --- a/src/a-d/ConnorsRsi/ConnorsRsi.Api.cs +++ b/src/a-d/ConnorsRsi/ConnorsRsi.Api.cs @@ -4,7 +4,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // SERIES, from CHAIN - public static IReadOnlyList GetConnorsRsi( + public static IReadOnlyList ToConnorsRsi( this IReadOnlyList results, int rsiPeriods = 3, int streakPeriods = 2, diff --git a/src/a-d/Correlation/Correlation.Api.cs b/src/a-d/Correlation/Correlation.Api.cs index cfd99f390..e24ac26bb 100644 --- a/src/a-d/Correlation/Correlation.Api.cs +++ b/src/a-d/Correlation/Correlation.Api.cs @@ -1,10 +1,10 @@ namespace Skender.Stock.Indicators; // CORRELATION COEFFICIENT (API) -public static partial class Indicator +public static partial class Correlation { // SERIES, from CHAINS (both inputs reusable) - public static IReadOnlyList GetCorrelation( + public static IReadOnlyList ToCorrelation( this IEnumerable sourceA, IEnumerable sourceB, int lookbackPeriods) diff --git a/src/a-d/Correlation/Correlation.Common.cs b/src/a-d/Correlation/Correlation.Common.cs deleted file mode 100644 index 043d2d37a..000000000 --- a/src/a-d/Correlation/Correlation.Common.cs +++ /dev/null @@ -1,30 +0,0 @@ -namespace Skender.Stock.Indicators; - -// CORRELATION COEFFICIENT (COMMON) - -public static class Correlation -{ - // parameter validation - internal static void Validate( - List sourceA, - List sourceB, - int lookbackPeriods) - where T : ISeries - { - // check parameter arguments - if (lookbackPeriods <= 0) - { - throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, - "Lookback periods must be greater than 0 for Correlation."); - } - - // check quotes - if (sourceA.Count != sourceB.Count) - { - throw new InvalidQuotesException( - nameof(sourceB), - "B quotes should have at least as many records as A quotes for Correlation."); - } - } - -} diff --git a/src/a-d/Correlation/Correlation.StaticSeries.cs b/src/a-d/Correlation/Correlation.StaticSeries.cs index a07a0092e..3d6be5563 100644 --- a/src/a-d/Correlation/Correlation.StaticSeries.cs +++ b/src/a-d/Correlation/Correlation.StaticSeries.cs @@ -2,7 +2,7 @@ namespace Skender.Stock.Indicators; // CORRELATION COEFFICIENT (SERIES) -public static partial class Indicator +public static partial class Correlation { private static List CalcCorrelation( this List sourceA, @@ -62,7 +62,7 @@ private static List CalcCorrelation( } // calculate correlation - private static CorrResult PeriodCorrelation( + internal static CorrResult PeriodCorrelation( DateTime timestamp, double[] dataA, double[] dataB) diff --git a/src/a-d/Correlation/Correlation.Utilities.cs b/src/a-d/Correlation/Correlation.Utilities.cs index dafbf54fa..eb889b27c 100644 --- a/src/a-d/Correlation/Correlation.Utilities.cs +++ b/src/a-d/Correlation/Correlation.Utilities.cs @@ -1,6 +1,6 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +public static partial class Correlation { // remove recommended periods /// @@ -13,4 +13,27 @@ public static IReadOnlyList RemoveWarmupPeriods( return results.Remove(removePeriods); } + + // parameter validation + internal static void Validate( + List sourceA, + List sourceB, + int lookbackPeriods) + where T : ISeries + { + // check parameter arguments + if (lookbackPeriods <= 0) + { + throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, + "Lookback periods must be greater than 0 for Correlation."); + } + + // check quotes + if (sourceA.Count != sourceB.Count) + { + throw new InvalidQuotesException( + nameof(sourceB), + "B quotes should have at least as many records as A quotes for Correlation."); + } + } } diff --git a/src/a-d/Dema/Dema.Api.cs b/src/a-d/Dema/Dema.Api.cs index bbabc1acb..6354fce81 100644 --- a/src/a-d/Dema/Dema.Api.cs +++ b/src/a-d/Dema/Dema.Api.cs @@ -4,7 +4,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // SERIES, from CHAIN - public static IReadOnlyList GetDema( + public static IReadOnlyList ToDema( this IReadOnlyList results, int lookbackPeriods) where T : IReusable diff --git a/src/a-d/Doji/Doji.Api.cs b/src/a-d/Doji/Doji.Api.cs index feeb2ce96..9dabc60f3 100644 --- a/src/a-d/Doji/Doji.Api.cs +++ b/src/a-d/Doji/Doji.Api.cs @@ -17,7 +17,7 @@ public static partial class Indicator /// Optional.Maximum absolute percent difference in open and close price. /// Time series of Doji values. /// Invalid parameter value provided. - public static IReadOnlyList GetDoji( + public static IReadOnlyList ToDoji( this IEnumerable quotes, double maxPriceChangePercent = 0.1) where TQuote : IQuote => quotes diff --git a/src/a-d/Donchian/Donchian.Api.cs b/src/a-d/Donchian/Donchian.Api.cs index 1a3d7db7d..7d9d57dfb 100644 --- a/src/a-d/Donchian/Donchian.Api.cs +++ b/src/a-d/Donchian/Donchian.Api.cs @@ -6,7 +6,7 @@ public static partial class Indicator // SERIES, from TQuote /// /// - public static IReadOnlyList GetDonchian( + public static IReadOnlyList ToDonchian( this IEnumerable quotes, int lookbackPeriods = 20) where TQuote : IQuote => quotes diff --git a/src/a-d/Dpo/Dpo.Api.cs b/src/a-d/Dpo/Dpo.Api.cs index 740f3b503..4c224e5e4 100644 --- a/src/a-d/Dpo/Dpo.Api.cs +++ b/src/a-d/Dpo/Dpo.Api.cs @@ -4,7 +4,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // SERIES, from CHAIN - public static IReadOnlyList GetDpo( + public static IReadOnlyList ToDpo( this IReadOnlyList results, int lookbackPeriods) where T : IReusable diff --git a/src/a-d/Dynamic/Dynamic.Api.cs b/src/a-d/Dynamic/Dynamic.Api.cs index 9a953f59f..7fbccb8ca 100644 --- a/src/a-d/Dynamic/Dynamic.Api.cs +++ b/src/a-d/Dynamic/Dynamic.Api.cs @@ -5,7 +5,7 @@ namespace Skender.Stock.Indicators; public static partial class MgDynamic { // SERIES, from CHAIN - public static IReadOnlyList GetDynamic( + public static IReadOnlyList ToDynamic( this IReadOnlyList results, int lookbackPeriods, double kFactor = 0.6) diff --git a/src/e-k/ElderRay/ElderRay.Api.cs b/src/e-k/ElderRay/ElderRay.Api.cs index 4c437b693..fbc8f4a7a 100644 --- a/src/e-k/ElderRay/ElderRay.Api.cs +++ b/src/e-k/ElderRay/ElderRay.Api.cs @@ -6,7 +6,7 @@ public static partial class Indicator // SERIES, from TQuote /// /// - public static IReadOnlyList GetElderRay( + public static IReadOnlyList ToElderRay( this IEnumerable quotes, int lookbackPeriods = 13) where TQuote : IQuote => quotes diff --git a/src/e-k/Epma/Epma.Api.cs b/src/e-k/Epma/Epma.Api.cs index 0937ac444..6136f921a 100644 --- a/src/e-k/Epma/Epma.Api.cs +++ b/src/e-k/Epma/Epma.Api.cs @@ -4,7 +4,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // SERIES, from CHAIN - public static IReadOnlyList GetEpma( + public static IReadOnlyList ToEpma( this IReadOnlyList results, int lookbackPeriods) where T : IReusable diff --git a/src/e-k/Fcb/Fcb.Api.cs b/src/e-k/Fcb/Fcb.Api.cs index 0b48e1fde..1345e3a9a 100644 --- a/src/e-k/Fcb/Fcb.Api.cs +++ b/src/e-k/Fcb/Fcb.Api.cs @@ -6,7 +6,7 @@ public static partial class Indicator // SERIES, from TQuote /// /// - public static IReadOnlyList GetFcb( + public static IReadOnlyList ToFcb( this IEnumerable quotes, int windowSpan = 2) where TQuote : IQuote => quotes diff --git a/src/e-k/FisherTransform/FisherTransform.Api.cs b/src/e-k/FisherTransform/FisherTransform.Api.cs index 51cec1dc9..db9488809 100644 --- a/src/e-k/FisherTransform/FisherTransform.Api.cs +++ b/src/e-k/FisherTransform/FisherTransform.Api.cs @@ -4,7 +4,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // SERIES, from CHAIN - public static IReadOnlyList GetFisherTransform( + public static IReadOnlyList ToFisherTransform( this IReadOnlyList results, int lookbackPeriods = 10) where T : IReusable diff --git a/src/e-k/ForceIndex/ForceIndex.Api.cs b/src/e-k/ForceIndex/ForceIndex.Api.cs index f095cf270..34bf5ab9d 100644 --- a/src/e-k/ForceIndex/ForceIndex.Api.cs +++ b/src/e-k/ForceIndex/ForceIndex.Api.cs @@ -6,7 +6,7 @@ public static partial class Indicator // SERIES, from TQuote /// /// - public static IReadOnlyList GetForceIndex( + public static IReadOnlyList ToForceIndex( this IEnumerable quotes, int lookbackPeriods = 2) where TQuote : IQuote => quotes diff --git a/src/e-k/Fractal/Fractal.Api.cs b/src/e-k/Fractal/Fractal.Api.cs index 01972eeb4..82e1c436e 100644 --- a/src/e-k/Fractal/Fractal.Api.cs +++ b/src/e-k/Fractal/Fractal.Api.cs @@ -5,7 +5,7 @@ public static partial class Indicator { /// /// - public static IReadOnlyList GetFractal( + public static IReadOnlyList ToFractal( this IEnumerable quotes, int windowSpan = 2, EndType endType = EndType.HighLow) diff --git a/src/e-k/Gator/Gator.Api.cs b/src/e-k/Gator/Gator.Api.cs index 0682aaf92..384112566 100644 --- a/src/e-k/Gator/Gator.Api.cs +++ b/src/e-k/Gator/Gator.Api.cs @@ -21,11 +21,11 @@ public static partial class Indicator /// Time series of Gator values. // See Alligator API for explanation of unusual setup. - public static IReadOnlyList GetGator( + public static IReadOnlyList ToGator( this IEnumerable source) where T : IReusable => source - .GetAlligator() + .ToAlligator() .GetGator(); // SERIES, from [custom] Alligator diff --git a/src/e-k/HeikinAshi/HeikinAshi.Api.cs b/src/e-k/HeikinAshi/HeikinAshi.Api.cs index d17a73c29..f46747dee 100644 --- a/src/e-k/HeikinAshi/HeikinAshi.Api.cs +++ b/src/e-k/HeikinAshi/HeikinAshi.Api.cs @@ -6,7 +6,7 @@ public static partial class Indicator // SERIES, from TQuote /// /// - public static IReadOnlyList GetHeikinAshi( + public static IReadOnlyList ToHeikinAshi( this IEnumerable quotes) where TQuote : IQuote => quotes .ToSortedList() diff --git a/src/e-k/Hma/Hma.Api.cs b/src/e-k/Hma/Hma.Api.cs index 8d11e4041..c5c247fa8 100644 --- a/src/e-k/Hma/Hma.Api.cs +++ b/src/e-k/Hma/Hma.Api.cs @@ -4,7 +4,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // SERIES, from CHAIN - public static IReadOnlyList GetHma( + public static IReadOnlyList ToHma( this IReadOnlyList results, int lookbackPeriods) where T : IReusable diff --git a/src/e-k/HtTrendline/HtTrendline.Api.cs b/src/e-k/HtTrendline/HtTrendline.Api.cs index 96d163808..4f70cec5f 100644 --- a/src/e-k/HtTrendline/HtTrendline.Api.cs +++ b/src/e-k/HtTrendline/HtTrendline.Api.cs @@ -17,7 +17,7 @@ public static partial class Indicator /// /// Time-series values to transform. /// Time series of HTL values and smoothed price. - public static IReadOnlyList GetHtTrendline( + public static IReadOnlyList ToHtTrendline( this IEnumerable source) where T : IReusable => source diff --git a/src/e-k/Hurst/Hurst.Api.cs b/src/e-k/Hurst/Hurst.Api.cs index ae882f69c..cc50f6ca5 100644 --- a/src/e-k/Hurst/Hurst.Api.cs +++ b/src/e-k/Hurst/Hurst.Api.cs @@ -4,7 +4,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // SERIES, from CHAIN - public static IReadOnlyList GetHurst( + public static IReadOnlyList ToHurst( this IReadOnlyList results, int lookbackPeriods = 100) where T : IReusable diff --git a/src/e-k/Ichimoku/Ichimoku.Api.cs b/src/e-k/Ichimoku/Ichimoku.Api.cs index d0d80c0c3..818d5d2e8 100644 --- a/src/e-k/Ichimoku/Ichimoku.Api.cs +++ b/src/e-k/Ichimoku/Ichimoku.Api.cs @@ -5,7 +5,7 @@ public static partial class Indicator { /// /// - public static IReadOnlyList GetIchimoku( + public static IReadOnlyList ToIchimoku( this IEnumerable quotes, int tenkanPeriods = 9, int kijunPeriods = 26, diff --git a/src/e-k/Kama/Kama.Api.cs b/src/e-k/Kama/Kama.Api.cs index 8c9484f62..3edfeaa42 100644 --- a/src/e-k/Kama/Kama.Api.cs +++ b/src/e-k/Kama/Kama.Api.cs @@ -5,7 +5,7 @@ namespace Skender.Stock.Indicators; public static partial class Kama { // SERIES, from CHAIN - public static IReadOnlyList GetKama( + public static IReadOnlyList ToKama( this IEnumerable source, int erPeriods = 10, int fastPeriods = 2, diff --git a/src/e-k/Keltner/Keltner.Api.cs b/src/e-k/Keltner/Keltner.Api.cs index 7bffd9e49..e5ec5722b 100644 --- a/src/e-k/Keltner/Keltner.Api.cs +++ b/src/e-k/Keltner/Keltner.Api.cs @@ -6,7 +6,7 @@ public static partial class Indicator // SERIES, from TQuote /// /// - public static IReadOnlyList GetKeltner( + public static IReadOnlyList ToKeltner( this IEnumerable quotes, int emaPeriods = 20, double multiplier = 2, diff --git a/src/e-k/Kvo/Kvo.Api.cs b/src/e-k/Kvo/Kvo.Api.cs index b00bc2768..961b6e4db 100644 --- a/src/e-k/Kvo/Kvo.Api.cs +++ b/src/e-k/Kvo/Kvo.Api.cs @@ -6,7 +6,7 @@ public static partial class Indicator // SERIES, from TQuote /// /// - public static IReadOnlyList GetKvo( + public static IReadOnlyList ToKvo( this IEnumerable quotes, int fastPeriods = 34, int slowPeriods = 55, diff --git a/src/m-r/MaEnvelopes/MaEnvelopes.Api.cs b/src/m-r/MaEnvelopes/MaEnvelopes.Api.cs index d83d0b2f8..b68d153a8 100644 --- a/src/m-r/MaEnvelopes/MaEnvelopes.Api.cs +++ b/src/m-r/MaEnvelopes/MaEnvelopes.Api.cs @@ -4,7 +4,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // SERIES, from CHAIN - public static IReadOnlyList GetMaEnvelopes( + public static IReadOnlyList ToMaEnvelopes( this IReadOnlyList results, int lookbackPeriods, double percentOffset = 2.5, diff --git a/src/m-r/Macd/MacdApi.cs b/src/m-r/Macd/MacdApi.cs index a5d342aea..502edebf0 100644 --- a/src/m-r/Macd/MacdApi.cs +++ b/src/m-r/Macd/MacdApi.cs @@ -4,7 +4,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // SERIES, from CHAIN - public static IReadOnlyList GetMacd( + public static IReadOnlyList ToMacd( this IReadOnlyList results, int fastPeriods = 12, int slowPeriods = 26, diff --git a/src/m-r/Mama/Mama.Api.cs b/src/m-r/Mama/Mama.Api.cs index 34264484d..f9c6d57b4 100644 --- a/src/m-r/Mama/Mama.Api.cs +++ b/src/m-r/Mama/Mama.Api.cs @@ -4,7 +4,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // SERIES, from CHAIN - public static IReadOnlyList GetMama( + public static IReadOnlyList ToMama( this IReadOnlyList results, double fastLimit = 0.5, double slowLimit = 0.05) diff --git a/src/m-r/Marubozu/Marubozu.Api.cs b/src/m-r/Marubozu/Marubozu.Api.cs index b0315cc7c..5b91b90af 100644 --- a/src/m-r/Marubozu/Marubozu.Api.cs +++ b/src/m-r/Marubozu/Marubozu.Api.cs @@ -6,7 +6,7 @@ public static partial class Indicator // SERIES, from TQuote /// /// - public static IReadOnlyList GetMarubozu( + public static IReadOnlyList ToMarubozu( this IEnumerable quotes, double minBodyPercent = 95) where TQuote : IQuote => quotes diff --git a/src/m-r/Mfi/Mfi.Api.cs b/src/m-r/Mfi/Mfi.Api.cs index 6dc4d0bab..502e4f090 100644 --- a/src/m-r/Mfi/Mfi.Api.cs +++ b/src/m-r/Mfi/Mfi.Api.cs @@ -6,7 +6,7 @@ public static partial class Indicator // SERIES, from TQuote /// /// - public static IReadOnlyList GetMfi( + public static IReadOnlyList ToMfi( this IEnumerable quotes, int lookbackPeriods = 14) where TQuote : IQuote => quotes diff --git a/src/m-r/Obv/Obv.Api.cs b/src/m-r/Obv/Obv.Api.cs index 8eefcd0b8..0431a263a 100644 --- a/src/m-r/Obv/Obv.Api.cs +++ b/src/m-r/Obv/Obv.Api.cs @@ -6,7 +6,7 @@ public static partial class Indicator // SERIES, from TQuote /// /// - public static IReadOnlyList GetObv( + public static IReadOnlyList ToObv( this IEnumerable quotes) where TQuote : IQuote => quotes .ToQuoteDList() diff --git a/src/m-r/ParabolicSar/ParabolicSar.Api.cs b/src/m-r/ParabolicSar/ParabolicSar.Api.cs index 56da5dbdd..f43fd562d 100644 --- a/src/m-r/ParabolicSar/ParabolicSar.Api.cs +++ b/src/m-r/ParabolicSar/ParabolicSar.Api.cs @@ -6,7 +6,7 @@ public static partial class Indicator // SERIES, from TQuote /// /// - public static IReadOnlyList GetParabolicSar( + public static IReadOnlyList ToParabolicSar( this IEnumerable quotes, double accelerationStep = 0.02, double maxAccelerationFactor = 0.2) diff --git a/src/m-r/PivotPoints/PivotPoints.Api.cs b/src/m-r/PivotPoints/PivotPoints.Api.cs index be099965a..c6d715677 100644 --- a/src/m-r/PivotPoints/PivotPoints.Api.cs +++ b/src/m-r/PivotPoints/PivotPoints.Api.cs @@ -6,7 +6,7 @@ public static partial class Indicator // SERIES, from TQuote /// /// - public static IReadOnlyList GetPivotPoints( + public static IReadOnlyList ToPivotPoints( this IEnumerable quotes, PeriodSize windowSize, PivotPointType pointType = PivotPointType.Standard) diff --git a/src/m-r/Pivots/Pivots.Api.cs b/src/m-r/Pivots/Pivots.Api.cs index d2157f35a..551159008 100644 --- a/src/m-r/Pivots/Pivots.Api.cs +++ b/src/m-r/Pivots/Pivots.Api.cs @@ -6,7 +6,7 @@ public static partial class Indicator // SERIES, from TQuote /// /// - public static IReadOnlyList GetPivots( + public static IReadOnlyList ToPivots( this IEnumerable quotes, int leftSpan = 2, int rightSpan = 2, diff --git a/src/m-r/Pmo/Pmo.Api.cs b/src/m-r/Pmo/Pmo.Api.cs index 99801c5d0..fcf815367 100644 --- a/src/m-r/Pmo/Pmo.Api.cs +++ b/src/m-r/Pmo/Pmo.Api.cs @@ -4,7 +4,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // SERIES, from CHAIN - public static IReadOnlyList GetPmo( + public static IReadOnlyList ToPmo( this IReadOnlyList results, int timePeriods = 35, int smoothPeriods = 20, diff --git a/src/m-r/Prs/Prs.Api.cs b/src/m-r/Prs/Prs.Api.cs index f169896d3..347e0709a 100644 --- a/src/m-r/Prs/Prs.Api.cs +++ b/src/m-r/Prs/Prs.Api.cs @@ -4,7 +4,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // SERIES, from CHAINS (both inputs reusable) - public static IReadOnlyList GetPrs( + public static IReadOnlyList ToPrs( this IEnumerable quotesEval, IEnumerable quotesBase, int? lookbackPeriods = null) diff --git a/src/m-r/Pvo/Pvo.Api.cs b/src/m-r/Pvo/Pvo.Api.cs index 0c24ea386..321f7b018 100644 --- a/src/m-r/Pvo/Pvo.Api.cs +++ b/src/m-r/Pvo/Pvo.Api.cs @@ -6,7 +6,7 @@ public static partial class Indicator // SERIES, from TQuote /// /// - public static IReadOnlyList GetPvo( + public static IReadOnlyList ToPvo( this IEnumerable quotes, int fastPeriods = 12, int slowPeriods = 26, diff --git a/src/m-r/Renko/Renko.Api.cs b/src/m-r/Renko/Renko.Api.cs index 9f2b1c5df..a70e86b5a 100644 --- a/src/m-r/Renko/Renko.Api.cs +++ b/src/m-r/Renko/Renko.Api.cs @@ -5,7 +5,7 @@ namespace Skender.Stock.Indicators; public static partial class Renko { // SERIES, from TQuote - public static IReadOnlyList GetRenko( + public static IReadOnlyList ToRenko( this IEnumerable quotes, decimal brickSize, EndType endType = EndType.Close) diff --git a/src/m-r/Roc/Roc.Api.cs b/src/m-r/Roc/Roc.Api.cs index a6759f4e5..43fda5055 100644 --- a/src/m-r/Roc/Roc.Api.cs +++ b/src/m-r/Roc/Roc.Api.cs @@ -4,7 +4,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // SERIES, from CHAIN - public static IReadOnlyList GetRoc( + public static IReadOnlyList ToRoc( this IReadOnlyList results, int lookbackPeriods) where T : IReusable diff --git a/src/m-r/RocWb/RocWb.Api.cs b/src/m-r/RocWb/RocWb.Api.cs index ed5f5bed1..94f3e65c9 100644 --- a/src/m-r/RocWb/RocWb.Api.cs +++ b/src/m-r/RocWb/RocWb.Api.cs @@ -4,7 +4,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // SERIES, from CHAIN - public static IReadOnlyList GetRocWb( + public static IReadOnlyList ToRocWb( this IReadOnlyList results, int lookbackPeriods, int emaPeriods, diff --git a/src/m-r/RollingPivots/RollingPivots.Api.cs b/src/m-r/RollingPivots/RollingPivots.Api.cs index e7759d288..2adb3b664 100644 --- a/src/m-r/RollingPivots/RollingPivots.Api.cs +++ b/src/m-r/RollingPivots/RollingPivots.Api.cs @@ -6,7 +6,7 @@ public static partial class Indicator // SERIES, from TQuote /// /// - public static IReadOnlyList GetRollingPivots( + public static IReadOnlyList ToRollingPivots( this IEnumerable quotes, int windowPeriods, int offsetPeriods, diff --git a/src/m-r/Rsi/Rsi.Api.cs b/src/m-r/Rsi/Rsi.Api.cs index 85f27accd..1023e4b8e 100644 --- a/src/m-r/Rsi/Rsi.Api.cs +++ b/src/m-r/Rsi/Rsi.Api.cs @@ -4,7 +4,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // SERIES, from CHAIN - public static IReadOnlyList GetRsi( + public static IReadOnlyList ToRsi( this IReadOnlyList results, int lookbackPeriods = 14) where T : IReusable diff --git a/src/s-z/Slope/Slope.Api.cs b/src/s-z/Slope/Slope.Api.cs index 1760f9ae2..8a2df0575 100644 --- a/src/s-z/Slope/Slope.Api.cs +++ b/src/s-z/Slope/Slope.Api.cs @@ -4,7 +4,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // SERIES, from CHAIN - public static IReadOnlyList GetSlope( + public static IReadOnlyList ToSlope( this IReadOnlyList results, int lookbackPeriods) where T : IReusable diff --git a/src/s-z/SmaAnalysis/SmaAnalysis.Api.cs b/src/s-z/SmaAnalysis/SmaAnalysis.Api.cs index 0dfe24f95..fb9cd3a88 100644 --- a/src/s-z/SmaAnalysis/SmaAnalysis.Api.cs +++ b/src/s-z/SmaAnalysis/SmaAnalysis.Api.cs @@ -6,7 +6,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // ANALYSIS, from CHAIN - public static IReadOnlyList GetSmaAnalysis( + public static IReadOnlyList ToSmaAnalysis( this IEnumerable source, int lookbackPeriods) where T : IReusable diff --git a/src/s-z/Smi/Smi.Api.cs b/src/s-z/Smi/Smi.Api.cs index 6bfefa7e3..a6abdc0c2 100644 --- a/src/s-z/Smi/Smi.Api.cs +++ b/src/s-z/Smi/Smi.Api.cs @@ -6,7 +6,7 @@ public static partial class Indicator // SERIES, from TQuote /// /// - public static IReadOnlyList GetSmi( + public static IReadOnlyList ToSmi( this IEnumerable quotes, int lookbackPeriods = 13, int firstSmoothPeriods = 25, diff --git a/src/s-z/Smma/Smma.Api.cs b/src/s-z/Smma/Smma.Api.cs index b792078a9..88eb1c5c8 100644 --- a/src/s-z/Smma/Smma.Api.cs +++ b/src/s-z/Smma/Smma.Api.cs @@ -4,7 +4,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // SERIES, from CHAIN - public static IReadOnlyList GetSmma( + public static IReadOnlyList ToSmma( this IReadOnlyList results, int lookbackPeriods) where T : IReusable diff --git a/src/s-z/StarcBands/StarcBands.Api.cs b/src/s-z/StarcBands/StarcBands.Api.cs index 572e2fddb..9ce66033b 100644 --- a/src/s-z/StarcBands/StarcBands.Api.cs +++ b/src/s-z/StarcBands/StarcBands.Api.cs @@ -6,7 +6,7 @@ public static partial class Indicator // SERIES, from TQuote /// /// - public static IReadOnlyList GetStarcBands( + public static IReadOnlyList ToStarcBands( this IEnumerable quotes, int smaPeriods, double multiplier = 2, diff --git a/src/s-z/Stc/Stc.Api.cs b/src/s-z/Stc/Stc.Api.cs index aa8b638b5..2da7c4075 100644 --- a/src/s-z/Stc/Stc.Api.cs +++ b/src/s-z/Stc/Stc.Api.cs @@ -4,7 +4,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // SERIES, from CHAIN - public static IReadOnlyList GetStc( + public static IReadOnlyList ToStc( this IReadOnlyList results, int cyclePeriods = 10, int fastPeriods = 23, diff --git a/src/s-z/StdDev/StdDev.Api.cs b/src/s-z/StdDev/StdDev.Api.cs index 6bc98569e..05ef0f06e 100644 --- a/src/s-z/StdDev/StdDev.Api.cs +++ b/src/s-z/StdDev/StdDev.Api.cs @@ -4,7 +4,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // SERIES, from CHAIN - public static IReadOnlyList GetStdDev( + public static IReadOnlyList ToStdDev( this IReadOnlyList results, int lookbackPeriods) where T : IReusable diff --git a/src/s-z/StdDevChannels/StdDevChannels.Api.cs b/src/s-z/StdDevChannels/StdDevChannels.Api.cs index 5557f4274..6851171dd 100644 --- a/src/s-z/StdDevChannels/StdDevChannels.Api.cs +++ b/src/s-z/StdDevChannels/StdDevChannels.Api.cs @@ -4,7 +4,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // SERIES, from CHAIN - public static IReadOnlyList GetStdDevChannels( + public static IReadOnlyList ToStdDevChannels( this IReadOnlyList results, int? lookbackPeriods = 20, double stdDeviations = 2) diff --git a/src/s-z/Stoch/Stoch.Api.cs b/src/s-z/Stoch/Stoch.Api.cs index 6b4d434e9..4cba11ab3 100644 --- a/src/s-z/Stoch/Stoch.Api.cs +++ b/src/s-z/Stoch/Stoch.Api.cs @@ -6,7 +6,7 @@ public static partial class Indicator // SERIES, from TQuote (standard) /// /// - public static IReadOnlyList GetStoch( + public static IReadOnlyList ToStoch( this IEnumerable quotes, int lookbackPeriods = 14, int signalPeriods = 3, @@ -21,7 +21,7 @@ public static IReadOnlyList GetStoch( // SERIES, from TQuote (extended) /// /// - public static IReadOnlyList GetStoch( + public static IReadOnlyList ToStoch( this IEnumerable quotes, int lookbackPeriods, int signalPeriods, diff --git a/src/s-z/StochRsi/StochRsi.Api.cs b/src/s-z/StochRsi/StochRsi.Api.cs index cb0c41945..10853a986 100644 --- a/src/s-z/StochRsi/StochRsi.Api.cs +++ b/src/s-z/StochRsi/StochRsi.Api.cs @@ -4,7 +4,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // SERIES, from CHAIN - public static IReadOnlyList GetStochRsi( + public static IReadOnlyList ToStochRsi( this IReadOnlyList results, int rsiPeriods, int stochPeriods, diff --git a/src/s-z/SuperTrend/SuperTrend.Api.cs b/src/s-z/SuperTrend/SuperTrend.Api.cs index fba7807fd..cc9ddb23f 100644 --- a/src/s-z/SuperTrend/SuperTrend.Api.cs +++ b/src/s-z/SuperTrend/SuperTrend.Api.cs @@ -6,7 +6,7 @@ public static partial class Indicator // SERIES, from TQuote /// /// - public static IReadOnlyList GetSuperTrend( + public static IReadOnlyList ToSuperTrend( this IEnumerable quotes, int lookbackPeriods = 10, double multiplier = 3) diff --git a/src/s-z/T3/T3.Api.cs b/src/s-z/T3/T3.Api.cs index fbfb6794d..af3fa182c 100644 --- a/src/s-z/T3/T3.Api.cs +++ b/src/s-z/T3/T3.Api.cs @@ -4,7 +4,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // SERIES, from CHAIN - public static IReadOnlyList GetT3( + public static IReadOnlyList ToT3( this IReadOnlyList results, int lookbackPeriods = 5, double volumeFactor = 0.7) diff --git a/src/s-z/Tema/Tema.Api.cs b/src/s-z/Tema/Tema.Api.cs index b3b6f0107..50965ec0c 100644 --- a/src/s-z/Tema/Tema.Api.cs +++ b/src/s-z/Tema/Tema.Api.cs @@ -4,7 +4,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // SERIES, from CHAIN - public static IReadOnlyList GetTema( + public static IReadOnlyList ToTema( this IReadOnlyList results, int lookbackPeriods) where T : IReusable diff --git a/src/s-z/Tr/Tr.Api.cs b/src/s-z/Tr/Tr.Api.cs index a3596c016..3999229d1 100644 --- a/src/s-z/Tr/Tr.Api.cs +++ b/src/s-z/Tr/Tr.Api.cs @@ -7,7 +7,7 @@ public static partial class Tr // SERIES, from TQuote /// /// - public static IReadOnlyList GetTr( + public static IReadOnlyList ToTr( this IEnumerable quotes) where TQuote : IQuote => quotes .ToQuoteDList() diff --git a/src/s-z/Trix/Trix.Api.cs b/src/s-z/Trix/Trix.Api.cs index 3b114888d..0dad6ca8b 100644 --- a/src/s-z/Trix/Trix.Api.cs +++ b/src/s-z/Trix/Trix.Api.cs @@ -4,7 +4,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // SERIES, from CHAIN - public static IReadOnlyList GetTrix( + public static IReadOnlyList ToTrix( this IReadOnlyList results, int lookbackPeriods) where T : IReusable diff --git a/src/s-z/Tsi/Tsi.Api.cs b/src/s-z/Tsi/Tsi.Api.cs index 4d688f345..137f65929 100644 --- a/src/s-z/Tsi/Tsi.Api.cs +++ b/src/s-z/Tsi/Tsi.Api.cs @@ -4,7 +4,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // SERIES, from CHAIN - public static IReadOnlyList GetTsi( + public static IReadOnlyList ToTsi( this IReadOnlyList results, int lookbackPeriods = 25, int smoothPeriods = 13, diff --git a/src/s-z/UlcerIndex/UlcerIndex.Api.cs b/src/s-z/UlcerIndex/UlcerIndex.Api.cs index bb5322f22..61248598e 100644 --- a/src/s-z/UlcerIndex/UlcerIndex.Api.cs +++ b/src/s-z/UlcerIndex/UlcerIndex.Api.cs @@ -4,7 +4,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // SERIES, from CHAIN - public static IReadOnlyList GetUlcerIndex( + public static IReadOnlyList ToUlcerIndex( this IReadOnlyList results, int lookbackPeriods = 14) where T : IReusable diff --git a/src/s-z/Ultimate/Ultimate.Api.cs b/src/s-z/Ultimate/Ultimate.Api.cs index e76a7cad1..8b6cc2844 100644 --- a/src/s-z/Ultimate/Ultimate.Api.cs +++ b/src/s-z/Ultimate/Ultimate.Api.cs @@ -6,7 +6,7 @@ public static partial class Indicator // SERIES, from TQuote /// /// - public static IReadOnlyList GetUltimate( + public static IReadOnlyList ToUltimate( this IEnumerable quotes, int shortPeriods = 7, int middlePeriods = 14, diff --git a/src/s-z/VolatilityStop/VolatilityStop.Api.cs b/src/s-z/VolatilityStop/VolatilityStop.Api.cs index e2dec1829..4c551ada7 100644 --- a/src/s-z/VolatilityStop/VolatilityStop.Api.cs +++ b/src/s-z/VolatilityStop/VolatilityStop.Api.cs @@ -6,7 +6,7 @@ public static partial class Indicator // SERIES, from TQuote /// /// - public static IReadOnlyList GetVolatilityStop( + public static IReadOnlyList ToVolatilityStop( this IEnumerable quotes, int lookbackPeriods = 7, double multiplier = 3) diff --git a/src/s-z/Vortex/Vortex.Api.cs b/src/s-z/Vortex/Vortex.Api.cs index 8396c507d..837067dce 100644 --- a/src/s-z/Vortex/Vortex.Api.cs +++ b/src/s-z/Vortex/Vortex.Api.cs @@ -6,7 +6,7 @@ public static partial class Indicator // SERIES, from TQuote /// /// - public static IReadOnlyList GetVortex( + public static IReadOnlyList ToVortex( this IEnumerable quotes, int lookbackPeriods) where TQuote : IQuote => quotes diff --git a/src/s-z/Vwap/Vwap.Api.cs b/src/s-z/Vwap/Vwap.Api.cs index 4caa822f2..bf28da1bc 100644 --- a/src/s-z/Vwap/Vwap.Api.cs +++ b/src/s-z/Vwap/Vwap.Api.cs @@ -6,7 +6,7 @@ public static partial class Indicator // SERIES, from TQuote /// /// - public static IReadOnlyList GetVwap( + public static IReadOnlyList ToVwap( this IEnumerable quotes, DateTime? startDate = null) where TQuote : IQuote => quotes diff --git a/src/s-z/Vwma/Vwma.Api.cs b/src/s-z/Vwma/Vwma.Api.cs index 99845d0c5..edc82abf3 100644 --- a/src/s-z/Vwma/Vwma.Api.cs +++ b/src/s-z/Vwma/Vwma.Api.cs @@ -6,7 +6,7 @@ public static partial class Indicator // SERIES, from TQuote /// /// - public static IReadOnlyList GetVwma( + public static IReadOnlyList ToVwma( this IEnumerable quotes, int lookbackPeriods) where TQuote : IQuote => quotes diff --git a/src/s-z/WilliamsR/WilliamsR.Api.cs b/src/s-z/WilliamsR/WilliamsR.Api.cs index d8c8ef219..21b8e4a80 100644 --- a/src/s-z/WilliamsR/WilliamsR.Api.cs +++ b/src/s-z/WilliamsR/WilliamsR.Api.cs @@ -6,7 +6,7 @@ public static partial class Indicator // SERIES, from TQuote /// /// - public static IReadOnlyList GetWilliamsR( + public static IReadOnlyList ToWilliamsR( this IEnumerable quotes, int lookbackPeriods = 14) where TQuote : IQuote => quotes diff --git a/src/s-z/Wma/Wma.Api.cs b/src/s-z/Wma/Wma.Api.cs index f6d77132d..209e4f1fd 100644 --- a/src/s-z/Wma/Wma.Api.cs +++ b/src/s-z/Wma/Wma.Api.cs @@ -4,7 +4,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // SERIES, from CHAIN - public static IReadOnlyList GetWma( + public static IReadOnlyList ToWma( this IReadOnlyList results, int lookbackPeriods) where T : IReusable diff --git a/src/s-z/ZigZag/ZigZag.Api.cs b/src/s-z/ZigZag/ZigZag.Api.cs index 1bfbf81fa..531d2b7bf 100644 --- a/src/s-z/ZigZag/ZigZag.Api.cs +++ b/src/s-z/ZigZag/ZigZag.Api.cs @@ -6,7 +6,7 @@ public static partial class Indicator // SERIES, from TQuote /// /// - public static IReadOnlyList GetZigZag( + public static IReadOnlyList ToZigZag( this IEnumerable quotes, EndType endType = EndType.Close, decimal percentChange = 5) diff --git a/tests/indicators/_common/Generics/RemoveWarmup.Tests.cs b/tests/indicators/_common/Generics/RemoveWarmup.Tests.cs index 3f19c57bc..99abb398b 100644 --- a/tests/indicators/_common/Generics/RemoveWarmup.Tests.cs +++ b/tests/indicators/_common/Generics/RemoveWarmup.Tests.cs @@ -8,14 +8,14 @@ public void Standard() { // specific periods IReadOnlyList results = Quotes - .GetHeikinAshi() + .ToHeikinAshi() .RemoveWarmupPeriods(102); Assert.AreEqual(400, results.Count); // bad remove period Assert.ThrowsException(() - => Quotes.GetAdx().RemoveWarmupPeriods(-1)); + => Quotes.ToAdx().RemoveWarmupPeriods(-1)); } [TestMethod] @@ -23,7 +23,7 @@ public void TooMany() { // more than available IReadOnlyList results = Quotes - .GetHeikinAshi() + .ToHeikinAshi() .RemoveWarmupPeriods(600); Assert.AreEqual(0, results.Count); diff --git a/tests/indicators/_common/Reusable/Reusable.Utilities.Tests.cs b/tests/indicators/_common/Reusable/Reusable.Utilities.Tests.cs index 14bda1648..72c8433e6 100644 --- a/tests/indicators/_common/Reusable/Reusable.Utilities.Tests.cs +++ b/tests/indicators/_common/Reusable/Reusable.Utilities.Tests.cs @@ -7,7 +7,7 @@ public class Reusable : TestBase public void Condense() { List original = Quotes - .GetAdx() + .ToAdx() .ToList(); // make a few more in the middle null and NaN diff --git a/tests/indicators/a-d/Adl/Adl.StaticSeries.Tests.cs b/tests/indicators/a-d/Adl/Adl.StaticSeries.Tests.cs index d336216fa..1c98e391d 100644 --- a/tests/indicators/a-d/Adl/Adl.StaticSeries.Tests.cs +++ b/tests/indicators/a-d/Adl/Adl.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class Adl : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = Quotes - .GetAdl(); + .ToAdl(); // proper quantities Assert.AreEqual(502, results.Count); @@ -28,7 +28,7 @@ public override void Standard() public void Chainor() { IReadOnlyList results = Quotes - .GetAdl() + .ToAdl() .ToSma(10); // assertions @@ -42,7 +42,7 @@ public void Chainor() public override void BadData() { IReadOnlyList r = BadQuotes - .GetAdl(); + .ToAdl(); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => double.IsNaN(x.Adl))); @@ -52,7 +52,7 @@ public override void BadData() public void BigData() { IReadOnlyList r = BigQuotes - .GetAdl(); + .ToAdl(); Assert.AreEqual(1246, r.Count); } @@ -61,7 +61,7 @@ public void BigData() public void RandomData() { IReadOnlyList r = RandomQuotes - .GetAdl(); + .ToAdl(); Assert.AreEqual(1000, r.Count); } @@ -70,12 +70,12 @@ public void RandomData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetAdl(); + .ToAdl(); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetAdl(); + .ToAdl(); Assert.AreEqual(1, r1.Count); } diff --git a/tests/indicators/a-d/Adl/Adl.StreamHub.Tests.cs b/tests/indicators/a-d/Adl/Adl.StreamHub.Tests.cs index db3ba55b1..9b83c46a3 100644 --- a/tests/indicators/a-d/Adl/Adl.StreamHub.Tests.cs +++ b/tests/indicators/a-d/Adl/Adl.StreamHub.Tests.cs @@ -56,7 +56,7 @@ IReadOnlyList streamList // time-series, for comparison IReadOnlyList seriesList = quotesList - .GetAdl(); + .ToAdl(); // assert, should equal series streamList.Should().HaveCount(length - 1); @@ -102,7 +102,7 @@ IReadOnlyList streamList // time-series, for comparison IReadOnlyList seriesList = quotesList - .GetAdl() + .ToAdl() .ToSma(smaPeriods); // assert, should equal series diff --git a/tests/indicators/a-d/Adx/Adx.StaticSeries.Tests.cs b/tests/indicators/a-d/Adx/Adx.StaticSeries.Tests.cs index fbf8b2a65..fc01d9292 100644 --- a/tests/indicators/a-d/Adx/Adx.StaticSeries.Tests.cs +++ b/tests/indicators/a-d/Adx/Adx.StaticSeries.Tests.cs @@ -6,7 +6,7 @@ public class Adx : StaticSeriesTestBase [TestMethod] public override void Standard() { - IReadOnlyList results = Quotes.GetAdx(); + IReadOnlyList results = Quotes.ToAdx(); // proper quantities Assert.AreEqual(502, results.Count); @@ -46,7 +46,7 @@ public override void Standard() public void Chainor() { IReadOnlyList results = Quotes - .GetAdx() + .ToAdx() .ToSma(10); Assert.AreEqual(502, results.Count); @@ -56,7 +56,7 @@ public void Chainor() [TestMethod] public override void BadData() { - IReadOnlyList r = BadQuotes.GetAdx(20); + IReadOnlyList r = BadQuotes.ToAdx(20); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Adx is double.NaN)); @@ -65,7 +65,7 @@ public override void BadData() [TestMethod] public void BigData() { - IReadOnlyList r = BigQuotes.GetAdx(200); + IReadOnlyList r = BigQuotes.ToAdx(200); Assert.AreEqual(1246, r.Count); } @@ -73,11 +73,11 @@ public void BigData() [TestMethod] public override void NoQuotes() { - IReadOnlyList r0 = Noquotes.GetAdx(5); + IReadOnlyList r0 = Noquotes.ToAdx(5); Assert.AreEqual(0, r0.Count); - IReadOnlyList r1 = Onequote.GetAdx(5); + IReadOnlyList r1 = Onequote.ToAdx(5); Assert.AreEqual(1, r1.Count); } @@ -90,7 +90,7 @@ public void Issue859() .Select(Imports.QuoteFromCsv) .OrderByDescending(x => x.Timestamp); - IReadOnlyList r = test859.GetAdx(); + IReadOnlyList r = test859.ToAdx(); Assert.AreEqual(0, r.Count(x => x.Adx is double.NaN)); Assert.AreEqual(595, r.Count); @@ -99,7 +99,7 @@ public void Issue859() [TestMethod] public void Zeroes() { - IReadOnlyList r = ZeroesQuotes.GetAdx(); + IReadOnlyList r = ZeroesQuotes.ToAdx(); Assert.AreEqual(0, r.Count(x => x.Adx is double.NaN)); Assert.AreEqual(200, r.Count); @@ -109,7 +109,7 @@ public void Zeroes() public void Removed() { IReadOnlyList results = Quotes - .GetAdx() + .ToAdx() .RemoveWarmupPeriods(); // assertions @@ -126,5 +126,5 @@ public void Exceptions() => // bad lookback period Assert.ThrowsException(() => - Quotes.GetAdx(1)); + Quotes.ToAdx(1)); } diff --git a/tests/indicators/a-d/Alligator/Alligator.StaticSeries.Tests.cs b/tests/indicators/a-d/Alligator/Alligator.StaticSeries.Tests.cs index 50399eeb0..e8c682b40 100644 --- a/tests/indicators/a-d/Alligator/Alligator.StaticSeries.Tests.cs +++ b/tests/indicators/a-d/Alligator/Alligator.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class Alligator : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = Quotes - .GetAlligator(); + .ToAlligator(); // proper quantities Assert.AreEqual(502, results.Count); @@ -47,7 +47,7 @@ public void Chainee() { IReadOnlyList results = Quotes .ToSma(2) - .GetAlligator(); + .ToAlligator(); Assert.AreEqual(502, results.Count); Assert.AreEqual(481, results.Count(x => x.Jaw != null)); @@ -57,7 +57,7 @@ public void Chainee() public override void BadData() { IReadOnlyList r = BadQuotes - .GetAlligator(3, 3, 2, 1, 1, 1); + .ToAlligator(3, 3, 2, 1, 1, 1); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Jaw is double.NaN)); @@ -67,12 +67,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetAlligator(); + .ToAlligator(); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetAlligator(); + .ToAlligator(); Assert.AreEqual(1, r1.Count); } @@ -81,7 +81,7 @@ public override void NoQuotes() public void Condense() { IReadOnlyList results = Quotes - .GetAlligator() + .ToAlligator() .Condense(); Assert.AreEqual(495, results.Count); @@ -96,7 +96,7 @@ public void Condense() public void Removed() { IReadOnlyList results = Quotes - .GetAlligator() + .ToAlligator() .RemoveWarmupPeriods(); Assert.AreEqual(502 - 21 - 250, results.Count); @@ -123,34 +123,34 @@ public void Exceptions() { // bad jaw lookback periods Assert.ThrowsException(() => - Quotes.GetAlligator(13, 8, 13)); + Quotes.ToAlligator(13, 8, 13)); // bad teeth lookback periods Assert.ThrowsException(() => - Quotes.GetAlligator(13, 8, 8, 5, 8)); + Quotes.ToAlligator(13, 8, 8, 5, 8)); // bad lips lookback periods Assert.ThrowsException(() => - Quotes.GetAlligator(13, 8, 8, 5, 0)); + Quotes.ToAlligator(13, 8, 8, 5, 0)); // bad jaw offset periods Assert.ThrowsException(() => - Quotes.GetAlligator(13, 0)); + Quotes.ToAlligator(13, 0)); // bad teeth offset periods Assert.ThrowsException(() => - Quotes.GetAlligator(13, 8, 8, 0)); + Quotes.ToAlligator(13, 8, 8, 0)); // bad lips offset periods Assert.ThrowsException(() => - Quotes.GetAlligator(13, 8, 8, 5, 5, 0)); + Quotes.ToAlligator(13, 8, 8, 5, 5, 0)); // bad jaw + offset periods Assert.ThrowsException(() => - Quotes.GetAlligator(13, 8, 12, 11)); + Quotes.ToAlligator(13, 8, 12, 11)); // bad teeth + offset periods Assert.ThrowsException(() => - Quotes.GetAlligator(13, 8, 8, 5, 7, 7)); + Quotes.ToAlligator(13, 8, 8, 5, 7, 7)); } } diff --git a/tests/indicators/a-d/Alligator/Alligator.StreamHub.Tests.cs b/tests/indicators/a-d/Alligator/Alligator.StreamHub.Tests.cs index bfe92a4e1..22a33b156 100644 --- a/tests/indicators/a-d/Alligator/Alligator.StreamHub.Tests.cs +++ b/tests/indicators/a-d/Alligator/Alligator.StreamHub.Tests.cs @@ -57,7 +57,7 @@ IReadOnlyList streamList // time-series, for comparison IReadOnlyList seriesList = quotesList - .GetAlligator(); + .ToAlligator(); // assert, should equal series streamList.Should().HaveCount(length - 1); @@ -118,7 +118,7 @@ IReadOnlyList streamList IReadOnlyList seriesList = quotesList .ToSma(10) - .GetAlligator(); + .ToAlligator(); // assert, should equal series streamList.Should().HaveCount(length - 1); diff --git a/tests/indicators/a-d/Alma/Alma.StaticSeries.Tests.cs b/tests/indicators/a-d/Alma/Alma.StaticSeries.Tests.cs index de8e61331..d9ccb1884 100644 --- a/tests/indicators/a-d/Alma/Alma.StaticSeries.Tests.cs +++ b/tests/indicators/a-d/Alma/Alma.StaticSeries.Tests.cs @@ -11,7 +11,7 @@ public override void Standard() double sigma = 6; IReadOnlyList results = Quotes - .GetAlma(lookbackPeriods, offset, sigma); + .ToAlma(lookbackPeriods, offset, sigma); // proper quantities Assert.AreEqual(502, results.Count); @@ -42,7 +42,7 @@ public void UseReusable() { IReadOnlyList results = Quotes .Use(CandlePart.Close) - .GetAlma(10); + .ToAlma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(493, results.Count(x => x.Alma != null)); @@ -56,7 +56,7 @@ public void Chainee() { IReadOnlyList results = Quotes .ToSma(2) - .GetAlma(10); + .ToAlma(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(492, results.Count(x => x.Alma != null)); @@ -70,7 +70,7 @@ public void Chainor() double sigma = 6; IReadOnlyList results = Quotes - .GetAlma(lookbackPeriods, offset, sigma) + .ToAlma(lookbackPeriods, offset, sigma) .ToSma(10); Assert.AreEqual(502, results.Count); @@ -81,12 +81,12 @@ public void Chainor() public void NaN() { IReadOnlyList r1 - = Data.GetBtcUsdNan().GetAlma(); + = Data.GetBtcUsdNan().ToAlma(); Assert.AreEqual(0, r1.Count(x => x.Alma is double.NaN)); IReadOnlyList r2 - = Data.GetBtcUsdNan().GetAlma(20); + = Data.GetBtcUsdNan().ToAlma(20); Assert.AreEqual(0, r2.Count(x => x.Alma is double.NaN)); } @@ -94,7 +94,7 @@ IReadOnlyList r2 [TestMethod] public override void BadData() { - IReadOnlyList r = BadQuotes.GetAlma(14, 0.5, 3); + IReadOnlyList r = BadQuotes.ToAlma(14, 0.5, 3); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Alma is double.NaN)); @@ -103,11 +103,11 @@ public override void BadData() [TestMethod] public override void NoQuotes() { - IReadOnlyList r0 = Noquotes.GetAlma(); + IReadOnlyList r0 = Noquotes.ToAlma(); Assert.AreEqual(0, r0.Count); - IReadOnlyList r1 = Onequote.GetAlma(); + IReadOnlyList r1 = Onequote.ToAlma(); Assert.AreEqual(1, r1.Count); } @@ -116,7 +116,7 @@ public override void NoQuotes() public void Removed() { IReadOnlyList results = Quotes - .GetAlma(10) + .ToAlma(10) .RemoveWarmupPeriods(); // assertions @@ -131,14 +131,14 @@ public void Exceptions() { // bad lookback period Assert.ThrowsException(() => - Quotes.GetAlma(0, 1, 5)); + Quotes.ToAlma(0, 1, 5)); // bad offset Assert.ThrowsException(() => - Quotes.GetAlma(15, 1.1, 3)); + Quotes.ToAlma(15, 1.1, 3)); // bad sigma Assert.ThrowsException(() => - Quotes.GetAlma(10, 0.5, 0)); + Quotes.ToAlma(10, 0.5, 0)); } } diff --git a/tests/indicators/a-d/Aroon/Aroon.StaticSeries.Tests.cs b/tests/indicators/a-d/Aroon/Aroon.StaticSeries.Tests.cs index 79e77cc5b..db6dcba18 100644 --- a/tests/indicators/a-d/Aroon/Aroon.StaticSeries.Tests.cs +++ b/tests/indicators/a-d/Aroon/Aroon.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class Aroon : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = Quotes - .GetAroon(); + .ToAroon(); // proper quantities Assert.AreEqual(502, results.Count); @@ -46,7 +46,7 @@ public override void Standard() public void Chainor() { IReadOnlyList results = Quotes - .GetAroon() + .ToAroon() .ToSma(10); Assert.AreEqual(502, results.Count); @@ -57,7 +57,7 @@ public void Chainor() public override void BadData() { IReadOnlyList r = BadQuotes - .GetAroon(20); + .ToAroon(20); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Oscillator is double.NaN)); @@ -67,12 +67,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetAroon(); + .ToAroon(); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetAroon(); + .ToAroon(); Assert.AreEqual(1, r1.Count); } @@ -81,7 +81,7 @@ public override void NoQuotes() public void Removed() { IReadOnlyList results = Quotes - .GetAroon() + .ToAroon() .RemoveWarmupPeriods(); // assertions @@ -97,5 +97,5 @@ public void Removed() [TestMethod] public void Exceptions() => Assert.ThrowsException(() - => Quotes.GetAroon(0)); + => Quotes.ToAroon(0)); } diff --git a/tests/indicators/a-d/Atr/Atr.StaticSeries.Tests.cs b/tests/indicators/a-d/Atr/Atr.StaticSeries.Tests.cs index 8e7fbab50..0682f0fc3 100644 --- a/tests/indicators/a-d/Atr/Atr.StaticSeries.Tests.cs +++ b/tests/indicators/a-d/Atr/Atr.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class Atr : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = Quotes - .GetAtr(); + .ToAtr(); // proper quantities Assert.AreEqual(502, results.Count); @@ -44,10 +44,10 @@ public override void Standard() public void MatchingTrueRange() { IReadOnlyList resultsAtr = Quotes - .GetAtr(14); + .ToAtr(14); IReadOnlyList resultsTr = Quotes - .GetTr(); + .ToTr(); for (int i = 0; i < Quotes.Count; i++) { @@ -65,7 +65,7 @@ public void MatchingTrueRange() public void Chainor() { IReadOnlyList results = Quotes - .GetAtr(10) + .ToAtr(10) .ToSma(10); Assert.AreEqual(502, results.Count); @@ -76,7 +76,7 @@ public void Chainor() public override void BadData() { IReadOnlyList r = BadQuotes - .GetAtr(20); + .ToAtr(20); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Atr is double.NaN)); @@ -86,12 +86,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetAtr(); + .ToAtr(); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetAtr(); + .ToAtr(); Assert.AreEqual(1, r1.Count); } @@ -100,7 +100,7 @@ public override void NoQuotes() public void Removed() { IReadOnlyList results = Quotes - .GetAtr() + .ToAtr() .RemoveWarmupPeriods(); // assertions @@ -116,5 +116,5 @@ public void Removed() [TestMethod] public void Exceptions() => Assert.ThrowsException(() => - Quotes.GetAtr(1)); + Quotes.ToAtr(1)); } diff --git a/tests/indicators/a-d/Atr/Atr.StreamHub.Tests.cs b/tests/indicators/a-d/Atr/Atr.StreamHub.Tests.cs index ba3ca5f7c..ced05e39e 100644 --- a/tests/indicators/a-d/Atr/Atr.StreamHub.Tests.cs +++ b/tests/indicators/a-d/Atr/Atr.StreamHub.Tests.cs @@ -56,7 +56,7 @@ IReadOnlyList streamList // time-series, for comparison IReadOnlyList seriesList = quotesList - .GetAtr(14); + .ToAtr(14); // assert, should equal series streamList.Should().HaveCount(length - 1); @@ -102,7 +102,7 @@ IReadOnlyList streamList // time-series, for comparison IReadOnlyList seriesList = quotesList - .GetAtr(14) + .ToAtr(14) .ToSma(smaPeriods); // assert, should equal series diff --git a/tests/indicators/a-d/AtrStop/AtrStop.StaticSeries.Tests.cs b/tests/indicators/a-d/AtrStop/AtrStop.StaticSeries.Tests.cs index d51d939dc..091b89486 100644 --- a/tests/indicators/a-d/AtrStop/AtrStop.StaticSeries.Tests.cs +++ b/tests/indicators/a-d/AtrStop/AtrStop.StaticSeries.Tests.cs @@ -10,7 +10,7 @@ public override void Standard() double multiplier = 3; IReadOnlyList results = Quotes - .GetAtrStop(lookbackPeriods, multiplier); + .ToAtrStop(lookbackPeriods, multiplier); // proper quantities Assert.AreEqual(502, results.Count); @@ -55,7 +55,7 @@ public void HighLow() double multiplier = 3; IReadOnlyList results = Quotes - .GetAtrStop(lookbackPeriods, multiplier, EndType.HighLow); + .ToAtrStop(lookbackPeriods, multiplier, EndType.HighLow); // proper quantities Assert.AreEqual(502, results.Count); @@ -97,7 +97,7 @@ public void HighLow() public override void BadData() { IReadOnlyList r = BadQuotes - .GetAtrStop(7); + .ToAtrStop(7); Assert.AreEqual(502, r.Count); } @@ -106,12 +106,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetAtrStop(); + .ToAtrStop(); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetAtrStop(); + .ToAtrStop(); Assert.AreEqual(1, r1.Count); } @@ -123,7 +123,7 @@ public void Condense() double multiplier = 3; IReadOnlyList results = Quotes - .GetAtrStop(lookbackPeriods, multiplier) + .ToAtrStop(lookbackPeriods, multiplier) .Condense(); // assertions @@ -142,7 +142,7 @@ public void Removed() double multiplier = 3; IReadOnlyList results = Quotes - .GetAtrStop(lookbackPeriods, multiplier) + .ToAtrStop(lookbackPeriods, multiplier) .RemoveWarmupPeriods(); // assertions @@ -159,10 +159,10 @@ public void Exceptions() { // bad lookback period Assert.ThrowsException(() - => Quotes.GetAtrStop(1)); + => Quotes.ToAtrStop(1)); // bad multiplier Assert.ThrowsException(() - => Quotes.GetAtrStop(7, 0)); + => Quotes.ToAtrStop(7, 0)); } } diff --git a/tests/indicators/a-d/AtrStop/AtrStop.StreamHub.Tests.cs b/tests/indicators/a-d/AtrStop/AtrStop.StreamHub.Tests.cs index 8beda6360..b36b6141d 100644 --- a/tests/indicators/a-d/AtrStop/AtrStop.StreamHub.Tests.cs +++ b/tests/indicators/a-d/AtrStop/AtrStop.StreamHub.Tests.cs @@ -57,7 +57,7 @@ IReadOnlyList streamList // time-series, for comparison IEnumerable seriesList = quotesList - .GetAtrStop(); + .ToAtrStop(); // assert, should equal series streamList.Should().HaveCount(length - 1); @@ -89,7 +89,7 @@ IReadOnlyList streamList // time-series, for comparison IEnumerable seriesList = Quotes - .GetAtrStop(endType: EndType.HighLow); + .ToAtrStop(endType: EndType.HighLow); // assert, should equal series streamList.Should().HaveCount(Quotes.Count); diff --git a/tests/indicators/a-d/Awesome/Awesome.StaticSeries.Tests.cs b/tests/indicators/a-d/Awesome/Awesome.StaticSeries.Tests.cs index 49eab3994..92982f51e 100644 --- a/tests/indicators/a-d/Awesome/Awesome.StaticSeries.Tests.cs +++ b/tests/indicators/a-d/Awesome/Awesome.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class Awesome : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = Quotes - .GetAwesome(); + .ToAwesome(); // proper quantities Assert.AreEqual(502, results.Count); @@ -36,7 +36,7 @@ public void UseReusable() { IReadOnlyList results = Quotes .Use(CandlePart.Close) - .GetAwesome(); + .ToAwesome(); Assert.AreEqual(502, results.Count); Assert.AreEqual(469, results.Count(x => x.Oscillator != null)); @@ -47,7 +47,7 @@ public void Chainee() { IReadOnlyList results = Quotes .ToSma(2) - .GetAwesome(); + .ToAwesome(); Assert.AreEqual(502, results.Count); Assert.AreEqual(468, results.Count(x => x.Oscillator != null)); @@ -57,7 +57,7 @@ public void Chainee() public void Chainor() { IReadOnlyList results = Quotes - .GetAwesome() + .ToAwesome() .ToSma(10); Assert.AreEqual(502, results.Count); @@ -68,7 +68,7 @@ public void Chainor() public override void BadData() { IReadOnlyList r = BadQuotes - .GetAwesome(); + .ToAwesome(); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Oscillator is double.NaN)); @@ -78,12 +78,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetAwesome(); + .ToAwesome(); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetAwesome(); + .ToAwesome(); Assert.AreEqual(1, r1.Count); } @@ -92,7 +92,7 @@ public override void NoQuotes() public void Removed() { IReadOnlyList results = Quotes - .GetAwesome() + .ToAwesome() .RemoveWarmupPeriods(); // assertions @@ -108,10 +108,10 @@ public void Exceptions() { // bad fast period Assert.ThrowsException(() => - Quotes.GetAwesome(0)); + Quotes.ToAwesome(0)); // bad slow period Assert.ThrowsException(() => - Quotes.GetAwesome(25, 25)); + Quotes.ToAwesome(25, 25)); } } diff --git a/tests/indicators/a-d/Beta/Beta.StaticSeries.Tests.cs b/tests/indicators/a-d/Beta/Beta.StaticSeries.Tests.cs index cfced403d..f2797f1c7 100644 --- a/tests/indicators/a-d/Beta/Beta.StaticSeries.Tests.cs +++ b/tests/indicators/a-d/Beta/Beta.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class Beta : StaticSeriesTestBase public void All() { IReadOnlyList results = OtherQuotes - .GetBeta(Quotes, 20, BetaType.All); + .ToBeta(Quotes, 20, BetaType.All); // proper quantities Assert.AreEqual(502, results.Count); @@ -51,7 +51,7 @@ public void All() public override void Standard() { IReadOnlyList results = OtherQuotes - .GetBeta(Quotes, 20); + .ToBeta(Quotes, 20); // proper quantities Assert.AreEqual(502, results.Count); @@ -66,7 +66,7 @@ public override void Standard() public void Up() { IReadOnlyList results = OtherQuotes - .GetBeta(Quotes, 20, BetaType.Up); + .ToBeta(Quotes, 20, BetaType.Up); // proper quantities Assert.AreEqual(502, results.Count); @@ -81,7 +81,7 @@ public void Up() public void Down() { IReadOnlyList results = OtherQuotes - .GetBeta(Quotes, 20, BetaType.Down); + .ToBeta(Quotes, 20, BetaType.Down); // proper quantities Assert.AreEqual(502, results.Count); @@ -97,7 +97,7 @@ public void UseReusable() { IReadOnlyList results = OtherQuotes .Use(CandlePart.Close) - .GetBeta(Quotes.Use(CandlePart.Close), 20); + .ToBeta(Quotes.Use(CandlePart.Close), 20); Assert.AreEqual(502, results.Count); Assert.AreEqual(482, results.Count(x => x.Beta != null)); @@ -107,7 +107,7 @@ public void UseReusable() public void Chainor() { IReadOnlyList results = OtherQuotes - .GetBeta(Quotes, 20) + .ToBeta(Quotes, 20) .ToSma(10); Assert.AreEqual(502, results.Count); @@ -119,7 +119,7 @@ public void Chainee() { IReadOnlyList results = Quotes .ToSma(2) - .GetBeta(OtherQuotes.ToSma(2), 20); + .ToBeta(OtherQuotes.ToSma(2), 20); Assert.AreEqual(502, results.Count); Assert.AreEqual(481, results.Count(x => x.Beta != null)); @@ -130,19 +130,19 @@ public void Chainee() public override void BadData() { IReadOnlyList r1 = BadQuotes - .GetBeta(BadQuotes, 15); + .ToBeta(BadQuotes, 15); Assert.AreEqual(502, r1.Count); Assert.AreEqual(0, r1.Count(x => x.Beta is double.NaN)); IReadOnlyList r2 = BadQuotes - .GetBeta(BadQuotes, 15, BetaType.Up); + .ToBeta(BadQuotes, 15, BetaType.Up); Assert.AreEqual(502, r2.Count); Assert.AreEqual(0, r2.Count(x => x.BetaUp is double.NaN)); IReadOnlyList r3 = BadQuotes - .GetBeta(BadQuotes, 15, BetaType.Down); + .ToBeta(BadQuotes, 15, BetaType.Down); Assert.AreEqual(502, r3.Count); Assert.AreEqual(0, r3.Count(x => x.BetaDown is double.NaN)); @@ -152,7 +152,7 @@ public override void BadData() public void BigData() { IReadOnlyList r = BigQuotes - .GetBeta(BigQuotes, 150, BetaType.All); + .ToBeta(BigQuotes, 150, BetaType.All); Assert.AreEqual(1246, r.Count); } @@ -173,7 +173,7 @@ public void BetaMsft() IReadOnlyList results = evalQuotes .Aggregate(PeriodSize.Month) - .GetBeta(mktQuotes.Aggregate(PeriodSize.Month), 60); + .ToBeta(mktQuotes.Aggregate(PeriodSize.Month), 60); Assert.AreEqual(0.91, results[385].Beta.Round(2)); } @@ -182,7 +182,7 @@ public void BetaMsft() public void Removed() { IReadOnlyList results = OtherQuotes - .GetBeta(Quotes, 20) + .ToBeta(Quotes, 20) .RemoveWarmupPeriods(); // assertions @@ -197,7 +197,7 @@ public void SameSame() { // Beta should be 1 if evaluating against self IReadOnlyList results = Quotes - .GetBeta(Quotes, 20); + .ToBeta(Quotes, 20); // proper quantities Assert.AreEqual(502, results.Count); @@ -212,12 +212,12 @@ public void SameSame() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetBeta(Noquotes, 5); + .ToBeta(Noquotes, 5); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetBeta(Onequote, 5); + .ToBeta(Onequote, 5); Assert.AreEqual(1, r1.Count); } @@ -252,7 +252,7 @@ public void NoMatch() ]; Assert.ThrowsException(() - => quoteA.GetBeta(quoteB, 3)); + => quoteA.ToBeta(quoteB, 3)); } [TestMethod] @@ -260,12 +260,12 @@ public void Exceptions() { // bad lookback period Assert.ThrowsException(() - => Quotes.GetBeta(OtherQuotes, 0)); + => Quotes.ToBeta(OtherQuotes, 0)); // bad evaluation quotes IReadOnlyList eval = Data.GetCompare(300).ToList(); Assert.ThrowsException(() - => Quotes.GetBeta(eval, 30)); + => Quotes.ToBeta(eval, 30)); } } diff --git a/tests/indicators/a-d/BollingerBands/BollingerBands.StaticSeries.Tests.cs b/tests/indicators/a-d/BollingerBands/BollingerBands.StaticSeries.Tests.cs index b8e028e06..a0fa51e21 100644 --- a/tests/indicators/a-d/BollingerBands/BollingerBands.StaticSeries.Tests.cs +++ b/tests/indicators/a-d/BollingerBands/BollingerBands.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class BollingerBands : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = - Quotes.GetBollingerBands(); + Quotes.ToBollingerBands(); // proper quantities Assert.AreEqual(502, results.Count); @@ -41,7 +41,7 @@ public void UseReusable() { IReadOnlyList results = Quotes .Use(CandlePart.Close) - .GetBollingerBands(); + .ToBollingerBands(); Assert.AreEqual(502, results.Count); Assert.AreEqual(483, results.Count(x => x.Sma != null)); @@ -52,7 +52,7 @@ public void Chainee() { IReadOnlyList results = Quotes .ToSma(2) - .GetBollingerBands(); + .ToBollingerBands(); Assert.AreEqual(502, results.Count); Assert.AreEqual(482, results.Count(x => x.UpperBand != null)); @@ -62,7 +62,7 @@ public void Chainee() public void Chainor() { IReadOnlyList results = Quotes - .GetBollingerBands() + .ToBollingerBands() .ToSma(10); Assert.AreEqual(502, results.Count); @@ -73,7 +73,7 @@ public void Chainor() public override void BadData() { IReadOnlyList r = BadQuotes - .GetBollingerBands(15, 3); + .ToBollingerBands(15, 3); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.UpperBand is double.NaN)); @@ -83,12 +83,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetBollingerBands(); + .ToBollingerBands(); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetBollingerBands(); + .ToBollingerBands(); Assert.AreEqual(1, r1.Count); } @@ -97,7 +97,7 @@ public override void NoQuotes() public void Removed() { IReadOnlyList results = Quotes - .GetBollingerBands() + .ToBollingerBands() .RemoveWarmupPeriods(); // assertions @@ -117,10 +117,10 @@ public void Exceptions() { // bad lookback period Assert.ThrowsException(() => - Quotes.GetBollingerBands(1)); + Quotes.ToBollingerBands(1)); // bad standard deviation Assert.ThrowsException(() => - Quotes.GetBollingerBands(2, 0)); + Quotes.ToBollingerBands(2, 0)); } } diff --git a/tests/indicators/a-d/Bop/Bop.StaticSeries.Tests.cs b/tests/indicators/a-d/Bop/Bop.StaticSeries.Tests.cs index 10ea4d8e9..cb297e871 100644 --- a/tests/indicators/a-d/Bop/Bop.StaticSeries.Tests.cs +++ b/tests/indicators/a-d/Bop/Bop.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class Bop : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = Quotes - .GetBop(); + .ToBop(); // proper quantities Assert.AreEqual(502, results.Count); @@ -34,7 +34,7 @@ public override void Standard() public void Chainor() { IReadOnlyList results = Quotes - .GetBop() + .ToBop() .ToSma(10); Assert.AreEqual(502, results.Count); @@ -45,7 +45,7 @@ public void Chainor() public void NaN() { IEnumerable r = Data.GetBtcUsdNan() - .GetBop(50); + .ToBop(50); Assert.AreEqual(0, r.Count(x => x.Bop is double.NaN)); } @@ -54,7 +54,7 @@ public void NaN() public override void BadData() { IReadOnlyList r = BadQuotes - .GetBop(); + .ToBop(); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Bop is double.NaN)); @@ -64,11 +64,11 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetBop(); + .ToBop(); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetBop(); + .ToBop(); Assert.AreEqual(1, r1.Count); } @@ -76,7 +76,7 @@ public override void NoQuotes() public void Removed() { IReadOnlyList results = Quotes - .GetBop() + .ToBop() .RemoveWarmupPeriods(); // assertions @@ -90,5 +90,5 @@ public void Removed() [TestMethod] public void Exceptions() => Assert.ThrowsException(() - => Quotes.GetBop(0)); + => Quotes.ToBop(0)); } diff --git a/tests/indicators/a-d/Cci/Cci.StaticSeries.Tests.cs b/tests/indicators/a-d/Cci/Cci.StaticSeries.Tests.cs index 2807b47c7..c4550ed6a 100644 --- a/tests/indicators/a-d/Cci/Cci.StaticSeries.Tests.cs +++ b/tests/indicators/a-d/Cci/Cci.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class Cci : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = Quotes - .GetCci(); + .ToCci(); // proper quantities Assert.AreEqual(502, results.Count); @@ -22,7 +22,7 @@ public override void Standard() public void Chainor() { IReadOnlyList results = Quotes - .GetCci() + .ToCci() .ToSma(10); Assert.AreEqual(502, results.Count); @@ -33,7 +33,7 @@ public void Chainor() public override void BadData() { IReadOnlyList r = BadQuotes - .GetCci(15); + .ToCci(15); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Cci is double.NaN)); @@ -43,12 +43,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetCci(); + .ToCci(); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetCci(); + .ToCci(); Assert.AreEqual(1, r1.Count); } @@ -57,7 +57,7 @@ public override void NoQuotes() public void Removed() { IReadOnlyList results = Quotes - .GetCci() + .ToCci() .RemoveWarmupPeriods(); // assertions @@ -71,5 +71,5 @@ public void Removed() [TestMethod] public void Exceptions() => Assert.ThrowsException(() - => Quotes.GetCci(0)); + => Quotes.ToCci(0)); } diff --git a/tests/indicators/a-d/ChaikinOsc/ChaikinOsc.StaticSeries.Tests.cs b/tests/indicators/a-d/ChaikinOsc/ChaikinOsc.StaticSeries.Tests.cs index a9cc6474f..613c34cb6 100644 --- a/tests/indicators/a-d/ChaikinOsc/ChaikinOsc.StaticSeries.Tests.cs +++ b/tests/indicators/a-d/ChaikinOsc/ChaikinOsc.StaticSeries.Tests.cs @@ -10,7 +10,7 @@ public override void Standard() int slowPeriods = 10; IReadOnlyList results = Quotes - .GetChaikinOsc(fastPeriods, slowPeriods); + .ToChaikinOsc(fastPeriods, slowPeriods); // proper quantities Assert.AreEqual(502, results.Count); @@ -28,7 +28,7 @@ public override void Standard() public void Chainor() { IReadOnlyList results = Quotes - .GetChaikinOsc() + .ToChaikinOsc() .ToSma(10); Assert.AreEqual(502, results.Count); @@ -39,7 +39,7 @@ public void Chainor() public override void BadData() { IReadOnlyList r = BadQuotes - .GetChaikinOsc(5, 15); + .ToChaikinOsc(5, 15); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Oscillator is double.NaN)); @@ -49,12 +49,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetChaikinOsc(); + .ToChaikinOsc(); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetChaikinOsc(); + .ToChaikinOsc(); Assert.AreEqual(1, r1.Count); } @@ -66,7 +66,7 @@ public void Removed() int slowPeriods = 10; IReadOnlyList results = Quotes - .GetChaikinOsc(fastPeriods, slowPeriods) + .ToChaikinOsc(fastPeriods, slowPeriods) .RemoveWarmupPeriods(); // assertions @@ -84,10 +84,10 @@ public void Exceptions() { // bad fast lookback Assert.ThrowsException(() => - Quotes.GetChaikinOsc(0)); + Quotes.ToChaikinOsc(0)); // bad slow lookback Assert.ThrowsException(() => - Quotes.GetChaikinOsc(10, 5)); + Quotes.ToChaikinOsc(10, 5)); } } diff --git a/tests/indicators/a-d/Chandelier/Chandelier.StaticSeries.Tests.cs b/tests/indicators/a-d/Chandelier/Chandelier.StaticSeries.Tests.cs index 727f00fdb..92b8663d0 100644 --- a/tests/indicators/a-d/Chandelier/Chandelier.StaticSeries.Tests.cs +++ b/tests/indicators/a-d/Chandelier/Chandelier.StaticSeries.Tests.cs @@ -9,7 +9,7 @@ public override void Standard() int lookbackPeriods = 22; IReadOnlyList longResult = - Quotes.GetChandelier(lookbackPeriods); + Quotes.ToChandelier(lookbackPeriods); // proper quantities Assert.AreEqual(502, longResult.Count); @@ -24,7 +24,7 @@ public override void Standard() // short IReadOnlyList shortResult = - Quotes.GetChandelier(lookbackPeriods, 3, ChandelierType.Short); + Quotes.ToChandelier(lookbackPeriods, 3, ChandelierType.Short); ChandelierResult c = shortResult[501]; Assert.AreEqual(246.4240, c.ChandelierExit.Round(4)); @@ -34,7 +34,7 @@ public override void Standard() public void Chainor() { IReadOnlyList results = Quotes - .GetChandelier() + .ToChandelier() .ToSma(10); Assert.AreEqual(502, results.Count); @@ -45,7 +45,7 @@ public void Chainor() public override void BadData() { IReadOnlyList r = BadQuotes - .GetChandelier(15, 2); + .ToChandelier(15, 2); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.ChandelierExit is double.NaN)); @@ -55,12 +55,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetChandelier(); + .ToChandelier(); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetChandelier(); + .ToChandelier(); Assert.AreEqual(1, r1.Count); } @@ -69,7 +69,7 @@ public override void NoQuotes() public void Removed() { IReadOnlyList results = Quotes - .GetChandelier() + .ToChandelier() .RemoveWarmupPeriods(); // assertions @@ -84,14 +84,14 @@ public void Exceptions() { // bad lookback period Assert.ThrowsException(() => - Quotes.GetChandelier(0)); + Quotes.ToChandelier(0)); // bad multiplier Assert.ThrowsException(() => - Quotes.GetChandelier(25, 0)); + Quotes.ToChandelier(25, 0)); // bad type Assert.ThrowsException(() => - Quotes.GetChandelier(25, 2, (ChandelierType)int.MaxValue)); + Quotes.ToChandelier(25, 2, (ChandelierType)int.MaxValue)); } } diff --git a/tests/indicators/a-d/Chop/Chop.StaticSeries.Tests.cs b/tests/indicators/a-d/Chop/Chop.StaticSeries.Tests.cs index 5610f776f..0563157d0 100644 --- a/tests/indicators/a-d/Chop/Chop.StaticSeries.Tests.cs +++ b/tests/indicators/a-d/Chop/Chop.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class Chop : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = Quotes - .GetChop(); + .ToChop(); // proper quantities Assert.AreEqual(502, results.Count); @@ -31,7 +31,7 @@ public override void Standard() public void Chainor() { IReadOnlyList results = Quotes - .GetChop() + .ToChop() .ToSma(10); Assert.AreEqual(502, results.Count); @@ -43,7 +43,7 @@ public void SmallLookback() { int lookbackPeriods = 2; IReadOnlyList results = Quotes - .GetChop(lookbackPeriods); + .ToChop(lookbackPeriods); // proper quantities Assert.AreEqual(502, results.Count); @@ -54,7 +54,7 @@ public void SmallLookback() public override void BadData() { IReadOnlyList r = BadQuotes - .GetChop(20); + .ToChop(20); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Chop is double.NaN)); @@ -64,12 +64,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetChop(); + .ToChop(); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetChop(); + .ToChop(); Assert.AreEqual(1, r1.Count); } @@ -78,7 +78,7 @@ public override void NoQuotes() public void Removed() { IReadOnlyList results = Quotes - .GetChop() + .ToChop() .RemoveWarmupPeriods(); // assertions @@ -92,5 +92,5 @@ public void Removed() [TestMethod] public void Exceptions() => Assert.ThrowsException(() - => Quotes.GetChop(1)); + => Quotes.ToChop(1)); } diff --git a/tests/indicators/a-d/Cmf/Cmf.StaticSeries.Tests.cs b/tests/indicators/a-d/Cmf/Cmf.StaticSeries.Tests.cs index 30120cfcb..f6c5814c0 100644 --- a/tests/indicators/a-d/Cmf/Cmf.StaticSeries.Tests.cs +++ b/tests/indicators/a-d/Cmf/Cmf.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class Cmf : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = Quotes - .GetCmf(); + .ToCmf(); // proper quantities Assert.AreEqual(502, results.Count); @@ -34,7 +34,7 @@ public override void Standard() public void Chainor() { IReadOnlyList results = Quotes - .GetCmf() + .ToCmf() .ToSma(10); Assert.AreEqual(502, results.Count); @@ -45,7 +45,7 @@ public void Chainor() public override void BadData() { IReadOnlyList r = BadQuotes - .GetCmf(15); + .ToCmf(15); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Cmf is double.NaN)); @@ -55,7 +55,7 @@ public override void BadData() public void BigData() { IReadOnlyList r = BigQuotes - .GetCmf(150); + .ToCmf(150); Assert.AreEqual(1246, r.Count); } @@ -64,12 +64,12 @@ public void BigData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetCmf(); + .ToCmf(); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetCmf(); + .ToCmf(); Assert.AreEqual(1, r1.Count); } @@ -78,7 +78,7 @@ public override void NoQuotes() public void Removed() { IReadOnlyList results = Quotes - .GetCmf() + .ToCmf() .RemoveWarmupPeriods(); // assertions @@ -94,5 +94,5 @@ public void Removed() [TestMethod] public void Exceptions() => Assert.ThrowsException(() - => Quotes.GetCmf(0)); + => Quotes.ToCmf(0)); } diff --git a/tests/indicators/a-d/Cmo/Cmo.StaticSeries.Tests.cs b/tests/indicators/a-d/Cmo/Cmo.StaticSeries.Tests.cs index ad5aa350a..37ca7fa75 100644 --- a/tests/indicators/a-d/Cmo/Cmo.StaticSeries.Tests.cs +++ b/tests/indicators/a-d/Cmo/Cmo.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class Cmo : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = Quotes - .GetCmo(14); + .ToCmo(14); // proper quantities Assert.AreEqual(502, results.Count); @@ -32,7 +32,7 @@ public void UseReusable() { IReadOnlyList results = Quotes .Use(CandlePart.Close) - .GetCmo(14); + .ToCmo(14); Assert.AreEqual(502, results.Count); Assert.AreEqual(488, results.Count(x => x.Cmo != null)); @@ -43,7 +43,7 @@ public void Chainee() { IReadOnlyList results = Quotes .ToSma(2) - .GetCmo(20); + .ToCmo(20); Assert.AreEqual(502, results.Count); Assert.AreEqual(481, results.Count(x => x.Cmo != null)); @@ -53,7 +53,7 @@ public void Chainee() public void Chainor() { IReadOnlyList results = Quotes - .GetCmo(20) + .ToCmo(20) .ToSma(10); Assert.AreEqual(502, results.Count); @@ -64,7 +64,7 @@ public void Chainor() public override void BadData() { IReadOnlyList r = BadQuotes - .GetCmo(35); + .ToCmo(35); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Cmo is double.NaN)); @@ -74,12 +74,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetCmo(5); + .ToCmo(5); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetCmo(5); + .ToCmo(5); Assert.AreEqual(1, r1.Count); } @@ -88,7 +88,7 @@ public override void NoQuotes() public void Removed() { IReadOnlyList results = Quotes - .GetCmo(14) + .ToCmo(14) .RemoveWarmupPeriods(); // assertions @@ -102,5 +102,5 @@ public void Removed() [TestMethod] public void Exceptions() => Assert.ThrowsException(() - => Quotes.GetCmo(0)); + => Quotes.ToCmo(0)); } diff --git a/tests/indicators/a-d/ConnorsRsi/ConnorsRsi.StaticSeries.Tests.cs b/tests/indicators/a-d/ConnorsRsi/ConnorsRsi.StaticSeries.Tests.cs index 5d8bd2bd3..3e1c6e07c 100644 --- a/tests/indicators/a-d/ConnorsRsi/ConnorsRsi.StaticSeries.Tests.cs +++ b/tests/indicators/a-d/ConnorsRsi/ConnorsRsi.StaticSeries.Tests.cs @@ -12,7 +12,7 @@ public override void Standard() int startPeriod = Math.Max(rsiPeriods, Math.Max(streakPeriods, rankPeriods)) + 2; IReadOnlyList results1 = Quotes - .GetConnorsRsi(rsiPeriods, streakPeriods, rankPeriods); + .ToConnorsRsi(rsiPeriods, streakPeriods, rankPeriods); // proper quantities Assert.AreEqual(502, results1.Count); @@ -26,7 +26,7 @@ public override void Standard() Assert.AreEqual(74.7662, r1.ConnorsRsi.Round(4)); // different parameters - IReadOnlyList results2 = Quotes.GetConnorsRsi(14, 20, 10).ToList(); + IReadOnlyList results2 = Quotes.ToConnorsRsi(14, 20, 10).ToList(); ConnorsRsiResult r2 = results2[501]; Assert.AreEqual(42.0773, r2.Rsi.Round(4)); Assert.AreEqual(52.7386, r2.RsiStreak.Round(4)); @@ -39,7 +39,7 @@ public void UseReusable() { IReadOnlyList results = Quotes .Use(CandlePart.Close) - .GetConnorsRsi(); + .ToConnorsRsi(); Assert.AreEqual(502, results.Count); Assert.AreEqual(401, results.Count(x => x.ConnorsRsi != null)); @@ -50,7 +50,7 @@ public void Chainee() { IReadOnlyList results = Quotes .ToSma(2) - .GetConnorsRsi(); + .ToConnorsRsi(); Assert.AreEqual(502, results.Count); Assert.AreEqual(400, results.Count(x => x.ConnorsRsi != null)); @@ -60,7 +60,7 @@ public void Chainee() public void Chainor() { IReadOnlyList results = Quotes - .GetConnorsRsi() + .ToConnorsRsi() .ToSma(10); Assert.AreEqual(502, results.Count); @@ -71,7 +71,7 @@ public void Chainor() public override void BadData() { IReadOnlyList r = BadQuotes - .GetConnorsRsi(4, 3, 25); + .ToConnorsRsi(4, 3, 25); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Rsi is double.NaN)); @@ -81,12 +81,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetConnorsRsi(); + .ToConnorsRsi(); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetConnorsRsi(); + .ToConnorsRsi(); Assert.AreEqual(1, r1.Count); } @@ -102,7 +102,7 @@ public void Removed() int removePeriods = Math.Max(rsiPeriods, Math.Max(streakPeriods, rankPeriods)) + 2; IReadOnlyList results = Quotes - .GetConnorsRsi(rsiPeriods, streakPeriods, rankPeriods) + .ToConnorsRsi(rsiPeriods, streakPeriods, rankPeriods) .RemoveWarmupPeriods(); // assertions @@ -120,14 +120,14 @@ public void Exceptions() { // bad RSI period Assert.ThrowsException(() => - Quotes.GetConnorsRsi(1)); + Quotes.ToConnorsRsi(1)); // bad Streak period Assert.ThrowsException(() => - Quotes.GetConnorsRsi(3, 1)); + Quotes.ToConnorsRsi(3, 1)); // bad Rank period Assert.ThrowsException(() => - Quotes.GetConnorsRsi(3, 2, 1)); + Quotes.ToConnorsRsi(3, 2, 1)); } } diff --git a/tests/indicators/a-d/Correlation/Correlation.StaticSeries.Tests.cs b/tests/indicators/a-d/Correlation/Correlation.StaticSeries.Tests.cs index 3a203c39b..07df155fd 100644 --- a/tests/indicators/a-d/Correlation/Correlation.StaticSeries.Tests.cs +++ b/tests/indicators/a-d/Correlation/Correlation.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class Correlation : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = Quotes - .GetCorrelation(OtherQuotes, 20); + .ToCorrelation(OtherQuotes, 20); // proper quantities // should always be the same number of results as there is quotes @@ -37,7 +37,7 @@ public void UseReusable() { IReadOnlyList results = Quotes .Use(CandlePart.Close) - .GetCorrelation(OtherQuotes.Use(CandlePart.Close), 20); + .ToCorrelation(OtherQuotes.Use(CandlePart.Close), 20); Assert.AreEqual(502, results.Count); Assert.AreEqual(483, results.Count(x => x.Correlation != null)); @@ -47,7 +47,7 @@ public void UseReusable() public void Chainor() { IReadOnlyList results = Quotes - .GetCorrelation(OtherQuotes, 20) + .ToCorrelation(OtherQuotes, 20) .ToSma(10); Assert.AreEqual(502, results.Count); @@ -59,7 +59,7 @@ public void Chainee() { IReadOnlyList results = Quotes .ToSma(2) - .GetCorrelation(OtherQuotes.ToSma(2), 20); + .ToCorrelation(OtherQuotes.ToSma(2), 20); Assert.AreEqual(502, results.Count); Assert.AreEqual(482, results.Count(x => x.Correlation != null)); @@ -70,7 +70,7 @@ public void Chainee() public override void BadData() { IReadOnlyList r = BadQuotes - .GetCorrelation(BadQuotes, 15); + .ToCorrelation(BadQuotes, 15); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Correlation is double.NaN)); @@ -80,7 +80,7 @@ public override void BadData() public void BigData() { IReadOnlyList r = BigQuotes - .GetCorrelation(BigQuotes, 150); + .ToCorrelation(BigQuotes, 150); Assert.AreEqual(1246, r.Count); } @@ -89,12 +89,12 @@ public void BigData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetCorrelation(Noquotes, 10); + .ToCorrelation(Noquotes, 10); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetCorrelation(Onequote, 10); + .ToCorrelation(Onequote, 10); Assert.AreEqual(1, r1.Count); } @@ -103,7 +103,7 @@ public override void NoQuotes() public void Removed() { IReadOnlyList results = Quotes - .GetCorrelation(OtherQuotes, 20) + .ToCorrelation(OtherQuotes, 20) .RemoveWarmupPeriods(); // assertions @@ -119,15 +119,15 @@ public void Exceptions() { // bad lookback period Assert.ThrowsException(() => - Quotes.GetCorrelation(OtherQuotes, 0)); + Quotes.ToCorrelation(OtherQuotes, 0)); // bad eval quotes IEnumerable eval = Data.GetCompare(300); Assert.ThrowsException(() => - Quotes.GetCorrelation(eval, 30)); + Quotes.ToCorrelation(eval, 30)); // mismatched quotes Assert.ThrowsException(() => - MismatchQuotes.GetCorrelation(OtherQuotes, 20)); + MismatchQuotes.ToCorrelation(OtherQuotes, 20)); } } diff --git a/tests/indicators/a-d/Dema/Dema.StaticSeries.Tests.cs b/tests/indicators/a-d/Dema/Dema.StaticSeries.Tests.cs index 2ec06a281..b98a3b5f7 100644 --- a/tests/indicators/a-d/Dema/Dema.StaticSeries.Tests.cs +++ b/tests/indicators/a-d/Dema/Dema.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class Dema : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = Quotes - .GetDema(20); + .ToDema(20); // proper quantities Assert.AreEqual(502, results.Count); @@ -32,7 +32,7 @@ public void UseReusable() { IReadOnlyList results = Quotes .Use(CandlePart.Close) - .GetDema(20); + .ToDema(20); Assert.AreEqual(502, results.Count); Assert.AreEqual(483, results.Count(x => x.Dema != null)); @@ -43,7 +43,7 @@ public void Chainee() { IReadOnlyList results = Quotes .ToSma(2) - .GetDema(20); + .ToDema(20); Assert.AreEqual(502, results.Count); Assert.AreEqual(482, results.Count(x => x.Dema != null)); @@ -53,7 +53,7 @@ public void Chainee() public void Chainor() { IReadOnlyList results = Quotes - .GetDema(20) + .ToDema(20) .ToSma(10); Assert.AreEqual(502, results.Count); @@ -64,7 +64,7 @@ public void Chainor() public override void BadData() { IReadOnlyList r = BadQuotes - .GetDema(15); + .ToDema(15); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Dema is double.NaN)); @@ -74,12 +74,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetDema(5); + .ToDema(5); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetDema(5); + .ToDema(5); Assert.AreEqual(1, r1.Count); } @@ -88,7 +88,7 @@ public override void NoQuotes() public void Removed() { IReadOnlyList results = Quotes - .GetDema(20) + .ToDema(20) .RemoveWarmupPeriods(); // assertions @@ -102,5 +102,5 @@ public void Removed() [TestMethod] public void Exceptions() => Assert.ThrowsException(() - => Quotes.GetDema(0)); + => Quotes.ToDema(0)); } diff --git a/tests/indicators/a-d/Doji/Doji.StaticSeries.Tests.cs b/tests/indicators/a-d/Doji/Doji.StaticSeries.Tests.cs index 0bbd6614a..6b0622535 100644 --- a/tests/indicators/a-d/Doji/Doji.StaticSeries.Tests.cs +++ b/tests/indicators/a-d/Doji/Doji.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class Doji : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = Quotes - .GetDoji(); + .ToDoji(); // proper quantities Assert.AreEqual(502, results.Count); @@ -43,7 +43,7 @@ public override void Standard() public override void BadData() { IReadOnlyList r = BadQuotes - .GetDoji(); + .ToDoji(); Assert.AreEqual(502, r.Count); } @@ -52,12 +52,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetDoji(); + .ToDoji(); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetDoji(); + .ToDoji(); Assert.AreEqual(1, r1.Count); } @@ -66,7 +66,7 @@ public override void NoQuotes() public void Condense() { IReadOnlyList results = Quotes - .GetDoji() + .ToDoji() .Condense(); Assert.AreEqual(112, results.Count); @@ -77,9 +77,9 @@ public void Exceptions() { // bad maximum change value Assert.ThrowsException(() => - Quotes.GetDoji(-0.00001)); + Quotes.ToDoji(-0.00001)); Assert.ThrowsException(() => - Quotes.GetDoji(0.50001)); + Quotes.ToDoji(0.50001)); } } diff --git a/tests/indicators/a-d/Donchian/Donchian.StaticSeries.Tests.cs b/tests/indicators/a-d/Donchian/Donchian.StaticSeries.Tests.cs index 362476c98..c16cee7b4 100644 --- a/tests/indicators/a-d/Donchian/Donchian.StaticSeries.Tests.cs +++ b/tests/indicators/a-d/Donchian/Donchian.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class Donchian : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = Quotes - .GetDonchian(); + .ToDonchian(); // proper quantities Assert.AreEqual(502, results.Count); @@ -52,7 +52,7 @@ public override void Standard() public override void BadData() { IReadOnlyList r = BadQuotes - .GetDonchian(15); + .ToDonchian(15); Assert.AreEqual(502, r.Count); } @@ -61,12 +61,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetDonchian(); + .ToDonchian(); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetDonchian(); + .ToDonchian(); Assert.AreEqual(1, r1.Count); } @@ -75,7 +75,7 @@ public override void NoQuotes() public void Condense() { IReadOnlyList results = Quotes - .GetDonchian() + .ToDonchian() .Condense(); // assertions @@ -92,7 +92,7 @@ public void Condense() public void Removed() { IReadOnlyList results = Quotes - .GetDonchian() + .ToDonchian() .RemoveWarmupPeriods(); // assertions @@ -109,5 +109,5 @@ public void Removed() [TestMethod] public void Exceptions() => Assert.ThrowsException(() - => Quotes.GetDonchian(0)); + => Quotes.ToDonchian(0)); } diff --git a/tests/indicators/a-d/Dpo/Dpo.StaticSeries.Tests.cs b/tests/indicators/a-d/Dpo/Dpo.StaticSeries.Tests.cs index 5694b4f84..f6a3c71b3 100644 --- a/tests/indicators/a-d/Dpo/Dpo.StaticSeries.Tests.cs +++ b/tests/indicators/a-d/Dpo/Dpo.StaticSeries.Tests.cs @@ -24,7 +24,7 @@ public override void Standard() } // calculate actual data - IReadOnlyList act = qot.GetDpo(14); + IReadOnlyList act = qot.ToDpo(14); // assertions Assert.AreEqual(exp.Count, act.Count); @@ -46,7 +46,7 @@ public void UseReusable() { IReadOnlyList results = Quotes .Use(CandlePart.Close) - .GetDpo(14); + .ToDpo(14); Assert.AreEqual(502, results.Count); Assert.AreEqual(489, results.Count(x => x.Dpo != null)); @@ -57,7 +57,7 @@ public void Chainee() { IReadOnlyList results = Quotes .ToSma(2) - .GetDpo(14); + .ToDpo(14); Assert.AreEqual(502, results.Count); Assert.AreEqual(488, results.Count(x => x.Dpo != null)); @@ -67,7 +67,7 @@ public void Chainee() public void Chainor() { IReadOnlyList results = Quotes - .GetDpo(14) + .ToDpo(14) .ToSma(10); Assert.AreEqual(502, results.Count); @@ -78,7 +78,7 @@ public void Chainor() public override void BadData() { IReadOnlyList r = BadQuotes - .GetDpo(5); + .ToDpo(5); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Dpo is double.NaN)); @@ -88,12 +88,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetDpo(5); + .ToDpo(5); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetDpo(5); + .ToDpo(5); Assert.AreEqual(1, r1.Count); } @@ -102,5 +102,5 @@ public override void NoQuotes() [TestMethod] public void Exceptions() => Assert.ThrowsException(() - => Quotes.GetDpo(0)); + => Quotes.ToDpo(0)); } diff --git a/tests/indicators/a-d/Dynamic/Dynamic.StaticSeries.Tests.cs b/tests/indicators/a-d/Dynamic/Dynamic.StaticSeries.Tests.cs index 5baf359bf..6f2a47247 100644 --- a/tests/indicators/a-d/Dynamic/Dynamic.StaticSeries.Tests.cs +++ b/tests/indicators/a-d/Dynamic/Dynamic.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class McGinleyDynamic : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = Quotes - .GetDynamic(14); + .ToDynamic(14); // assertions Assert.AreEqual(502, results.Count); @@ -32,7 +32,7 @@ public void UseReusable() { IReadOnlyList results = Quotes .Use(CandlePart.Close) - .GetDynamic(20); + .ToDynamic(20); Assert.AreEqual(502, results.Count); Assert.AreEqual(501, results.Count(x => x.Dynamic != null)); @@ -44,7 +44,7 @@ public void Chainee() { IReadOnlyList results = Quotes .ToSma(10) - .GetDynamic(14); + .ToDynamic(14); Assert.AreEqual(502, results.Count); Assert.AreEqual(492, results.Count(x => x.Dynamic != null)); @@ -54,7 +54,7 @@ public void Chainee() public void Chainor() { IReadOnlyList results = Quotes - .GetDynamic(14) + .ToDynamic(14) .ToSma(10); Assert.AreEqual(502, results.Count); @@ -65,7 +65,7 @@ public void Chainor() public override void BadData() { IReadOnlyList r = BadQuotes - .GetDynamic(15); + .ToDynamic(15); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Dynamic is double.NaN)); @@ -75,12 +75,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetDynamic(14); + .ToDynamic(14); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetDynamic(14); + .ToDynamic(14); Assert.AreEqual(1, r1.Count); } @@ -90,10 +90,10 @@ public void Exceptions() { // bad lookback period Assert.ThrowsException(() - => Quotes.GetDynamic(0)); + => Quotes.ToDynamic(0)); // bad k-factor Assert.ThrowsException(() - => Quotes.GetDynamic(14, 0)); + => Quotes.ToDynamic(14, 0)); } } diff --git a/tests/indicators/e-k/ElderRay/ElderRay.StaticSeries.Tests.cs b/tests/indicators/e-k/ElderRay/ElderRay.StaticSeries.Tests.cs index 5f3d300eb..f857c4df9 100644 --- a/tests/indicators/e-k/ElderRay/ElderRay.StaticSeries.Tests.cs +++ b/tests/indicators/e-k/ElderRay/ElderRay.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class ElderRay : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = Quotes - .GetElderRay(); + .ToElderRay(); // proper quantities Assert.AreEqual(502, results.Count); @@ -50,7 +50,7 @@ public override void Standard() public void Chainor() { IReadOnlyList results = Quotes - .GetElderRay() + .ToElderRay() .ToSma(10); Assert.AreEqual(502, results.Count); @@ -61,7 +61,7 @@ public void Chainor() public override void BadData() { IReadOnlyList r = BadQuotes - .GetElderRay(); + .ToElderRay(); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.BullPower is double.NaN)); @@ -71,12 +71,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetElderRay(); + .ToElderRay(); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetElderRay(); + .ToElderRay(); Assert.AreEqual(1, r1.Count); } @@ -85,7 +85,7 @@ public override void NoQuotes() public void Removed() { IReadOnlyList results = Quotes - .GetElderRay() + .ToElderRay() .RemoveWarmupPeriods(); // assertions @@ -101,5 +101,5 @@ public void Removed() [TestMethod] public void Exceptions() => Assert.ThrowsException(() - => Quotes.GetElderRay(0)); + => Quotes.ToElderRay(0)); } diff --git a/tests/indicators/e-k/Ema/Ema.StaticSeries.Tests.cs b/tests/indicators/e-k/Ema/Ema.StaticSeries.Tests.cs index 71b1a5d69..39a670a7f 100644 --- a/tests/indicators/e-k/Ema/Ema.StaticSeries.Tests.cs +++ b/tests/indicators/e-k/Ema/Ema.StaticSeries.Tests.cs @@ -96,7 +96,7 @@ public void Chainor() public void ChaineeMore() { IReadOnlyList results = Quotes - .GetRsi() + .ToRsi() .ToEma(20); // assertions diff --git a/tests/indicators/e-k/Epma/Epma.StaticSeries.Tests.cs b/tests/indicators/e-k/Epma/Epma.StaticSeries.Tests.cs index d1d8fc1f0..6756a5159 100644 --- a/tests/indicators/e-k/Epma/Epma.StaticSeries.Tests.cs +++ b/tests/indicators/e-k/Epma/Epma.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class Epma : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = Quotes - .GetEpma(20); + .ToEpma(20); // proper quantities Assert.AreEqual(502, results.Count); @@ -35,7 +35,7 @@ public void UseReusable() { IReadOnlyList results = Quotes .Use(CandlePart.Close) - .GetEpma(20); + .ToEpma(20); Assert.AreEqual(502, results.Count); Assert.AreEqual(483, results.Count(x => x.Epma != null)); @@ -46,7 +46,7 @@ public void Chainee() { IReadOnlyList results = Quotes .ToSma(2) - .GetEpma(20); + .ToEpma(20); Assert.AreEqual(502, results.Count); Assert.AreEqual(482, results.Count(x => x.Epma != null)); @@ -56,7 +56,7 @@ public void Chainee() public void Chainor() { IReadOnlyList results = Quotes - .GetEpma(20) + .ToEpma(20) .ToSma(10); Assert.AreEqual(502, results.Count); @@ -67,7 +67,7 @@ public void Chainor() public override void BadData() { IReadOnlyList r = BadQuotes - .GetEpma(15); + .ToEpma(15); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Epma is double.NaN)); @@ -77,12 +77,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetEpma(5); + .ToEpma(5); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetEpma(5); + .ToEpma(5); Assert.AreEqual(1, r1.Count); } @@ -91,7 +91,7 @@ public override void NoQuotes() public void Removed() { IReadOnlyList results = Quotes - .GetEpma(20) + .ToEpma(20) .RemoveWarmupPeriods(); // assertions @@ -105,5 +105,5 @@ public void Removed() [TestMethod] public void Exceptions() => Assert.ThrowsException(() - => Quotes.GetEpma(0)); + => Quotes.ToEpma(0)); } diff --git a/tests/indicators/e-k/Fcb/Fcb.StaticSeries.Tests.cs b/tests/indicators/e-k/Fcb/Fcb.StaticSeries.Tests.cs index 09ca48d44..e0742cacd 100644 --- a/tests/indicators/e-k/Fcb/Fcb.StaticSeries.Tests.cs +++ b/tests/indicators/e-k/Fcb/Fcb.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class Fcb : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = Quotes - .GetFcb(); + .ToFcb(); // proper quantities Assert.AreEqual(502, results.Count); @@ -44,7 +44,7 @@ public override void Standard() public override void BadData() { IReadOnlyList r = BadQuotes - .GetFcb(); + .ToFcb(); Assert.AreEqual(502, r.Count); } @@ -53,12 +53,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetFcb(); + .ToFcb(); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetFcb(); + .ToFcb(); Assert.AreEqual(1, r1.Count); } @@ -67,7 +67,7 @@ public override void NoQuotes() public void Condense() { IReadOnlyList results = Quotes - .GetFcb() + .ToFcb() .Condense(); // assertions @@ -82,7 +82,7 @@ public void Condense() public void Removed() { IReadOnlyList results = Quotes - .GetFcb() + .ToFcb() .RemoveWarmupPeriods(); // assertions @@ -97,5 +97,5 @@ public void Removed() [TestMethod] public void Exceptions() => Assert.ThrowsException(() - => Quotes.GetFcb(1)); + => Quotes.ToFcb(1)); } diff --git a/tests/indicators/e-k/FisherTransform/FisherTransform.StaticSeries.Tests.cs b/tests/indicators/e-k/FisherTransform/FisherTransform.StaticSeries.Tests.cs index c0649936e..e826b2b5d 100644 --- a/tests/indicators/e-k/FisherTransform/FisherTransform.StaticSeries.Tests.cs +++ b/tests/indicators/e-k/FisherTransform/FisherTransform.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class FisherTransform : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = Quotes - .GetFisherTransform(); + .ToFisherTransform(); // proper quantities Assert.AreEqual(502, results.Count); @@ -50,7 +50,7 @@ public void UseReusable() { IReadOnlyList results = Quotes .Use(CandlePart.Close) - .GetFisherTransform(); + .ToFisherTransform(); Assert.AreEqual(502, results.Count); Assert.AreEqual(501, results.Count(x => x.Fisher != 0)); @@ -61,7 +61,7 @@ public void Chainee() { IReadOnlyList results = Quotes .ToSma(2) - .GetFisherTransform(); + .ToFisherTransform(); Assert.AreEqual(502, results.Count); Assert.AreEqual(501, results.Count(x => x.Fisher != 0)); @@ -71,7 +71,7 @@ public void Chainee() public void Chainor() { IReadOnlyList results = Quotes - .GetFisherTransform() + .ToFisherTransform() .ToSma(10); Assert.AreEqual(502, results.Count); @@ -82,7 +82,7 @@ public void Chainor() public override void BadData() { IReadOnlyList r = BadQuotes - .GetFisherTransform(9); + .ToFisherTransform(9); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Fisher is double.NaN)); @@ -92,12 +92,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetFisherTransform(); + .ToFisherTransform(); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetFisherTransform(); + .ToFisherTransform(); Assert.AreEqual(1, r1.Count); } @@ -106,5 +106,5 @@ public override void NoQuotes() [TestMethod] public void Exceptions() => Assert.ThrowsException(() - => Quotes.GetFisherTransform(0)); + => Quotes.ToFisherTransform(0)); } diff --git a/tests/indicators/e-k/ForceIndex/ForceIndex.StaticSeries.Tests.cs b/tests/indicators/e-k/ForceIndex/ForceIndex.StaticSeries.Tests.cs index a5d6d6e64..0e9d54eed 100644 --- a/tests/indicators/e-k/ForceIndex/ForceIndex.StaticSeries.Tests.cs +++ b/tests/indicators/e-k/ForceIndex/ForceIndex.StaticSeries.Tests.cs @@ -6,7 +6,7 @@ public class ForceIndex : StaticSeriesTestBase [TestMethod] public override void Standard() { - IReadOnlyList r = Quotes.GetForceIndex(13).ToList(); + IReadOnlyList r = Quotes.ToForceIndex(13).ToList(); // proper quantities Assert.AreEqual(502, r.Count); @@ -26,7 +26,7 @@ public override void Standard() public void Chainor() { IReadOnlyList results = Quotes - .GetForceIndex(13) + .ToForceIndex(13) .ToSma(10); Assert.AreEqual(502, results.Count); @@ -37,7 +37,7 @@ public void Chainor() public override void BadData() { IReadOnlyList r = BadQuotes - .GetForceIndex(); + .ToForceIndex(); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.ForceIndex is double.NaN)); @@ -47,12 +47,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetForceIndex(5); + .ToForceIndex(5); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetForceIndex(5); + .ToForceIndex(5); Assert.AreEqual(1, r1.Count); } @@ -61,7 +61,7 @@ public override void NoQuotes() public void Removed() { IReadOnlyList results = Quotes - .GetForceIndex(13) + .ToForceIndex(13) .RemoveWarmupPeriods(); // assertions @@ -75,5 +75,5 @@ public void Removed() [TestMethod] public void Exceptions() => Assert.ThrowsException(() - => Quotes.GetForceIndex(0)); + => Quotes.ToForceIndex(0)); } diff --git a/tests/indicators/e-k/Fractal/Fractal.StaticSeries.Tests.cs b/tests/indicators/e-k/Fractal/Fractal.StaticSeries.Tests.cs index 9f9dfc51c..20e7a52dc 100644 --- a/tests/indicators/e-k/Fractal/Fractal.StaticSeries.Tests.cs +++ b/tests/indicators/e-k/Fractal/Fractal.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class Fractal : StaticSeriesTestBase public override void Standard() // Span 2 { IReadOnlyList results = Quotes - .GetFractal(); + .ToFractal(); // proper quantities Assert.AreEqual(502, results.Count); @@ -81,7 +81,7 @@ public void StandardSpan4() public override void BadData() { IReadOnlyList r = BadQuotes - .GetFractal(); + .ToFractal(); Assert.AreEqual(502, r.Count); } @@ -90,12 +90,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetFractal(); + .ToFractal(); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetFractal(); + .ToFractal(); Assert.AreEqual(1, r1.Count); } @@ -104,7 +104,7 @@ public override void NoQuotes() public void Condense() { IReadOnlyList results = Quotes - .GetFractal() + .ToFractal() .Condense(); Assert.AreEqual(129, results.Count); @@ -114,5 +114,5 @@ public void Condense() [TestMethod] public void Exceptions() => Assert.ThrowsException(() - => Quotes.GetFractal(1)); + => Quotes.ToFractal(1)); } diff --git a/tests/indicators/e-k/Gator/Gator.StaticSeries.Tests.cs b/tests/indicators/e-k/Gator/Gator.StaticSeries.Tests.cs index fff0d1027..994f1026a 100644 --- a/tests/indicators/e-k/Gator/Gator.StaticSeries.Tests.cs +++ b/tests/indicators/e-k/Gator/Gator.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class Gator : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = Quotes - .GetGator(); + .ToGator(); // proper quantities Assert.AreEqual(502, results.Count); @@ -76,7 +76,7 @@ public override void Standard() public void FromAlligator() { IReadOnlyList results = Quotes - .GetAlligator() + .ToAlligator() .GetGator(); // proper quantities @@ -147,7 +147,7 @@ public void UseReusable() { IReadOnlyList results = Quotes .Use(CandlePart.Close) - .GetGator(); + .ToGator(); Assert.AreEqual(502, results.Count); Assert.AreEqual(482, results.Count(x => x.Upper != null)); @@ -158,7 +158,7 @@ public void Chainee() { IReadOnlyList results = Quotes .ToSma(2) - .GetGator(); + .ToGator(); Assert.AreEqual(502, results.Count); Assert.AreEqual(481, results.Count(x => x.Upper != null)); @@ -168,7 +168,7 @@ public void Chainee() public override void BadData() { IReadOnlyList r = BadQuotes - .GetGator(); + .ToGator(); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Upper is double.NaN)); @@ -178,12 +178,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetGator(); + .ToGator(); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetGator(); + .ToGator(); Assert.AreEqual(1, r1.Count); } @@ -192,7 +192,7 @@ public override void NoQuotes() public void Condense() { IReadOnlyList results = Quotes - .GetGator() + .ToGator() .Condense(); // assertions @@ -209,7 +209,7 @@ public void Condense() public void Removed() { IReadOnlyList results = Quotes - .GetGator() + .ToGator() .RemoveWarmupPeriods(); // assertions diff --git a/tests/indicators/e-k/HeikinAshi/HeikinAshi.StaticSeries.Tests.cs b/tests/indicators/e-k/HeikinAshi/HeikinAshi.StaticSeries.Tests.cs index 0c6e0e1e3..6d452026e 100644 --- a/tests/indicators/e-k/HeikinAshi/HeikinAshi.StaticSeries.Tests.cs +++ b/tests/indicators/e-k/HeikinAshi/HeikinAshi.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class HeikinAshi : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = Quotes - .GetHeikinAshi(); + .ToHeikinAshi(); // proper quantities Assert.AreEqual(502, results.Count); @@ -24,7 +24,7 @@ public override void Standard() [TestMethod] public void UseAsQuotes() { - IReadOnlyList haQuotes = Quotes.GetHeikinAshi(); + IReadOnlyList haQuotes = Quotes.ToHeikinAshi(); IReadOnlyList haSma = haQuotes.ToSma(5); Assert.AreEqual(498, haSma.Count(x => x.Sma != null)); } @@ -33,7 +33,7 @@ public void UseAsQuotes() public override void BadData() { IReadOnlyList r = BadQuotes - .GetHeikinAshi(); + .ToHeikinAshi(); Assert.AreEqual(502, r.Count); } @@ -42,12 +42,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetHeikinAshi(); + .ToHeikinAshi(); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetHeikinAshi(); + .ToHeikinAshi(); Assert.AreEqual(1, r1.Count); } diff --git a/tests/indicators/e-k/Hma/Hma.StaticSeries.Tests.cs b/tests/indicators/e-k/Hma/Hma.StaticSeries.Tests.cs index 6e196317c..a0bfafe45 100644 --- a/tests/indicators/e-k/Hma/Hma.StaticSeries.Tests.cs +++ b/tests/indicators/e-k/Hma/Hma.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class Hma : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = Quotes - .GetHma(20); + .ToHma(20); // proper quantities Assert.AreEqual(502, results.Count); @@ -26,7 +26,7 @@ public void UseReusable() { IReadOnlyList results = Quotes .Use(CandlePart.Close) - .GetHma(20); + .ToHma(20); Assert.AreEqual(502, results.Count); Assert.AreEqual(480, results.Count(x => x.Hma != null)); @@ -37,7 +37,7 @@ public void Chainee() { IReadOnlyList results = Quotes .ToSma(2) - .GetHma(19); + .ToHma(19); Assert.AreEqual(502, results.Count); Assert.AreEqual(480, results.Count(x => x.Hma != null)); @@ -47,7 +47,7 @@ public void Chainee() public void Chainor() { IReadOnlyList results = Quotes - .GetHma(20) + .ToHma(20) .ToSma(10); Assert.AreEqual(502, results.Count); @@ -58,7 +58,7 @@ public void Chainor() public override void BadData() { IReadOnlyList r = BadQuotes - .GetHma(15); + .ToHma(15); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Hma is double.NaN)); @@ -68,12 +68,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetHma(5); + .ToHma(5); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetHma(5); + .ToHma(5); Assert.AreEqual(1, r1.Count); } @@ -82,7 +82,7 @@ public override void NoQuotes() public void Removed() { IReadOnlyList results = Quotes - .GetHma(20) + .ToHma(20) .RemoveWarmupPeriods(); // assertions @@ -96,5 +96,5 @@ public void Removed() [TestMethod] public void Exceptions() => Assert.ThrowsException(() - => Quotes.GetHma(1)); + => Quotes.ToHma(1)); } diff --git a/tests/indicators/e-k/HtTrendline/HtTrendline.StaticSeries.Tests.cs b/tests/indicators/e-k/HtTrendline/HtTrendline.StaticSeries.Tests.cs index 0e0572559..d3ce7c5fd 100644 --- a/tests/indicators/e-k/HtTrendline/HtTrendline.StaticSeries.Tests.cs +++ b/tests/indicators/e-k/HtTrendline/HtTrendline.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class HtTrendline : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = Quotes - .GetHtTrendline(); + .ToHtTrendline(); // proper quantities // should always be the same number of results as there is quotes @@ -61,7 +61,7 @@ public void UseReusable() { IReadOnlyList results = Quotes .Use(CandlePart.Close) - .GetHtTrendline(); + .ToHtTrendline(); Assert.AreEqual(502, results.Count); Assert.AreEqual(502, results.Count(x => x.Trendline != null)); @@ -72,7 +72,7 @@ public void Chainee() { IReadOnlyList results = Quotes .ToSma(2) - .GetHtTrendline(); + .ToHtTrendline(); Assert.AreEqual(502, results.Count); Assert.AreEqual(501, results.Count(x => x.Trendline != null)); @@ -82,7 +82,7 @@ public void Chainee() public void Chainor() { IReadOnlyList results = Quotes - .GetHtTrendline() + .ToHtTrendline() .ToSma(10); Assert.AreEqual(502, results.Count); @@ -93,7 +93,7 @@ public void Chainor() public override void BadData() { IReadOnlyList r = BadQuotes - .GetHtTrendline(); + .ToHtTrendline(); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Trendline is double.NaN)); @@ -103,7 +103,7 @@ public override void BadData() public void Removed() { IReadOnlyList results = Quotes - .GetHtTrendline() + .ToHtTrendline() .RemoveWarmupPeriods(); // assertions @@ -120,7 +120,7 @@ public void PennyData() IEnumerable penny = Data.GetPenny(); IReadOnlyList r = penny - .GetHtTrendline(); + .ToHtTrendline(); Assert.AreEqual(533, r.Count); } @@ -129,12 +129,12 @@ public void PennyData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetHtTrendline(); + .ToHtTrendline(); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetHtTrendline(); + .ToHtTrendline(); Assert.AreEqual(1, r1.Count); } diff --git a/tests/indicators/e-k/Hurst/Hurst.StaticSeries.Tests.cs b/tests/indicators/e-k/Hurst/Hurst.StaticSeries.Tests.cs index e44dc3060..f596df5c5 100644 --- a/tests/indicators/e-k/Hurst/Hurst.StaticSeries.Tests.cs +++ b/tests/indicators/e-k/Hurst/Hurst.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class Hurst : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = LongestQuotes - .GetHurst(LongestQuotes.Count - 1); + .ToHurst(LongestQuotes.Count - 1); // assertions @@ -25,7 +25,7 @@ public void UseReusable() { IReadOnlyList results = Quotes .Use(CandlePart.Close) - .GetHurst(); + .ToHurst(); Assert.AreEqual(502, results.Count); Assert.AreEqual(402, results.Count(x => x.HurstExponent != null)); @@ -35,7 +35,7 @@ public void UseReusable() public void Chainor() { IReadOnlyList results = Quotes - .GetHurst() + .ToHurst() .ToSma(10); Assert.AreEqual(502, results.Count); @@ -47,7 +47,7 @@ public void Chainee() { IReadOnlyList results = Quotes .ToSma(10) - .GetHurst(); + .ToHurst(); Assert.AreEqual(502, results.Count); Assert.AreEqual(393, results.Count(x => x.HurstExponent != null)); @@ -57,7 +57,7 @@ public void Chainee() public override void BadData() { IReadOnlyList r = BadQuotes - .GetHurst(150); + .ToHurst(150); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.HurstExponent is double.NaN)); @@ -67,12 +67,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetHurst(); + .ToHurst(); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetHurst(); + .ToHurst(); Assert.AreEqual(1, r1.Count); } @@ -80,7 +80,7 @@ public override void NoQuotes() [TestMethod] public void Removed() { - IReadOnlyList results = LongestQuotes.GetHurst(LongestQuotes.Count - 1) + IReadOnlyList results = LongestQuotes.ToHurst(LongestQuotes.Count - 1) .RemoveWarmupPeriods(); // assertions @@ -94,5 +94,5 @@ public void Removed() [TestMethod] public void Exceptions() => Assert.ThrowsException(() - => Quotes.GetHurst(19)); + => Quotes.ToHurst(19)); } diff --git a/tests/indicators/e-k/Ichimoku/Ichimoku.StaticSeries.Tests.cs b/tests/indicators/e-k/Ichimoku/Ichimoku.StaticSeries.Tests.cs index 15b047ec1..fd077faa0 100644 --- a/tests/indicators/e-k/Ichimoku/Ichimoku.StaticSeries.Tests.cs +++ b/tests/indicators/e-k/Ichimoku/Ichimoku.StaticSeries.Tests.cs @@ -11,7 +11,7 @@ public override void Standard() int senkouBPeriods = 52; IReadOnlyList results = Quotes - .GetIchimoku(tenkanPeriods, kijunPeriods, senkouBPeriods); + .ToIchimoku(tenkanPeriods, kijunPeriods, senkouBPeriods); // proper quantities Assert.AreEqual(502, results.Count); @@ -64,7 +64,7 @@ public void Extended() public override void BadData() { IReadOnlyList r = BadQuotes - .GetIchimoku(); + .ToIchimoku(); Assert.AreEqual(502, r.Count); } @@ -73,12 +73,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetIchimoku(); + .ToIchimoku(); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetIchimoku(); + .ToIchimoku(); Assert.AreEqual(1, r1.Count); } @@ -87,7 +87,7 @@ public override void NoQuotes() public void Condense() { IReadOnlyList results = Quotes - .GetIchimoku() + .ToIchimoku() .Condense(); Assert.AreEqual(502, results.Count); @@ -98,15 +98,15 @@ public void Exceptions() { // bad signal period Assert.ThrowsException(() => - Quotes.GetIchimoku(0)); + Quotes.ToIchimoku(0)); // bad short span period Assert.ThrowsException(() => - Quotes.GetIchimoku(9, 0)); + Quotes.ToIchimoku(9, 0)); // bad long span period Assert.ThrowsException(() => - Quotes.GetIchimoku(9, 26, 26)); + Quotes.ToIchimoku(9, 26, 26)); // invalid offsets Assert.ThrowsException(() => diff --git a/tests/indicators/e-k/Kama/Kama.StaticSeries.Tests.cs b/tests/indicators/e-k/Kama/Kama.StaticSeries.Tests.cs index 82f5ba206..bbd19115c 100644 --- a/tests/indicators/e-k/Kama/Kama.StaticSeries.Tests.cs +++ b/tests/indicators/e-k/Kama/Kama.StaticSeries.Tests.cs @@ -11,7 +11,7 @@ public override void Standard() int slowPeriods = 30; IReadOnlyList results = Quotes - .GetKama(erPeriods, fastPeriods, slowPeriods); + .ToKama(erPeriods, fastPeriods, slowPeriods); // proper quantities Assert.AreEqual(502, results.Count); @@ -53,7 +53,7 @@ public void UseReusable() { IReadOnlyList results = Quotes .Use(CandlePart.Close) - .GetKama(); + .ToKama(); Assert.AreEqual(502, results.Count); Assert.AreEqual(493, results.Count(x => x.Kama != null)); @@ -64,7 +64,7 @@ public void Chainee() { IReadOnlyList results = Quotes .ToSma(2) - .GetKama(); + .ToKama(); Assert.AreEqual(502, results.Count); Assert.AreEqual(492, results.Count(x => x.Kama != null)); @@ -74,7 +74,7 @@ public void Chainee() public void Chainor() { IReadOnlyList results = Quotes - .GetKama() + .ToKama() .ToSma(10); Assert.AreEqual(502, results.Count); @@ -85,7 +85,7 @@ public void Chainor() public override void BadData() { IReadOnlyList r = BadQuotes - .GetKama(); + .ToKama(); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Kama is double.NaN)); @@ -95,12 +95,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetKama(); + .ToKama(); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetKama(); + .ToKama(); Assert.AreEqual(1, r1.Count); } @@ -113,7 +113,7 @@ public void Removed() int slowPeriods = 30; IReadOnlyList results = Quotes - .GetKama(erPeriods, fastPeriods, slowPeriods) + .ToKama(erPeriods, fastPeriods, slowPeriods) .RemoveWarmupPeriods(); // assertions @@ -129,14 +129,14 @@ public void Exceptions() { // bad ER period Assert.ThrowsException(() => - Quotes.GetKama(0)); + Quotes.ToKama(0)); // bad fast period Assert.ThrowsException(() => - Quotes.GetKama(10, 0)); + Quotes.ToKama(10, 0)); // bad slow period Assert.ThrowsException(() => - Quotes.GetKama(10, 5, 5)); + Quotes.ToKama(10, 5, 5)); } } diff --git a/tests/indicators/e-k/Keltner/Keltner.StaticSeries.Tests.cs b/tests/indicators/e-k/Keltner/Keltner.StaticSeries.Tests.cs index 2fd7625ce..ce3dc3c2f 100644 --- a/tests/indicators/e-k/Keltner/Keltner.StaticSeries.Tests.cs +++ b/tests/indicators/e-k/Keltner/Keltner.StaticSeries.Tests.cs @@ -11,7 +11,7 @@ public override void Standard() int atrPeriods = 10; IReadOnlyList results = Quotes - .GetKeltner(emaPeriods, multiplier, atrPeriods); + .ToKeltner(emaPeriods, multiplier, atrPeriods); // proper quantities Assert.AreEqual(502, results.Count); @@ -40,7 +40,7 @@ public override void Standard() public override void BadData() { IReadOnlyList r = BadQuotes - .GetKeltner(10, 3, 15); + .ToKeltner(10, 3, 15); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.UpperBand is double.NaN)); @@ -50,12 +50,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetKeltner(); + .ToKeltner(); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetKeltner(); + .ToKeltner(); Assert.AreEqual(1, r1.Count); } @@ -68,7 +68,7 @@ public void Condense() int atrPeriods = 10; IReadOnlyList results = Quotes - .GetKeltner(emaPeriods, multiplier, atrPeriods) + .ToKeltner(emaPeriods, multiplier, atrPeriods) .Condense(); // assertions @@ -90,7 +90,7 @@ public void Removed() int n = Math.Max(emaPeriods, atrPeriods); IReadOnlyList results = Quotes - .GetKeltner(emaPeriods, multiplier, atrPeriods) + .ToKeltner(emaPeriods, multiplier, atrPeriods) .RemoveWarmupPeriods(); // assertions @@ -108,14 +108,14 @@ public void Exceptions() { // bad EMA period Assert.ThrowsException(() => - Quotes.GetKeltner(1)); + Quotes.ToKeltner(1)); // bad ATR period Assert.ThrowsException(() => - Quotes.GetKeltner(20, 2, 1)); + Quotes.ToKeltner(20, 2, 1)); // bad multiplier Assert.ThrowsException(() => - Quotes.GetKeltner(20, 0)); + Quotes.ToKeltner(20, 0)); } } diff --git a/tests/indicators/e-k/Kvo/Kvo.StaticSeries.Tests.cs b/tests/indicators/e-k/Kvo/Kvo.StaticSeries.Tests.cs index d68cce515..34dccb79f 100644 --- a/tests/indicators/e-k/Kvo/Kvo.StaticSeries.Tests.cs +++ b/tests/indicators/e-k/Kvo/Kvo.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class Klinger : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = - Quotes.GetKvo(); + Quotes.ToKvo(); // proper quantities Assert.AreEqual(502, results.Count); @@ -48,7 +48,7 @@ public override void Standard() public void Chainor() { IReadOnlyList results = Quotes - .GetKvo() + .ToKvo() .ToSma(10); Assert.AreEqual(502, results.Count); @@ -59,7 +59,7 @@ public void Chainor() public override void BadData() { IReadOnlyList r = BadQuotes - .GetKvo(); + .ToKvo(); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Oscillator is double.NaN)); @@ -69,12 +69,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetKvo(); + .ToKvo(); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetKvo(); + .ToKvo(); Assert.AreEqual(1, r1.Count); } @@ -83,7 +83,7 @@ public override void NoQuotes() public void Removed() { IReadOnlyList results = Quotes - .GetKvo() + .ToKvo() .RemoveWarmupPeriods(); // assertions @@ -99,14 +99,14 @@ public void Exceptions() { // bad fast period Assert.ThrowsException(() => - Quotes.GetKvo(2)); + Quotes.ToKvo(2)); // bad slow period Assert.ThrowsException(() => - Quotes.GetKvo(20, 20)); + Quotes.ToKvo(20, 20)); // bad signal period Assert.ThrowsException(() => - Quotes.GetKvo(34, 55, 0)); + Quotes.ToKvo(34, 55, 0)); } } diff --git a/tests/indicators/m-r/MaEnvelopes/MaEnvelopes.StaticSeries.Tests.cs b/tests/indicators/m-r/MaEnvelopes/MaEnvelopes.StaticSeries.Tests.cs index 5a24b70f5..13aa3ddd7 100644 --- a/tests/indicators/m-r/MaEnvelopes/MaEnvelopes.StaticSeries.Tests.cs +++ b/tests/indicators/m-r/MaEnvelopes/MaEnvelopes.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class MaEnvelopes : StaticSeriesTestBase public override void Standard() // SMA { IReadOnlyList results = - Quotes.GetMaEnvelopes(20); + Quotes.ToMaEnvelopes(20); // proper quantities Assert.AreEqual(502, results.Count); @@ -34,7 +34,7 @@ public override void Standard() // SMA public void Alma() { IReadOnlyList results = - Quotes.GetMaEnvelopes(10, 2.5, MaType.ALMA); + Quotes.ToMaEnvelopes(10, 2.5, MaType.ALMA); // proper quantities Assert.AreEqual(502, results.Count); @@ -61,7 +61,7 @@ public void Alma() public void Dema() { IReadOnlyList results = - Quotes.GetMaEnvelopes(20, 2.5, MaType.DEMA); + Quotes.ToMaEnvelopes(20, 2.5, MaType.DEMA); // proper quantities Assert.AreEqual(502, results.Count); @@ -88,7 +88,7 @@ public void Dema() public void Epma() { IReadOnlyList results = - Quotes.GetMaEnvelopes(20, 2.5, MaType.EPMA); + Quotes.ToMaEnvelopes(20, 2.5, MaType.EPMA); // proper quantities Assert.AreEqual(502, results.Count); @@ -115,7 +115,7 @@ public void Epma() public void Ema() { IReadOnlyList results = - Quotes.GetMaEnvelopes(20, 2.5, MaType.EMA); + Quotes.ToMaEnvelopes(20, 2.5, MaType.EMA); // proper quantities Assert.AreEqual(502, results.Count); @@ -142,7 +142,7 @@ public void Ema() public void Hma() { IReadOnlyList results = - Quotes.GetMaEnvelopes(20, 2.5, MaType.HMA); + Quotes.ToMaEnvelopes(20, 2.5, MaType.HMA); // proper quantities Assert.AreEqual(502, results.Count); @@ -164,7 +164,7 @@ public void Hma() public void Smma() { IReadOnlyList results = - Quotes.GetMaEnvelopes(20, 2.5, MaType.SMMA); + Quotes.ToMaEnvelopes(20, 2.5, MaType.SMMA); // proper quantities Assert.AreEqual(502, results.Count); @@ -191,7 +191,7 @@ public void Smma() public void Tema() { IReadOnlyList results = - Quotes.GetMaEnvelopes(20, 2.5, MaType.TEMA); + Quotes.ToMaEnvelopes(20, 2.5, MaType.TEMA); // proper quantities Assert.AreEqual(502, results.Count); @@ -218,7 +218,7 @@ public void Tema() public void Wma() { IReadOnlyList results = - Quotes.GetMaEnvelopes(20, 2.5, MaType.WMA); + Quotes.ToMaEnvelopes(20, 2.5, MaType.WMA); // proper quantities Assert.AreEqual(502, results.Count); @@ -241,7 +241,7 @@ public void UseReusable() { IReadOnlyList results = Quotes .Use(CandlePart.Close) - .GetMaEnvelopes(10); + .ToMaEnvelopes(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(493, results.Count(x => x.Centerline != null)); @@ -252,7 +252,7 @@ public void Chainee() { IReadOnlyList results = Quotes .ToSma(2) - .GetMaEnvelopes(10); + .ToMaEnvelopes(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(492, results.Count(x => x.Centerline != null)); @@ -262,42 +262,42 @@ public void Chainee() public override void BadData() { IReadOnlyList a = BadQuotes - .GetMaEnvelopes(5, 2.5, MaType.ALMA); + .ToMaEnvelopes(5, 2.5, MaType.ALMA); Assert.AreEqual(502, a.Count); IReadOnlyList d = BadQuotes - .GetMaEnvelopes(5, 2.5, MaType.DEMA); + .ToMaEnvelopes(5, 2.5, MaType.DEMA); Assert.AreEqual(502, d.Count); IReadOnlyList p = BadQuotes - .GetMaEnvelopes(5, 2.5, MaType.EPMA); + .ToMaEnvelopes(5, 2.5, MaType.EPMA); Assert.AreEqual(502, p.Count); IReadOnlyList e = BadQuotes - .GetMaEnvelopes(5, 2.5, MaType.EMA); + .ToMaEnvelopes(5, 2.5, MaType.EMA); Assert.AreEqual(502, e.Count); IReadOnlyList h = BadQuotes - .GetMaEnvelopes(5, 2.5, MaType.HMA); + .ToMaEnvelopes(5, 2.5, MaType.HMA); Assert.AreEqual(502, h.Count); IReadOnlyList s = BadQuotes - .GetMaEnvelopes(5); + .ToMaEnvelopes(5); Assert.AreEqual(502, s.Count); IReadOnlyList t = BadQuotes - .GetMaEnvelopes(5, 2.5, MaType.TEMA); + .ToMaEnvelopes(5, 2.5, MaType.TEMA); Assert.AreEqual(502, t.Count); IReadOnlyList w = BadQuotes - .GetMaEnvelopes(5, 2.5, MaType.WMA); + .ToMaEnvelopes(5, 2.5, MaType.WMA); Assert.AreEqual(502, w.Count); } @@ -306,12 +306,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetMaEnvelopes(10); + .ToMaEnvelopes(10); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetMaEnvelopes(10); + .ToMaEnvelopes(10); Assert.AreEqual(1, r1.Count); } @@ -320,7 +320,7 @@ public override void NoQuotes() public void Condense() { IReadOnlyList results = Quotes - .GetMaEnvelopes(20) + .ToMaEnvelopes(20) .Condense(); Assert.AreEqual(483, results.Count); @@ -331,11 +331,11 @@ public void Exceptions() { // bad offset period Assert.ThrowsException(() => - Quotes.GetMaEnvelopes(14, 0)); + Quotes.ToMaEnvelopes(14, 0)); // bad MA period Assert.ThrowsException(() => - Quotes.GetMaEnvelopes(14, 5, MaType.KAMA)); + Quotes.ToMaEnvelopes(14, 5, MaType.KAMA)); // note: insufficient quotes is tested elsewhere } diff --git a/tests/indicators/m-r/Macd/Macd.StaticSeries.Tests.cs b/tests/indicators/m-r/Macd/Macd.StaticSeries.Tests.cs index dbceb87eb..63f78539e 100644 --- a/tests/indicators/m-r/Macd/Macd.StaticSeries.Tests.cs +++ b/tests/indicators/m-r/Macd/Macd.StaticSeries.Tests.cs @@ -11,7 +11,7 @@ public override void Standard() int signalPeriods = 9; IReadOnlyList results = - Quotes.GetMacd(fastPeriods, slowPeriods, signalPeriods); + Quotes.ToMacd(fastPeriods, slowPeriods, signalPeriods); // proper quantities Assert.AreEqual(502, results.Count); @@ -47,7 +47,7 @@ public void UseReusable() { IReadOnlyList results = Quotes .Use(CandlePart.Close) - .GetMacd(); + .ToMacd(); Assert.AreEqual(502, results.Count); Assert.AreEqual(477, results.Count(x => x.Macd != null)); @@ -58,7 +58,7 @@ public void Chainee() { IReadOnlyList results = Quotes .ToSma(2) - .GetMacd(); + .ToMacd(); Assert.AreEqual(502, results.Count); Assert.AreEqual(476, results.Count(x => x.Macd != null)); @@ -68,7 +68,7 @@ public void Chainee() public void Chainor() { IReadOnlyList results = Quotes - .GetMacd() + .ToMacd() .ToSma(10); Assert.AreEqual(502, results.Count); @@ -79,7 +79,7 @@ public void Chainor() public override void BadData() { IReadOnlyList r = BadQuotes - .GetMacd(10, 20, 5); + .ToMacd(10, 20, 5); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Macd is double.NaN)); @@ -89,12 +89,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetMacd(); + .ToMacd(); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetMacd(); + .ToMacd(); Assert.AreEqual(1, r1.Count); } @@ -107,7 +107,7 @@ public void Removed() int signalPeriods = 9; IReadOnlyList results = Quotes - .GetMacd(fastPeriods, slowPeriods, signalPeriods) + .ToMacd(fastPeriods, slowPeriods, signalPeriods) .RemoveWarmupPeriods(); // assertions @@ -124,14 +124,14 @@ public void Exceptions() { // bad fast period Assert.ThrowsException(() => - Quotes.GetMacd(0)); + Quotes.ToMacd(0)); // bad slow periods must be larger than faster period Assert.ThrowsException(() => - Quotes.GetMacd(12, 12)); + Quotes.ToMacd(12, 12)); // bad signal period Assert.ThrowsException(() => - Quotes.GetMacd(12, 26, -1)); + Quotes.ToMacd(12, 26, -1)); } } diff --git a/tests/indicators/m-r/Mama/Mama.StaticSeries.Tests.cs b/tests/indicators/m-r/Mama/Mama.StaticSeries.Tests.cs index 747029e66..bdb748645 100644 --- a/tests/indicators/m-r/Mama/Mama.StaticSeries.Tests.cs +++ b/tests/indicators/m-r/Mama/Mama.StaticSeries.Tests.cs @@ -10,7 +10,7 @@ public override void Standard() double slowLimit = 0.05; IReadOnlyList results = Quotes - .GetMama(fastLimit, slowLimit); + .ToMama(fastLimit, slowLimit); // proper quantities Assert.AreEqual(502, results.Count); @@ -51,7 +51,7 @@ public void UseReusable() { IReadOnlyList results = Quotes .Use(CandlePart.Close) - .GetMama(); + .ToMama(); Assert.AreEqual(502, results.Count); Assert.AreEqual(497, results.Count(x => x.Mama != null)); @@ -62,7 +62,7 @@ public void Chainee() { IReadOnlyList results = Quotes .ToSma(2) - .GetMama(); + .ToMama(); Assert.AreEqual(502, results.Count); Assert.AreEqual(496, results.Count(x => x.Mama != null)); @@ -72,7 +72,7 @@ public void Chainee() public void Chainor() { IReadOnlyList results = Quotes - .GetMama() + .ToMama() .ToSma(10); Assert.AreEqual(502, results.Count); @@ -83,7 +83,7 @@ public void Chainor() public override void BadData() { IReadOnlyList r = BadQuotes - .GetMama(); + .ToMama(); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Mama is double.NaN)); @@ -92,11 +92,11 @@ public override void BadData() [TestMethod] public override void NoQuotes() { - IReadOnlyList r0 = Noquotes.GetMama(); + IReadOnlyList r0 = Noquotes.ToMama(); Assert.AreEqual(0, r0.Count); - IReadOnlyList r1 = Onequote.GetMama(); + IReadOnlyList r1 = Onequote.ToMama(); Assert.AreEqual(1, r1.Count); } @@ -108,7 +108,7 @@ public void Removed() double slowLimit = 0.05; IReadOnlyList results = Quotes - .GetMama(fastLimit, slowLimit) + .ToMama(fastLimit, slowLimit) .RemoveWarmupPeriods(); // assertions @@ -124,14 +124,14 @@ public void Exceptions() { // bad fast period (same as slow period) Assert.ThrowsException(() => - Quotes.GetMama(0.5, 0.5)); + Quotes.ToMama(0.5, 0.5)); // bad fast period (cannot be 1 or more) Assert.ThrowsException(() => - Quotes.GetMama(1, 0.5)); + Quotes.ToMama(1, 0.5)); // bad slow period Assert.ThrowsException(() => - Quotes.GetMama(0.5, 0)); + Quotes.ToMama(0.5, 0)); } } diff --git a/tests/indicators/m-r/Marubozu/Marubozu.StaticSeries.Tests.cs b/tests/indicators/m-r/Marubozu/Marubozu.StaticSeries.Tests.cs index 98e858f49..66ba37050 100644 --- a/tests/indicators/m-r/Marubozu/Marubozu.StaticSeries.Tests.cs +++ b/tests/indicators/m-r/Marubozu/Marubozu.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class Marubozu : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = Quotes - .GetMarubozu(); + .ToMarubozu(); // proper quantities Assert.AreEqual(502, results.Count); @@ -43,7 +43,7 @@ public override void Standard() public override void BadData() { IReadOnlyList r = BadQuotes - .GetMarubozu(); + .ToMarubozu(); Assert.AreEqual(502, r.Count); } @@ -52,12 +52,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetMarubozu(); + .ToMarubozu(); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetMarubozu(); + .ToMarubozu(); Assert.AreEqual(1, r1.Count); } @@ -66,7 +66,7 @@ public override void NoQuotes() public void Condense() { IReadOnlyList results = Quotes - .GetMarubozu() + .ToMarubozu() .Condense(); Assert.AreEqual(6, results.Count); @@ -77,9 +77,9 @@ public void Exceptions() { // bad minimum body percent values Assert.ThrowsException(() => - Quotes.GetMarubozu(79.9)); + Quotes.ToMarubozu(79.9)); Assert.ThrowsException(() => - Quotes.GetMarubozu(100.1)); + Quotes.ToMarubozu(100.1)); } } diff --git a/tests/indicators/m-r/Mfi/Mfi.StaticSeries.Tests.cs b/tests/indicators/m-r/Mfi/Mfi.StaticSeries.Tests.cs index f79332ed8..bd5be8d19 100644 --- a/tests/indicators/m-r/Mfi/Mfi.StaticSeries.Tests.cs +++ b/tests/indicators/m-r/Mfi/Mfi.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class Mfi : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = Quotes - .GetMfi(); + .ToMfi(); // proper quantities Assert.AreEqual(502, results.Count); @@ -25,7 +25,7 @@ public override void Standard() public void Chainor() { IReadOnlyList results = Quotes - .GetMfi() + .ToMfi() .ToSma(10); Assert.AreEqual(502, results.Count); @@ -38,7 +38,7 @@ public void SmallLookback() int lookbackPeriods = 4; IReadOnlyList results = Quotes - .GetMfi(lookbackPeriods); + .ToMfi(lookbackPeriods); // proper quantities Assert.AreEqual(502, results.Count); @@ -56,7 +56,7 @@ public void SmallLookback() public override void BadData() { IReadOnlyList r = BadQuotes - .GetMfi(15); + .ToMfi(15); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Mfi is double.NaN)); @@ -66,12 +66,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetMfi(); + .ToMfi(); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetMfi(); + .ToMfi(); Assert.AreEqual(1, r1.Count); } @@ -82,7 +82,7 @@ public void Removed() int lookbackPeriods = 14; IReadOnlyList results = Quotes - .GetMfi(lookbackPeriods) + .ToMfi(lookbackPeriods) .RemoveWarmupPeriods(); // assertions @@ -96,5 +96,5 @@ public void Removed() [TestMethod] public void Exceptions() => Assert.ThrowsException(() - => Quotes.GetMfi(1)); + => Quotes.ToMfi(1)); } diff --git a/tests/indicators/m-r/Obv/Obv.StaticSeries.Tests.cs b/tests/indicators/m-r/Obv/Obv.StaticSeries.Tests.cs index ae62e85c4..a0127f678 100644 --- a/tests/indicators/m-r/Obv/Obv.StaticSeries.Tests.cs +++ b/tests/indicators/m-r/Obv/Obv.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class Obv : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = Quotes - .GetObv(); + .ToObv(); // proper quantities Assert.AreEqual(502, results.Count); @@ -24,7 +24,7 @@ public override void Standard() public void Chainor() { IReadOnlyList results = Quotes - .GetObv() + .ToObv() .ToSma(10); Assert.AreEqual(502, results.Count); @@ -35,7 +35,7 @@ public void Chainor() public override void BadData() { IReadOnlyList r = BadQuotes - .GetObv(); + .ToObv(); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => double.IsNaN(x.Obv))); @@ -45,7 +45,7 @@ public override void BadData() public void BigData() { IReadOnlyList r = BigQuotes - .GetObv(); + .ToObv(); Assert.AreEqual(1246, r.Count); } @@ -54,12 +54,12 @@ public void BigData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetObv(); + .ToObv(); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetObv(); + .ToObv(); Assert.AreEqual(1, r1.Count); } diff --git a/tests/indicators/m-r/ParabolicSar/ParabolicSar.StaticSeries.Tests.cs b/tests/indicators/m-r/ParabolicSar/ParabolicSar.StaticSeries.Tests.cs index a5510c360..bdadbe5a1 100644 --- a/tests/indicators/m-r/ParabolicSar/ParabolicSar.StaticSeries.Tests.cs +++ b/tests/indicators/m-r/ParabolicSar/ParabolicSar.StaticSeries.Tests.cs @@ -10,7 +10,7 @@ public override void Standard() double maxAccelerationFactor = 0.2; IReadOnlyList results = - Quotes.GetParabolicSar(acclerationStep, maxAccelerationFactor) + Quotes.ToParabolicSar(acclerationStep, maxAccelerationFactor) .ToList(); // proper quantities @@ -77,7 +77,7 @@ public void Extended() public void Chainor() { IReadOnlyList results = Quotes - .GetParabolicSar() + .ToParabolicSar() .ToSma(10); Assert.AreEqual(502, results.Count); @@ -95,7 +95,7 @@ public void InsufficientQuotes() .Take(10); IReadOnlyList results = - insufficientQuotes.GetParabolicSar(acclerationStep, maxAccelerationFactor) + insufficientQuotes.ToParabolicSar(acclerationStep, maxAccelerationFactor) .ToList(); // assertions @@ -119,12 +119,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetParabolicSar(); + .ToParabolicSar(); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetParabolicSar(); + .ToParabolicSar(); Assert.AreEqual(1, r1.Count); } @@ -136,7 +136,7 @@ public void Removed() double maxAccelerationFactor = 0.2; IReadOnlyList results = Quotes - .GetParabolicSar(acclerationStep, maxAccelerationFactor) + .ToParabolicSar(acclerationStep, maxAccelerationFactor) .RemoveWarmupPeriods(); // assertions @@ -152,15 +152,15 @@ public void Exceptions() { // bad acceleration step Assert.ThrowsException(() => - Quotes.GetParabolicSar(0, 1)); + Quotes.ToParabolicSar(0, 1)); // insufficient acceleration step Assert.ThrowsException(() => - Quotes.GetParabolicSar(0.02, 0)); + Quotes.ToParabolicSar(0.02, 0)); // step larger than factor Assert.ThrowsException(() => - Quotes.GetParabolicSar(6, 2)); + Quotes.ToParabolicSar(6, 2)); // insufficient initial factor Assert.ThrowsException(() => diff --git a/tests/indicators/m-r/PivotPoints/PivotPoints.StaticSeries.Tests.cs b/tests/indicators/m-r/PivotPoints/PivotPoints.StaticSeries.Tests.cs index 7277120fa..26fd5e7e6 100644 --- a/tests/indicators/m-r/PivotPoints/PivotPoints.StaticSeries.Tests.cs +++ b/tests/indicators/m-r/PivotPoints/PivotPoints.StaticSeries.Tests.cs @@ -10,7 +10,7 @@ public override void Standard() PivotPointType pointType = PivotPointType.Standard; IReadOnlyList results = Quotes - .GetPivotPoints(periodSize, pointType); + .ToPivotPoints(periodSize, pointType); // proper quantities Assert.AreEqual(502, results.Count); @@ -91,7 +91,7 @@ public void Camarilla() PivotPointType pointType = PivotPointType.Camarilla; IEnumerable h = Data.GetDefault(38); - IReadOnlyList results = h.GetPivotPoints(periodSize, pointType); + IReadOnlyList results = h.ToPivotPoints(periodSize, pointType); // proper quantities Assert.AreEqual(38, results.Count); @@ -161,7 +161,7 @@ public void Demark() PivotPointType pointType = PivotPointType.Demark; IReadOnlyList results = Quotes - .GetPivotPoints(periodSize, pointType); + .ToPivotPoints(periodSize, pointType); // proper quantities Assert.AreEqual(502, results.Count); @@ -246,7 +246,7 @@ public void Fibonacci() PivotPointType pointType = PivotPointType.Fibonacci; IEnumerable h = Data.GetIntraday(300); - IReadOnlyList results = h.GetPivotPoints(periodSize, pointType); + IReadOnlyList results = h.ToPivotPoints(periodSize, pointType); // proper quantities Assert.AreEqual(300, results.Count); @@ -317,7 +317,7 @@ public void Woodie() PivotPointType pointType = PivotPointType.Woodie; IEnumerable h = Data.GetIntraday(); - IReadOnlyList results = h.GetPivotPoints(periodSize, pointType); + IReadOnlyList results = h.ToPivotPoints(periodSize, pointType); // proper quantities Assert.AreEqual(1564, results.Count); @@ -376,7 +376,7 @@ public void Woodie() public override void BadData() { IReadOnlyList r = BadQuotes - .GetPivotPoints(PeriodSize.Week); + .ToPivotPoints(PeriodSize.Week); Assert.AreEqual(502, r.Count); } @@ -385,12 +385,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetPivotPoints(PeriodSize.Week); + .ToPivotPoints(PeriodSize.Week); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetPivotPoints(PeriodSize.Week); + .ToPivotPoints(PeriodSize.Week); Assert.AreEqual(1, r1.Count); } @@ -402,7 +402,7 @@ public void Removed() PivotPointType pointType = PivotPointType.Standard; IReadOnlyList results = Quotes - .GetPivotPoints(periodSize, pointType) + .ToPivotPoints(periodSize, pointType) .RemoveWarmupPeriods(); // assertions @@ -426,11 +426,11 @@ public void Exceptions() // bad pointtype size Assert.ThrowsException(() => Quotes - .GetPivotPoints(PeriodSize.Week, (PivotPointType)999)); + .ToPivotPoints(PeriodSize.Week, (PivotPointType)999)); // bad window size Assert.ThrowsException(() => Quotes - .GetPivotPoints(PeriodSize.ThreeMinutes)); + .ToPivotPoints(PeriodSize.ThreeMinutes)); } } diff --git a/tests/indicators/m-r/Pivots/Pivots.StaticSeries.Tests.cs b/tests/indicators/m-r/Pivots/Pivots.StaticSeries.Tests.cs index c3cb6298f..ef3c9385f 100644 --- a/tests/indicators/m-r/Pivots/Pivots.StaticSeries.Tests.cs +++ b/tests/indicators/m-r/Pivots/Pivots.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class Pivots : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = Quotes - .GetPivots(4, 4); + .ToPivots(4, 4); // proper quantities Assert.AreEqual(502, results.Count); @@ -88,7 +88,7 @@ public override void Standard() public override void BadData() { IReadOnlyList r = BadQuotes - .GetPivots(); + .ToPivots(); Assert.AreEqual(502, r.Count); } @@ -97,12 +97,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetPivots(); + .ToPivots(); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetPivots(); + .ToPivots(); Assert.AreEqual(1, r1.Count); } @@ -111,7 +111,7 @@ public override void NoQuotes() public void Condense() { IReadOnlyList results = Quotes - .GetPivots(4, 4) + .ToPivots(4, 4) .Condense(); Assert.AreEqual(67, results.Count); @@ -122,14 +122,14 @@ public void Exceptions() { // bad left span Assert.ThrowsException(() => - Quotes.GetPivots(1)); + Quotes.ToPivots(1)); // bad right span Assert.ThrowsException(() => - Quotes.GetPivots(2, 1)); + Quotes.ToPivots(2, 1)); // bad lookback window Assert.ThrowsException(() => - Quotes.GetPivots(20, 10, 20, EndType.Close)); + Quotes.ToPivots(20, 10, 20, EndType.Close)); } } diff --git a/tests/indicators/m-r/Pmo/Pmo.StaticSeries.Tests.cs b/tests/indicators/m-r/Pmo/Pmo.StaticSeries.Tests.cs index 0f1d971ac..97f15b910 100644 --- a/tests/indicators/m-r/Pmo/Pmo.StaticSeries.Tests.cs +++ b/tests/indicators/m-r/Pmo/Pmo.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class Pmo : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = Quotes - .GetPmo(); + .ToPmo(); // proper quantities Assert.AreEqual(502, results.Count); @@ -29,7 +29,7 @@ public void UseReusable() { IReadOnlyList results = Quotes .Use(CandlePart.Close) - .GetPmo(); + .ToPmo(); Assert.AreEqual(502, results.Count); Assert.AreEqual(448, results.Count(x => x.Pmo != null)); @@ -40,7 +40,7 @@ public void Chainee() { IReadOnlyList results = Quotes .ToSma(2) - .GetPmo(); + .ToPmo(); Assert.AreEqual(502, results.Count); Assert.AreEqual(447, results.Count(x => x.Pmo != null)); @@ -50,7 +50,7 @@ public void Chainee() public void Chainor() { IReadOnlyList results = Quotes - .GetPmo() + .ToPmo() .ToSma(10); Assert.AreEqual(502, results.Count); @@ -61,7 +61,7 @@ public void Chainor() public override void BadData() { IReadOnlyList r = BadQuotes - .GetPmo(25, 15, 5); + .ToPmo(25, 15, 5); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Pmo is double.NaN)); @@ -71,12 +71,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetPmo(); + .ToPmo(); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetPmo(); + .ToPmo(); Assert.AreEqual(1, r1.Count); } @@ -85,7 +85,7 @@ public override void NoQuotes() public void Removed() { IReadOnlyList results = Quotes - .GetPmo() + .ToPmo() .RemoveWarmupPeriods(); // assertions @@ -101,14 +101,14 @@ public void Exceptions() { // bad time period Assert.ThrowsException(() => - Quotes.GetPmo(1)); + Quotes.ToPmo(1)); // bad smoothing period Assert.ThrowsException(() => - Quotes.GetPmo(5, 0)); + Quotes.ToPmo(5, 0)); // bad signal period Assert.ThrowsException(() => - Quotes.GetPmo(5, 5, 0)); + Quotes.ToPmo(5, 5, 0)); } } diff --git a/tests/indicators/m-r/Prs/Prs.StaticSeries.Tests.cs b/tests/indicators/m-r/Prs/Prs.StaticSeries.Tests.cs index 14a6b43ad..debcc99da 100644 --- a/tests/indicators/m-r/Prs/Prs.StaticSeries.Tests.cs +++ b/tests/indicators/m-r/Prs/Prs.StaticSeries.Tests.cs @@ -9,7 +9,7 @@ public override void Standard() int lookbackPeriods = 30; IReadOnlyList results = OtherQuotes - .GetPrs(Quotes, lookbackPeriods); + .ToPrs(Quotes, lookbackPeriods); // proper quantities Assert.AreEqual(502, results.Count); @@ -34,7 +34,7 @@ public void UseReusable() { IReadOnlyList results = OtherQuotes .Use(CandlePart.Close) - .GetPrs(Quotes.Use(CandlePart.Close), 20); + .ToPrs(Quotes.Use(CandlePart.Close), 20); Assert.AreEqual(502, results.Count); Assert.AreEqual(502, results.Count(x => x.Prs != null)); @@ -44,7 +44,7 @@ public void UseReusable() public void Chainor() { IReadOnlyList results = OtherQuotes - .GetPrs(Quotes, 20) + .ToPrs(Quotes, 20) .ToSma(10); Assert.AreEqual(502, results.Count); @@ -56,7 +56,7 @@ public void Chainee() { IReadOnlyList results = Quotes .ToSma(2) - .GetPrs(OtherQuotes.ToSma(2), 20); + .ToPrs(OtherQuotes.ToSma(2), 20); Assert.AreEqual(502, results.Count); Assert.AreEqual(501, results.Count(x => x.Prs != null)); @@ -67,7 +67,7 @@ public void Chainee() public override void BadData() { IReadOnlyList r = BadQuotes - .GetPrs(BadQuotes, 15); + .ToPrs(BadQuotes, 15); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Prs is double.NaN)); @@ -77,12 +77,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetPrs(Noquotes); + .ToPrs(Noquotes); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetPrs(Onequote); + .ToPrs(Onequote); Assert.AreEqual(1, r1.Count); } @@ -92,18 +92,18 @@ public void Exceptions() { // bad lookback period Assert.ThrowsException(() => - OtherQuotes.GetPrs(Quotes, 0)); + OtherQuotes.ToPrs(Quotes, 0)); // insufficient quotes Assert.ThrowsException(() => - Data.GetCompare(13).GetPrs(Quotes, 14)); + Data.GetCompare(13).ToPrs(Quotes, 14)); // insufficient eval quotes Assert.ThrowsException(() => - Data.GetCompare(300).GetPrs(Quotes, 14)); + Data.GetCompare(300).ToPrs(Quotes, 14)); // mismatch quotes Assert.ThrowsException(() => - OtherQuotes.GetPrs(MismatchQuotes, 14)); + OtherQuotes.ToPrs(MismatchQuotes, 14)); } } diff --git a/tests/indicators/m-r/Pvo/Pvo.StaticSeries.Tests.cs b/tests/indicators/m-r/Pvo/Pvo.StaticSeries.Tests.cs index 866c40d04..6b5e8123d 100644 --- a/tests/indicators/m-r/Pvo/Pvo.StaticSeries.Tests.cs +++ b/tests/indicators/m-r/Pvo/Pvo.StaticSeries.Tests.cs @@ -11,7 +11,7 @@ public override void Standard() int signalPeriods = 9; IReadOnlyList results = - Quotes.GetPvo(fastPeriods, slowPeriods, signalPeriods); + Quotes.ToPvo(fastPeriods, slowPeriods, signalPeriods); // proper quantities Assert.AreEqual(502, results.Count); @@ -50,7 +50,7 @@ public override void Standard() public void Chainor() { IReadOnlyList results = Quotes - .GetPvo() + .ToPvo() .ToSma(10); Assert.AreEqual(502, results.Count); @@ -61,7 +61,7 @@ public void Chainor() public override void BadData() { IReadOnlyList r = BadQuotes - .GetPvo(10, 20, 5); + .ToPvo(10, 20, 5); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Pvo is double.NaN)); @@ -71,12 +71,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetPvo(); + .ToPvo(); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetPvo(); + .ToPvo(); Assert.AreEqual(1, r1.Count); } @@ -89,7 +89,7 @@ public void Removed() int signalPeriods = 9; IReadOnlyList results = Quotes - .GetPvo(fastPeriods, slowPeriods, signalPeriods) + .ToPvo(fastPeriods, slowPeriods, signalPeriods) .RemoveWarmupPeriods(); // assertions @@ -106,14 +106,14 @@ public void Exceptions() { // bad fast period Assert.ThrowsException(() => - Quotes.GetPvo(0)); + Quotes.ToPvo(0)); // bad slow periods must be larger than faster period Assert.ThrowsException(() => - Quotes.GetPvo(12, 12)); + Quotes.ToPvo(12, 12)); // bad signal period Assert.ThrowsException(() => - Quotes.GetPvo(12, 26, -1)); + Quotes.ToPvo(12, 26, -1)); } } diff --git a/tests/indicators/m-r/Renko/Renko.StaticSeries.Tests.cs b/tests/indicators/m-r/Renko/Renko.StaticSeries.Tests.cs index df8046942..1a2ed70ac 100644 --- a/tests/indicators/m-r/Renko/Renko.StaticSeries.Tests.cs +++ b/tests/indicators/m-r/Renko/Renko.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class Renko : StaticSeriesTestBase public override void Standard() // close { IReadOnlyList results = Quotes - .GetRenko(2.5m); + .ToRenko(2.5m); // assertions @@ -45,7 +45,7 @@ public override void Standard() // close public void StandardHighLow() { IReadOnlyList results = Quotes - .GetRenko(2.5m, EndType.HighLow); + .ToRenko(2.5m, EndType.HighLow); // assertions @@ -107,7 +107,7 @@ public void Atr() [TestMethod] public void UseAsQuotes() { - IReadOnlyList renkoQuotes = Quotes.GetRenko(2.5m); + IReadOnlyList renkoQuotes = Quotes.ToRenko(2.5m); IReadOnlyList renkoSma = renkoQuotes.ToSma(5); Assert.AreEqual(108, renkoSma.Count(x => x.Sma != null)); } @@ -116,7 +116,7 @@ public void UseAsQuotes() public override void BadData() { IReadOnlyList r = BadQuotes - .GetRenko(100m); + .ToRenko(100m); Assert.AreNotEqual(0, r.Count); } @@ -125,7 +125,7 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetRenko(0.01m); + .ToRenko(0.01m); Assert.AreEqual(0, r0.Count); } @@ -135,10 +135,10 @@ public void Exceptions() { // bad arguments Assert.ThrowsException(() - => Quotes.GetRenko(0)); + => Quotes.ToRenko(0)); // bad end type Assert.ThrowsException(() - => Quotes.GetRenko(2, (EndType)int.MaxValue)); + => Quotes.ToRenko(2, (EndType)int.MaxValue)); } } diff --git a/tests/indicators/m-r/Renko/Renko.StreamHub.Tests.cs b/tests/indicators/m-r/Renko/Renko.StreamHub.Tests.cs index 8899267f2..c995d2dc7 100644 --- a/tests/indicators/m-r/Renko/Renko.StreamHub.Tests.cs +++ b/tests/indicators/m-r/Renko/Renko.StreamHub.Tests.cs @@ -59,7 +59,7 @@ IReadOnlyList streamList // time-series, for comparison IReadOnlyList seriesList = quotesList - .GetRenko(brickSize, endType); + .ToRenko(brickSize, endType); // assert, should equal series streamList.Should().BeEquivalentTo(seriesList); @@ -105,7 +105,7 @@ IReadOnlyList streamList // time-series, for comparison IReadOnlyList seriesList = quotesList - .GetRenko(brickSize, endType) + .ToRenko(brickSize, endType) .ToSma(smaPeriods); // assert, should equal series diff --git a/tests/indicators/m-r/Roc/Roc.StaticSeries.Tests.cs b/tests/indicators/m-r/Roc/Roc.StaticSeries.Tests.cs index a246ab33d..1042bca94 100644 --- a/tests/indicators/m-r/Roc/Roc.StaticSeries.Tests.cs +++ b/tests/indicators/m-r/Roc/Roc.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class Roc : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = Quotes - .GetRoc(20); + .ToRoc(20); // proper quantities Assert.AreEqual(502, results.Count); @@ -33,7 +33,7 @@ public void UseReusable() { IReadOnlyList results = Quotes .Use(CandlePart.Close) - .GetRoc(20); + .ToRoc(20); Assert.AreEqual(502, results.Count); Assert.AreEqual(482, results.Count(x => x.Roc != null)); @@ -44,7 +44,7 @@ public void Chainee() { IReadOnlyList results = Quotes .ToSma(2) - .GetRoc(20); + .ToRoc(20); Assert.AreEqual(502, results.Count); Assert.AreEqual(481, results.Count(x => x.Roc != null)); @@ -54,7 +54,7 @@ public void Chainee() public void Chainor() { IReadOnlyList results = Quotes - .GetRoc(20) + .ToRoc(20) .ToSma(10); Assert.AreEqual(502, results.Count); @@ -65,7 +65,7 @@ public void Chainor() public override void BadData() { IReadOnlyList r = BadQuotes - .GetRoc(35); + .ToRoc(35); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Roc is double.NaN)); @@ -75,12 +75,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetRoc(5); + .ToRoc(5); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetRoc(5); + .ToRoc(5); Assert.AreEqual(1, r1.Count); } @@ -89,7 +89,7 @@ public override void NoQuotes() public void Removed() { IReadOnlyList results = Quotes - .GetRoc(20) + .ToRoc(20) .RemoveWarmupPeriods(); // assertions @@ -103,5 +103,5 @@ public void Removed() public void Exceptions() => // bad lookback period Assert.ThrowsException(() => - Quotes.GetRoc(0)); + Quotes.ToRoc(0)); } diff --git a/tests/indicators/m-r/RocWb/RocWb.StaticSeries.Tests.cs b/tests/indicators/m-r/RocWb/RocWb.StaticSeries.Tests.cs index 584af10ae..65bd3dd2e 100644 --- a/tests/indicators/m-r/RocWb/RocWb.StaticSeries.Tests.cs +++ b/tests/indicators/m-r/RocWb/RocWb.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class RocWb : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = Quotes - .GetRocWb(20, 3, 20); + .ToRocWb(20, 3, 20); // proper quantities Assert.AreEqual(502, results.Count); @@ -71,7 +71,7 @@ public void UseReusable() { IReadOnlyList results = Quotes .Use(CandlePart.Close) - .GetRocWb(20, 3, 20); + .ToRocWb(20, 3, 20); Assert.AreEqual(502, results.Count); Assert.AreEqual(482, results.Count(x => x.Roc != null)); @@ -82,7 +82,7 @@ public void Chainee() { IReadOnlyList results = Quotes .ToSma(2) - .GetRocWb(20, 3, 20); + .ToRocWb(20, 3, 20); Assert.AreEqual(502, results.Count); Assert.AreEqual(481, results.Count(x => x.Roc != null)); @@ -92,7 +92,7 @@ public void Chainee() public void Chainor() { IReadOnlyList results = Quotes - .GetRocWb(20, 3, 20) + .ToRocWb(20, 3, 20) .ToSma(10); Assert.AreEqual(502, results.Count); @@ -103,7 +103,7 @@ public void Chainor() public override void BadData() { IReadOnlyList r = BadQuotes - .GetRocWb(35, 3, 35); + .ToRocWb(35, 3, 35); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Roc is double.NaN)); @@ -113,12 +113,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetRocWb(5, 3, 2); + .ToRocWb(5, 3, 2); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetRocWb(5, 3, 2); + .ToRocWb(5, 3, 2); Assert.AreEqual(1, r1.Count); } @@ -127,7 +127,7 @@ public override void NoQuotes() public void Removed() { IReadOnlyList results = Quotes - .GetRocWb(20, 3, 20) + .ToRocWb(20, 3, 20) .RemoveWarmupPeriods(); // assertions @@ -145,14 +145,14 @@ public void Exceptions() { // bad lookback period Assert.ThrowsException(() => - Quotes.GetRocWb(0, 3, 12)); + Quotes.ToRocWb(0, 3, 12)); // bad EMA period Assert.ThrowsException(() => - Quotes.GetRocWb(14, 0, 14)); + Quotes.ToRocWb(14, 0, 14)); // bad STDDEV period Assert.ThrowsException(() => - Quotes.GetRocWb(15, 3, 16)); + Quotes.ToRocWb(15, 3, 16)); } } diff --git a/tests/indicators/m-r/RollingPivots/RollingPivots.StaticSeries.Tests.cs b/tests/indicators/m-r/RollingPivots/RollingPivots.StaticSeries.Tests.cs index b5735dda2..456ea905d 100644 --- a/tests/indicators/m-r/RollingPivots/RollingPivots.StaticSeries.Tests.cs +++ b/tests/indicators/m-r/RollingPivots/RollingPivots.StaticSeries.Tests.cs @@ -11,7 +11,7 @@ public override void Standard() PivotPointType pointType = PivotPointType.Standard; IReadOnlyList results = - Quotes.GetRollingPivots(windowPeriods, offsetPeriods, pointType); + Quotes.ToRollingPivots(windowPeriods, offsetPeriods, pointType); // proper quantities Assert.AreEqual(502, results.Count); @@ -84,7 +84,7 @@ public void Camarilla() IEnumerable h = Data.GetDefault(38); IReadOnlyList results = h - .GetRollingPivots(windowPeriods, offsetPeriods, pointType); + .ToRollingPivots(windowPeriods, offsetPeriods, pointType); // proper quantities Assert.AreEqual(38, results.Count); @@ -155,7 +155,7 @@ public void Demark() PivotPointType pointType = PivotPointType.Demark; IReadOnlyList results = Quotes - .GetRollingPivots(windowPeriods, offsetPeriods, pointType); + .ToRollingPivots(windowPeriods, offsetPeriods, pointType); // proper quantities Assert.AreEqual(502, results.Count); @@ -239,7 +239,7 @@ public void Fibonacci() IEnumerable h = Data.GetIntraday(300); IReadOnlyList results = - h.GetRollingPivots(windowPeriods, offsetPeriods, pointType); + h.ToRollingPivots(windowPeriods, offsetPeriods, pointType); // proper quantities Assert.AreEqual(300, results.Count); @@ -313,7 +313,7 @@ public void Woodie() IEnumerable h = Data.GetIntraday(); IReadOnlyList results = h - .GetRollingPivots(windowPeriods, offsetPeriods, pointType); + .ToRollingPivots(windowPeriods, offsetPeriods, pointType); // proper quantities Assert.AreEqual(1564, results.Count); @@ -372,7 +372,7 @@ public void Woodie() public override void BadData() { IReadOnlyList r = BadQuotes - .GetRollingPivots(5, 5); + .ToRollingPivots(5, 5); Assert.AreEqual(502, r.Count); } @@ -381,12 +381,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetRollingPivots(5, 2); + .ToRollingPivots(5, 2); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetRollingPivots(5, 2); + .ToRollingPivots(5, 2); Assert.AreEqual(1, r1.Count); } @@ -399,7 +399,7 @@ public void Removed() PivotPointType pointType = PivotPointType.Standard; IReadOnlyList results = Quotes - .GetRollingPivots(windowPeriods, offsetPeriods, pointType) + .ToRollingPivots(windowPeriods, offsetPeriods, pointType) .RemoveWarmupPeriods(); // assertions @@ -422,10 +422,10 @@ public void Exceptions() { // bad window period Assert.ThrowsException(() => - Quotes.GetRollingPivots(0, 10)); + Quotes.ToRollingPivots(0, 10)); // bad offset period Assert.ThrowsException(() => - Quotes.GetRollingPivots(10, -1)); + Quotes.ToRollingPivots(10, -1)); } } diff --git a/tests/indicators/m-r/Rsi/Rsi.StaticSeries.Tests.cs b/tests/indicators/m-r/Rsi/Rsi.StaticSeries.Tests.cs index de79ccff7..e5c60430b 100644 --- a/tests/indicators/m-r/Rsi/Rsi.StaticSeries.Tests.cs +++ b/tests/indicators/m-r/Rsi/Rsi.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class Rsi : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = Quotes - .GetRsi(); + .ToRsi(); // proper quantities Assert.AreEqual(502, results.Count); @@ -32,7 +32,7 @@ public void SmallLookback() { int lookbackPeriods = 1; IReadOnlyList results = Quotes - .GetRsi(lookbackPeriods); + .ToRsi(lookbackPeriods); // proper quantities Assert.AreEqual(502, results.Count); @@ -52,7 +52,7 @@ public void CryptoData() IReadOnlyList btc = Data.GetBitcoin(); IReadOnlyList r = btc - .GetRsi(1); + .ToRsi(1); Assert.AreEqual(1246, r.Count); } @@ -62,7 +62,7 @@ public void UseReusable() { IReadOnlyList results = Quotes .Use(CandlePart.Close) - .GetRsi(); + .ToRsi(); Assert.AreEqual(502, results.Count); Assert.AreEqual(488, results.Count(x => x.Rsi != null)); @@ -73,7 +73,7 @@ public void Chainee() { IReadOnlyList results = Quotes .ToSma(2) - .GetRsi(); + .ToRsi(); Assert.AreEqual(502, results.Count); Assert.AreEqual(487, results.Count(x => x.Rsi != null)); @@ -83,7 +83,7 @@ public void Chainee() public void Chainor() { IReadOnlyList results = Quotes - .GetRsi() + .ToRsi() .ToSma(10); Assert.AreEqual(502, results.Count); @@ -94,7 +94,7 @@ public void Chainor() public void NaN() { IEnumerable r = Data.GetBtcUsdNan() - .GetRsi(); + .ToRsi(); Assert.AreEqual(0, r.Count(x => x.Rsi is double.NaN)); } @@ -103,7 +103,7 @@ public void NaN() public override void BadData() { IReadOnlyList r = BadQuotes - .GetRsi(20); + .ToRsi(20); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Rsi is double.NaN)); @@ -113,12 +113,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetRsi(); + .ToRsi(); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetRsi(); + .ToRsi(); Assert.AreEqual(1, r1.Count); } @@ -127,7 +127,7 @@ public override void NoQuotes() public void Removed() { IReadOnlyList results = Quotes - .GetRsi() + .ToRsi() .RemoveWarmupPeriods(); // assertions @@ -141,5 +141,5 @@ public void Removed() [TestMethod] public void Exceptions() => Assert.ThrowsException(() - => Quotes.GetRsi(0)); + => Quotes.ToRsi(0)); } diff --git a/tests/indicators/s-z/Slope/Slope.StaticSeries.Tests.cs b/tests/indicators/s-z/Slope/Slope.StaticSeries.Tests.cs index 168aed275..9fc6af0f4 100644 --- a/tests/indicators/s-z/Slope/Slope.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/Slope/Slope.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class Slope : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = Quotes - .GetSlope(20); + .ToSlope(20); // proper quantities Assert.AreEqual(502, results.Count); @@ -43,7 +43,7 @@ public void UseReusable() { IReadOnlyList results = Quotes .Use(CandlePart.Close) - .GetSlope(20); + .ToSlope(20); Assert.AreEqual(502, results.Count); Assert.AreEqual(483, results.Count(x => x.Slope != null)); @@ -54,7 +54,7 @@ public void Chainee() { IReadOnlyList results = Quotes .ToSma(2) - .GetSlope(20); + .ToSlope(20); Assert.AreEqual(502, results.Count); Assert.AreEqual(482, results.Count(x => x.Slope != null)); @@ -64,7 +64,7 @@ public void Chainee() public void Chainor() { IReadOnlyList results = Quotes - .GetSlope(20) + .ToSlope(20) .ToSma(10); Assert.AreEqual(502, results.Count); @@ -75,7 +75,7 @@ public void Chainor() public override void BadData() { IReadOnlyList r = BadQuotes - .GetSlope(15); + .ToSlope(15); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Slope is double.NaN)); @@ -85,7 +85,7 @@ public override void BadData() public void BigData() { IReadOnlyList r = BigQuotes - .GetSlope(250); + .ToSlope(250); Assert.AreEqual(1246, r.Count); } @@ -94,12 +94,12 @@ public void BigData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetSlope(5); + .ToSlope(5); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetSlope(5); + .ToSlope(5); Assert.AreEqual(1, r1.Count); } @@ -108,7 +108,7 @@ public override void NoQuotes() public void Removed() { IReadOnlyList results = Quotes - .GetSlope(20) + .ToSlope(20) .RemoveWarmupPeriods(); // assertions @@ -126,5 +126,5 @@ public void Removed() [TestMethod] public void Exceptions() => Assert.ThrowsException(() - => Quotes.GetSlope(1)); + => Quotes.ToSlope(1)); } diff --git a/tests/indicators/s-z/SmaAnalysis/SmaAnalysis.StaticSeries.Tests.cs b/tests/indicators/s-z/SmaAnalysis/SmaAnalysis.StaticSeries.Tests.cs index 31452ea82..1b41ece3d 100644 --- a/tests/indicators/s-z/SmaAnalysis/SmaAnalysis.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/SmaAnalysis/SmaAnalysis.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class SmaAnalyses : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = Quotes - .GetSmaAnalysis(20); + .ToSmaAnalysis(20); // proper quantities Assert.AreEqual(502, results.Count); @@ -26,7 +26,7 @@ public void UseReusable() { IReadOnlyList results = Quotes .Use(CandlePart.Close) - .GetSmaAnalysis(20); + .ToSmaAnalysis(20); Assert.AreEqual(502, results.Count); Assert.AreEqual(483, results.Count(x => x.Sma != null)); @@ -37,7 +37,7 @@ public void Chainee() { IReadOnlyList results = Quotes .ToSma(2) - .GetSmaAnalysis(20); + .ToSmaAnalysis(20); Assert.AreEqual(502, results.Count); Assert.AreEqual(482, results.Count(x => x.Sma != null)); @@ -47,7 +47,7 @@ public void Chainee() public void Chainor() { IReadOnlyList results = Quotes - .GetSmaAnalysis(10) + .ToSmaAnalysis(10) .ToEma(10); Assert.AreEqual(502, results.Count); @@ -58,7 +58,7 @@ public void Chainor() public override void BadData() { IReadOnlyList r = BadQuotes - .GetSmaAnalysis(15); + .ToSmaAnalysis(15); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Mape is double.NaN)); @@ -68,12 +68,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetSmaAnalysis(6); + .ToSmaAnalysis(6); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetSmaAnalysis(6); + .ToSmaAnalysis(6); Assert.AreEqual(1, r1.Count); } @@ -82,7 +82,7 @@ public override void NoQuotes() public void Removed() { IReadOnlyList results = Quotes - .GetSmaAnalysis(20) + .ToSmaAnalysis(20) .RemoveWarmupPeriods(); // assertions @@ -94,5 +94,5 @@ public void Removed() [TestMethod] public void Exceptions() => Assert.ThrowsException(() - => Quotes.GetSmaAnalysis(0)); + => Quotes.ToSmaAnalysis(0)); } diff --git a/tests/indicators/s-z/Smi/Smi.StaticSeries.Tests.cs b/tests/indicators/s-z/Smi/Smi.StaticSeries.Tests.cs index 46ea3bc3e..5dc184c73 100644 --- a/tests/indicators/s-z/Smi/Smi.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/Smi/Smi.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class Smi : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = Quotes - .GetSmi(14, 20, 5); + .ToSmi(14, 20, 5); // proper quantities Assert.AreEqual(502, results.Count); @@ -48,7 +48,7 @@ public override void Standard() public void Chainor() { IReadOnlyList results = Quotes - .GetSmi(14, 20, 5) + .ToSmi(14, 20, 5) .ToSma(10); Assert.AreEqual(502, results.Count); @@ -59,7 +59,7 @@ public void Chainor() public void NoSignal() { IReadOnlyList results = Quotes - .GetSmi(5, 20, 20, 1); + .ToSmi(5, 20, 20, 1); // signal equals oscillator SmiResult r1 = results[487]; @@ -73,7 +73,7 @@ public void NoSignal() public void SmallPeriods() { IReadOnlyList results = Quotes - .GetSmi(1, 1, 1, 5); + .ToSmi(1, 1, 1, 5); // sample values SmiResult r51 = results[51]; @@ -93,7 +93,7 @@ public void SmallPeriods() public override void BadData() { IReadOnlyList r = BadQuotes - .GetSmi(5, 5, 1, 5); + .ToSmi(5, 5, 1, 5); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Smi is double.NaN)); @@ -103,12 +103,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetSmi(5, 5); + .ToSmi(5, 5); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetSmi(5, 3, 3); + .ToSmi(5, 3, 3); Assert.AreEqual(1, r1.Count); } @@ -117,7 +117,7 @@ public override void NoQuotes() public void Removed() { IReadOnlyList results = Quotes - .GetSmi(14, 20, 5) + .ToSmi(14, 20, 5) .RemoveWarmupPeriods(); // assertions @@ -133,18 +133,18 @@ public void Exceptions() { // bad lookback period Assert.ThrowsException(() => - Quotes.GetSmi(0, 5, 5, 5)); + Quotes.ToSmi(0, 5, 5, 5)); // bad first smooth period Assert.ThrowsException(() => - Quotes.GetSmi(14, 0, 5, 5)); + Quotes.ToSmi(14, 0, 5, 5)); // bad second smooth period Assert.ThrowsException(() => - Quotes.GetSmi(14, 3, 0, 5)); + Quotes.ToSmi(14, 3, 0, 5)); // bad signal Assert.ThrowsException(() => - Quotes.GetSmi(9, 3, 1, 0)); + Quotes.ToSmi(9, 3, 1, 0)); } } diff --git a/tests/indicators/s-z/Smma/Smma.StaticSeries.Tests.cs b/tests/indicators/s-z/Smma/Smma.StaticSeries.Tests.cs index aad46502e..b2370be85 100644 --- a/tests/indicators/s-z/Smma/Smma.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/Smma/Smma.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class Smma : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = Quotes - .GetSmma(20); + .ToSmma(20); // proper quantities Assert.AreEqual(502, results.Count); @@ -30,7 +30,7 @@ public void UseReusable() { IReadOnlyList results = Quotes .Use(CandlePart.Close) - .GetSmma(20); + .ToSmma(20); Assert.AreEqual(502, results.Count); Assert.AreEqual(483, results.Count(x => x.Smma != null)); @@ -41,7 +41,7 @@ public void Chainee() { IReadOnlyList results = Quotes .ToSma(2) - .GetSmma(20); + .ToSmma(20); Assert.AreEqual(502, results.Count); Assert.AreEqual(482, results.Count(x => x.Smma != null)); @@ -51,7 +51,7 @@ public void Chainee() public void Chainor() { IReadOnlyList results = Quotes - .GetSmma(20) + .ToSmma(20) .ToSma(10); Assert.AreEqual(502, results.Count); @@ -62,7 +62,7 @@ public void Chainor() public override void BadData() { IReadOnlyList r = BadQuotes - .GetSmma(15); + .ToSmma(15); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Smma is double.NaN)); @@ -72,12 +72,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetSmma(5); + .ToSmma(5); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetSmma(5); + .ToSmma(5); Assert.AreEqual(1, r1.Count); } @@ -86,7 +86,7 @@ public override void NoQuotes() public void Removed() { IReadOnlyList results = Quotes - .GetSmma(20) + .ToSmma(20) .RemoveWarmupPeriods(); // assertions @@ -98,5 +98,5 @@ public void Removed() [TestMethod] public void Exceptions() => Assert.ThrowsException(() - => Quotes.GetSmma(0)); + => Quotes.ToSmma(0)); } diff --git a/tests/indicators/s-z/StarcBands/StarcBands.StaticSeries.Tests.cs b/tests/indicators/s-z/StarcBands/StarcBands.StaticSeries.Tests.cs index 7467d3585..86030fed3 100644 --- a/tests/indicators/s-z/StarcBands/StarcBands.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/StarcBands/StarcBands.StaticSeries.Tests.cs @@ -11,7 +11,7 @@ public override void Standard() int atrPeriods = 14; IReadOnlyList results = Quotes - .GetStarcBands(smaPeriods, multiplier, atrPeriods); + .ToStarcBands(smaPeriods, multiplier, atrPeriods); // proper quantities Assert.AreEqual(502, results.Count); @@ -50,7 +50,7 @@ public override void Standard() public override void BadData() { IReadOnlyList r = BadQuotes - .GetStarcBands(10, 3, 15); + .ToStarcBands(10, 3, 15); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.UpperBand is double.NaN)); @@ -60,12 +60,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetStarcBands(10); + .ToStarcBands(10); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetStarcBands(10); + .ToStarcBands(10); Assert.AreEqual(1, r1.Count); } @@ -79,7 +79,7 @@ public void Condense() int lookbackPeriods = Math.Max(smaPeriods, atrPeriods); IReadOnlyList results = Quotes - .GetStarcBands(smaPeriods, multiplier, atrPeriods) + .ToStarcBands(smaPeriods, multiplier, atrPeriods) .Condense(); // assertions @@ -100,7 +100,7 @@ public void Removed() int lookbackPeriods = Math.Max(smaPeriods, atrPeriods); IReadOnlyList results = Quotes - .GetStarcBands(smaPeriods, multiplier, atrPeriods) + .ToStarcBands(smaPeriods, multiplier, atrPeriods) .RemoveWarmupPeriods(); // assertions @@ -117,14 +117,14 @@ public void Exceptions() { // bad EMA period Assert.ThrowsException(() => - Quotes.GetStarcBands(1)); + Quotes.ToStarcBands(1)); // bad ATR period Assert.ThrowsException(() => - Quotes.GetStarcBands(20, 2, 1)); + Quotes.ToStarcBands(20, 2, 1)); // bad multiplier Assert.ThrowsException(() => - Quotes.GetStarcBands(20, 0)); + Quotes.ToStarcBands(20, 0)); } } diff --git a/tests/indicators/s-z/Stc/Stc.StaticSeries.Tests.cs b/tests/indicators/s-z/Stc/Stc.StaticSeries.Tests.cs index 37480617f..9cf0fbb6b 100644 --- a/tests/indicators/s-z/Stc/Stc.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/Stc/Stc.StaticSeries.Tests.cs @@ -11,7 +11,7 @@ public override void Standard() int slowPeriods = 26; IReadOnlyList results = Quotes - .GetStc(cyclePeriods, fastPeriods, slowPeriods); + .ToStc(cyclePeriods, fastPeriods, slowPeriods); // proper quantities Assert.AreEqual(502, results.Count); @@ -39,7 +39,7 @@ public void UseReusable() { IReadOnlyList results = Quotes .Use(CandlePart.Close) - .GetStc(9, 12, 26); + .ToStc(9, 12, 26); Assert.AreEqual(502, results.Count); Assert.AreEqual(467, results.Count(x => x.Stc != null)); @@ -50,7 +50,7 @@ public void Chainee() { IReadOnlyList results = Quotes .ToSma(2) - .GetStc(9, 12, 26); + .ToStc(9, 12, 26); Assert.AreEqual(502, results.Count); Assert.AreEqual(466, results.Count(x => x.Stc != null)); @@ -60,7 +60,7 @@ public void Chainee() public void Chainor() { IReadOnlyList results = Quotes - .GetStc(9, 12, 26) + .ToStc(9, 12, 26) .ToSma(10); Assert.AreEqual(502, results.Count); @@ -71,7 +71,7 @@ public void Chainor() public override void BadData() { IReadOnlyList r = BadQuotes - .GetStc(); + .ToStc(); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Stc is double.NaN)); @@ -81,12 +81,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetStc(); + .ToStc(); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetStc(); + .ToStc(); Assert.AreEqual(1, r1.Count); } @@ -99,7 +99,7 @@ public void Issue1107() RandomGbm quotes = new(58); IReadOnlyList results = quotes - .GetStc(); + .ToStc(); Assert.AreEqual(58, results.Count); } @@ -112,7 +112,7 @@ public void Removed() int slowPeriods = 26; IReadOnlyList results = Quotes - .GetStc(cyclePeriods, fastPeriods, slowPeriods) + .ToStc(cyclePeriods, fastPeriods, slowPeriods) .RemoveWarmupPeriods(); // assertions @@ -127,14 +127,14 @@ public void Exceptions() { // bad fast period Assert.ThrowsException(() => - Quotes.GetStc(9, 0, 26)); + Quotes.ToStc(9, 0, 26)); // bad slow periods must be larger than faster period Assert.ThrowsException(() => - Quotes.GetStc(9, 12, 12)); + Quotes.ToStc(9, 12, 12)); // bad signal period Assert.ThrowsException(() => - Quotes.GetStc(-1, 12, 26)); + Quotes.ToStc(-1, 12, 26)); } } diff --git a/tests/indicators/s-z/StdDev/StdDev.StaticSeries.Tests.cs b/tests/indicators/s-z/StdDev/StdDev.StaticSeries.Tests.cs index ab4eb254e..c4fbc30b0 100644 --- a/tests/indicators/s-z/StdDev/StdDev.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/StdDev/StdDev.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class StdDev : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = Quotes - .GetStdDev(10); + .ToStdDev(10); // proper quantities Assert.AreEqual(502, results.Count); @@ -41,7 +41,7 @@ public void UseReusable() { IReadOnlyList results = Quotes .Use(CandlePart.Close) - .GetStdDev(10); + .ToStdDev(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(493, results.Count(x => x.StdDev != null)); @@ -52,7 +52,7 @@ public void Chainee() { IReadOnlyList results = Quotes .ToSma(2) - .GetStdDev(10); + .ToStdDev(10); Assert.AreEqual(502, results.Count); Assert.AreEqual(492, results.Count(x => x.StdDev != null)); @@ -62,7 +62,7 @@ public void Chainee() public void Chainor() { IReadOnlyList results = Quotes - .GetStdDev(10) + .ToStdDev(10) .ToSma(10); Assert.AreEqual(502, results.Count); @@ -73,7 +73,7 @@ public void Chainor() public override void BadData() { IReadOnlyList r = BadQuotes - .GetStdDev(15); + .ToStdDev(15); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.StdDev is double.NaN)); @@ -83,7 +83,7 @@ public override void BadData() public void BigData() { IReadOnlyList r = BigQuotes - .GetStdDev(200); + .ToStdDev(200); Assert.AreEqual(1246, r.Count); } @@ -92,12 +92,12 @@ public void BigData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetStdDev(10); + .ToStdDev(10); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetStdDev(10); + .ToStdDev(10); Assert.AreEqual(1, r1.Count); } @@ -106,7 +106,7 @@ public override void NoQuotes() public void Removed() { IReadOnlyList results = Quotes - .GetStdDev(10) + .ToStdDev(10) .RemoveWarmupPeriods(); // assertions @@ -123,5 +123,5 @@ public void Exceptions() => // bad lookback period Assert.ThrowsException(() => - Quotes.GetStdDev(1)); + Quotes.ToStdDev(1)); } diff --git a/tests/indicators/s-z/StdDevChannels/StdDevChannels.StaticSeries.Tests.cs b/tests/indicators/s-z/StdDevChannels/StdDevChannels.StaticSeries.Tests.cs index 14b5e5af3..dc145f82b 100644 --- a/tests/indicators/s-z/StdDevChannels/StdDevChannels.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/StdDevChannels/StdDevChannels.StaticSeries.Tests.cs @@ -10,7 +10,7 @@ public override void Standard() double standardDeviations = 2; IReadOnlyList results = - Quotes.GetStdDevChannels(lookbackPeriods, standardDeviations); + Quotes.ToStdDevChannels(lookbackPeriods, standardDeviations); // proper quantities Assert.AreEqual(502, results.Count); @@ -68,7 +68,7 @@ public void FullHistory() // null provided for lookback period IReadOnlyList results = - Quotes.GetStdDevChannels(null); + Quotes.ToStdDevChannels(null); // proper quantities Assert.AreEqual(502, results.Count); @@ -100,7 +100,7 @@ public void UseReusable() { IReadOnlyList results = Quotes .Use(CandlePart.Close) - .GetStdDevChannels(); + .ToStdDevChannels(); Assert.AreEqual(502, results.Count); Assert.AreEqual(500, results.Count(x => x.Centerline != null)); @@ -111,7 +111,7 @@ public void Chainee() { IReadOnlyList results = Quotes .ToSma(2) - .GetStdDevChannels(); + .ToStdDevChannels(); Assert.AreEqual(502, results.Count); Assert.AreEqual(500, results.Count(x => x.Centerline != null)); @@ -121,7 +121,7 @@ public void Chainee() public override void BadData() { IReadOnlyList r = BadQuotes - .GetStdDevChannels(); + .ToStdDevChannels(); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.UpperChannel is double.NaN)); @@ -131,12 +131,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetStdDevChannels(); + .ToStdDevChannels(); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetStdDevChannels(); + .ToStdDevChannels(); Assert.AreEqual(1, r1.Count); } @@ -148,7 +148,7 @@ public void Condense() double standardDeviations = 2; IReadOnlyList results = Quotes - .GetStdDevChannels(lookbackPeriods, standardDeviations) + .ToStdDevChannels(lookbackPeriods, standardDeviations) .Condense(); // assertions @@ -167,7 +167,7 @@ public void Removed() double standardDeviations = 2; IReadOnlyList results = Quotes - .GetStdDevChannels(lookbackPeriods, standardDeviations) + .ToStdDevChannels(lookbackPeriods, standardDeviations) .RemoveWarmupPeriods(); // assertions @@ -184,10 +184,10 @@ public void Exceptions() { // bad lookback period Assert.ThrowsException(() => - Quotes.GetStdDevChannels(0)); + Quotes.ToStdDevChannels(0)); // bad standard deviations Assert.ThrowsException(() => - Quotes.GetStdDevChannels(20, 0)); + Quotes.ToStdDevChannels(20, 0)); } } diff --git a/tests/indicators/s-z/Stoch/Stoch.StaticSeries.Tests.cs b/tests/indicators/s-z/Stoch/Stoch.StaticSeries.Tests.cs index bb5f2cf90..6e8fe7a1b 100644 --- a/tests/indicators/s-z/Stoch/Stoch.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/Stoch/Stoch.StaticSeries.Tests.cs @@ -11,7 +11,7 @@ public override void Standard() // Slow int smoothPeriods = 3; IReadOnlyList results = Quotes - .GetStoch(lookbackPeriods, signalPeriods, smoothPeriods); + .ToStoch(lookbackPeriods, signalPeriods, smoothPeriods); // proper quantities Assert.AreEqual(502, results.Count); @@ -72,7 +72,7 @@ public override void Standard() // Slow public void Extended() // with extra parameters { IReadOnlyList results = - Quotes.GetStoch(9, 3, 3, 5, 4, MaType.SMMA); + Quotes.ToStoch(9, 3, 3, 5, 4, MaType.SMMA); // proper quantities Assert.AreEqual(502, results.Count); @@ -115,7 +115,7 @@ public void Extended() // with extra parameters public void Chainor() { IReadOnlyList results = Quotes - .GetStoch() + .ToStoch() .ToSma(10); Assert.AreEqual(502, results.Count); @@ -130,7 +130,7 @@ public void NoSignal() const int smoothPeriods = 3; IReadOnlyList results = Quotes - .GetStoch(lookbackPeriods, signalPeriods, smoothPeriods); + .ToStoch(lookbackPeriods, signalPeriods, smoothPeriods); // signal equals oscillator StochResult r1 = results[487]; @@ -148,7 +148,7 @@ public void Fast() int smoothPeriods = 1; IReadOnlyList results = Quotes - .GetStoch(lookbackPeriods, signalPeriods, smoothPeriods); + .ToStoch(lookbackPeriods, signalPeriods, smoothPeriods); // sample values StochResult r1 = results[487]; @@ -168,7 +168,7 @@ public void FastSmall() int smoothPeriods = 1; IReadOnlyList results = Quotes - .GetStoch(lookbackPeriods, signalPeriods, smoothPeriods); + .ToStoch(lookbackPeriods, signalPeriods, smoothPeriods); // sample values StochResult r1 = results[70]; @@ -182,7 +182,7 @@ public void FastSmall() public override void BadData() { IReadOnlyList r = BadQuotes - .GetStoch(15); + .ToStoch(15); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Oscillator is double.NaN)); @@ -192,12 +192,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetStoch(); + .ToStoch(); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetStoch(); + .ToStoch(); Assert.AreEqual(1, r1.Count); } @@ -210,7 +210,7 @@ public void Removed() int smoothPeriods = 3; IReadOnlyList results = Quotes - .GetStoch(lookbackPeriods, signalPeriods, smoothPeriods) + .ToStoch(lookbackPeriods, signalPeriods, smoothPeriods) .RemoveWarmupPeriods(); // assertions @@ -231,7 +231,7 @@ public void Boundary() IReadOnlyList results = Data .GetRandom(2500) - .GetStoch(lookbackPeriods, signalPeriods, smoothPeriods); + .ToStoch(lookbackPeriods, signalPeriods, smoothPeriods); // test boundary condition @@ -264,26 +264,26 @@ public void Exceptions() { // bad lookback period Assert.ThrowsException(() => - Quotes.GetStoch(0)); + Quotes.ToStoch(0)); // bad signal period Assert.ThrowsException(() => - Quotes.GetStoch(14, 0)); + Quotes.ToStoch(14, 0)); // bad smoothing period Assert.ThrowsException(() => - Quotes.GetStoch(14, 3, 0)); + Quotes.ToStoch(14, 3, 0)); // bad kFactor Assert.ThrowsException(() => - Quotes.GetStoch(9, 3, 1, 0, 2, MaType.SMA)); + Quotes.ToStoch(9, 3, 1, 0, 2, MaType.SMA)); // bad dFactor Assert.ThrowsException(() => - Quotes.GetStoch(9, 3, 1, 3, 0, MaType.SMA)); + Quotes.ToStoch(9, 3, 1, 3, 0, MaType.SMA)); // bad MA type Assert.ThrowsException(() => - Quotes.GetStoch(9, 3, 3, 3, 2, MaType.ALMA)); + Quotes.ToStoch(9, 3, 3, 3, 2, MaType.ALMA)); } } diff --git a/tests/indicators/s-z/StochRsi/StochRsi.StaticSeries.Tests.cs b/tests/indicators/s-z/StochRsi/StochRsi.StaticSeries.Tests.cs index 71cdf7289..2efbd0983 100644 --- a/tests/indicators/s-z/StochRsi/StochRsi.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/StochRsi/StochRsi.StaticSeries.Tests.cs @@ -12,7 +12,7 @@ public override void Standard() // Fast RSI int smoothPeriods = 1; IReadOnlyList results = - Quotes.GetStochRsi(rsiPeriods, stochPeriods, signalPeriods, smoothPeriods); + Quotes.ToStochRsi(rsiPeriods, stochPeriods, signalPeriods, smoothPeriods); // assertions @@ -48,7 +48,7 @@ public void SlowRsi() int smoothPeriods = 3; IReadOnlyList results = - Quotes.GetStochRsi(rsiPeriods, stochPeriods, signalPeriods, smoothPeriods); + Quotes.ToStochRsi(rsiPeriods, stochPeriods, signalPeriods, smoothPeriods); // assertions @@ -80,7 +80,7 @@ public void UseReusable() { IReadOnlyList results = Quotes .Use(CandlePart.Close) - .GetStochRsi(14, 14, 3); + .ToStochRsi(14, 14, 3); Assert.AreEqual(502, results.Count); Assert.AreEqual(475, results.Count(x => x.StochRsi != null)); @@ -92,7 +92,7 @@ public void Chainee() { IReadOnlyList results = Quotes .ToSma(2) - .GetStochRsi(14, 14, 3); + .ToStochRsi(14, 14, 3); Assert.AreEqual(502, results.Count); Assert.AreEqual(474, results.Count(x => x.StochRsi != null)); @@ -102,7 +102,7 @@ public void Chainee() public void Chainor() { IReadOnlyList results = Quotes - .GetStochRsi(14, 14, 3, 3) + .ToStochRsi(14, 14, 3, 3) .ToSma(10); Assert.AreEqual(502, results.Count); @@ -113,7 +113,7 @@ public void Chainor() public override void BadData() { IReadOnlyList r = BadQuotes - .GetStochRsi(15, 20, 3, 2); + .ToStochRsi(15, 20, 3, 2); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.StochRsi is double.NaN)); @@ -123,12 +123,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetStochRsi(10, 20, 3); + .ToStochRsi(10, 20, 3); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetStochRsi(8, 13, 2); + .ToStochRsi(8, 13, 2); Assert.AreEqual(1, r1.Count); } @@ -142,7 +142,7 @@ public void Removed() int smoothPeriods = 3; IReadOnlyList results = Quotes - .GetStochRsi(rsiPeriods, stochPeriods, signalPeriods, smoothPeriods) + .ToStochRsi(rsiPeriods, stochPeriods, signalPeriods, smoothPeriods) .RemoveWarmupPeriods(); // assertions @@ -159,18 +159,18 @@ public void Exceptions() { // bad RSI period Assert.ThrowsException(() => - Quotes.GetStochRsi(0, 14, 3)); + Quotes.ToStochRsi(0, 14, 3)); // bad STO period Assert.ThrowsException(() => - Quotes.GetStochRsi(14, 0, 3, 3)); + Quotes.ToStochRsi(14, 0, 3, 3)); // bad STO signal period Assert.ThrowsException(() => - Quotes.GetStochRsi(14, 14, 0)); + Quotes.ToStochRsi(14, 14, 0)); // bad STO smoothing period Assert.ThrowsException(() => - Quotes.GetStochRsi(14, 14, 3, 0)); + Quotes.ToStochRsi(14, 14, 3, 0)); } } diff --git a/tests/indicators/s-z/SuperTrend/SuperTrend.StaticSeries.Tests.cs b/tests/indicators/s-z/SuperTrend/SuperTrend.StaticSeries.Tests.cs index 31860967a..0732cab82 100644 --- a/tests/indicators/s-z/SuperTrend/SuperTrend.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/SuperTrend/SuperTrend.StaticSeries.Tests.cs @@ -10,7 +10,7 @@ public override void Standard() const double multiplier = 3; IReadOnlyList results = Quotes - .GetSuperTrend(lookbackPeriods, multiplier); + .ToSuperTrend(lookbackPeriods, multiplier); // proper quantities Assert.AreEqual(502, results.Count); @@ -54,7 +54,7 @@ public void Bitcoin() IEnumerable h = Data.GetBitcoin(); IReadOnlyList results = h - .GetSuperTrend(); + .ToSuperTrend(); Assert.AreEqual(1246, results.Count); @@ -66,7 +66,7 @@ public void Bitcoin() public override void BadData() { IReadOnlyList r = BadQuotes - .GetSuperTrend(7); + .ToSuperTrend(7); Assert.AreEqual(502, r.Count); } @@ -75,12 +75,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetSuperTrend(); + .ToSuperTrend(); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetSuperTrend(); + .ToSuperTrend(); Assert.AreEqual(1, r1.Count); } @@ -92,7 +92,7 @@ public void Condense() double multiplier = 3; IReadOnlyList results = Quotes - .GetSuperTrend(lookbackPeriods, multiplier) + .ToSuperTrend(lookbackPeriods, multiplier) .Condense(); // assertions @@ -111,7 +111,7 @@ public void Removed() double multiplier = 3; IReadOnlyList results = Quotes - .GetSuperTrend(lookbackPeriods, multiplier) + .ToSuperTrend(lookbackPeriods, multiplier) .RemoveWarmupPeriods(); // assertions @@ -128,10 +128,10 @@ public void Exceptions() { // bad lookback period Assert.ThrowsException(() => - Quotes.GetSuperTrend(1)); + Quotes.ToSuperTrend(1)); // bad multiplier Assert.ThrowsException(() => - Quotes.GetSuperTrend(7, 0)); + Quotes.ToSuperTrend(7, 0)); } } diff --git a/tests/indicators/s-z/T3/T3.StaticSeries.Tests.cs b/tests/indicators/s-z/T3/T3.StaticSeries.Tests.cs index 5b10b3763..5cb40775b 100644 --- a/tests/indicators/s-z/T3/T3.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/T3/T3.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class T3 : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = Quotes - .GetT3(); + .ToT3(); // proper quantities Assert.AreEqual(502, results.Count); @@ -38,7 +38,7 @@ public void UseReusable() { IReadOnlyList results = Quotes .Use(CandlePart.Close) - .GetT3(); + .ToT3(); Assert.AreEqual(502, results.Count); Assert.AreEqual(502, results.Count(x => x.T3 != null)); @@ -49,7 +49,7 @@ public void Chainee() { IReadOnlyList results = Quotes .ToSma(2) - .GetT3(); + .ToT3(); Assert.AreEqual(502, results.Count); Assert.AreEqual(501, results.Count(x => x.T3 != null)); @@ -59,7 +59,7 @@ public void Chainee() public void Chainor() { IReadOnlyList results = Quotes - .GetT3() + .ToT3() .ToSma(10); Assert.AreEqual(502, results.Count); @@ -69,7 +69,7 @@ public void Chainor() public override void BadData() { IReadOnlyList r = BadQuotes - .GetT3(); + .ToT3(); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.T3 is double.NaN)); @@ -79,12 +79,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetT3(); + .ToT3(); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetT3(); + .ToT3(); Assert.AreEqual(1, r1.Count); } @@ -94,10 +94,10 @@ public void Exceptions() { // bad lookback period Assert.ThrowsException(() => - Quotes.GetT3(0)); + Quotes.ToT3(0)); // bad volume factor Assert.ThrowsException(() => - Quotes.GetT3(25, 0)); + Quotes.ToT3(25, 0)); } } diff --git a/tests/indicators/s-z/Tema/Tema.StaticSeries.Tests.cs b/tests/indicators/s-z/Tema/Tema.StaticSeries.Tests.cs index 2878835ae..23e39b123 100644 --- a/tests/indicators/s-z/Tema/Tema.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/Tema/Tema.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class Tema : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = Quotes - .GetTema(20); + .ToTema(20); // proper quantities Assert.AreEqual(502, results.Count); @@ -32,7 +32,7 @@ public void UseReusable() { IReadOnlyList results = Quotes .Use(CandlePart.Close) - .GetTema(20); + .ToTema(20); Assert.AreEqual(502, results.Count); Assert.AreEqual(483, results.Count(x => x.Tema != null)); @@ -43,7 +43,7 @@ public void Chainee() { IReadOnlyList results = Quotes .ToSma(2) - .GetTema(20); + .ToTema(20); Assert.AreEqual(502, results.Count); Assert.AreEqual(482, results.Count(x => x.Tema != null)); @@ -53,7 +53,7 @@ public void Chainee() public void Chainor() { IReadOnlyList results = Quotes - .GetTema(20) + .ToTema(20) .ToSma(10); Assert.AreEqual(502, results.Count); @@ -64,7 +64,7 @@ public void Chainor() public override void BadData() { IReadOnlyList r = BadQuotes - .GetTema(15); + .ToTema(15); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Tema is double.NaN)); @@ -74,12 +74,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetTema(5); + .ToTema(5); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetTema(5); + .ToTema(5); Assert.AreEqual(1, r1.Count); } @@ -88,7 +88,7 @@ public override void NoQuotes() public void Removed() { IReadOnlyList results = Quotes - .GetTema(20) + .ToTema(20) .RemoveWarmupPeriods(); // assertions @@ -102,5 +102,5 @@ public void Removed() [TestMethod] public void Exceptions() => Assert.ThrowsException(() - => Quotes.GetTema(0)); + => Quotes.ToTema(0)); } diff --git a/tests/indicators/s-z/Tr/Tr.StaticSeries.Tests.cs b/tests/indicators/s-z/Tr/Tr.StaticSeries.Tests.cs index 1e5a2b71d..e44f90c03 100644 --- a/tests/indicators/s-z/Tr/Tr.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/Tr/Tr.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class Tr : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = Quotes - .GetTr(); + .ToTr(); // proper quantities Assert.AreEqual(502, results.Count); @@ -41,11 +41,11 @@ public void Chainor() { // same as ATR IReadOnlyList results = Quotes - .GetTr() - .GetSmma(14); + .ToTr() + .ToSmma(14); IReadOnlyList atrResults = Quotes - .GetAtr(); + .ToAtr(); for (int i = 0; i < results.Count; i++) { @@ -61,7 +61,7 @@ public void Chainor() public override void BadData() { IReadOnlyList r = BadQuotes - .GetTr(); + .ToTr(); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Tr is double.NaN)); @@ -71,12 +71,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetTr(); + .ToTr(); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetTr(); + .ToTr(); Assert.AreEqual(1, r1.Count); } diff --git a/tests/indicators/s-z/Tr/Tr.StreamHub.Tests.cs b/tests/indicators/s-z/Tr/Tr.StreamHub.Tests.cs index 3b94e3cd0..8225ac7f0 100644 --- a/tests/indicators/s-z/Tr/Tr.StreamHub.Tests.cs +++ b/tests/indicators/s-z/Tr/Tr.StreamHub.Tests.cs @@ -56,7 +56,7 @@ IReadOnlyList streamList // time-series, for comparison IReadOnlyList seriesList = quotesList - .GetTr(); + .ToTr(); // assert, should equal series streamList.Should().HaveCount(length - 1); @@ -102,7 +102,7 @@ IReadOnlyList streamList // time-series, for comparison IReadOnlyList seriesList = quotesList - .GetTr() + .ToTr() .ToSma(smaPeriods); // assert, should equal series diff --git a/tests/indicators/s-z/Trix/Trix.StaticSeries.Tests.cs b/tests/indicators/s-z/Trix/Trix.StaticSeries.Tests.cs index 88b041932..626d544b5 100644 --- a/tests/indicators/s-z/Trix/Trix.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/Trix/Trix.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class Trix : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = Quotes - .GetTrix(20); + .ToTrix(20); // proper quantities Assert.AreEqual(502, results.Count); @@ -37,7 +37,7 @@ public void UseReusable() { IReadOnlyList results = Quotes .Use(CandlePart.Close) - .GetTrix(20); + .ToTrix(20); Assert.AreEqual(502, results.Count); Assert.AreEqual(482, results.Count(x => x.Trix != null)); @@ -48,7 +48,7 @@ public void Chainee() { IReadOnlyList results = Quotes .ToSma(2) - .GetTrix(20); + .ToTrix(20); Assert.AreEqual(502, results.Count); Assert.AreEqual(481, results.Count(x => x.Trix != null)); @@ -58,7 +58,7 @@ public void Chainee() public void Chainor() { IReadOnlyList results = Quotes - .GetTrix(20) + .ToTrix(20) .ToSma(10); Assert.AreEqual(502, results.Count); @@ -69,7 +69,7 @@ public void Chainor() public override void BadData() { IReadOnlyList r = BadQuotes - .GetTrix(15); + .ToTrix(15); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Trix is double.NaN)); @@ -79,12 +79,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetTrix(5); + .ToTrix(5); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetTrix(5); + .ToTrix(5); Assert.AreEqual(1, r1.Count); } @@ -93,7 +93,7 @@ public override void NoQuotes() public void Removed() { IReadOnlyList results = Quotes - .GetTrix(20) + .ToTrix(20) .RemoveWarmupPeriods(); // assertions @@ -108,5 +108,5 @@ public void Removed() [TestMethod] public void Exceptions() => Assert.ThrowsException(() - => Quotes.GetTrix(0)); + => Quotes.ToTrix(0)); } diff --git a/tests/indicators/s-z/Tsi/Tsi.StaticSeries.Tests.cs b/tests/indicators/s-z/Tsi/Tsi.StaticSeries.Tests.cs index 1557345d0..ec96ba655 100644 --- a/tests/indicators/s-z/Tsi/Tsi.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/Tsi/Tsi.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class Tsi : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = Quotes - .GetTsi(); + .ToTsi(); // proper quantities Assert.AreEqual(502, results.Count); @@ -45,7 +45,7 @@ public void UseReusable() { IReadOnlyList results = Quotes .Use(CandlePart.Close) - .GetTsi(); + .ToTsi(); Assert.AreEqual(502, results.Count); Assert.AreEqual(465, results.Count(x => x.Tsi != null)); @@ -56,7 +56,7 @@ public void Chainee() { IReadOnlyList results = Quotes .ToSma(2) - .GetTsi(); + .ToTsi(); Assert.AreEqual(502, results.Count); Assert.AreEqual(464, results.Count(x => x.Tsi != null)); @@ -66,7 +66,7 @@ public void Chainee() public void Chainor() { IReadOnlyList results = Quotes - .GetTsi() + .ToTsi() .ToSma(10); Assert.AreEqual(502, results.Count); @@ -77,7 +77,7 @@ public void Chainor() public override void BadData() { IReadOnlyList r = BadQuotes - .GetTsi(); + .ToTsi(); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Tsi is double.NaN)); @@ -87,7 +87,7 @@ public override void BadData() public void BigData() { IReadOnlyList r = BigQuotes - .GetTsi(); + .ToTsi(); Assert.AreEqual(1246, r.Count); } @@ -96,12 +96,12 @@ public void BigData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetTsi(); + .ToTsi(); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetTsi(); + .ToTsi(); Assert.AreEqual(1, r1.Count); } @@ -110,7 +110,7 @@ public override void NoQuotes() public void Removed() { IReadOnlyList results = Quotes - .GetTsi() + .ToTsi() .RemoveWarmupPeriods(); // assertions @@ -126,14 +126,14 @@ public void Exceptions() { // bad lookback period Assert.ThrowsException(() => - Quotes.GetTsi(0)); + Quotes.ToTsi(0)); // bad smoothing period Assert.ThrowsException(() => - Quotes.GetTsi(25, 0)); + Quotes.ToTsi(25, 0)); // bad signal period Assert.ThrowsException(() => - Quotes.GetTsi(25, 13, -1)); + Quotes.ToTsi(25, 13, -1)); } } diff --git a/tests/indicators/s-z/UlcerIndex/UlcerIndex.StaticSeries.Tests.cs b/tests/indicators/s-z/UlcerIndex/UlcerIndex.StaticSeries.Tests.cs index d38b6646b..8e08fa5f7 100644 --- a/tests/indicators/s-z/UlcerIndex/UlcerIndex.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/UlcerIndex/UlcerIndex.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class UlcerIndex : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = Quotes - .GetUlcerIndex(); + .ToUlcerIndex(); // proper quantities Assert.AreEqual(502, results.Count); @@ -23,7 +23,7 @@ public void UseReusable() { IReadOnlyList results = Quotes .Use(CandlePart.Close) - .GetUlcerIndex(); + .ToUlcerIndex(); Assert.AreEqual(502, results.Count); Assert.AreEqual(489, results.Count(x => x.UlcerIndex != null)); @@ -34,7 +34,7 @@ public void Chainee() { IReadOnlyList results = Quotes .ToSma(2) - .GetUlcerIndex(); + .ToUlcerIndex(); Assert.AreEqual(502, results.Count); Assert.AreEqual(488, results.Count(x => x.UlcerIndex != null)); @@ -44,7 +44,7 @@ public void Chainee() public void Chainor() { IReadOnlyList results = Quotes - .GetUlcerIndex() + .ToUlcerIndex() .ToSma(10); Assert.AreEqual(502, results.Count); @@ -55,7 +55,7 @@ public void Chainor() public override void BadData() { IReadOnlyList r = BadQuotes - .GetUlcerIndex(15); + .ToUlcerIndex(15); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.UlcerIndex is double.NaN)); @@ -65,12 +65,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetUlcerIndex(); + .ToUlcerIndex(); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetUlcerIndex(); + .ToUlcerIndex(); Assert.AreEqual(1, r1.Count); } @@ -79,7 +79,7 @@ public override void NoQuotes() public void Removed() { IReadOnlyList results = Quotes - .GetUlcerIndex() + .ToUlcerIndex() .RemoveWarmupPeriods(); // assertions @@ -93,5 +93,5 @@ public void Removed() [TestMethod] public void Exceptions() => Assert.ThrowsException(() - => Quotes.GetUlcerIndex(0)); + => Quotes.ToUlcerIndex(0)); } diff --git a/tests/indicators/s-z/Ultimate/Ultimate.StaticSeries.Tests.cs b/tests/indicators/s-z/Ultimate/Ultimate.StaticSeries.Tests.cs index e2ab1a19a..8571195da 100644 --- a/tests/indicators/s-z/Ultimate/Ultimate.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/Ultimate/Ultimate.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class Ultimate : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = Quotes - .GetUltimate(); + .ToUltimate(); // proper quantities Assert.AreEqual(502, results.Count); @@ -28,7 +28,7 @@ public override void Standard() public void Chainor() { IReadOnlyList results = Quotes - .GetUltimate() + .ToUltimate() .ToSma(10); Assert.AreEqual(502, results.Count); @@ -39,7 +39,7 @@ public void Chainor() public override void BadData() { IReadOnlyList r = BadQuotes - .GetUltimate(1, 2, 3); + .ToUltimate(1, 2, 3); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Ultimate is double.NaN)); @@ -49,12 +49,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetUltimate(); + .ToUltimate(); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetUltimate(); + .ToUltimate(); Assert.AreEqual(1, r1.Count); } @@ -63,7 +63,7 @@ public override void NoQuotes() public void Removed() { IReadOnlyList results = Quotes - .GetUltimate() + .ToUltimate() .RemoveWarmupPeriods(); // assertions @@ -78,14 +78,14 @@ public void Exceptions() { // bad short period Assert.ThrowsException(() => - Quotes.GetUltimate(0)); + Quotes.ToUltimate(0)); // bad middle period Assert.ThrowsException(() => - Quotes.GetUltimate(7, 6)); + Quotes.ToUltimate(7, 6)); // bad long period Assert.ThrowsException(() => - Quotes.GetUltimate(7, 14, 11)); + Quotes.ToUltimate(7, 14, 11)); } } diff --git a/tests/indicators/s-z/VolatilityStop/VolatilityStop.StaticSeries.Tests.cs b/tests/indicators/s-z/VolatilityStop/VolatilityStop.StaticSeries.Tests.cs index 5e5198956..66687b868 100644 --- a/tests/indicators/s-z/VolatilityStop/VolatilityStop.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/VolatilityStop/VolatilityStop.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class VolatilityStop : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = - Quotes.GetVolatilityStop(14); + Quotes.ToVolatilityStop(14); // proper quantities Assert.AreEqual(502, results.Count); @@ -64,7 +64,7 @@ public override void Standard() public void Chainor() { IReadOnlyList results = Quotes - .GetVolatilityStop() + .ToVolatilityStop() .ToSma(10); Assert.AreEqual(502, results.Count); @@ -75,7 +75,7 @@ public void Chainor() public override void BadData() { IReadOnlyList r = BadQuotes - .GetVolatilityStop(); + .ToVolatilityStop(); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Sar is double.NaN)); @@ -85,12 +85,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetVolatilityStop(); + .ToVolatilityStop(); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetVolatilityStop(); + .ToVolatilityStop(); Assert.AreEqual(1, r1.Count); } @@ -99,7 +99,7 @@ public override void NoQuotes() public void Removed() { IReadOnlyList results = Quotes - .GetVolatilityStop(14) + .ToVolatilityStop(14) .RemoveWarmupPeriods(); // assertions @@ -115,10 +115,10 @@ public void Exceptions() { // bad lookback period Assert.ThrowsException(() => - Quotes.GetVolatilityStop(1)); + Quotes.ToVolatilityStop(1)); // bad multiplier Assert.ThrowsException(() => - Quotes.GetVolatilityStop(20, 0)); + Quotes.ToVolatilityStop(20, 0)); } } diff --git a/tests/indicators/s-z/Vortex/Vortex.StaticSeries.Tests.cs b/tests/indicators/s-z/Vortex/Vortex.StaticSeries.Tests.cs index 8ef219ea8..389863567 100644 --- a/tests/indicators/s-z/Vortex/Vortex.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/Vortex/Vortex.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class Vortex : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = Quotes - .GetVortex(14); + .ToVortex(14); // proper quantities Assert.AreEqual(502, results.Count); @@ -39,7 +39,7 @@ public override void Standard() public override void BadData() { IReadOnlyList r = BadQuotes - .GetVortex(20); + .ToVortex(20); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Pvi is double.NaN)); @@ -49,12 +49,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetVortex(5); + .ToVortex(5); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetVortex(5); + .ToVortex(5); Assert.AreEqual(1, r1.Count); } @@ -63,7 +63,7 @@ public override void NoQuotes() public void Condense() { IReadOnlyList results = Quotes - .GetVortex(14) + .ToVortex(14) .Condense(); // assertions @@ -78,7 +78,7 @@ public void Condense() public void Removed() { IReadOnlyList results = Quotes - .GetVortex(14) + .ToVortex(14) .RemoveWarmupPeriods(); // assertions @@ -93,5 +93,5 @@ public void Removed() [TestMethod] public void Exceptions() => Assert.ThrowsException(() - => Quotes.GetVortex(1)); + => Quotes.ToVortex(1)); } diff --git a/tests/indicators/s-z/Vwap/Vwap.StaticSeries.Tests.cs b/tests/indicators/s-z/Vwap/Vwap.StaticSeries.Tests.cs index 041b4ea1c..998368ce2 100644 --- a/tests/indicators/s-z/Vwap/Vwap.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/Vwap/Vwap.StaticSeries.Tests.cs @@ -10,7 +10,7 @@ public class Vwap : StaticSeriesTestBase [TestMethod] public override void Standard() { - IReadOnlyList results = intraday.GetVwap(); + IReadOnlyList results = intraday.ToVwap(); // proper quantities Assert.AreEqual(391, results.Count); @@ -37,7 +37,7 @@ public void WithStartDate() DateTime.ParseExact("2020-12-15 10:00", "yyyy-MM-dd h:mm", englishCulture); IReadOnlyList results = intraday - .GetVwap(startDate); + .ToVwap(startDate); // proper quantities Assert.AreEqual(391, results.Count); @@ -61,7 +61,7 @@ public void WithStartDate() public void Chainor() { IReadOnlyList results = Quotes - .GetVwap() + .ToVwap() .ToSma(10); Assert.AreEqual(502, results.Count); @@ -72,7 +72,7 @@ public void Chainor() public override void BadData() { IReadOnlyList r = BadQuotes - .GetVwap(); + .ToVwap(); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Vwap is double.NaN)); @@ -82,12 +82,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetVwap(); + .ToVwap(); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetVwap(); + .ToVwap(); Assert.AreEqual(1, r1.Count); } @@ -97,7 +97,7 @@ public void Removed() { // no start date IReadOnlyList results = intraday - .GetVwap() + .ToVwap() .RemoveWarmupPeriods(); // assertions @@ -111,7 +111,7 @@ public void Removed() DateTime.ParseExact("2020-12-15 10:00", "yyyy-MM-dd h:mm", englishCulture); IReadOnlyList sdResults = intraday - .GetVwap(startDate) + .ToVwap(startDate) .RemoveWarmupPeriods(); // assertions @@ -129,6 +129,6 @@ public void Exceptions() DateTime.ParseExact("2000-12-15", "yyyy-MM-dd", englishCulture); Assert.ThrowsException(() => - Quotes.GetVwap(startDate)); + Quotes.ToVwap(startDate)); } } diff --git a/tests/indicators/s-z/Vwma/Vwma.StaticSeries.Tests.cs b/tests/indicators/s-z/Vwma/Vwma.StaticSeries.Tests.cs index 8b3e75ec0..8cfc11cc0 100644 --- a/tests/indicators/s-z/Vwma/Vwma.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/Vwma/Vwma.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class Vwma : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = Quotes - .GetVwma(10); + .ToVwma(10); // proper quantities Assert.AreEqual(502, results.Count); @@ -28,7 +28,7 @@ public override void Standard() public void Chainor() { IReadOnlyList results = Quotes - .GetVwma(10) + .ToVwma(10) .ToSma(10); Assert.AreEqual(502, results.Count); @@ -39,7 +39,7 @@ public void Chainor() public override void BadData() { IReadOnlyList r = BadQuotes - .GetVwma(15); + .ToVwma(15); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Vwma is double.NaN)); @@ -49,12 +49,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetVwma(4); + .ToVwma(4); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetVwma(4); + .ToVwma(4); Assert.AreEqual(1, r1.Count); } @@ -63,7 +63,7 @@ public override void NoQuotes() public void Removed() { IReadOnlyList results = Quotes - .GetVwma(10) + .ToVwma(10) .RemoveWarmupPeriods(); // assertions @@ -77,5 +77,5 @@ public void Removed() [TestMethod] public void Exceptions() => Assert.ThrowsException(() - => Quotes.GetVwma(0)); + => Quotes.ToVwma(0)); } diff --git a/tests/indicators/s-z/WilliamsR/WilliamsR.StaticSeries.Tests.cs b/tests/indicators/s-z/WilliamsR/WilliamsR.StaticSeries.Tests.cs index cee2ffdea..c0af8b3e2 100644 --- a/tests/indicators/s-z/WilliamsR/WilliamsR.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/WilliamsR/WilliamsR.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class WilliamsR : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = Quotes - .GetWilliamsR(); + .ToWilliamsR(); // proper quantities Assert.AreEqual(502, results.Count); @@ -37,7 +37,7 @@ public override void Standard() public void Chainor() { IReadOnlyList results = Quotes - .GetWilliamsR() + .ToWilliamsR() .ToSma(10); Assert.AreEqual(502, results.Count); @@ -48,7 +48,7 @@ public void Chainor() public override void BadData() { IReadOnlyList results = BadQuotes - .GetWilliamsR(20); + .ToWilliamsR(20); Assert.AreEqual(502, results.Count); Assert.AreEqual(0, results.Count(x => x.WilliamsR is double.NaN)); @@ -58,12 +58,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetWilliamsR(); + .ToWilliamsR(); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetWilliamsR(); + .ToWilliamsR(); Assert.AreEqual(1, r1.Count); } @@ -72,7 +72,7 @@ public override void NoQuotes() public void Removed() { IReadOnlyList results = Quotes - .GetWilliamsR() + .ToWilliamsR() .RemoveWarmupPeriods(); // assertions @@ -87,7 +87,7 @@ public void Boundary() { IReadOnlyList results = Data .GetRandom(2500) - .GetWilliamsR(); + .ToWilliamsR(); // analyze boundary for (int i = 0; i < results.Count; i++) @@ -116,7 +116,7 @@ public void Issue1127() // get indicators IReadOnlyList resultsList = quotesList - .GetWilliamsR(); + .ToWilliamsR(); Console.WriteLine($"%R from {length} quotes."); @@ -140,5 +140,5 @@ public void Issue1127() [TestMethod] public void Exceptions() => Assert.ThrowsException(() - => Quotes.GetWilliamsR(0)); + => Quotes.ToWilliamsR(0)); } diff --git a/tests/indicators/s-z/Wma/Wma.StaticSeries.Tests.cs b/tests/indicators/s-z/Wma/Wma.StaticSeries.Tests.cs index adaa328d7..842b28399 100644 --- a/tests/indicators/s-z/Wma/Wma.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/Wma/Wma.StaticSeries.Tests.cs @@ -7,7 +7,7 @@ public class Wma : StaticSeriesTestBase public override void Standard() { IReadOnlyList results = Quotes - .GetWma(20); + .ToWma(20); // proper quantities Assert.AreEqual(502, results.Count); @@ -26,7 +26,7 @@ public void UseReusable() { IReadOnlyList results = Quotes .Use(CandlePart.Close) - .GetWma(20); + .ToWma(20); Assert.AreEqual(502, results.Count); Assert.AreEqual(483, results.Count(x => x.Wma != null)); @@ -37,7 +37,7 @@ public void Chainee() { IReadOnlyList results = Quotes .ToSma(2) - .GetWma(20); + .ToWma(20); Assert.AreEqual(502, results.Count); Assert.AreEqual(482, results.Count(x => x.Wma != null)); @@ -47,7 +47,7 @@ public void Chainee() public void Chainor() { IReadOnlyList results = Quotes - .GetWma(20) + .ToWma(20) .ToSma(10); Assert.AreEqual(502, results.Count); @@ -58,11 +58,11 @@ public void Chainor() public void Chaining() { IReadOnlyList standard = Quotes - .GetWma(17); + .ToWma(17); IReadOnlyList results = Quotes .Use(CandlePart.Close) - .GetWma(17); + .ToWma(17); // assertions for (int i = 0; i < results.Count; i++) @@ -79,7 +79,7 @@ public void Chaining() public override void BadData() { IReadOnlyList r = BadQuotes - .GetWma(15); + .ToWma(15); Assert.AreEqual(502, r.Count); Assert.AreEqual(0, r.Count(x => x.Wma is double.NaN)); @@ -89,12 +89,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetWma(5); + .ToWma(5); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetWma(5); + .ToWma(5); Assert.AreEqual(1, r1.Count); } @@ -103,7 +103,7 @@ public override void NoQuotes() public void Removed() { IReadOnlyList results = Quotes - .GetWma(20) + .ToWma(20) .RemoveWarmupPeriods(); // assertions @@ -117,5 +117,5 @@ public void Removed() [TestMethod] public void Exceptions() => Assert.ThrowsException(() - => Quotes.GetWma(0)); + => Quotes.ToWma(0)); } diff --git a/tests/indicators/s-z/ZigZag/ZigZag.StaticSeries.Tests.cs b/tests/indicators/s-z/ZigZag/ZigZag.StaticSeries.Tests.cs index 0a57b7b76..3994d2863 100644 --- a/tests/indicators/s-z/ZigZag/ZigZag.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/ZigZag/ZigZag.StaticSeries.Tests.cs @@ -9,7 +9,7 @@ public class ZigZag : StaticSeriesTestBase public override void Standard() // on Close { IReadOnlyList results = - Quotes.GetZigZag(EndType.Close, 3); + Quotes.ToZigZag(EndType.Close, 3); // proper quantities Assert.AreEqual(502, results.Count); @@ -60,7 +60,7 @@ public override void Standard() // on Close public void StandardHighLow() { IReadOnlyList results = - Quotes.GetZigZag(EndType.HighLow, 3); + Quotes.ToZigZag(EndType.HighLow, 3); // proper quantities Assert.AreEqual(502, results.Count); @@ -111,7 +111,7 @@ public void StandardHighLow() public void Chainor() { IReadOnlyList results = Quotes - .GetZigZag(EndType.Close, 3) + .ToZigZag(EndType.Close, 3) .ToSma(10); Assert.AreEqual(502, results.Count); @@ -128,7 +128,7 @@ public void NoEntry() .DeserializeObject>(json); IReadOnlyList results = quotes - .GetZigZag(); + .ToZigZag(); Assert.AreEqual(0, results.Count(x => x.PointType != null)); } @@ -143,7 +143,7 @@ public void Issue632() .DeserializeObject>(json); IReadOnlyList resultsList = quotesList - .GetZigZag(); + .ToZigZag(); Assert.AreEqual(17, resultsList.Count); } @@ -152,12 +152,12 @@ public void Issue632() public override void BadData() { IReadOnlyList r1 = BadQuotes - .GetZigZag(); + .ToZigZag(); Assert.AreEqual(502, r1.Count); IReadOnlyList r2 = BadQuotes - .GetZigZag(EndType.HighLow); + .ToZigZag(EndType.HighLow); Assert.AreEqual(502, r2.Count); } @@ -166,12 +166,12 @@ public override void BadData() public override void NoQuotes() { IReadOnlyList r0 = Noquotes - .GetZigZag(); + .ToZigZag(); Assert.AreEqual(0, r0.Count); IReadOnlyList r1 = Onequote - .GetZigZag(); + .ToZigZag(); Assert.AreEqual(1, r1.Count); } @@ -180,7 +180,7 @@ public override void NoQuotes() public void Condense() { IReadOnlyList results = Quotes - .GetZigZag(EndType.Close, 3) + .ToZigZag(EndType.Close, 3) .Condense(); // assertions @@ -196,12 +196,12 @@ public void SchrodingerScenario() .DeserializeObject>(json) .OrderBy(x => x.Timestamp); - IReadOnlyList r1 = h.GetZigZag(EndType.Close, 0.25m).ToList(); + IReadOnlyList r1 = h.ToZigZag(EndType.Close, 0.25m).ToList(); Assert.AreEqual(342, r1.Count); // first period has High/Low that exceeds threhold // where it is both a H and L pivot simultaenously - IReadOnlyList r2 = h.GetZigZag(EndType.HighLow, 3).ToList(); + IReadOnlyList r2 = h.ToZigZag(EndType.HighLow, 3).ToList(); Assert.AreEqual(342, r2.Count); } @@ -210,10 +210,10 @@ public void Exceptions() { // bad lookback period Assert.ThrowsException(() - => Quotes.GetZigZag(EndType.Close, 0)); + => Quotes.ToZigZag(EndType.Close, 0)); // bad end type Assert.ThrowsException(() - => Quotes.GetZigZag((EndType)int.MaxValue, 2)); + => Quotes.ToZigZag((EndType)int.MaxValue, 2)); } } diff --git a/tests/other/Convergence.Tests.cs b/tests/other/Convergence.Tests.cs index 232a52a47..541bb7cca 100644 --- a/tests/other/Convergence.Tests.cs +++ b/tests/other/Convergence.Tests.cs @@ -12,7 +12,7 @@ public void Adx() foreach (int qty in QuotesQuantities) { IReadOnlyList qts = Data.GetLongish(qty); - IReadOnlyList r = qts.GetAdx(); + IReadOnlyList r = qts.ToAdx(); AdxResult l = r[^1]; Console.WriteLine($"ADX(14) on {l.Timestamp:d} with {qts.Count,4} historical qts: {l.Adx:N8}"); @@ -25,7 +25,7 @@ public void Alligator() foreach (int qty in QuotesQuantities) { IReadOnlyList quotes = Data.GetLongish(qty); - IReadOnlyList r = quotes.GetAlligator(); + IReadOnlyList r = quotes.ToAlligator(); AlligatorResult l = r[^1]; Console.WriteLine( @@ -40,7 +40,7 @@ public void Atr() foreach (int qty in QuotesQuantities) { IReadOnlyList qts = Data.GetLongish(qty); - IReadOnlyList r = qts.GetAtr(); + IReadOnlyList r = qts.ToAtr(); AtrResult l = r[^1]; Console.WriteLine($"ATR(14) on {l.Timestamp:d} with {qts.Count,4} periods: {l.Atr:N8}"); @@ -53,7 +53,7 @@ public void ChaikinOsc() foreach (int qty in QuotesQuantities) { IReadOnlyList qts = Data.GetLongish(qty); - IReadOnlyList r = qts.GetChaikinOsc(); + IReadOnlyList r = qts.ToChaikinOsc(); ChaikinOscResult l = r[^1]; Console.WriteLine($"CHAIKIN OSC on {l.Timestamp:d} with {qts.Count,4} periods: {l.Oscillator:N8}"); @@ -66,7 +66,7 @@ public void ConnorsRsi() foreach (int qty in QuotesQuantities) { IReadOnlyList qts = Data.GetLongish(qty); - IReadOnlyList r = qts.GetConnorsRsi(3, 2, 10); + IReadOnlyList r = qts.ToConnorsRsi(3, 2, 10); ConnorsRsiResult l = r[^1]; Console.WriteLine($"CRSI on {l.Timestamp:d} with {qts.Count,4} periods: {l.ConnorsRsi:N8}"); @@ -79,7 +79,7 @@ public void Dema() foreach (int qty in QuotesQuantities) { IReadOnlyList qts = Data.GetLongish(qty); - IReadOnlyList r = qts.GetDema(15); + IReadOnlyList r = qts.ToDema(15); DemaResult l = r[^1]; Console.WriteLine($"DEMA(15) on {l.Timestamp:d} with {qts.Count,4} periods: {l.Dema:N8}"); @@ -92,7 +92,7 @@ public void Dynamic() foreach (int qty in QuotesQuantities) { IReadOnlyList qts = Data.GetLongish(qty); - IReadOnlyList r = qts.GetDynamic(100); + IReadOnlyList r = qts.ToDynamic(100); DynamicResult l = r[^1]; Console.WriteLine($"DYNAMIC(15) on {l.Timestamp:d} with {qts.Count,4} periods: {l.Dynamic:N8}"); @@ -118,7 +118,7 @@ public void FisherTransform() foreach (int qty in QuotesQuantities) { IReadOnlyList qts = Data.GetLongish(qty); - IReadOnlyList r = qts.GetFisherTransform(); + IReadOnlyList r = qts.ToFisherTransform(); FisherTransformResult l = r[^1]; Console.WriteLine($"FT(10) on {l.Timestamp:d} with {qts.Count,4} periods: {l.Fisher:N8}"); @@ -131,7 +131,7 @@ public void Gator() foreach (int qty in QuotesQuantities) { IReadOnlyList quotes = Data.GetLongish(qty); - IReadOnlyList r = quotes.GetGator(); + IReadOnlyList r = quotes.ToGator(); GatorResult l = r[^1]; Console.WriteLine( @@ -146,7 +146,7 @@ public void HtTrendline() foreach (int qty in QuotesQuantities) { IReadOnlyList qts = Data.GetLongish(qty); - IReadOnlyList r = qts.GetHtTrendline(); + IReadOnlyList r = qts.ToHtTrendline(); HtlResult l = r[^1]; Console.WriteLine($"HTL on {l.Timestamp:d} with {qts.Count,4} periods: {l.Trendline:N8}"); @@ -159,7 +159,7 @@ public void Kama() foreach (int qty in QuotesQuantities) { IReadOnlyList qts = Data.GetLongish(qty); - IReadOnlyList r = qts.GetKama(); + IReadOnlyList r = qts.ToKama(); KamaResult l = r[^1]; Console.WriteLine($"KAMA(10) on {l.Timestamp:d} with {qts.Count,4} periods: {l.Kama:N8}"); @@ -172,7 +172,7 @@ public void Keltner() foreach (int qty in QuotesQuantities) { IReadOnlyList qts = Data.GetLongish(qty); - IReadOnlyList r = qts.GetKeltner(100); + IReadOnlyList r = qts.ToKeltner(100); KeltnerResult l = r[^1]; Console.WriteLine($"KC-UP on {l.Timestamp:d} with {qts.Count,4} periods: {l.UpperBand:N8}"); @@ -185,7 +185,7 @@ public void Macd() foreach (int qty in QuotesQuantities) { IReadOnlyList qts = Data.GetLongish(15 + qty); - IReadOnlyList r = qts.GetMacd(); + IReadOnlyList r = qts.ToMacd(); MacdResult l = r[^1]; Console.WriteLine($"MACD on {l.Timestamp:d} with {qts.Count,4} periods: {l.Macd:N8}"); @@ -198,7 +198,7 @@ public void Mama() foreach (int qty in QuotesQuantities) { IReadOnlyList qts = Data.GetLongish(qty); - IReadOnlyList r = qts.GetMama(); + IReadOnlyList r = qts.ToMama(); MamaResult l = r[^1]; Console.WriteLine($"MAMA on {l.Timestamp:d} with {qts.Count,4} periods: {l.Mama:N8}"); @@ -211,7 +211,7 @@ public void Pmo() foreach (int qty in QuotesQuantities) { IReadOnlyList qts = Data.GetLongish(qty); - IReadOnlyList r = qts.GetPmo(); + IReadOnlyList r = qts.ToPmo(); PmoResult l = r[^1]; Console.WriteLine($"PMO on {l.Timestamp:d} with {qts.Count,4} periods: {l.Pmo:N8}"); @@ -224,7 +224,7 @@ public void Pvo() foreach (int qty in QuotesQuantities) { IReadOnlyList qts = Data.GetLongish(qty); - IReadOnlyList r = qts.GetPvo(); + IReadOnlyList r = qts.ToPvo(); PvoResult l = r[^1]; Console.WriteLine($"PVO on {l.Timestamp:d} with {qts.Count,4} periods: {l.Pvo:N8}"); @@ -237,7 +237,7 @@ public void Rsi() foreach (int qty in QuotesQuantities) { IReadOnlyList qts = Data.GetLongish(qty); - IReadOnlyList r = qts.GetRsi(); + IReadOnlyList r = qts.ToRsi(); RsiResult l = r[^1]; Console.WriteLine($"RSI(14) on {l.Timestamp:d} with {qts.Count,4} periods: {l.Rsi:N8}"); @@ -250,7 +250,7 @@ public void Smi() foreach (int qty in QuotesQuantities) { IReadOnlyList qts = Data.GetDefault(qty); - IReadOnlyList r = qts.GetSmi(14, 20, 5); + IReadOnlyList r = qts.ToSmi(14, 20, 5); SmiResult l = r[^1]; Console.WriteLine($"SMI on {l.Timestamp:d} with {qts.Count,4} periods: {l.Smi:N8}"); @@ -263,7 +263,7 @@ public void Smma() foreach (int qty in QuotesQuantities) { IReadOnlyList qts = Data.GetLongish(qty); - IReadOnlyList r = qts.GetSmma(15); + IReadOnlyList r = qts.ToSmma(15); SmmaResult l = r[^1]; Console.WriteLine($"SMMA(15) on {l.Timestamp:d} with {qts.Count,4} periods: {l.Smma:N8}"); @@ -276,7 +276,7 @@ public void StarcBands() foreach (int qty in QuotesQuantities) { IReadOnlyList qts = Data.GetLongish(qty); - IReadOnlyList r = qts.GetStarcBands(20); + IReadOnlyList r = qts.ToStarcBands(20); StarcBandsResult l = r[^1]; Console.WriteLine($"STARC UPPER on {l.Timestamp:d} with {qts.Count,4} periods: {l.UpperBand:N8}"); @@ -289,7 +289,7 @@ public void StochRsi() foreach (int qty in QuotesQuantities.Where(x => x <= 502)) { IReadOnlyList qts = Data.GetDefault(qty); - IReadOnlyList r = qts.GetStochRsi(14, 14, 3); + IReadOnlyList r = qts.ToStochRsi(14, 14, 3); StochRsiResult l = r[^1]; Console.WriteLine($"SRSI on {l.Timestamp:d} with {qts.Count,4} periods: {l.StochRsi:N8}"); @@ -302,7 +302,7 @@ public void T3() foreach (int qty in QuotesQuantities) { IReadOnlyList qts = Data.GetLongish(qty); - IReadOnlyList r = qts.GetT3(20); + IReadOnlyList r = qts.ToT3(20); T3Result l = r[^1]; Console.WriteLine($"T3 on {l.Timestamp:d} with {qts.Count,4} periods: {l.T3:N8}"); @@ -315,7 +315,7 @@ public void Tema() foreach (int qty in QuotesQuantities) { IReadOnlyList qts = Data.GetLongish(qty); - IReadOnlyList r = qts.GetTema(15); + IReadOnlyList r = qts.ToTema(15); TemaResult l = r[^1]; Console.WriteLine($"TEMA on {l.Timestamp:d} with {qts.Count,4} periods: {l.Tema:N8}"); @@ -328,7 +328,7 @@ public void Trix() foreach (int qty in QuotesQuantities) { IReadOnlyList qts = Data.GetLongish(qty); - IReadOnlyList r = qts.GetTrix(15); + IReadOnlyList r = qts.ToTrix(15); TrixResult l = r[^1]; Console.WriteLine($"TRIX on {l.Timestamp:d} with {qts.Count,4} periods: {l.Trix:N8}"); @@ -341,7 +341,7 @@ public void Tsi() foreach (int qty in QuotesQuantities) { IReadOnlyList qts = Data.GetLongish(20 + qty); - IReadOnlyList r = qts.GetTsi(); + IReadOnlyList r = qts.ToTsi(); TsiResult l = r[^1]; Console.WriteLine($"TSI on {l.Timestamp:d} with {qts.Count,4} periods: {l.Tsi:N8}"); @@ -354,7 +354,7 @@ public void Vortex() foreach (int qty in QuotesQuantities) { IReadOnlyList qts = Data.GetLongish(qty); - IReadOnlyList r = qts.GetVortex(14); + IReadOnlyList r = qts.ToVortex(14); VortexResult l = r[^1]; Console.WriteLine($"VI+ on {l.Timestamp:d} with {qts.Count,4} periods: {l.Pvi:N8}"); diff --git a/tests/other/PublicApi.Interface.Tests.cs b/tests/other/PublicApi.Interface.Tests.cs index 7e66e061e..1b307baed 100644 --- a/tests/other/PublicApi.Interface.Tests.cs +++ b/tests/other/PublicApi.Interface.Tests.cs @@ -99,14 +99,14 @@ public void StreamMany() // from quote provider provider.EndTransmission(); // get static equivalents for comparison - IEnumerable staticAdl = quotes.GetAdl(); - IReadOnlyList staticAtr = quotes.GetAtr(); - IReadOnlyList staticAtrStop = quotes.GetAtrStop(); - IEnumerable staticAlligator = quotes.GetAlligator(); + IEnumerable staticAdl = quotes.ToAdl(); + IReadOnlyList staticAtr = quotes.ToAtr(); + IReadOnlyList staticAtrStop = quotes.ToAtrStop(); + IEnumerable staticAlligator = quotes.ToAlligator(); IEnumerable staticEma = quotes.ToEma(20); IEnumerable staticQuotePart = quotes.Use(CandlePart.OHL3); IEnumerable staticSma = quotes.ToSma(20); - IReadOnlyList staticTr = quotes.GetTr(); + IReadOnlyList staticTr = quotes.ToTr(); // final results should persist in scope IReadOnlyList streamAdl = adlHub.Results; diff --git a/tests/performance/Perf.StaticSeries.cs b/tests/performance/Perf.StaticSeries.cs index cdecc570e..6892ef6e4 100644 --- a/tests/performance/Perf.StaticSeries.cs +++ b/tests/performance/Perf.StaticSeries.cs @@ -9,269 +9,269 @@ public class SeriesIndicators private static readonly IReadOnlyList o = Data.GetCompare(); [Benchmark] - public object GetAdl() => q.GetAdl(); + public object ToAdl() => q.ToAdl(); [Benchmark] - public object GetAdx() => q.GetAdx(); + public object ToAdx() => q.ToAdx(); [Benchmark] - public object GetAlligator() => q.GetAlligator(); + public object ToAlligator() => q.ToAlligator(); [Benchmark] - public object GetAlma() => q.GetAlma(); + public object ToAlma() => q.ToAlma(); [Benchmark] - public object GetAroon() => q.GetAroon(); + public object ToAroon() => q.ToAroon(); [Benchmark] - public object GetAtr() => q.GetAtr(); + public object ToAtr() => q.ToAtr(); [Benchmark] - public object GetAtrStop() => q.GetAtrStop(); + public object ToAtrStop() => q.ToAtrStop(); [Benchmark] - public object GetAwesome() => q.GetAwesome(); + public object ToAwesome() => q.ToAwesome(); [Benchmark] - public object GetBeta() => Indicator.GetBeta(q, o, 20, BetaType.Standard); + public object ToBeta() => Beta.ToBeta(q, o, 20, BetaType.Standard); [Benchmark] - public object GetBetaUp() => Indicator.GetBeta(q, o, 20, BetaType.Up); + public object ToBetaUp() => Beta.ToBeta(q, o, 20, BetaType.Up); [Benchmark] - public object GetBetaDown() => Indicator.GetBeta(q, o, 20, BetaType.Down); + public object ToBetaDown() => Beta.ToBeta(q, o, 20, BetaType.Down); [Benchmark] - public object GetBetaAll() => Indicator.GetBeta(q, o, 20, BetaType.All); + public object ToBetaAll() => Beta.ToBeta(q, o, 20, BetaType.All); [Benchmark] - public object GetBollingerBands() => q.GetBollingerBands(); + public object ToBollingerBands() => q.ToBollingerBands(); [Benchmark] - public object GetBop() => q.GetBop(); + public object ToBop() => q.ToBop(); [Benchmark] - public object GetCci() => q.GetCci(); + public object ToCci() => q.ToCci(); [Benchmark] - public object GetChaikinOsc() => q.GetChaikinOsc(); + public object ToChaikinOsc() => q.ToChaikinOsc(); [Benchmark] - public object GetChandelier() => q.GetChandelier(); + public object ToChandelier() => q.ToChandelier(); [Benchmark] - public object GetChop() => q.GetChop(); + public object ToChop() => q.ToChop(); [Benchmark] - public object GetCmf() => q.GetCmf(); + public object ToCmf() => q.ToCmf(); [Benchmark] - public object GetCmo() => q.GetCmo(14); + public object ToCmo() => q.ToCmo(14); [Benchmark] - public object GetConnorsRsi() => q.GetConnorsRsi(); + public object ToConnorsRsi() => q.ToConnorsRsi(); [Benchmark] - public object GetCorrelation() => q.GetCorrelation(o, 20); + public object ToCorrelation() => q.ToCorrelation(o, 20); [Benchmark] - public object GetDema() => q.GetDema(14); + public object ToDema() => q.ToDema(14); [Benchmark] - public object GetDoji() => q.GetDoji(); + public object ToDoji() => q.ToDoji(); [Benchmark] - public object GetDonchian() => q.GetDonchian(); + public object ToDonchian() => q.ToDonchian(); [Benchmark] - public object GetDpo() => q.GetDpo(14); + public object ToDpo() => q.ToDpo(14); [Benchmark] - public object GetDynamic() => q.GetDynamic(20); + public object ToDynamic() => q.ToDynamic(20); [Benchmark] - public object GetElderRay() => q.GetElderRay(); + public object ToElderRay() => q.ToElderRay(); [Benchmark] - public object GetEma() => q.ToEma(14); + public object ToEma() => q.ToEma(14); [Benchmark] - public object GetEpma() => q.GetEpma(14); + public object ToEpma() => q.ToEpma(14); [Benchmark] - public object GetFcb() => q.GetFcb(14); + public object ToFcb() => q.ToFcb(14); [Benchmark] - public object GetFisherTransform() => q.GetFisherTransform(10); + public object ToFisherTransform() => q.ToFisherTransform(10); [Benchmark] - public object GetForceIndex() => q.GetForceIndex(13); + public object ToForceIndex() => q.ToForceIndex(13); [Benchmark] - public object GetFractal() => q.GetFractal(); + public object ToFractal() => q.ToFractal(); [Benchmark] - public object GetGator() => q.GetGator(); + public object ToGator() => q.ToGator(); [Benchmark] - public object GetHeikinAshi() => q.GetHeikinAshi(); + public object ToHeikinAshi() => q.ToHeikinAshi(); [Benchmark] - public object GetHma() => q.GetHma(14); + public object ToHma() => q.ToHma(14); [Benchmark] - public object GetHtTrendline() => q.GetHtTrendline(); + public object ToHtTrendline() => q.ToHtTrendline(); [Benchmark] - public object GetHurst() => q.GetHurst(); + public object ToHurst() => q.ToHurst(); [Benchmark] - public object GetIchimoku() => q.GetIchimoku(); + public object ToIchimoku() => q.ToIchimoku(); [Benchmark] - public object GetKama() => q.GetKama(); + public object ToKama() => q.ToKama(); [Benchmark] - public object GetKlinger() => q.GetKvo(); + public object ToKlinger() => q.ToKvo(); [Benchmark] - public object GetKeltner() => q.GetKeltner(); + public object ToKeltner() => q.ToKeltner(); [Benchmark] - public object GetKvo() => q.GetKvo(); + public object ToKvo() => q.ToKvo(); [Benchmark] - public object GetMacd() => q.GetMacd(); + public object ToMacd() => q.ToMacd(); [Benchmark] - public object GetMaEnvelopes() => q.GetMaEnvelopes(20, 2.5, MaType.SMA); + public object ToMaEnvelopes() => q.ToMaEnvelopes(20, 2.5, MaType.SMA); [Benchmark] - public object GetMama() => q.GetMama(); + public object ToMama() => q.ToMama(); [Benchmark] - public object GetMarubozu() => q.GetMarubozu(); + public object ToMarubozu() => q.ToMarubozu(); [Benchmark] - public object GetMfi() => q.GetMfi(); + public object ToMfi() => q.ToMfi(); [Benchmark] - public object GetObv() => q.GetObv(); + public object ToObv() => q.ToObv(); [Benchmark] - public object GetParabolicSar() => q.GetParabolicSar(); + public object ToParabolicSar() => q.ToParabolicSar(); [Benchmark] - public object GetPivotPoints() => q.GetPivotPoints(PeriodSize.Month, PivotPointType.Standard); + public object ToPivotPoints() => q.ToPivotPoints(PeriodSize.Month, PivotPointType.Standard); [Benchmark] - public object GetPivots() => q.GetPivots(); + public object ToPivots() => q.ToPivots(); [Benchmark] - public object GetPmo() => q.GetPmo(); + public object ToPmo() => q.ToPmo(); [Benchmark] - public object GetPrs() => q.GetPrs(o); + public object ToPrs() => q.ToPrs(o); [Benchmark] - public object GetPvo() => q.GetPvo(); + public object ToPvo() => q.ToPvo(); [Benchmark] - public object GetRenko() => q.GetRenko(2.5m); + public object ToRenko() => q.ToRenko(2.5m); [Benchmark] - public object GetRenkoAtr() => q.GetRenko(14); + public object ToRenkoAtr() => q.ToRenko(14); [Benchmark] - public object GetRoc() => q.GetRoc(20); + public object ToRoc() => q.ToRoc(20); [Benchmark] - public object GetRocWb() => q.GetRocWb(12, 3, 12); + public object ToRocWb() => q.ToRocWb(12, 3, 12); [Benchmark] - public object GetRollingPivots() => q.GetRollingPivots(14, 1); + public object ToRollingPivots() => q.ToRollingPivots(14, 1); [Benchmark] - public object GetRsi() => q.GetRsi(); + public object ToRsi() => q.ToRsi(); [Benchmark] - public object GetSlope() => q.GetSlope(20); + public object ToSlope() => q.ToSlope(20); [Benchmark] - public object GetSma() => q.ToSma(10); + public object ToSma() => q.ToSma(10); [Benchmark] - public object GetSmaAnalysis() => q.GetSmaAnalysis(10); + public object ToSmaAnalysis() => q.ToSmaAnalysis(10); [Benchmark] - public object GetSmi() => q.GetSmi(5, 20, 5, 3); + public object ToSmi() => q.ToSmi(5, 20, 5, 3); [Benchmark] - public object GetSmma() => q.GetSmma(10); + public object ToSmma() => q.ToSmma(10); [Benchmark] - public object GetStarcBands() => q.GetStarcBands(10); + public object ToStarcBands() => q.ToStarcBands(10); [Benchmark] - public object GetStc() => q.GetStc(); + public object ToStc() => q.ToStc(); [Benchmark] - public object GetStdDev() => q.GetStdDev(20); + public object ToStdDev() => q.ToStdDev(20); [Benchmark] - public object GetStdDevChannels() => q.GetStdDevChannels(); + public object ToStdDevChannels() => q.ToStdDevChannels(); [Benchmark] - public object GetStoch() => q.GetStoch(); + public object ToStoch() => q.ToStoch(); [Benchmark] - public object GetStochSMMA() => q.GetStoch(9, 3, 3, 3, 2, MaType.SMMA); + public object ToStochSMMA() => q.ToStoch(9, 3, 3, 3, 2, MaType.SMMA); [Benchmark] - public object GetStochRsi() => q.GetStochRsi(14, 14, 3); + public object ToStochRsi() => q.ToStochRsi(14, 14, 3); [Benchmark] - public object GetSuperTrend() => q.GetSuperTrend(); + public object ToSuperTrend() => q.ToSuperTrend(); [Benchmark] - public object GetT3() => q.GetT3(); + public object ToT3() => q.ToT3(); [Benchmark] - public object GetTema() => q.GetTema(14); + public object ToTema() => q.ToTema(14); [Benchmark] - public object GetTr() => q.GetTr(); + public object ToTr() => q.ToTr(); [Benchmark] - public object GetTrix() => q.GetTrix(14); + public object ToTrix() => q.ToTrix(14); [Benchmark] - public object GetTsi() => q.GetTsi(); + public object ToTsi() => q.ToTsi(); [Benchmark] - public object GetUlcerIndex() => q.GetUlcerIndex(); + public object ToUlcerIndex() => q.ToUlcerIndex(); [Benchmark] - public object GetUltimate() => q.GetUltimate(); + public object ToUltimate() => q.ToUltimate(); [Benchmark] - public object GetVolatilityStop() => q.GetVolatilityStop(); + public object ToVolatilityStop() => q.ToVolatilityStop(); [Benchmark] - public object GetVortex() => q.GetVortex(14); + public object ToVortex() => q.ToVortex(14); [Benchmark] - public object GetVwap() => q.GetVwap(); + public object ToVwap() => q.ToVwap(); [Benchmark] - public object GetVwma() => q.GetVwma(14); + public object ToVwma() => q.ToVwma(14); [Benchmark] - public object GetWilliamsR() => q.GetWilliamsR(); + public object ToWilliamsR() => q.ToWilliamsR(); [Benchmark] - public object GetWma() => q.GetWma(14); + public object ToWma() => q.ToWma(14); [Benchmark] - public object GetZigZag() => q.GetZigZag(); + public object ToZigZag() => q.ToZigZag(); } From 5711cc54eed285bcdc19f3036424992ab6bb07fc Mon Sep 17 00:00:00 2001 From: Dave Skender <8432125+DaveSkender@users.noreply.github.com> Date: Mon, 14 Oct 2024 14:30:27 -0400 Subject: [PATCH 29/38] improve quote validation tests --- .../_common/Quotes/Quote.Validation.Tests.cs | 30 +++++++- tests/indicators/_testdata/TestData.Tests.cs | 77 +++++++++++++++++++ tests/other/PublicApi.Interface.Tests.cs | 14 +++- 3 files changed, 115 insertions(+), 6 deletions(-) create mode 100644 tests/indicators/_testdata/TestData.Tests.cs diff --git a/tests/indicators/_common/Quotes/Quote.Validation.Tests.cs b/tests/indicators/_common/Quotes/Quote.Validation.Tests.cs index a4f27eb64..d5af907a5 100644 --- a/tests/indicators/_common/Quotes/Quote.Validation.Tests.cs +++ b/tests/indicators/_common/Quotes/Quote.Validation.Tests.cs @@ -78,7 +78,7 @@ public void ValidateCut() [TestMethod] public void ValidateDuplicates() { - IReadOnlyList badHistory = new List + IReadOnlyList dupQuotes = new List { new(Timestamp: DateTime.ParseExact("2017-01-03", "yyyy-MM-dd", englishCulture), Open: 214.86m, High: 220.33m, Low: 210.96m, Close: 216.99m, Volume: 5923254), new(Timestamp: DateTime.ParseExact("2017-01-04", "yyyy-MM-dd", englishCulture), Open: 214.75m, High: 228.00m, Low: 214.31m, Close: 226.99m, Volume: 11213471), @@ -87,6 +87,32 @@ public void ValidateDuplicates() new(Timestamp: DateTime.ParseExact("2017-01-06", "yyyy-MM-dd", englishCulture), Open: 228.97m, High: 231.92m, Low: 228.00m, Close: 231.28m, Volume: 3979484) }; - Assert.ThrowsException(() => badHistory.Validate()); + InvalidQuotesException dx + = Assert.ThrowsException( + () => dupQuotes.Validate()); + + dx.Message.Should() + .Be("Duplicate date found on 1/6/2017 12:00:00 AM. (Parameter 'quotes')"); } + + [TestMethod] + public void ValidateOutOfSequence() + { + IReadOnlyList unorderedQuotes = new List + { + new(Timestamp: DateTime.ParseExact("2017-01-03", "yyyy-MM-dd", englishCulture), Open: 214.86m, High: 220.33m, Low: 210.96m, Close: 216.99m, Volume: 5923254), + new(Timestamp: DateTime.ParseExact("2017-01-04", "yyyy-MM-dd", englishCulture), Open: 214.75m, High: 228.00m, Low: 214.31m, Close: 226.99m, Volume: 11213471), + new(Timestamp: DateTime.ParseExact("2017-01-06", "yyyy-MM-dd", englishCulture), Open: 228.97m, High: 231.92m, Low: 228.00m, Close: 231.28m, Volume: 3979484), + new(Timestamp: DateTime.ParseExact("2017-01-05", "yyyy-MM-dd", englishCulture), Open: 226.42m, High: 227.48m, Low: 221.95m, Close: 226.75m, Volume: 5911695), + new(Timestamp: DateTime.ParseExact("2017-01-06", "yyyy-MM-dd", englishCulture), Open: 226.93m, High: 230.31m, Low: 225.45m, Close: 229.01m, Volume: 5527893) + }; + + InvalidQuotesException dx + = Assert.ThrowsException( + () => unorderedQuotes.Validate()); + + dx.Message.Should() + .Be("Quotes are out of sequence on 1/5/2017 12:00:00 AM. (Parameter 'quotes')"); + } + } diff --git a/tests/indicators/_testdata/TestData.Tests.cs b/tests/indicators/_testdata/TestData.Tests.cs new file mode 100644 index 000000000..7fcf9406f --- /dev/null +++ b/tests/indicators/_testdata/TestData.Tests.cs @@ -0,0 +1,77 @@ +namespace TestOfTests; + +[TestClass] +public class TestData : TestBase +{ + // Test the test data to + // ensure it meets the expected format + + [TestMethod] + public void QuotesIsValid() + { + Quotes.Should().HaveCount(502); + Quotes.Validate(); + } + + [TestMethod] + public void OtherQuotesIsValid() + { + OtherQuotes.Should().HaveCount(502); + OtherQuotes.Validate(); + } + + [TestMethod] + public void BadQuotesIsInvalid() + { + BadQuotes.Should().HaveCount(502); + + // duplicates + Assert.ThrowsException( + () => BadQuotes.Validate()); + } + + [TestMethod] + public void BigQuotesIsValid() + { + BigQuotes.Should().HaveCount(1246); + BigQuotes.Validate(); + } + + [TestMethod] + public void LongishQuotesIsValid() + { + LongishQuotes.Should().HaveCount(5285); + LongishQuotes.Validate(); + } + + [TestMethod] + public void LongestQuotesIsValid() + { + LongestQuotes.Should().HaveCount(15821); + LongestQuotes.Validate(); + } + + [TestMethod] + public void MismatchQuotesIsValid() + { + MismatchQuotes.Should().HaveCount(502); + + // out of sequence + Assert.ThrowsException( + () => MismatchQuotes.Validate()); + } + + [TestMethod] + public void RandomQuotesIsValid() + { + RandomQuotes.Should().HaveCount(1000); + RandomQuotes.Validate(); + } + + [TestMethod] + public void ZeroesQuotesIsValid() + { + ZeroesQuotes.Should().HaveCount(200); + ZeroesQuotes.Validate(); + } +} diff --git a/tests/other/PublicApi.Interface.Tests.cs b/tests/other/PublicApi.Interface.Tests.cs index 1b307baed..95a3ab60d 100644 --- a/tests/other/PublicApi.Interface.Tests.cs +++ b/tests/other/PublicApi.Interface.Tests.cs @@ -25,12 +25,18 @@ public void QuoteValidation() .ToList(); // has duplicates - Assert.ThrowsException( - () => quotesBad.Validate()); + InvalidQuotesException dx + = Assert.ThrowsException( + () => quotesBad.Validate()); + + dx.Message.Should().Contain("Duplicate date found"); // out of order - Assert.ThrowsException( - () => reverse.Validate()); + InvalidQuotesException sx + = Assert.ThrowsException( + () => reverse.Validate()); + + sx.Message.Should().Contain("Quotes are out of sequence"); } [TestMethod] From 6b4c81ceca88a4bec5109af90a965b9f01d6f14b Mon Sep 17 00:00:00 2001 From: Dave Skender <8432125+DaveSkender@users.noreply.github.com> Date: Mon, 14 Oct 2024 16:48:15 -0400 Subject: [PATCH 30/38] refactor: use readonly list input a-z, common --- docs/examples/CustomIndicators/AtrWma.cs | 2 +- src/_common/Candles/Candles.Utilities.cs | 2 +- src/_common/ObsoleteV3.cs | 21 +++--- src/_common/Quotes/Quote.Aggregates.cs | 6 +- src/_common/Quotes/Quote.Api.cs | 11 --- src/_common/Quotes/Quote.Converters.cs | 7 +- src/_common/Quotes/Quote.Models.cs | 2 +- src/_common/Quotes/Quote.StreamHub.cs | 10 +++ src/_common/Quotes/Quote.Validation.cs | 12 ++-- src/_common/Reusable/Reusable.Utilities.cs | 15 ++-- ...ePart.Api.cs => QuotePart.StaticSeries.cs} | 26 +++---- ...se.StreamHub.cs => QuotePart.StreamHub.cs} | 11 ++- .../Use (QuotePart)/QuotePart.Utilities.cs | 7 +- src/_common/Use (QuotePart)/Use.Api.cs | 27 -------- src/a-d/Adl/Adl.Api.cs | 12 ---- src/a-d/Adl/Adl.StreamHub.cs | 25 ++++--- src/a-d/Adl/Adl.Utilities.cs | 4 +- src/a-d/Adx/Adx.Api.cs | 16 ----- src/a-d/Adx/Adx.StaticSeries.cs | 11 ++- src/a-d/Adx/Adx.Utilities.cs | 6 +- src/a-d/Alligator/Alligator.Api.cs | 69 ------------------- src/a-d/Alligator/Alligator.StaticSeries.cs | 39 +++++++++++ src/a-d/Alligator/Alligator.StreamHub.cs | 28 +++++++- src/a-d/Alligator/Alligator.Utilities.cs | 2 + src/a-d/Alma/Alma.Api.cs | 16 ----- src/a-d/Alma/Alma.Common.cs | 33 --------- src/a-d/Alma/Alma.StaticSeries.cs | 15 ++-- src/a-d/Alma/Alma.Utilities.cs | 34 ++++++--- src/a-d/Aroon/Aroon.Api.cs | 15 ---- src/a-d/Aroon/Aroon.StaticSeries.cs | 7 ++ src/a-d/Aroon/Aroon.Utilities.cs | 12 ---- src/a-d/Atr/Atr.Api.cs | 23 ------- src/a-d/Atr/Atr.StaticSeries.cs | 10 ++- src/a-d/Atr/Atr.StreamHub.cs | 11 ++- src/a-d/Atr/Atr.Utilities.cs | 11 --- src/a-d/AtrStop/AtrStop.Api.cs | 27 -------- src/a-d/AtrStop/AtrStop.StaticSeries.cs | 9 +++ src/a-d/AtrStop/AtrStop.StreamHub.cs | 13 +++- src/a-d/AtrStop/AtrStop.Utilities.cs | 4 +- src/a-d/Awesome/Awesome.Api.cs | 15 ---- src/a-d/Awesome/Awesome.StaticSeries.cs | 11 ++- src/a-d/Awesome/Awesome.Utilities.cs | 12 ---- src/a-d/Beta/Beta.Api.cs | 22 ------ src/a-d/Beta/Beta.StaticSeries.cs | 11 +-- src/a-d/Beta/Beta.Utilities.cs | 16 +---- src/a-d/BollingerBands/BollingerBands.Api.cs | 15 ---- .../BollingerBands/BollingerBands.Common.cs | 26 ------- .../BollingerBands.StaticSeries.cs | 13 ++-- .../BollingerBands.Utilities.cs | 23 ++++++- src/a-d/Bop/Bop.Api.cs | 15 ---- src/a-d/Bop/Bop.Common.cs | 19 ----- src/a-d/Bop/Bop.StaticSeries.cs | 9 ++- src/a-d/Bop/Bop.Utilities.cs | 22 +++--- src/a-d/Cci/Cci.Api.cs | 15 ---- src/a-d/Cci/Cci.Common.cs | 19 ----- src/a-d/Cci/Cci.StaticSeries.cs | 9 ++- src/a-d/Cci/Cci.Utilities.cs | 23 ++++--- src/a-d/ChaikinOsc/ChaikinOsc.Api.cs | 16 ----- src/a-d/ChaikinOsc/ChaikinOsc.Common.cs | 26 ------- src/a-d/ChaikinOsc/ChaikinOsc.StaticSeries.cs | 17 ++--- src/a-d/ChaikinOsc/ChaikinOsc.Utilities.cs | 25 ++++++- src/a-d/Chandelier/Chandelier.Api.cs | 17 ----- src/a-d/Chandelier/Chandelier.Common.cs | 26 ------- src/a-d/Chandelier/Chandelier.StaticSeries.cs | 13 +++- src/a-d/Chandelier/Chandelier.Utilities.cs | 27 +++++--- src/a-d/Chop/Chop.Api.cs | 15 ---- src/a-d/Chop/Chop.Common.cs | 19 ----- src/a-d/Chop/Chop.StaticSeries.cs | 9 ++- src/a-d/Chop/Chop.Utilities.cs | 22 +++--- src/a-d/Cmf/Cmf.Api.cs | 15 ---- src/a-d/Cmf/Cmf.Common.cs | 19 ----- src/a-d/Cmf/Cmf.StaticSeries.cs | 11 ++- src/a-d/Cmf/Cmf.Utilities.cs | 23 ++++--- src/a-d/Cmo/Cmo.Api.cs | 14 ---- src/a-d/Cmo/Cmo.Common.cs | 19 ----- src/a-d/Cmo/Cmo.StaticSeries.cs | 11 +-- src/a-d/Cmo/Cmo.Utilities.cs | 22 +++--- src/a-d/ConnorsRsi/ConnorsRsi.Api.cs | 16 ----- src/a-d/ConnorsRsi/ConnorsRsi.Common.cs | 33 --------- src/a-d/ConnorsRsi/ConnorsRsi.StaticSeries.cs | 21 +++--- src/a-d/ConnorsRsi/ConnorsRsi.Utilities.cs | 34 ++++++--- src/a-d/Correlation/Correlation.Api.cs | 16 ----- .../Correlation/Correlation.StaticSeries.cs | 10 +-- src/a-d/Correlation/Correlation.Utilities.cs | 16 +---- src/a-d/Dema/Dema.Api.cs | 14 ---- src/a-d/Dema/Dema.Common.cs | 19 ----- src/a-d/Dema/Dema.StaticSeries.cs | 9 +-- src/a-d/Dema/Dema.Utilities.cs | 18 ++++- src/a-d/Doji/Doji.Api.cs | 26 ------- src/a-d/Doji/Doji.StaticSeries.cs | 25 ++++++- .../{Doji.Common.cs => Doji.Utilities.cs} | 5 +- src/a-d/Donchian/Donchian.Api.cs | 15 ---- src/a-d/Donchian/Donchian.Common.cs | 19 ----- src/a-d/Donchian/Donchian.StaticSeries.cs | 11 ++- src/a-d/Donchian/Donchian.Utilities.cs | 20 +++++- src/a-d/Dpo/Dpo.Api.cs | 14 ---- src/a-d/Dpo/Dpo.StaticSeries.cs | 10 +-- .../Dpo/{Dpo.Common.cs => Dpo.Utilities.cs} | 4 +- src/a-d/Dynamic/Dynamic.Api.cs | 16 ----- src/a-d/Dynamic/Dynamic.StaticSeries.cs | 9 +-- .../a-d/Adx/Adx.StaticSeries.Tests.cs | 5 +- .../Correlation.StaticSeries.Tests.cs | 2 +- 102 files changed, 586 insertions(+), 1073 deletions(-) delete mode 100644 src/_common/Quotes/Quote.Api.cs rename src/_common/Use (QuotePart)/{QuotePart.Api.cs => QuotePart.StaticSeries.cs} (50%) rename src/_common/Use (QuotePart)/{Use.StreamHub.cs => QuotePart.StreamHub.cs} (79%) delete mode 100644 src/_common/Use (QuotePart)/Use.Api.cs delete mode 100644 src/a-d/Adl/Adl.Api.cs delete mode 100644 src/a-d/Adx/Adx.Api.cs delete mode 100644 src/a-d/Alligator/Alligator.Api.cs delete mode 100644 src/a-d/Alma/Alma.Api.cs delete mode 100644 src/a-d/Alma/Alma.Common.cs delete mode 100644 src/a-d/Aroon/Aroon.Api.cs delete mode 100644 src/a-d/Atr/Atr.Api.cs delete mode 100644 src/a-d/AtrStop/AtrStop.Api.cs delete mode 100644 src/a-d/Awesome/Awesome.Api.cs delete mode 100644 src/a-d/Beta/Beta.Api.cs delete mode 100644 src/a-d/BollingerBands/BollingerBands.Api.cs delete mode 100644 src/a-d/BollingerBands/BollingerBands.Common.cs delete mode 100644 src/a-d/Bop/Bop.Api.cs delete mode 100644 src/a-d/Bop/Bop.Common.cs delete mode 100644 src/a-d/Cci/Cci.Api.cs delete mode 100644 src/a-d/Cci/Cci.Common.cs delete mode 100644 src/a-d/ChaikinOsc/ChaikinOsc.Api.cs delete mode 100644 src/a-d/ChaikinOsc/ChaikinOsc.Common.cs delete mode 100644 src/a-d/Chandelier/Chandelier.Api.cs delete mode 100644 src/a-d/Chandelier/Chandelier.Common.cs delete mode 100644 src/a-d/Chop/Chop.Api.cs delete mode 100644 src/a-d/Chop/Chop.Common.cs delete mode 100644 src/a-d/Cmf/Cmf.Api.cs delete mode 100644 src/a-d/Cmf/Cmf.Common.cs delete mode 100644 src/a-d/Cmo/Cmo.Api.cs delete mode 100644 src/a-d/Cmo/Cmo.Common.cs delete mode 100644 src/a-d/ConnorsRsi/ConnorsRsi.Api.cs delete mode 100644 src/a-d/ConnorsRsi/ConnorsRsi.Common.cs delete mode 100644 src/a-d/Correlation/Correlation.Api.cs delete mode 100644 src/a-d/Dema/Dema.Api.cs delete mode 100644 src/a-d/Dema/Dema.Common.cs delete mode 100644 src/a-d/Doji/Doji.Api.cs rename src/a-d/Doji/{Doji.Common.cs => Doji.Utilities.cs} (89%) delete mode 100644 src/a-d/Donchian/Donchian.Api.cs delete mode 100644 src/a-d/Donchian/Donchian.Common.cs delete mode 100644 src/a-d/Dpo/Dpo.Api.cs rename src/a-d/Dpo/{Dpo.Common.cs => Dpo.Utilities.cs} (84%) delete mode 100644 src/a-d/Dynamic/Dynamic.Api.cs diff --git a/docs/examples/CustomIndicators/AtrWma.cs b/docs/examples/CustomIndicators/AtrWma.cs index e1cf570cd..9414070b2 100644 --- a/docs/examples/CustomIndicators/AtrWma.cs +++ b/docs/examples/CustomIndicators/AtrWma.cs @@ -18,7 +18,7 @@ public static class CustomIndicators { // Custom ATR WMA calculation public static IReadOnlyList GetAtrWma( - this IEnumerable quotes, + this IReadOnlyList quotes, int lookbackPeriods) where TQuote : IQuote { diff --git a/src/_common/Candles/Candles.Utilities.cs b/src/_common/Candles/Candles.Utilities.cs index 579c4b25b..f8b01e196 100644 --- a/src/_common/Candles/Candles.Utilities.cs +++ b/src/_common/Candles/Candles.Utilities.cs @@ -19,7 +19,7 @@ public static CandleProperties ToCandle( // convert/sort quotes into candles list public static IReadOnlyList ToCandles( - this IEnumerable quotes) + this IReadOnlyList quotes) where TQuote : IQuote => quotes .Select(x => x.ToCandle()) .OrderBy(x => x.Timestamp) diff --git a/src/_common/ObsoleteV3.cs b/src/_common/ObsoleteV3.cs index 1f78baa0f..c7f4152ed 100644 --- a/src/_common/ObsoleteV3.cs +++ b/src/_common/ObsoleteV3.cs @@ -31,7 +31,7 @@ public static IEnumerable GetAlligator( [ExcludeFromCodeCoverage] [Obsolete("Replace `GetEma(..)` with `ToEma(..)`", false)] // v3.0.0 public static IEnumerable GetEma( - this IEnumerable quotes, int lookbackPeriods) + this IReadOnlyList quotes, int lookbackPeriods) where TQuote : IQuote => quotes.ToSortedList().ToEma(lookbackPeriods); @@ -40,14 +40,14 @@ public static IEnumerable GetEma( [ExcludeFromCodeCoverage] [Obsolete("Use a chained `results.GetSma(smaPeriods)` to generate a moving average.", true)] // v3.0.0 public static IEnumerable GetAdl( - this IEnumerable quotes, int smaPeriods) + this IReadOnlyList quotes, int smaPeriods) where TQuote : IQuote => quotes.ToSortedList().ToAdl(); [ExcludeFromCodeCoverage] [Obsolete("Use a chained `results.GetSma(smaPeriods)` to generate a moving average.", true)] // v3.0.0 public static IEnumerable GetObv( - this IEnumerable quotes, int smaPeriods) + this IReadOnlyList quotes, int smaPeriods) where TQuote : IQuote => quotes.ToObv(); @@ -56,26 +56,31 @@ public static IEnumerable GetObv( public static IEnumerable GetPrs( this IEnumerable quotesEval, IEnumerable quotesBase, int lookbackPeriods, int smaPeriods) where TQuote : IQuote - => quotesEval.Use(CandlePart.Close).ToPrs(quotesBase.Use(CandlePart.Close), lookbackPeriods); + => quotesEval + .ToSortedList() + .Use(CandlePart.Close) + .ToPrs( + quotesBase.ToSortedList() + .Use(CandlePart.Close), lookbackPeriods); [ExcludeFromCodeCoverage] [Obsolete("Use a chained `results.GetSma(smaPeriods)` to generate a moving average.", true)] // v3.0.0 public static IEnumerable GetRoc( - this IEnumerable quotes, int lookbackPeriods, int smaPeriods) + this IReadOnlyList quotes, int lookbackPeriods, int smaPeriods) where TQuote : IQuote => quotes.Use(CandlePart.Close).ToRoc(lookbackPeriods); [ExcludeFromCodeCoverage] [Obsolete("Use a chained `results.GetSma(smaPeriods)` to generate a moving average.", true)] // v3.0.0 public static IEnumerable GetStdDev( - this IEnumerable quotes, int lookbackPeriods, int smaPeriods) + this IReadOnlyList quotes, int lookbackPeriods, int smaPeriods) where TQuote : IQuote => quotes.Use(CandlePart.Close).ToList().CalcStdDev(lookbackPeriods); [ExcludeFromCodeCoverage] [Obsolete("Use a chained `results.GetSma(smaPeriods)` to generate a moving average.", true)] // v3.0.0 public static IEnumerable GetTrix( - this IEnumerable quotes, int lookbackPeriods, int smaPeriods) + this IReadOnlyList quotes, int lookbackPeriods, int smaPeriods) where TQuote : IQuote => quotes.Use(CandlePart.Close).ToList().CalcTrix(lookbackPeriods); @@ -84,7 +89,7 @@ public static IEnumerable GetTrix( [ExcludeFromCodeCoverage] [Obsolete("This method no longer defaults to Close. Rename Use() to Use(CandlePart.Close) for an explicit conversion.", false)] // v3.0.0 public static IEnumerable<(DateTime Timestamp, double Value)> Use( - this IEnumerable quotes) + this IReadOnlyList quotes) where TQuote : IQuote => quotes.Select(x => (x.Timestamp, x.Value)); diff --git a/src/_common/Quotes/Quote.Aggregates.cs b/src/_common/Quotes/Quote.Aggregates.cs index a06f93554..8af1b3ccd 100644 --- a/src/_common/Quotes/Quote.Aggregates.cs +++ b/src/_common/Quotes/Quote.Aggregates.cs @@ -2,13 +2,13 @@ namespace Skender.Stock.Indicators; // QUOTE UTILITIES -public static partial class Utility +public static partial class Quotes { // aggregation (quantization) /// /// public static IReadOnlyList Aggregate( - this IEnumerable quotes, + this IReadOnlyList quotes, PeriodSize newSize) where TQuote : IQuote { @@ -40,7 +40,7 @@ public static IReadOnlyList Aggregate( /// /// public static IReadOnlyList Aggregate( - this IEnumerable quotes, + this IReadOnlyList quotes, TimeSpan timeSpan) where TQuote : IQuote { diff --git a/src/_common/Quotes/Quote.Api.cs b/src/_common/Quotes/Quote.Api.cs deleted file mode 100644 index de8fb2a29..000000000 --- a/src/_common/Quotes/Quote.Api.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Skender.Stock.Indicators; - -// QUOTE (API) - -public static partial class Utility -{ - // OBSERVER, from Quote Provider (redistribution) - public static QuoteHub ToQuote( - this IQuoteProvider quoteProvider) - where TQuote : IQuote => new(quoteProvider); -} diff --git a/src/_common/Quotes/Quote.Converters.cs b/src/_common/Quotes/Quote.Converters.cs index 3aa55d0c1..f7186f683 100644 --- a/src/_common/Quotes/Quote.Converters.cs +++ b/src/_common/Quotes/Quote.Converters.cs @@ -4,13 +4,13 @@ namespace Skender.Stock.Indicators; // QUOTE UTILITIES (CONVERTERS) -public static partial class Utility +public static partial class Quotes { /* LISTS */ // convert TQuote type list to built-in Quote type list public static IReadOnlyList ToQuoteList( - this IEnumerable quotes) + this IReadOnlyList quotes) where TQuote : IQuote => quotes @@ -20,11 +20,10 @@ public static IReadOnlyList ToQuoteList( // convert TQuote type list to QuoteD type list internal static List ToQuoteDList( - this IEnumerable quotes) + this IReadOnlyList quotes) where TQuote : IQuote => quotes - .OrderBy(x => x.Timestamp) .Select(x => x.ToQuoteD()) .ToList(); diff --git a/src/_common/Quotes/Quote.Models.cs b/src/_common/Quotes/Quote.Models.cs index 28074d717..5d094449d 100644 --- a/src/_common/Quotes/Quote.Models.cs +++ b/src/_common/Quotes/Quote.Models.cs @@ -80,7 +80,7 @@ public record Quote decimal Low, decimal Close, decimal Volume -) : IReusable, IQuote +) : IQuote { public double Value => (double)Close; diff --git a/src/_common/Quotes/Quote.StreamHub.cs b/src/_common/Quotes/Quote.StreamHub.cs index 08cedbed3..6f43feb02 100644 --- a/src/_common/Quotes/Quote.StreamHub.cs +++ b/src/_common/Quotes/Quote.StreamHub.cs @@ -1,5 +1,15 @@ namespace Skender.Stock.Indicators; +#region hub initializer + +public static partial class Quotes +{ + public static QuoteHub ToQuote( + this IQuoteProvider quoteProvider) + where TQuote : IQuote => new(quoteProvider); +} +#endregion + /// /// Quote provider (abstract base) /// diff --git a/src/_common/Quotes/Quote.Validation.cs b/src/_common/Quotes/Quote.Validation.cs index 8063da563..04318e83b 100644 --- a/src/_common/Quotes/Quote.Validation.cs +++ b/src/_common/Quotes/Quote.Validation.cs @@ -1,10 +1,8 @@ -using System.Globalization; - namespace Skender.Stock.Indicators; // QUOTE UTILITIES: VALIDATION -public static partial class Utility +public static partial class Quotes { /// /// Check that quotes are valid and in ascending order. @@ -36,14 +34,14 @@ public static IReadOnlyList Validate( if (lastDate == currentDate) { - throw new InvalidQuotesException( - string.Format(CultureInfo.InvariantCulture, "Duplicate date found on {0}.", currentDate)); + string msg = $"Duplicate date found on {currentDate}."; + throw new InvalidQuotesException(nameof(quotes), msg); } if (lastDate > currentDate) { - throw new InvalidQuotesException( - string.Format(CultureInfo.InvariantCulture, "Quotes are out of sequence on {0}.", currentDate)); + string msg = $"Quotes are out of sequence on {currentDate}."; + throw new InvalidQuotesException(nameof(quotes), msg); } lastDate = currentDate; diff --git a/src/_common/Reusable/Reusable.Utilities.cs b/src/_common/Reusable/Reusable.Utilities.cs index 00a729560..d0439f591 100644 --- a/src/_common/Reusable/Reusable.Utilities.cs +++ b/src/_common/Reusable/Reusable.Utilities.cs @@ -2,11 +2,11 @@ namespace Skender.Stock.Indicators; // REUSABLE TYPE UTILITIES -public static partial class Utility +public static partial class Reusable { // convert IQuote type list to IReusable list public static IReadOnlyList ToReusableList( - this IEnumerable quotes, + this IReadOnlyList quotes, CandlePart candlePart) where TQuote : IQuote @@ -17,10 +17,6 @@ public static IReadOnlyList ToReusableList( /// /// Removes non-essential records containing null or NaN values. - /// See - /// documentation for more information. - /// /// /// Any reusable result type. /// Indicator results to evaluate. @@ -42,10 +38,6 @@ public static IReadOnlyList Condense( /// /// Removes the recommended quantity of results from the beginning /// of the results list using a reverse-engineering approach. - /// See - /// - /// documentation for more information. - /// /// /// Any reusable result type. /// Indicator results to evaluate. @@ -64,7 +56,8 @@ internal static IReadOnlyList RemoveWarmupPeriods( return results.Remove(removePeriods); // TODO: remove specific indicator 'RemoveWarmupPeriods()' methods - // that are now redundant to this generic method (not all are) + // that are now redundant to this generic method (not all are). + // Note: Some or all of these may already be removed. } // convert TQuote element to a basic chainable class diff --git a/src/_common/Use (QuotePart)/QuotePart.Api.cs b/src/_common/Use (QuotePart)/QuotePart.StaticSeries.cs similarity index 50% rename from src/_common/Use (QuotePart)/QuotePart.Api.cs rename to src/_common/Use (QuotePart)/QuotePart.StaticSeries.cs index 8f60682c2..9382eb58f 100644 --- a/src/_common/Use (QuotePart)/QuotePart.Api.cs +++ b/src/_common/Use (QuotePart)/QuotePart.StaticSeries.cs @@ -1,12 +1,11 @@ namespace Skender.Stock.Indicators; -// QUOTEPART (API) +// USE / QUOTE CONVERTER (SERIES) -public static partial class Utility +public static partial class QuoteParts { - // SERIES, from Quotes /// - /// Converts to + /// Converts to /// an list. /// /// @@ -14,22 +13,25 @@ public static partial class Utility /// use something other than the default Close price. /// /// - /// List of IQuote or IReusable items + /// Sorted list of IQuote or IReusable items /// /// List of IReusable items public static IReadOnlyList ToQuotePart( - this IEnumerable quotes, + this IReadOnlyList quotes, CandlePart candlePart) where TQuote : IQuote => quotes - .OrderBy(q => q.Timestamp) .Select(q => q.ToQuotePart(candlePart)) .ToList(); - // OBSERVER, from Quote Provider - public static QuotePartHub ToQuotePart( - this IQuoteProvider quoteProvider, + // QuotePart alias + /// + public static IReadOnlyList Use( + this IReadOnlyList quotes, CandlePart candlePart) - where TIn : IQuote - => new(quoteProvider, candlePart); + where TQuote : IQuote + => ToQuotePart(quotes, candlePart); + + // TODO: should we deprecate Use in favor of "ToQuotePart"? + // Probably not, this is a fairly simply alias. } diff --git a/src/_common/Use (QuotePart)/Use.StreamHub.cs b/src/_common/Use (QuotePart)/QuotePart.StreamHub.cs similarity index 79% rename from src/_common/Use (QuotePart)/Use.StreamHub.cs rename to src/_common/Use (QuotePart)/QuotePart.StreamHub.cs index c57db8906..4e7448fbe 100644 --- a/src/_common/Use (QuotePart)/Use.StreamHub.cs +++ b/src/_common/Use (QuotePart)/QuotePart.StreamHub.cs @@ -2,13 +2,22 @@ namespace Skender.Stock.Indicators; // USE / QUOTE CONVERTER (STREAM HUB) -#region hub interface +#region hub interface and initializer public interface IQuotePartHub { CandlePart CandlePartSelection { get; } // TODO: consider renaming to IBarPartHub, with IQuote to IBar } + +public static partial class QuoteParts +{ + public static QuotePartHub ToQuotePart( + this IQuoteProvider quoteProvider, + CandlePart candlePart) + where TIn : IQuote + => new(quoteProvider, candlePart); +} #endregion public class QuotePartHub diff --git a/src/_common/Use (QuotePart)/QuotePart.Utilities.cs b/src/_common/Use (QuotePart)/QuotePart.Utilities.cs index 398daa587..3fb863987 100644 --- a/src/_common/Use (QuotePart)/QuotePart.Utilities.cs +++ b/src/_common/Use (QuotePart)/QuotePart.Utilities.cs @@ -2,7 +2,7 @@ namespace Skender.Stock.Indicators; // QUOTEPART TYPE UTILITIES -public static partial class Utility +public static partial class QuoteParts { // convert TQuote element to a basic QuotePart class internal static QuotePart ToQuotePart(this IQuote q, CandlePart candlePart) @@ -61,13 +61,16 @@ internal static double QuotePartOrValue( /// /// List of IReusable items internal static List ToSortedList( - this IEnumerable items, CandlePart candlePart) + this IReadOnlyList items, CandlePart candlePart) where T : IReusable + // TODO: optimize this to avoid double-casting + => typeof(IQuote).IsAssignableFrom(typeof(T)) ? items .Cast() + .ToList() .Use(candlePart) .Cast() .ToSortedList() diff --git a/src/_common/Use (QuotePart)/Use.Api.cs b/src/_common/Use (QuotePart)/Use.Api.cs deleted file mode 100644 index b072f55f9..000000000 --- a/src/_common/Use (QuotePart)/Use.Api.cs +++ /dev/null @@ -1,27 +0,0 @@ -namespace Skender.Stock.Indicators; - -// USE (API) - -public static partial class Utility -{ - // SERIES, from Quotes - public static IReadOnlyList Use( - this IEnumerable quotes, - CandlePart candlePart) - where TQuote : IQuote - => quotes - .OrderBy(q => q.Timestamp) - .Select(q => q.ToQuotePart(candlePart)) - .ToList(); - - // SERIES, from Quotes (QuotePart alias) - /// - public static IReadOnlyList GetQuotePart( - this IEnumerable quotes, - CandlePart candlePart) - where TQuote : IQuote - => quotes - .OrderBy(q => q.Timestamp) - .Select(q => q.ToQuotePart(candlePart)) - .ToList(); -} diff --git a/src/a-d/Adl/Adl.Api.cs b/src/a-d/Adl/Adl.Api.cs deleted file mode 100644 index cb02c9b8f..000000000 --- a/src/a-d/Adl/Adl.Api.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace Skender.Stock.Indicators; - -// ACCUMULATION/DISTRIBUTION LINE (API) - -public static partial class Adl -{ - // OBSERVER, from Quote Provider - public static AdlHub ToAdl( - this IQuoteProvider quoteProvider) - where TIn : IQuote - => new(quoteProvider); -} diff --git a/src/a-d/Adl/Adl.StreamHub.cs b/src/a-d/Adl/Adl.StreamHub.cs index e2c17c144..279a07bf1 100644 --- a/src/a-d/Adl/Adl.StreamHub.cs +++ b/src/a-d/Adl/Adl.StreamHub.cs @@ -2,8 +2,19 @@ namespace Skender.Stock.Indicators; // ACCUMULATION/DISTRIBUTION LINE (STREAM HUB) -public class AdlHub - : ChainProvider +#region hub initializer + +public static partial class Adl +{ + // OBSERVER, from Quote Provider + public static AdlHub ToAdl( + this IQuoteProvider quoteProvider) + where TIn : IQuote + => new(quoteProvider); +} +#endregion + +public class AdlHub : ChainProvider where TIn : IQuote { #region constructors @@ -34,13 +45,5 @@ protected override (AdlResult result, int index) return (r, i); } - public override string ToString() - { - if (Cache.Count == 0) - { - return "ADL"; - } - - return $"ADL({Cache[0].Timestamp:d})"; - } + public override string ToString() => Cache.Count == 0 ? "ADL" : $"ADL({Cache[0].Timestamp:d})"; } diff --git a/src/a-d/Adl/Adl.Utilities.cs b/src/a-d/Adl/Adl.Utilities.cs index 5b22b3946..d964a392a 100644 --- a/src/a-d/Adl/Adl.Utilities.cs +++ b/src/a-d/Adl/Adl.Utilities.cs @@ -1,6 +1,6 @@ namespace Skender.Stock.Indicators; -// ACCUMULATION/DISTRIBUTION LINE (COMMON) +// ACCUMULATION/DISTRIBUTION LINE (UTILITIES) /// /// See the @@ -10,8 +10,6 @@ public static partial class Adl { /// /// Get the next incremental Accumulation/Distribution Line(ADL) value. - /// See documentation - /// for more information. /// /// timestamp /// High price, current period diff --git a/src/a-d/Adx/Adx.Api.cs b/src/a-d/Adx/Adx.Api.cs deleted file mode 100644 index 7a60a587b..000000000 --- a/src/a-d/Adx/Adx.Api.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace Skender.Stock.Indicators; - -// AVERAGE DIRECTIONAL INDEX (API) - -public static partial class Adx -{ - // SERIES, from TQuote - /// - /// - public static IReadOnlyList ToAdx( - this IEnumerable quotes, - int lookbackPeriods = 14) - where TQuote : IQuote => quotes - .ToQuoteDList() - .CalcAdx(lookbackPeriods); -} diff --git a/src/a-d/Adx/Adx.StaticSeries.cs b/src/a-d/Adx/Adx.StaticSeries.cs index 7944d6bb1..4cb309c05 100644 --- a/src/a-d/Adx/Adx.StaticSeries.cs +++ b/src/a-d/Adx/Adx.StaticSeries.cs @@ -4,12 +4,19 @@ namespace Skender.Stock.Indicators; public static partial class Adx { + public static IReadOnlyList ToAdx( + this IReadOnlyList quotes, + int lookbackPeriods = 14) + where TQuote : IQuote => quotes + .ToQuoteDList() + .CalcAdx(lookbackPeriods); + private static List CalcAdx( this List source, - int lookbackPeriods) + int lookbackPeriods = 14) { // check parameter arguments - Adx.Validate(lookbackPeriods); + Validate(lookbackPeriods); // initialize int length = source.Count; diff --git a/src/a-d/Adx/Adx.Utilities.cs b/src/a-d/Adx/Adx.Utilities.cs index f7e65d5f9..1611769cd 100644 --- a/src/a-d/Adx/Adx.Utilities.cs +++ b/src/a-d/Adx/Adx.Utilities.cs @@ -1,9 +1,11 @@ namespace Skender.Stock.Indicators; +// AVERAGE DIRECTIONAL INDEX (UTILITIES) + public static partial class Adx { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( this IReadOnlyList results) { @@ -11,7 +13,7 @@ public static IReadOnlyList RemoveWarmupPeriods( .ToList() .FindIndex(x => x.Pdi != null); - return results.Remove(2 * n + 100); + return results.Remove((2 * n) + 100); } // parameter validation diff --git a/src/a-d/Alligator/Alligator.Api.cs b/src/a-d/Alligator/Alligator.Api.cs deleted file mode 100644 index 06a613a74..000000000 --- a/src/a-d/Alligator/Alligator.Api.cs +++ /dev/null @@ -1,69 +0,0 @@ -namespace Skender.Stock.Indicators; - -// WILLIAMS ALLIGATOR (API) - -public static partial class Alligator -{ - // SERIES, from CHAIN - /// - /// Williams Alligator is an indicator that transposes multiple moving averages, - /// showing chart patterns that creator Bill Williams compared to an alligator's - /// feeding habits when describing market movement. - /// - /// See - /// documentation - /// for more information. - /// - /// - /// - /// T must be or type - /// - /// Time-series values to transform. - /// Lookback periods for the Jaw line. - /// Offset periods for the Jaw line. - /// Lookback periods for the Teeth line. - /// Offset periods for the Teeth line. - /// Lookback periods for the Lips line. - /// Offset periods for the Lips line. - /// Time series of Alligator values. - /// - /// Invalid parameter value provided. - /// - public static IReadOnlyList ToAlligator( - this IEnumerable source, - int jawPeriods = 13, - int jawOffset = 8, - int teethPeriods = 8, - int teethOffset = 5, - int lipsPeriods = 5, - int lipsOffset = 3) - where T : IReusable - => source - .ToSortedList(CandlePart.HL2) - .CalcAlligator( - jawPeriods, - jawOffset, - teethPeriods, - teethOffset, - lipsPeriods, - lipsOffset); - - // HUB, from Chain Provider - public static AlligatorHub ToAlligator( - this IChainProvider chainProvider, - int jawPeriods = 13, - int jawOffset = 8, - int teethPeriods = 8, - int teethOffset = 5, - int lipsPeriods = 5, - int lipsOffset = 3) - where TIn : IReusable - => new( - chainProvider, - jawPeriods, - jawOffset, - teethPeriods, - teethOffset, - lipsPeriods, - lipsOffset); -} diff --git a/src/a-d/Alligator/Alligator.StaticSeries.cs b/src/a-d/Alligator/Alligator.StaticSeries.cs index 887a98b9e..9707d8fb8 100644 --- a/src/a-d/Alligator/Alligator.StaticSeries.cs +++ b/src/a-d/Alligator/Alligator.StaticSeries.cs @@ -4,6 +4,45 @@ namespace Skender.Stock.Indicators; public static partial class Alligator { + // SERIES, from CHAIN + /// + /// Williams Alligator is an indicator that transposes multiple moving averages, + /// showing chart patterns that creator Bill Williams compared to an alligator's + /// feeding habits when describing market movement. + /// + /// + /// T must be or type + /// + /// Time-series values to transform. + /// Lookback periods for the Jaw line. + /// Offset periods for the Jaw line. + /// Lookback periods for the Teeth line. + /// Offset periods for the Teeth line. + /// Lookback periods for the Lips line. + /// Offset periods for the Lips line. + /// Time series of Alligator values. + /// + /// Invalid parameter value provided. + /// + public static IReadOnlyList ToAlligator( + this IReadOnlyList source, + int jawPeriods = 13, + int jawOffset = 8, + int teethPeriods = 8, + int teethOffset = 5, + int lipsPeriods = 5, + int lipsOffset = 3) + where T : IReusable + => source + .ToSortedList(CandlePart.HL2) + .CalcAlligator( + jawPeriods, + jawOffset, + teethPeriods, + teethOffset, + lipsPeriods, + lipsOffset); + internal static List CalcAlligator( this List source, int jawPeriods, diff --git a/src/a-d/Alligator/Alligator.StreamHub.cs b/src/a-d/Alligator/Alligator.StreamHub.cs index e7af60e4c..960548d9f 100644 --- a/src/a-d/Alligator/Alligator.StreamHub.cs +++ b/src/a-d/Alligator/Alligator.StreamHub.cs @@ -2,7 +2,7 @@ namespace Skender.Stock.Indicators; // WILLIAMS ALLIGATOR (STREAM HUB) -#region hub interface +#region hub interface and initializer public interface IAlligatorHub { @@ -13,11 +13,33 @@ public interface IAlligatorHub int LipsPeriods { get; } int LipsOffset { get; } } + +public static partial class Alligator +{ + // HUB, from Chain Provider + public static AlligatorHub ToAlligator( + this IChainProvider chainProvider, + int jawPeriods = 13, + int jawOffset = 8, + int teethPeriods = 8, + int teethOffset = 5, + int lipsPeriods = 5, + int lipsOffset = 3) + where TIn : IReusable + => new( + chainProvider, + jawPeriods, + jawOffset, + teethPeriods, + teethOffset, + lipsPeriods, + lipsOffset); +} #endregion public class AlligatorHub - : StreamHub, IAlligatorHub - where TIn : IReusable +: StreamHub, IAlligatorHub +where TIn : IReusable { #region constructors diff --git a/src/a-d/Alligator/Alligator.Utilities.cs b/src/a-d/Alligator/Alligator.Utilities.cs index b0a1fd257..03050cb34 100644 --- a/src/a-d/Alligator/Alligator.Utilities.cs +++ b/src/a-d/Alligator/Alligator.Utilities.cs @@ -1,5 +1,7 @@ namespace Skender.Stock.Indicators; +// WILLIAMS ALLIGATOR (UTILITIES) + public static partial class Alligator { // CONDENSE (REMOVE null results) diff --git a/src/a-d/Alma/Alma.Api.cs b/src/a-d/Alma/Alma.Api.cs deleted file mode 100644 index 1eb838afd..000000000 --- a/src/a-d/Alma/Alma.Api.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace Skender.Stock.Indicators; - -// ARNAUD LEGOUX MOVING AVERAGE (API) -public static partial class Indicator -{ - // SERIES, from CHAIN - public static IReadOnlyList ToAlma( - this IReadOnlyList results, - int lookbackPeriods = 9, - double offset = 0.85, - double sigma = 6) - where T : IReusable - => results - .ToSortedList() - .CalcAlma(lookbackPeriods, offset, sigma); -} diff --git a/src/a-d/Alma/Alma.Common.cs b/src/a-d/Alma/Alma.Common.cs deleted file mode 100644 index 8648271b5..000000000 --- a/src/a-d/Alma/Alma.Common.cs +++ /dev/null @@ -1,33 +0,0 @@ -namespace Skender.Stock.Indicators; - -// ARNAUD LEGOUX MOVING AVERAGE (COMMON) - -public static class Alma -{ - // parameter validation - internal static void Validate( - int lookbackPeriods, - double offset, - double sigma) - { - // check parameter arguments - if (lookbackPeriods <= 1) - { - throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, - "Lookback periods must be greater than 1 for ALMA."); - } - - if (offset is < 0 or > 1) - { - throw new ArgumentOutOfRangeException(nameof(offset), offset, - "Offset must be between 0 and 1 for ALMA."); - } - - if (sigma <= 0) - { - throw new ArgumentOutOfRangeException(nameof(sigma), sigma, - "Sigma must be greater than 0 for ALMA."); - } - } - -} diff --git a/src/a-d/Alma/Alma.StaticSeries.cs b/src/a-d/Alma/Alma.StaticSeries.cs index 34ee39a8e..372f68c9e 100644 --- a/src/a-d/Alma/Alma.StaticSeries.cs +++ b/src/a-d/Alma/Alma.StaticSeries.cs @@ -2,17 +2,18 @@ namespace Skender.Stock.Indicators; // ARNAUD LEGOUX MOVING AVERAGE (SERIES) -public static partial class Indicator +public static partial class Alma { - private static List CalcAlma( - this List source, - int lookbackPeriods, - double offset, - double sigma) + public static IReadOnlyList ToAlma( + this IReadOnlyList source, + int lookbackPeriods = 9, + double offset = 0.85, + double sigma = 6) where T : IReusable { // check parameter arguments - Alma.Validate(lookbackPeriods, offset, sigma); + ArgumentNullException.ThrowIfNull(source); + Validate(lookbackPeriods, offset, sigma); // initialize int length = source.Count; diff --git a/src/a-d/Alma/Alma.Utilities.cs b/src/a-d/Alma/Alma.Utilities.cs index 13542b0e0..da7f11eb8 100644 --- a/src/a-d/Alma/Alma.Utilities.cs +++ b/src/a-d/Alma/Alma.Utilities.cs @@ -1,16 +1,32 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// ARNAUD LEGOUX MOVING AVERAGE (UTILITIES) + +public static partial class Alma { - // remove recommended periods - /// - public static IReadOnlyList RemoveWarmupPeriods( - this IReadOnlyList results) + // parameter validation + internal static void Validate( + int lookbackPeriods, + double offset, + double sigma) { - int removePeriods = results - .ToList() - .FindIndex(x => x.Alma != null); + // check parameter arguments + if (lookbackPeriods <= 1) + { + throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, + "Lookback periods must be greater than 1 for ALMA."); + } + + if (offset is < 0 or > 1) + { + throw new ArgumentOutOfRangeException(nameof(offset), offset, + "Offset must be between 0 and 1 for ALMA."); + } - return results.Remove(removePeriods); + if (sigma <= 0) + { + throw new ArgumentOutOfRangeException(nameof(sigma), sigma, + "Sigma must be greater than 0 for ALMA."); + } } } diff --git a/src/a-d/Aroon/Aroon.Api.cs b/src/a-d/Aroon/Aroon.Api.cs deleted file mode 100644 index 17a2fc1ab..000000000 --- a/src/a-d/Aroon/Aroon.Api.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Skender.Stock.Indicators; - -// AROON OSCILLATOR (API) -public static partial class Aroon -{ - // SERIES, from TQuote - /// - /// - public static IReadOnlyList ToAroon( - this IEnumerable quotes, - int lookbackPeriods = 25) - where TQuote : IQuote => quotes - .ToQuoteDList() - .CalcAroon(lookbackPeriods); -} diff --git a/src/a-d/Aroon/Aroon.StaticSeries.cs b/src/a-d/Aroon/Aroon.StaticSeries.cs index 1d60eadad..4111c2111 100644 --- a/src/a-d/Aroon/Aroon.StaticSeries.cs +++ b/src/a-d/Aroon/Aroon.StaticSeries.cs @@ -4,6 +4,13 @@ namespace Skender.Stock.Indicators; public static partial class Aroon { + public static IReadOnlyList ToAroon( + this IReadOnlyList quotes, + int lookbackPeriods = 25) + where TQuote : IQuote => quotes + .ToQuoteDList() + .CalcAroon(lookbackPeriods); + private static List CalcAroon( this List source, int lookbackPeriods) diff --git a/src/a-d/Aroon/Aroon.Utilities.cs b/src/a-d/Aroon/Aroon.Utilities.cs index 9a3fde239..32f51769d 100644 --- a/src/a-d/Aroon/Aroon.Utilities.cs +++ b/src/a-d/Aroon/Aroon.Utilities.cs @@ -2,18 +2,6 @@ namespace Skender.Stock.Indicators; public static partial class Aroon { - // remove recommended periods - /// - public static IReadOnlyList RemoveWarmupPeriods( - this IReadOnlyList results) - { - int removePeriods = results - .ToList() - .FindIndex(x => x.Oscillator != null); - - return results.Remove(removePeriods); - } - // parameter validation internal static void Validate( int lookbackPeriods) diff --git a/src/a-d/Atr/Atr.Api.cs b/src/a-d/Atr/Atr.Api.cs deleted file mode 100644 index 39f5c7c08..000000000 --- a/src/a-d/Atr/Atr.Api.cs +++ /dev/null @@ -1,23 +0,0 @@ -namespace Skender.Stock.Indicators; - -// AVERAGE TRUE RANGE (API) - -public static partial class Atr -{ - // SERIES, from TQuote - /// - /// - public static IReadOnlyList ToAtr( - this IEnumerable quotes, - int lookbackPeriods = 14) - where TQuote : IQuote => quotes - .ToQuoteDList() - .CalcAtr(lookbackPeriods); - - // OBSERVER, from Quote Provider - public static AtrHub ToAtr( - this IQuoteProvider quoteProvider, - int lookbackPeriods = 14) - where TIn : IQuote - => new(quoteProvider, lookbackPeriods); -} diff --git a/src/a-d/Atr/Atr.StaticSeries.cs b/src/a-d/Atr/Atr.StaticSeries.cs index b517be680..8e4b50ada 100644 --- a/src/a-d/Atr/Atr.StaticSeries.cs +++ b/src/a-d/Atr/Atr.StaticSeries.cs @@ -4,13 +4,21 @@ namespace Skender.Stock.Indicators; public static partial class Atr { + // SERIES, from TQuote + public static IReadOnlyList ToAtr( + this IReadOnlyList quotes, + int lookbackPeriods = 14) + where TQuote : IQuote => quotes + .ToQuoteDList() + .CalcAtr(lookbackPeriods); + // calculate series internal static List CalcAtr( this List source, int lookbackPeriods) { // check parameter arguments - Atr.Validate(lookbackPeriods); + Validate(lookbackPeriods); // initialize int length = source.Count; diff --git a/src/a-d/Atr/Atr.StreamHub.cs b/src/a-d/Atr/Atr.StreamHub.cs index 5aba0234f..ead73a8ee 100644 --- a/src/a-d/Atr/Atr.StreamHub.cs +++ b/src/a-d/Atr/Atr.StreamHub.cs @@ -2,12 +2,21 @@ namespace Skender.Stock.Indicators; // AVERAGE TRUE RANGE (STREAM HUB) -#region hub interface +#region hub interface and initializer public interface IAtrHub { int LookbackPeriods { get; } } + +public static partial class Indicator +{ + public static AtrHub ToAtr( + this IQuoteProvider quoteProvider, + int lookbackPeriods = 14) + where TIn : IQuote + => new(quoteProvider, lookbackPeriods); +} #endregion public class AtrHub diff --git a/src/a-d/Atr/Atr.Utilities.cs b/src/a-d/Atr/Atr.Utilities.cs index 3b5790747..febeb0aa6 100644 --- a/src/a-d/Atr/Atr.Utilities.cs +++ b/src/a-d/Atr/Atr.Utilities.cs @@ -39,17 +39,6 @@ public static AtrResult Increment( atrp.NaN2Null()); } - // remove recommended periods - public static IReadOnlyList RemoveWarmupPeriods( - this IReadOnlyList results) - { - int removePeriods = results - .ToList() - .FindIndex(x => x.Atr != null); - - return results.Remove(removePeriods); - } - // parameter validation internal static void Validate( int lookbackPeriods) diff --git a/src/a-d/AtrStop/AtrStop.Api.cs b/src/a-d/AtrStop/AtrStop.Api.cs deleted file mode 100644 index cd4fbebee..000000000 --- a/src/a-d/AtrStop/AtrStop.Api.cs +++ /dev/null @@ -1,27 +0,0 @@ -namespace Skender.Stock.Indicators; - -// ATR TRAILING STOP (API) - -public static partial class AtrStop -{ - // SERIES, from TQuote - /// - /// - public static IReadOnlyList ToAtrStop( - this IEnumerable quotes, - int lookbackPeriods = 21, - double multiplier = 3, - EndType endType = EndType.Close) - where TQuote : IQuote => quotes - .ToQuoteDList() - .CalcAtrStop(lookbackPeriods, multiplier, endType); - - // OBSERVER, from Quote Provider - public static AtrStopHub ToAtrStop( - this IQuoteProvider quoteProvider, - int lookbackPeriods = 21, - double multiplier = 3, - EndType endType = EndType.Close) - where TIn : IQuote - => new(quoteProvider, lookbackPeriods, multiplier, endType); -} diff --git a/src/a-d/AtrStop/AtrStop.StaticSeries.cs b/src/a-d/AtrStop/AtrStop.StaticSeries.cs index 39980810d..1334e4902 100644 --- a/src/a-d/AtrStop/AtrStop.StaticSeries.cs +++ b/src/a-d/AtrStop/AtrStop.StaticSeries.cs @@ -4,6 +4,15 @@ namespace Skender.Stock.Indicators; public static partial class AtrStop { + public static IReadOnlyList ToAtrStop( + this IReadOnlyList quotes, + int lookbackPeriods = 21, + double multiplier = 3, + EndType endType = EndType.Close) + where TQuote : IQuote => quotes + .ToQuoteDList() + .CalcAtrStop(lookbackPeriods, multiplier, endType); + private static List CalcAtrStop( this List source, int lookbackPeriods, diff --git a/src/a-d/AtrStop/AtrStop.StreamHub.cs b/src/a-d/AtrStop/AtrStop.StreamHub.cs index 0b658d29e..20c0e7d0e 100644 --- a/src/a-d/AtrStop/AtrStop.StreamHub.cs +++ b/src/a-d/AtrStop/AtrStop.StreamHub.cs @@ -2,7 +2,7 @@ namespace Skender.Stock.Indicators; // ATR TRAILING STOP (STREAM HUB) -#region hub interface +#region hub interface and initializer public interface IAtrStopHub { @@ -10,6 +10,17 @@ public interface IAtrStopHub double Multiplier { get; } EndType EndType { get; } } + +public static partial class AtrStop +{ + public static AtrStopHub ToAtrStop( + this IQuoteProvider quoteProvider, + int lookbackPeriods = 21, + double multiplier = 3, + EndType endType = EndType.Close) + where TIn : IQuote + => new(quoteProvider, lookbackPeriods, multiplier, endType); +} #endregion public class AtrStopHub diff --git a/src/a-d/AtrStop/AtrStop.Utilities.cs b/src/a-d/AtrStop/AtrStop.Utilities.cs index 8f2bd1c5f..be667403f 100644 --- a/src/a-d/AtrStop/AtrStop.Utilities.cs +++ b/src/a-d/AtrStop/AtrStop.Utilities.cs @@ -5,7 +5,7 @@ namespace Skender.Stock.Indicators; public static partial class AtrStop { // CONDENSE (REMOVE null results) - /// + /// public static IReadOnlyList Condense( this IReadOnlyList results) { @@ -18,7 +18,7 @@ public static IReadOnlyList Condense( } // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( this IReadOnlyList results) { diff --git a/src/a-d/Awesome/Awesome.Api.cs b/src/a-d/Awesome/Awesome.Api.cs deleted file mode 100644 index 918f79bd7..000000000 --- a/src/a-d/Awesome/Awesome.Api.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Skender.Stock.Indicators; - -// AWESOME OSCILLATOR (API) -public static partial class Awesome -{ - // SERIES, from CHAIN - public static IReadOnlyList ToAwesome( - this IEnumerable source, - int fastPeriods = 5, - int slowPeriods = 34) - where T : IReusable - => source - .ToSortedList(CandlePart.HL2) - .CalcAwesome(fastPeriods, slowPeriods); -} diff --git a/src/a-d/Awesome/Awesome.StaticSeries.cs b/src/a-d/Awesome/Awesome.StaticSeries.cs index 67d20e027..c096bf060 100644 --- a/src/a-d/Awesome/Awesome.StaticSeries.cs +++ b/src/a-d/Awesome/Awesome.StaticSeries.cs @@ -4,6 +4,15 @@ namespace Skender.Stock.Indicators; public static partial class Awesome { + public static IReadOnlyList ToAwesome( + this IReadOnlyList source, + int fastPeriods = 5, + int slowPeriods = 34) + where T : IReusable + => source + .ToSortedList(CandlePart.HL2) + .CalcAwesome(fastPeriods, slowPeriods); + private static List CalcAwesome( this List source, int fastPeriods, @@ -11,7 +20,7 @@ private static List CalcAwesome( where T : IReusable { // check parameter arguments - Awesome.Validate(fastPeriods, slowPeriods); + Validate(fastPeriods, slowPeriods); // initialize int length = source.Count; diff --git a/src/a-d/Awesome/Awesome.Utilities.cs b/src/a-d/Awesome/Awesome.Utilities.cs index 5b48dbbaf..95396cb3d 100644 --- a/src/a-d/Awesome/Awesome.Utilities.cs +++ b/src/a-d/Awesome/Awesome.Utilities.cs @@ -2,18 +2,6 @@ namespace Skender.Stock.Indicators; public static partial class Awesome { - // remove recommended periods - /// - public static IReadOnlyList RemoveWarmupPeriods( - this IReadOnlyList results) - { - int removePeriods = results - .ToList() - .FindIndex(x => x.Oscillator != null); - - return results.Remove(removePeriods); - } - // parameter validation internal static void Validate( int fastPeriods, diff --git a/src/a-d/Beta/Beta.Api.cs b/src/a-d/Beta/Beta.Api.cs deleted file mode 100644 index 5b4ef72dc..000000000 --- a/src/a-d/Beta/Beta.Api.cs +++ /dev/null @@ -1,22 +0,0 @@ -namespace Skender.Stock.Indicators; - -// BETA COEFFICIENT (API) -public static partial class Beta -{ - // SERIES, from CHAINS (both inputs reusable) - public static IReadOnlyList ToBeta( - this IEnumerable evalSource, - IEnumerable mrktSource, - int lookbackPeriods, - BetaType type = BetaType.Standard) - where T : IReusable - { - List listEval - = evalSource.ToSortedList(); - - List listMrkt - = mrktSource.ToSortedList(); - - return CalcBeta(listEval, listMrkt, lookbackPeriods, type); - } -} diff --git a/src/a-d/Beta/Beta.StaticSeries.cs b/src/a-d/Beta/Beta.StaticSeries.cs index 48b50c8c0..d8e3280a6 100644 --- a/src/a-d/Beta/Beta.StaticSeries.cs +++ b/src/a-d/Beta/Beta.StaticSeries.cs @@ -4,16 +4,17 @@ namespace Skender.Stock.Indicators; public static partial class Beta { - // NOTE: sequence swapped from API - private static List CalcBeta( - List sourceEval, - List sourceMrkt, + public static IReadOnlyList ToBeta( + this IReadOnlyList sourceEval, + IReadOnlyList sourceMrkt, int lookbackPeriods, BetaType type = BetaType.Standard) where T : IReusable { // check parameter arguments - Beta.Validate(sourceEval, sourceMrkt, lookbackPeriods); + ArgumentNullException.ThrowIfNull(sourceEval); + ArgumentNullException.ThrowIfNull(sourceMrkt); + Validate(sourceEval, sourceMrkt, lookbackPeriods); // initialize int length = sourceEval.Count; diff --git a/src/a-d/Beta/Beta.Utilities.cs b/src/a-d/Beta/Beta.Utilities.cs index f4f6617a4..45a096dcf 100644 --- a/src/a-d/Beta/Beta.Utilities.cs +++ b/src/a-d/Beta/Beta.Utilities.cs @@ -2,22 +2,10 @@ namespace Skender.Stock.Indicators; public static partial class Beta { - // remove recommended periods - /// - public static IReadOnlyList RemoveWarmupPeriods( - this IReadOnlyList results) - { - int removePeriods = results - .ToList() - .FindIndex(x => x.Beta != null); - - return results.Remove(removePeriods); - } - // parameter validation internal static void Validate( - List sourceEval, - List sourceMrkt, + IReadOnlyList sourceEval, + IReadOnlyList sourceMrkt, int lookbackPeriods) where T : ISeries { diff --git a/src/a-d/BollingerBands/BollingerBands.Api.cs b/src/a-d/BollingerBands/BollingerBands.Api.cs deleted file mode 100644 index c79096c79..000000000 --- a/src/a-d/BollingerBands/BollingerBands.Api.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Skender.Stock.Indicators; - -// BOLLINGER BANDS (API) -public static partial class Indicator -{ - // SERIES, from CHAIN - public static IReadOnlyList ToBollingerBands( - this IReadOnlyList results, - int lookbackPeriods = 20, - double standardDeviations = 2) - where T : IReusable - => results - .ToSortedList() - .CalcBollingerBands(lookbackPeriods, standardDeviations); -} diff --git a/src/a-d/BollingerBands/BollingerBands.Common.cs b/src/a-d/BollingerBands/BollingerBands.Common.cs deleted file mode 100644 index a29ad0bf7..000000000 --- a/src/a-d/BollingerBands/BollingerBands.Common.cs +++ /dev/null @@ -1,26 +0,0 @@ -namespace Skender.Stock.Indicators; - -// BOLLINGER BANDS (COMMON) - -public static class BollingerBands -{ - // parameter validation - internal static void Validate( - int lookbackPeriods, - double standardDeviations) - { - // check parameter arguments - if (lookbackPeriods <= 1) - { - throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, - "Lookback periods must be greater than 1 for Bollinger Bands."); - } - - if (standardDeviations <= 0) - { - throw new ArgumentOutOfRangeException(nameof(standardDeviations), standardDeviations, - "Standard Deviations must be greater than 0 for Bollinger Bands."); - } - } - -} diff --git a/src/a-d/BollingerBands/BollingerBands.StaticSeries.cs b/src/a-d/BollingerBands/BollingerBands.StaticSeries.cs index cfdf3dc9d..8945cb590 100644 --- a/src/a-d/BollingerBands/BollingerBands.StaticSeries.cs +++ b/src/a-d/BollingerBands/BollingerBands.StaticSeries.cs @@ -2,16 +2,17 @@ namespace Skender.Stock.Indicators; // BOLLINGER BANDS (SERIES) -public static partial class Indicator +public static partial class BollingerBands { - private static List CalcBollingerBands( - this List source, - int lookbackPeriods, - double standardDeviations) + public static IReadOnlyList ToBollingerBands( + this IReadOnlyList source, + int lookbackPeriods = 20, + double standardDeviations = 2) where T : IReusable { // check parameter arguments - BollingerBands.Validate(lookbackPeriods, standardDeviations); + ArgumentNullException.ThrowIfNull(source); + Validate(lookbackPeriods, standardDeviations); // initialize int length = source.Count; diff --git a/src/a-d/BollingerBands/BollingerBands.Utilities.cs b/src/a-d/BollingerBands/BollingerBands.Utilities.cs index b8d3906cb..a90db9fe1 100644 --- a/src/a-d/BollingerBands/BollingerBands.Utilities.cs +++ b/src/a-d/BollingerBands/BollingerBands.Utilities.cs @@ -1,9 +1,9 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +public static partial class BollingerBands { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( this IReadOnlyList results) { @@ -13,4 +13,23 @@ public static IReadOnlyList RemoveWarmupPeriods( return results.Remove(removePeriods); } + + // parameter validation + internal static void Validate( + int lookbackPeriods, + double standardDeviations) + { + // check parameter arguments + if (lookbackPeriods <= 1) + { + throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, + "Lookback periods must be greater than 1 for Bollinger Bands."); + } + + if (standardDeviations <= 0) + { + throw new ArgumentOutOfRangeException(nameof(standardDeviations), standardDeviations, + "Standard Deviations must be greater than 0 for Bollinger Bands."); + } + } } diff --git a/src/a-d/Bop/Bop.Api.cs b/src/a-d/Bop/Bop.Api.cs deleted file mode 100644 index 9461ecdf2..000000000 --- a/src/a-d/Bop/Bop.Api.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Skender.Stock.Indicators; - -// BALANCE OF POWER (API) -public static partial class Indicator -{ - // SERIES, from TQuote - /// - /// - public static IReadOnlyList ToBop( - this IEnumerable quotes, - int smoothPeriods = 14) - where TQuote : IQuote => quotes - .ToQuoteDList() - .CalcBop(smoothPeriods); -} diff --git a/src/a-d/Bop/Bop.Common.cs b/src/a-d/Bop/Bop.Common.cs deleted file mode 100644 index 67c58d608..000000000 --- a/src/a-d/Bop/Bop.Common.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Skender.Stock.Indicators; - -// BALANCE OF POWER (COMMON) - -public static class Bop -{ - // parameter validation - internal static void Validate( - int smoothPeriods) - { - // check parameter arguments - if (smoothPeriods <= 0) - { - throw new ArgumentOutOfRangeException(nameof(smoothPeriods), smoothPeriods, - "Smoothing periods must be greater than 0 for BOP."); - } - } - -} diff --git a/src/a-d/Bop/Bop.StaticSeries.cs b/src/a-d/Bop/Bop.StaticSeries.cs index 35d59bdb0..86e75f669 100644 --- a/src/a-d/Bop/Bop.StaticSeries.cs +++ b/src/a-d/Bop/Bop.StaticSeries.cs @@ -2,8 +2,15 @@ namespace Skender.Stock.Indicators; // BALANCE OF POWER (SERIES) -public static partial class Indicator +public static partial class Bop { + public static IReadOnlyList ToBop( + this IReadOnlyList quotes, + int smoothPeriods = 14) + where TQuote : IQuote => quotes + .ToQuoteDList() + .CalcBop(smoothPeriods); + private static List CalcBop( this List source, int smoothPeriods) diff --git a/src/a-d/Bop/Bop.Utilities.cs b/src/a-d/Bop/Bop.Utilities.cs index cb36acf08..488440947 100644 --- a/src/a-d/Bop/Bop.Utilities.cs +++ b/src/a-d/Bop/Bop.Utilities.cs @@ -1,16 +1,18 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// BALANCE OF POWER (UTILITIES) + +public static partial class Bop { - // remove recommended periods - /// - public static IReadOnlyList RemoveWarmupPeriods( - this IReadOnlyList results) + // parameter validation + internal static void Validate( + int smoothPeriods) { - int removePeriods = results - .ToList() - .FindIndex(x => x.Bop != null); - - return results.Remove(removePeriods); + // check parameter arguments + if (smoothPeriods <= 0) + { + throw new ArgumentOutOfRangeException(nameof(smoothPeriods), smoothPeriods, + "Smoothing periods must be greater than 0 for BOP."); + } } } diff --git a/src/a-d/Cci/Cci.Api.cs b/src/a-d/Cci/Cci.Api.cs deleted file mode 100644 index 2ada8940a..000000000 --- a/src/a-d/Cci/Cci.Api.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Skender.Stock.Indicators; - -// COMMODITY CHANNEL INDEX (API) -public static partial class Indicator -{ - // SERIES, from TQuote - /// - /// - public static IReadOnlyList ToCci( - this IEnumerable quotes, - int lookbackPeriods = 20) - where TQuote : IQuote => quotes - .ToQuoteDList() - .CalcCci(lookbackPeriods); -} diff --git a/src/a-d/Cci/Cci.Common.cs b/src/a-d/Cci/Cci.Common.cs deleted file mode 100644 index 1f8501688..000000000 --- a/src/a-d/Cci/Cci.Common.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Skender.Stock.Indicators; - -// COMMODITY CHANNEL INDEX (COMMON) - -public static class Cci -{ - // parameter validation - internal static void Validate( - int lookbackPeriods) - { - // check parameter arguments - if (lookbackPeriods <= 0) - { - throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, - "Lookback periods must be greater than 0 for Commodity Channel Index."); - } - } - -} diff --git a/src/a-d/Cci/Cci.StaticSeries.cs b/src/a-d/Cci/Cci.StaticSeries.cs index 5f9ff1479..277ee46d2 100644 --- a/src/a-d/Cci/Cci.StaticSeries.cs +++ b/src/a-d/Cci/Cci.StaticSeries.cs @@ -2,8 +2,15 @@ namespace Skender.Stock.Indicators; // COMMODITY CHANNEL INDEX (SERIES) -public static partial class Indicator +public static partial class Cci { + public static IReadOnlyList ToCci( + this IReadOnlyList quotes, + int lookbackPeriods = 20) + where TQuote : IQuote => quotes + .ToQuoteDList() + .CalcCci(lookbackPeriods); + private static List CalcCci( this List source, int lookbackPeriods) diff --git a/src/a-d/Cci/Cci.Utilities.cs b/src/a-d/Cci/Cci.Utilities.cs index fee230bb7..34bce451c 100644 --- a/src/a-d/Cci/Cci.Utilities.cs +++ b/src/a-d/Cci/Cci.Utilities.cs @@ -1,16 +1,19 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// COMMODITY CHANNEL INDEX (UTILITIES) + +public static partial class Cci { - // remove recommended periods - /// - public static IReadOnlyList RemoveWarmupPeriods( - this IReadOnlyList results) + // parameter validation + internal static void Validate( + int lookbackPeriods) { - int removePeriods = results - .ToList() - .FindIndex(x => x.Cci != null); - - return results.Remove(removePeriods); + // check parameter arguments + if (lookbackPeriods <= 0) + { + throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, + "Lookback periods must be greater than 0 for Commodity Channel Index."); + } } + } diff --git a/src/a-d/ChaikinOsc/ChaikinOsc.Api.cs b/src/a-d/ChaikinOsc/ChaikinOsc.Api.cs deleted file mode 100644 index 5e5352a4d..000000000 --- a/src/a-d/ChaikinOsc/ChaikinOsc.Api.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace Skender.Stock.Indicators; - -// CHAIKIN OSCILLATOR -public static partial class Indicator -{ - // SERIES, from TQuote - /// - /// - public static IReadOnlyList ToChaikinOsc( - this IEnumerable quotes, - int fastPeriods = 3, - int slowPeriods = 10) - where TQuote : IQuote => quotes - .ToSortedList() - .CalcChaikinOsc(fastPeriods, slowPeriods); -} diff --git a/src/a-d/ChaikinOsc/ChaikinOsc.Common.cs b/src/a-d/ChaikinOsc/ChaikinOsc.Common.cs deleted file mode 100644 index 0b328680c..000000000 --- a/src/a-d/ChaikinOsc/ChaikinOsc.Common.cs +++ /dev/null @@ -1,26 +0,0 @@ -namespace Skender.Stock.Indicators; - -// CHAIKIN OSCILLATOR (COMMON) - -public static class ChaikinOsc -{ - // parameter validation - internal static void Validate( - int fastPeriods, - int slowPeriods) - { - // check parameter arguments - if (fastPeriods <= 0) - { - throw new ArgumentOutOfRangeException(nameof(fastPeriods), fastPeriods, - "Fast lookback periods must be greater than 0 for Chaikin Oscillator."); - } - - if (slowPeriods <= fastPeriods) - { - throw new ArgumentOutOfRangeException(nameof(slowPeriods), slowPeriods, - "Slow lookback periods must be greater than Fast lookback period for Chaikin Oscillator."); - } - } - -} diff --git a/src/a-d/ChaikinOsc/ChaikinOsc.StaticSeries.cs b/src/a-d/ChaikinOsc/ChaikinOsc.StaticSeries.cs index 257c8d69a..f3d1b3b6c 100644 --- a/src/a-d/ChaikinOsc/ChaikinOsc.StaticSeries.cs +++ b/src/a-d/ChaikinOsc/ChaikinOsc.StaticSeries.cs @@ -2,23 +2,24 @@ namespace Skender.Stock.Indicators; // CHAIKIN OSCILLATOR (SERIES) -public static partial class Indicator +public static partial class ChaikinOsc { - private static List CalcChaikinOsc( - this List source, - int fastPeriods, - int slowPeriods) + public static IReadOnlyList ToChaikinOsc( + this IReadOnlyList quotes, + int fastPeriods = 3, + int slowPeriods = 10) where TQuote : IQuote { // check parameter arguments - ChaikinOsc.Validate(fastPeriods, slowPeriods); + ArgumentNullException.ThrowIfNull(quotes); + Validate(fastPeriods, slowPeriods); // initialize - int length = source.Count; + int length = quotes.Count; List results = new(length); // money flow - var adlResults = source.ToAdl(); + IReadOnlyList adlResults = quotes.ToAdl(); // fast/slow EMA of ADL IReadOnlyList adlEmaSlow = adlResults.ToEma(slowPeriods); diff --git a/src/a-d/ChaikinOsc/ChaikinOsc.Utilities.cs b/src/a-d/ChaikinOsc/ChaikinOsc.Utilities.cs index edfeb413e..3e21a64c0 100644 --- a/src/a-d/ChaikinOsc/ChaikinOsc.Utilities.cs +++ b/src/a-d/ChaikinOsc/ChaikinOsc.Utilities.cs @@ -1,9 +1,11 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// CHAIKIN OSCILLATOR (UTILITIES) + +public static partial class ChaikinOsc { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( this IReadOnlyList results) { @@ -13,4 +15,23 @@ public static IReadOnlyList RemoveWarmupPeriods( return results.Remove(s + 100); } + + // parameter validation + internal static void Validate( + int fastPeriods, + int slowPeriods) + { + // check parameter arguments + if (fastPeriods <= 0) + { + throw new ArgumentOutOfRangeException(nameof(fastPeriods), fastPeriods, + "Fast lookback periods must be greater than 0 for Chaikin Oscillator."); + } + + if (slowPeriods <= fastPeriods) + { + throw new ArgumentOutOfRangeException(nameof(slowPeriods), slowPeriods, + "Slow lookback periods must be greater than Fast lookback period for Chaikin Oscillator."); + } + } } diff --git a/src/a-d/Chandelier/Chandelier.Api.cs b/src/a-d/Chandelier/Chandelier.Api.cs deleted file mode 100644 index cd0f6d502..000000000 --- a/src/a-d/Chandelier/Chandelier.Api.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace Skender.Stock.Indicators; - -// CHANDELIER EXIT (API) -public static partial class Indicator -{ - // SERIES, from TQuote - /// - /// - public static IReadOnlyList ToChandelier( - this IEnumerable quotes, - int lookbackPeriods = 22, - double multiplier = 3, - ChandelierType type = ChandelierType.Long) - where TQuote : IQuote => quotes - .ToQuoteDList() - .CalcChandelier(lookbackPeriods, multiplier, type); -} diff --git a/src/a-d/Chandelier/Chandelier.Common.cs b/src/a-d/Chandelier/Chandelier.Common.cs deleted file mode 100644 index 4f5d8020f..000000000 --- a/src/a-d/Chandelier/Chandelier.Common.cs +++ /dev/null @@ -1,26 +0,0 @@ -namespace Skender.Stock.Indicators; - -// CHANDELIER EXIT (COMMON) - -public static class Chandelier -{ - // parameter validation - internal static void Validate( - int lookbackPeriods, - double multiplier) - { - // check parameter arguments - if (lookbackPeriods <= 0) - { - throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, - "Lookback periods must be greater than 0 for Chandelier Exit."); - } - - if (multiplier <= 0) - { - throw new ArgumentOutOfRangeException(nameof(multiplier), multiplier, - "Multiplier must be greater than 0 for Chandelier Exit."); - } - } - -} diff --git a/src/a-d/Chandelier/Chandelier.StaticSeries.cs b/src/a-d/Chandelier/Chandelier.StaticSeries.cs index cfe7f18d3..42c833f26 100644 --- a/src/a-d/Chandelier/Chandelier.StaticSeries.cs +++ b/src/a-d/Chandelier/Chandelier.StaticSeries.cs @@ -2,8 +2,17 @@ namespace Skender.Stock.Indicators; // CHANDELIER EXIT (SERIES) -public static partial class Indicator +public static partial class Chandelier { + public static IReadOnlyList ToChandelier( + this IReadOnlyList quotes, + int lookbackPeriods = 22, + double multiplier = 3, + ChandelierType type = ChandelierType.Long) + where TQuote : IQuote => quotes + .ToQuoteDList() + .CalcChandelier(lookbackPeriods, multiplier, type); + private static List CalcChandelier( this List source, int lookbackPeriods, @@ -11,7 +20,7 @@ private static List CalcChandelier( ChandelierType type) { // check parameter arguments - Chandelier.Validate(lookbackPeriods, multiplier); + Validate(lookbackPeriods, multiplier); // initialize int length = source.Count; diff --git a/src/a-d/Chandelier/Chandelier.Utilities.cs b/src/a-d/Chandelier/Chandelier.Utilities.cs index 5ac5dc0b9..f61fe73ec 100644 --- a/src/a-d/Chandelier/Chandelier.Utilities.cs +++ b/src/a-d/Chandelier/Chandelier.Utilities.cs @@ -1,16 +1,25 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// CHANDELIER EXIT (UTILITIES) + +public static partial class Chandelier { - // remove recommended periods - /// - public static IReadOnlyList RemoveWarmupPeriods( - this IReadOnlyList results) + // parameter validation + internal static void Validate( + int lookbackPeriods, + double multiplier) { - int removePeriods = results - .ToList() - .FindIndex(x => x.ChandelierExit != null); + // check parameter arguments + if (lookbackPeriods <= 0) + { + throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, + "Lookback periods must be greater than 0 for Chandelier Exit."); + } - return results.Remove(removePeriods); + if (multiplier <= 0) + { + throw new ArgumentOutOfRangeException(nameof(multiplier), multiplier, + "Multiplier must be greater than 0 for Chandelier Exit."); + } } } diff --git a/src/a-d/Chop/Chop.Api.cs b/src/a-d/Chop/Chop.Api.cs deleted file mode 100644 index 7aac59be9..000000000 --- a/src/a-d/Chop/Chop.Api.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Skender.Stock.Indicators; - -// CHOPPINESS INDEX (API) -public static partial class Indicator -{ - // SERIES, from TQuote - /// - /// - public static IReadOnlyList ToChop( - this IEnumerable quotes, - int lookbackPeriods = 14) - where TQuote : IQuote => quotes - .ToQuoteDList() - .CalcChop(lookbackPeriods); -} diff --git a/src/a-d/Chop/Chop.Common.cs b/src/a-d/Chop/Chop.Common.cs deleted file mode 100644 index 3bf4cc474..000000000 --- a/src/a-d/Chop/Chop.Common.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Skender.Stock.Indicators; - -// CHOPPINESS INDEX (COMMON) - -public static class Chop -{ - // parameter validation - internal static void Validate( - int lookbackPeriods) - { - // check parameter arguments - if (lookbackPeriods <= 1) - { - throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, - "Lookback periods must be greater than 1 for CHOP."); - } - } - -} diff --git a/src/a-d/Chop/Chop.StaticSeries.cs b/src/a-d/Chop/Chop.StaticSeries.cs index a68a278f8..7452b4800 100644 --- a/src/a-d/Chop/Chop.StaticSeries.cs +++ b/src/a-d/Chop/Chop.StaticSeries.cs @@ -2,8 +2,15 @@ namespace Skender.Stock.Indicators; // CHOPPINESS INDEX (SERIES) -public static partial class Indicator +public static partial class Chop { + public static IReadOnlyList ToChop( + this IReadOnlyList quotes, + int lookbackPeriods = 14) + where TQuote : IQuote => quotes + .ToQuoteDList() + .CalcChop(lookbackPeriods); + private static List CalcChop( this List source, int lookbackPeriods) diff --git a/src/a-d/Chop/Chop.Utilities.cs b/src/a-d/Chop/Chop.Utilities.cs index bc05a29ba..08bdb70dc 100644 --- a/src/a-d/Chop/Chop.Utilities.cs +++ b/src/a-d/Chop/Chop.Utilities.cs @@ -1,16 +1,18 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// CHOPPINESS INDEX (UTILITIES) + +public static partial class Chop { - // remove recommended periods - /// - public static IReadOnlyList RemoveWarmupPeriods( - this IReadOnlyList results) + // parameter validation + internal static void Validate( + int lookbackPeriods) { - int removePeriods = results - .ToList() - .FindIndex(x => x.Chop != null); - - return results.Remove(removePeriods); + // check parameter arguments + if (lookbackPeriods <= 1) + { + throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, + "Lookback periods must be greater than 1 for CHOP."); + } } } diff --git a/src/a-d/Cmf/Cmf.Api.cs b/src/a-d/Cmf/Cmf.Api.cs deleted file mode 100644 index 8c3465e69..000000000 --- a/src/a-d/Cmf/Cmf.Api.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Skender.Stock.Indicators; - -// CHAIKIN MONEY FLOW (API) -public static partial class Indicator -{ - // SERIES, from TQuote - /// - /// - public static IReadOnlyList ToCmf( - this IEnumerable quotes, - int lookbackPeriods = 20) - where TQuote : IQuote => quotes - .ToSortedList() - .CalcCmf(lookbackPeriods); -} diff --git a/src/a-d/Cmf/Cmf.Common.cs b/src/a-d/Cmf/Cmf.Common.cs deleted file mode 100644 index 9731b7bd6..000000000 --- a/src/a-d/Cmf/Cmf.Common.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Skender.Stock.Indicators; - -// CHAIKIN MONEY FLOW (COMMON) - -public static class Cmf -{ - // parameter validation - internal static void Validate( - int lookbackPeriods) - { - // check parameter arguments - if (lookbackPeriods <= 0) - { - throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, - "Lookback periods must be greater than 0 for Chaikin Money Flow."); - } - } - -} diff --git a/src/a-d/Cmf/Cmf.StaticSeries.cs b/src/a-d/Cmf/Cmf.StaticSeries.cs index d2b2a79ac..0404549f0 100644 --- a/src/a-d/Cmf/Cmf.StaticSeries.cs +++ b/src/a-d/Cmf/Cmf.StaticSeries.cs @@ -2,8 +2,15 @@ namespace Skender.Stock.Indicators; // CHAIKIN MONEY FLOW (SERIES) -public static partial class Indicator +public static partial class Cmf { + public static IReadOnlyList ToCmf( + this IReadOnlyList quotes, + int lookbackPeriods = 20) + where TQuote : IQuote => quotes + .ToSortedList() + .CalcCmf(lookbackPeriods); + private static List CalcCmf( this List source, int lookbackPeriods) @@ -14,7 +21,7 @@ double[] volume = source.Select(v => (double)v.Volume).ToArray(); // check parameter arguments - Cmf.Validate(lookbackPeriods); + Validate(lookbackPeriods); // initialize int length = volume.Length; diff --git a/src/a-d/Cmf/Cmf.Utilities.cs b/src/a-d/Cmf/Cmf.Utilities.cs index 2fd812d8e..360263a04 100644 --- a/src/a-d/Cmf/Cmf.Utilities.cs +++ b/src/a-d/Cmf/Cmf.Utilities.cs @@ -1,16 +1,19 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// CHAIKIN MONEY FLOW (UTILITIES) + +public static partial class Cmf { - // remove recommended periods - /// - public static IReadOnlyList RemoveWarmupPeriods( - this IReadOnlyList results) + // parameter validation + internal static void Validate( + int lookbackPeriods) { - int removePeriods = results - .ToList() - .FindIndex(x => x.Cmf != null); - - return results.Remove(removePeriods); + // check parameter arguments + if (lookbackPeriods <= 0) + { + throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, + "Lookback periods must be greater than 0 for Chaikin Money Flow."); + } } + } diff --git a/src/a-d/Cmo/Cmo.Api.cs b/src/a-d/Cmo/Cmo.Api.cs deleted file mode 100644 index db1875b9e..000000000 --- a/src/a-d/Cmo/Cmo.Api.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Skender.Stock.Indicators; - -// CHANDE MOMENTUM OSCILLATOR (API) -public static partial class Indicator -{ - // SERIES, from CHAIN - public static IReadOnlyList ToCmo( - this IEnumerable source, - int lookbackPeriods) - where T : IReusable - => source - .ToSortedList() - .CalcCmo(lookbackPeriods); -} diff --git a/src/a-d/Cmo/Cmo.Common.cs b/src/a-d/Cmo/Cmo.Common.cs deleted file mode 100644 index a54d46479..000000000 --- a/src/a-d/Cmo/Cmo.Common.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Skender.Stock.Indicators; - -// CHANDE MOMENTUM OSCILLATOR (COMMON) - -public static class Cmo -{ - // parameter validation - internal static void Validate( - int lookbackPeriods) - { - // check parameter arguments - if (lookbackPeriods <= 0) - { - throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, - "Lookback periods must be greater than 0 for CMO."); - } - } - -} diff --git a/src/a-d/Cmo/Cmo.StaticSeries.cs b/src/a-d/Cmo/Cmo.StaticSeries.cs index 43640cf2a..8cd1d448f 100644 --- a/src/a-d/Cmo/Cmo.StaticSeries.cs +++ b/src/a-d/Cmo/Cmo.StaticSeries.cs @@ -2,15 +2,16 @@ namespace Skender.Stock.Indicators; // CHANDE MOMENTUM OSCILLATOR (SERIES) -public static partial class Indicator +public static partial class Cmo { - private static List CalcCmo( - this List source, + public static IReadOnlyList ToCmo( + this IReadOnlyList source, int lookbackPeriods) where T : IReusable { // check parameter arguments - Cmo.Validate(lookbackPeriods); + ArgumentNullException.ThrowIfNull(source); + Validate(lookbackPeriods); // initialize int length = source.Count; @@ -29,7 +30,7 @@ private static List CalcCmo( results.Add(new(source[0].Timestamp)); ticks.Add((null, double.NaN)); - // roll through remaining prices + // roll through remaining values for (int i = 1; i < length; i++) { T s = source[i]; diff --git a/src/a-d/Cmo/Cmo.Utilities.cs b/src/a-d/Cmo/Cmo.Utilities.cs index 715694baf..5ed18a20a 100644 --- a/src/a-d/Cmo/Cmo.Utilities.cs +++ b/src/a-d/Cmo/Cmo.Utilities.cs @@ -1,16 +1,18 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// CHANDE MOMENTUM OSCILLATOR (UTILITIES) + +public static partial class Cmo { - // remove recommended periods - /// - public static IReadOnlyList RemoveWarmupPeriods( - this IReadOnlyList results) + // parameter validation + internal static void Validate( + int lookbackPeriods) { - int removePeriods = results - .ToList() - .FindIndex(x => x.Cmo != null); - - return results.Remove(removePeriods); + // check parameter arguments + if (lookbackPeriods <= 0) + { + throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, + "Lookback periods must be greater than 0 for CMO."); + } } } diff --git a/src/a-d/ConnorsRsi/ConnorsRsi.Api.cs b/src/a-d/ConnorsRsi/ConnorsRsi.Api.cs deleted file mode 100644 index dfa5e4f7f..000000000 --- a/src/a-d/ConnorsRsi/ConnorsRsi.Api.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace Skender.Stock.Indicators; - -// CONNORS RSI (API) -public static partial class Indicator -{ - // SERIES, from CHAIN - public static IReadOnlyList ToConnorsRsi( - this IReadOnlyList results, - int rsiPeriods = 3, - int streakPeriods = 2, - int rankPeriods = 100) - where T : IReusable - => results - .ToSortedList() - .CalcConnorsRsi(rsiPeriods, streakPeriods, rankPeriods); -} diff --git a/src/a-d/ConnorsRsi/ConnorsRsi.Common.cs b/src/a-d/ConnorsRsi/ConnorsRsi.Common.cs deleted file mode 100644 index 85da8081f..000000000 --- a/src/a-d/ConnorsRsi/ConnorsRsi.Common.cs +++ /dev/null @@ -1,33 +0,0 @@ -namespace Skender.Stock.Indicators; - -// CONNORS RSI (COMMON) - -public static class ConnorsRsi -{ - // parameter validation - internal static void Validate( - int rsiPeriods, - int streakPeriods, - int rankPeriods) - { - // check parameter arguments - if (rsiPeriods <= 1) - { - throw new ArgumentOutOfRangeException(nameof(rsiPeriods), rsiPeriods, - "RSI period for Close price must be greater than 1 for ConnorsRsi."); - } - - if (streakPeriods <= 1) - { - throw new ArgumentOutOfRangeException(nameof(streakPeriods), streakPeriods, - "RSI period for Streak must be greater than 1 for ConnorsRsi."); - } - - if (rankPeriods <= 1) - { - throw new ArgumentOutOfRangeException(nameof(rankPeriods), rankPeriods, - "Percent Rank periods must be greater than 1 for ConnorsRsi."); - } - } - -} diff --git a/src/a-d/ConnorsRsi/ConnorsRsi.StaticSeries.cs b/src/a-d/ConnorsRsi/ConnorsRsi.StaticSeries.cs index 9fde8d627..9f224edca 100644 --- a/src/a-d/ConnorsRsi/ConnorsRsi.StaticSeries.cs +++ b/src/a-d/ConnorsRsi/ConnorsRsi.StaticSeries.cs @@ -2,17 +2,18 @@ namespace Skender.Stock.Indicators; // CONNORS RSI (SERIES) -public static partial class Indicator +public static partial class ConnorsRsi { - private static List CalcConnorsRsi( - this List source, - int rsiPeriods, - int streakPeriods, - int rankPeriods) + public static IReadOnlyList ToConnorsRsi( + this IReadOnlyList source, + int rsiPeriods = 3, + int streakPeriods = 2, + int rankPeriods = 100) where T : IReusable { // check parameter arguments - ConnorsRsi.Validate(rsiPeriods, streakPeriods, rankPeriods); + ArgumentNullException.ThrowIfNull(source); + Validate(rsiPeriods, streakPeriods, rankPeriods); // initialize int length = source.Count; @@ -28,7 +29,7 @@ IReadOnlyList streakInfo IReadOnlyList rsiStreak = streakInfo .Select(si => new QuotePart(si.Timestamp, si.Streak)) .ToList() - .CalcRsi(streakPeriods); + .ToRsi(streakPeriods); // compose final results for (int i = 0; i < length; i++) @@ -64,13 +65,13 @@ IReadOnlyList streakInfo // calculate baseline streak and rank private static List CalcStreak( - this List source, + this IReadOnlyList source, int rsiPeriods, int rankPeriods) where T : IReusable { // initialize - List rsiResults = CalcRsi(source, rsiPeriods); + IReadOnlyList rsiResults = source.ToRsi(rsiPeriods); int length = source.Count; List results = new(length); diff --git a/src/a-d/ConnorsRsi/ConnorsRsi.Utilities.cs b/src/a-d/ConnorsRsi/ConnorsRsi.Utilities.cs index 313953e5b..6fe17591f 100644 --- a/src/a-d/ConnorsRsi/ConnorsRsi.Utilities.cs +++ b/src/a-d/ConnorsRsi/ConnorsRsi.Utilities.cs @@ -1,16 +1,32 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// CONNORS RSI (UTILITIES) + +public static partial class ConnorsRsi { - // remove recommended periods - /// - public static IReadOnlyList RemoveWarmupPeriods( - this IReadOnlyList results) + // parameter validation + internal static void Validate( + int rsiPeriods, + int streakPeriods, + int rankPeriods) { - int n = results - .ToList() - .FindIndex(x => x.ConnorsRsi != null); + // check parameter arguments + if (rsiPeriods <= 1) + { + throw new ArgumentOutOfRangeException(nameof(rsiPeriods), rsiPeriods, + "RSI period for Close price must be greater than 1 for ConnorsRsi."); + } + + if (streakPeriods <= 1) + { + throw new ArgumentOutOfRangeException(nameof(streakPeriods), streakPeriods, + "RSI period for Streak must be greater than 1 for ConnorsRsi."); + } - return results.Remove(n); + if (rankPeriods <= 1) + { + throw new ArgumentOutOfRangeException(nameof(rankPeriods), rankPeriods, + "Percent Rank periods must be greater than 1 for ConnorsRsi."); + } } } diff --git a/src/a-d/Correlation/Correlation.Api.cs b/src/a-d/Correlation/Correlation.Api.cs deleted file mode 100644 index e24ac26bb..000000000 --- a/src/a-d/Correlation/Correlation.Api.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace Skender.Stock.Indicators; - -// CORRELATION COEFFICIENT (API) -public static partial class Correlation -{ - // SERIES, from CHAINS (both inputs reusable) - public static IReadOnlyList ToCorrelation( - this IEnumerable sourceA, - IEnumerable sourceB, - int lookbackPeriods) - where T : IReusable - => CalcCorrelation( - sourceA.ToSortedList(), - sourceB.ToSortedList(), - lookbackPeriods); -} diff --git a/src/a-d/Correlation/Correlation.StaticSeries.cs b/src/a-d/Correlation/Correlation.StaticSeries.cs index 3d6be5563..e82a4df70 100644 --- a/src/a-d/Correlation/Correlation.StaticSeries.cs +++ b/src/a-d/Correlation/Correlation.StaticSeries.cs @@ -4,14 +4,16 @@ namespace Skender.Stock.Indicators; public static partial class Correlation { - private static List CalcCorrelation( - this List sourceA, - List sourceB, + public static IReadOnlyList ToCorrelation( + this IReadOnlyList sourceA, + IReadOnlyList sourceB, int lookbackPeriods) where T : IReusable { // check parameter arguments - Correlation.Validate(sourceA, sourceB, lookbackPeriods); + ArgumentNullException.ThrowIfNull(sourceA); + ArgumentNullException.ThrowIfNull(sourceB); + Validate(sourceA, sourceB, lookbackPeriods); // initialize int length = sourceA.Count; diff --git a/src/a-d/Correlation/Correlation.Utilities.cs b/src/a-d/Correlation/Correlation.Utilities.cs index eb889b27c..00df00337 100644 --- a/src/a-d/Correlation/Correlation.Utilities.cs +++ b/src/a-d/Correlation/Correlation.Utilities.cs @@ -2,22 +2,10 @@ namespace Skender.Stock.Indicators; public static partial class Correlation { - // remove recommended periods - /// - public static IReadOnlyList RemoveWarmupPeriods( - this IReadOnlyList results) - { - int removePeriods = results - .ToList() - .FindIndex(x => x.Correlation != null); - - return results.Remove(removePeriods); - } - // parameter validation internal static void Validate( - List sourceA, - List sourceB, + IReadOnlyList sourceA, + IReadOnlyList sourceB, int lookbackPeriods) where T : ISeries { diff --git a/src/a-d/Dema/Dema.Api.cs b/src/a-d/Dema/Dema.Api.cs deleted file mode 100644 index 6354fce81..000000000 --- a/src/a-d/Dema/Dema.Api.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Skender.Stock.Indicators; - -// DOUBLE EXPONENTIAL MOVING AVERAGE - DEMA (API) -public static partial class Indicator -{ - // SERIES, from CHAIN - public static IReadOnlyList ToDema( - this IReadOnlyList results, - int lookbackPeriods) - where T : IReusable - => results - .ToSortedList() - .CalcDema(lookbackPeriods); -} diff --git a/src/a-d/Dema/Dema.Common.cs b/src/a-d/Dema/Dema.Common.cs deleted file mode 100644 index f948ca4e0..000000000 --- a/src/a-d/Dema/Dema.Common.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Skender.Stock.Indicators; - -// DOUBLE EXPONENTIAL MOVING AVERAGE (COMMON) - -public static class Dema -{ - // parameter validation - internal static void Validate( - int lookbackPeriods) - { - // check parameter arguments - if (lookbackPeriods <= 0) - { - throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, - "Lookback periods must be greater than 0 for DEMA."); - } - } - -} diff --git a/src/a-d/Dema/Dema.StaticSeries.cs b/src/a-d/Dema/Dema.StaticSeries.cs index c7653fd28..0a10cb5a9 100644 --- a/src/a-d/Dema/Dema.StaticSeries.cs +++ b/src/a-d/Dema/Dema.StaticSeries.cs @@ -2,15 +2,16 @@ namespace Skender.Stock.Indicators; // DOUBLE EXPONENTIAL MOVING AVERAGE (SERIES) -public static partial class Indicator +public static partial class Dema { - private static List CalcDema( - this List source, + public static IReadOnlyList ToDema( + this IReadOnlyList source, int lookbackPeriods) where T : IReusable { // check parameter arguments - Dema.Validate(lookbackPeriods); + ArgumentNullException.ThrowIfNull(source); + Validate(lookbackPeriods); // initialize int length = source.Count; diff --git a/src/a-d/Dema/Dema.Utilities.cs b/src/a-d/Dema/Dema.Utilities.cs index c31646de2..e04ddcead 100644 --- a/src/a-d/Dema/Dema.Utilities.cs +++ b/src/a-d/Dema/Dema.Utilities.cs @@ -1,9 +1,11 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// DOUBLE EXPONENTIAL MOVING AVERAGE (UTILITIES) + +public static partial class Dema { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( this IReadOnlyList results) { @@ -13,4 +15,16 @@ public static IReadOnlyList RemoveWarmupPeriods( return results.Remove(2 * n + 100); } + + // parameter validation + internal static void Validate( + int lookbackPeriods) + { + // check parameter arguments + if (lookbackPeriods <= 0) + { + throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, + "Lookback periods must be greater than 0 for DEMA."); + } + } } diff --git a/src/a-d/Doji/Doji.Api.cs b/src/a-d/Doji/Doji.Api.cs deleted file mode 100644 index 9dabc60f3..000000000 --- a/src/a-d/Doji/Doji.Api.cs +++ /dev/null @@ -1,26 +0,0 @@ -namespace Skender.Stock.Indicators; - -// DOJI (API) -public static partial class Indicator -{ - // SERIES, from TQuote - /// - /// Doji is a single candlestick pattern where open and close price are virtually identical, representing market indecision. - /// - /// See - /// documentation - /// for more information. - /// - /// - /// Configurable Quote type. See Guide for more information. - /// Historical price quotes. - /// Optional.Maximum absolute percent difference in open and close price. - /// Time series of Doji values. - /// Invalid parameter value provided. - public static IReadOnlyList ToDoji( - this IEnumerable quotes, - double maxPriceChangePercent = 0.1) - where TQuote : IQuote => quotes - .ToSortedList() - .CalcDoji(maxPriceChangePercent); -} diff --git a/src/a-d/Doji/Doji.StaticSeries.cs b/src/a-d/Doji/Doji.StaticSeries.cs index e51870665..44933ce8b 100644 --- a/src/a-d/Doji/Doji.StaticSeries.cs +++ b/src/a-d/Doji/Doji.StaticSeries.cs @@ -2,15 +2,36 @@ namespace Skender.Stock.Indicators; // DOJI (SERIES) -public static partial class Indicator +public static partial class Doji { + /// + /// Doji is a single candlestick pattern where open and close price + /// are virtually identical, representing market indecision. + /// + /// Configurable Quote type. + /// See Guide for more information. + /// Historical price quotes. + /// + /// Optional.Maximum absolute percent difference in open and close price. + /// + /// Time series of Doji values. + /// + /// Invalid parameter value provided. + /// + public static IReadOnlyList ToDoji( + this IReadOnlyList quotes, + double maxPriceChangePercent = 0.1) + where TQuote : IQuote => quotes + .ToSortedList() + .CalcDoji(maxPriceChangePercent); + private static List CalcDoji( this List quotesList, double maxPriceChangePercent) where TQuote : IQuote { // check parameter arguments - Doji.Validate(maxPriceChangePercent); + Validate(maxPriceChangePercent); // initialize int length = quotesList.Count; diff --git a/src/a-d/Doji/Doji.Common.cs b/src/a-d/Doji/Doji.Utilities.cs similarity index 89% rename from src/a-d/Doji/Doji.Common.cs rename to src/a-d/Doji/Doji.Utilities.cs index 9c57180d0..eb8b3988c 100644 --- a/src/a-d/Doji/Doji.Common.cs +++ b/src/a-d/Doji/Doji.Utilities.cs @@ -1,8 +1,8 @@ namespace Skender.Stock.Indicators; -// DOJI (COMMON) +// DOJI (UTILITIES) -public static class Doji +public static partial class Doji { // parameter validation internal static void Validate( @@ -15,5 +15,4 @@ internal static void Validate( "Maximum Percent Change must be between 0 and 0.5 for Doji (0% to 0.5%)."); } } - } diff --git a/src/a-d/Donchian/Donchian.Api.cs b/src/a-d/Donchian/Donchian.Api.cs deleted file mode 100644 index 7d9d57dfb..000000000 --- a/src/a-d/Donchian/Donchian.Api.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Skender.Stock.Indicators; - -// DONCHIAN CHANNEL (API) -public static partial class Indicator -{ - // SERIES, from TQuote - /// - /// - public static IReadOnlyList ToDonchian( - this IEnumerable quotes, - int lookbackPeriods = 20) - where TQuote : IQuote => quotes - .ToSortedList() - .CalcDonchian(lookbackPeriods); -} diff --git a/src/a-d/Donchian/Donchian.Common.cs b/src/a-d/Donchian/Donchian.Common.cs deleted file mode 100644 index ca6c80020..000000000 --- a/src/a-d/Donchian/Donchian.Common.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Skender.Stock.Indicators; - -// DONCHIAN CHANNEL (COMMON) - -public static class Donchian -{ - // parameter validation - internal static void Validate( - int lookbackPeriods) - { - // check parameter arguments - if (lookbackPeriods <= 0) - { - throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, - "Lookback periods must be greater than 0 for Donchian Channel."); - } - } - -} diff --git a/src/a-d/Donchian/Donchian.StaticSeries.cs b/src/a-d/Donchian/Donchian.StaticSeries.cs index 92a6ad431..0da8f0c62 100644 --- a/src/a-d/Donchian/Donchian.StaticSeries.cs +++ b/src/a-d/Donchian/Donchian.StaticSeries.cs @@ -2,15 +2,22 @@ namespace Skender.Stock.Indicators; // DONCHIAN CHANNEL (SERIES) -public static partial class Indicator +public static partial class Donchian { + public static IReadOnlyList ToDonchian( + this IReadOnlyList quotes, + int lookbackPeriods = 20) + where TQuote : IQuote => quotes + .ToSortedList() + .CalcDonchian(lookbackPeriods); + private static List CalcDonchian( this List quotesList, int lookbackPeriods) where TQuote : IQuote { // check parameter arguments - Donchian.Validate(lookbackPeriods); + Validate(lookbackPeriods); // initialize int length = quotesList.Count; diff --git a/src/a-d/Donchian/Donchian.Utilities.cs b/src/a-d/Donchian/Donchian.Utilities.cs index 4c7b45533..5cd392a2e 100644 --- a/src/a-d/Donchian/Donchian.Utilities.cs +++ b/src/a-d/Donchian/Donchian.Utilities.cs @@ -1,9 +1,11 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// DONCHIAN CHANNEL (UTILITIES) + +public static partial class Donchian { // CONDENSE (REMOVE null results) - /// + /// public static IReadOnlyList Condense( this IReadOnlyList results) { @@ -18,7 +20,7 @@ public static IReadOnlyList Condense( } // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( this IReadOnlyList results) { @@ -28,4 +30,16 @@ public static IReadOnlyList RemoveWarmupPeriods( return results.Remove(removePeriods); } + + // parameter validation + internal static void Validate( + int lookbackPeriods) + { + // check parameter arguments + if (lookbackPeriods <= 0) + { + throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, + "Lookback periods must be greater than 0 for Donchian Channel."); + } + } } diff --git a/src/a-d/Dpo/Dpo.Api.cs b/src/a-d/Dpo/Dpo.Api.cs deleted file mode 100644 index 4c224e5e4..000000000 --- a/src/a-d/Dpo/Dpo.Api.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Skender.Stock.Indicators; - -// DETRENDED PRICE OSCILLATOR (API) -public static partial class Indicator -{ - // SERIES, from CHAIN - public static IReadOnlyList ToDpo( - this IReadOnlyList results, - int lookbackPeriods) - where T : IReusable - => results - .ToSortedList() - .CalcDpo(lookbackPeriods); -} diff --git a/src/a-d/Dpo/Dpo.StaticSeries.cs b/src/a-d/Dpo/Dpo.StaticSeries.cs index 2c79a189d..1298baca3 100644 --- a/src/a-d/Dpo/Dpo.StaticSeries.cs +++ b/src/a-d/Dpo/Dpo.StaticSeries.cs @@ -2,16 +2,16 @@ namespace Skender.Stock.Indicators; // DETRENDED PRICE OSCILLATOR (SERIES) -public static partial class Indicator +public static partial class Dpo { - // calculate series - private static List CalcDpo( - this List source, + public static IReadOnlyList ToDpo( + this IReadOnlyList source, int lookbackPeriods) where T : IReusable { // check parameter arguments - Dpo.Validate(lookbackPeriods); + ArgumentNullException.ThrowIfNull(source); + Validate(lookbackPeriods); // initialize int length = source.Count; diff --git a/src/a-d/Dpo/Dpo.Common.cs b/src/a-d/Dpo/Dpo.Utilities.cs similarity index 84% rename from src/a-d/Dpo/Dpo.Common.cs rename to src/a-d/Dpo/Dpo.Utilities.cs index 06ae8a441..d6170d70c 100644 --- a/src/a-d/Dpo/Dpo.Common.cs +++ b/src/a-d/Dpo/Dpo.Utilities.cs @@ -1,8 +1,8 @@ namespace Skender.Stock.Indicators; -// DETRENDED PRICE OSCILLATOR (COMMON) +// DETRENDED PRICE OSCILLATOR (UTILITIES) -public static class Dpo +public static partial class Dpo { // parameter validation internal static void Validate( diff --git a/src/a-d/Dynamic/Dynamic.Api.cs b/src/a-d/Dynamic/Dynamic.Api.cs deleted file mode 100644 index 7fbccb8ca..000000000 --- a/src/a-d/Dynamic/Dynamic.Api.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace Skender.Stock.Indicators; - -// McGINLEY DYNAMIC (API) - -public static partial class MgDynamic -{ - // SERIES, from CHAIN - public static IReadOnlyList ToDynamic( - this IReadOnlyList results, - int lookbackPeriods, - double kFactor = 0.6) - where T : IReusable - => results - .ToSortedList() - .CalcDynamic(lookbackPeriods, kFactor); -} diff --git a/src/a-d/Dynamic/Dynamic.StaticSeries.cs b/src/a-d/Dynamic/Dynamic.StaticSeries.cs index 452fb3cc6..03c56c40e 100644 --- a/src/a-d/Dynamic/Dynamic.StaticSeries.cs +++ b/src/a-d/Dynamic/Dynamic.StaticSeries.cs @@ -4,14 +4,15 @@ namespace Skender.Stock.Indicators; public static partial class MgDynamic { - private static List CalcDynamic( - this List source, + public static IReadOnlyList ToDynamic( + this IReadOnlyList source, int lookbackPeriods, - double kFactor) + double kFactor = 0.6) where T : IReusable { // check parameter arguments - MgDynamic.Validate(lookbackPeriods, kFactor); + ArgumentNullException.ThrowIfNull(source); + Validate(lookbackPeriods, kFactor); // initialize int length = source.Count; diff --git a/tests/indicators/a-d/Adx/Adx.StaticSeries.Tests.cs b/tests/indicators/a-d/Adx/Adx.StaticSeries.Tests.cs index fc01d9292..ca0a5c213 100644 --- a/tests/indicators/a-d/Adx/Adx.StaticSeries.Tests.cs +++ b/tests/indicators/a-d/Adx/Adx.StaticSeries.Tests.cs @@ -85,10 +85,11 @@ public override void NoQuotes() [TestMethod] public void Issue859() { - IOrderedEnumerable test859 = File.ReadAllLines("a-d/Adx/issue859quotes.csv") + List test859 = File.ReadAllLines("a-d/Adx/issue859quotes.csv") .Skip(1) .Select(Imports.QuoteFromCsv) - .OrderByDescending(x => x.Timestamp); + .OrderByDescending(x => x.Timestamp) + .ToList(); IReadOnlyList r = test859.ToAdx(); diff --git a/tests/indicators/a-d/Correlation/Correlation.StaticSeries.Tests.cs b/tests/indicators/a-d/Correlation/Correlation.StaticSeries.Tests.cs index 07df155fd..5502f29db 100644 --- a/tests/indicators/a-d/Correlation/Correlation.StaticSeries.Tests.cs +++ b/tests/indicators/a-d/Correlation/Correlation.StaticSeries.Tests.cs @@ -122,7 +122,7 @@ public void Exceptions() Quotes.ToCorrelation(OtherQuotes, 0)); // bad eval quotes - IEnumerable eval = Data.GetCompare(300); + IReadOnlyList eval = Data.GetCompare(300); Assert.ThrowsException(() => Quotes.ToCorrelation(eval, 30)); From 43efa96662a5859af3ef8f1a8ec3c35c30452072 Mon Sep 17 00:00:00 2001 From: Dave Skender <8432125+DaveSkender@users.noreply.github.com> Date: Mon, 14 Oct 2024 17:52:50 -0400 Subject: [PATCH 31/38] refactor: use readonly list input e-k --- src/e-k/ElderRay/ElderRay.Api.cs | 15 ----- src/e-k/ElderRay/ElderRay.Common.cs | 19 ------- src/e-k/ElderRay/ElderRay.StaticSeries.cs | 11 +++- src/e-k/ElderRay/ElderRay.Utilities.cs | 18 +++++- src/e-k/Ema/Ema.Api.cs | 19 ------- src/e-k/Ema/Ema.StreamHub.cs | 19 +++++++ src/e-k/Epma/Epma.Api.cs | 14 ----- src/e-k/Epma/Epma.Common.cs | 19 ------- src/e-k/Epma/Epma.StaticSeries.cs | 12 ++-- src/e-k/Epma/Epma.Utilities.cs | 18 +++++- src/e-k/Fcb/Fcb.Api.cs | 15 ----- src/e-k/Fcb/Fcb.Common.cs | 19 ------- src/e-k/Fcb/Fcb.StaticSeries.cs | 17 +++--- src/e-k/Fcb/Fcb.Utilities.cs | 22 ++++++-- .../FisherTransform/FisherTransform.Api.cs | 14 ----- .../FisherTransform.StaticSeries.cs | 10 +++- ...Common.cs => FisherTransform.Utilities.cs} | 5 +- src/e-k/ForceIndex/ForceIndex.Api.cs | 15 ----- src/e-k/ForceIndex/ForceIndex.StaticSeries.cs | 9 ++- src/e-k/ForceIndex/ForceIndex.Utilities.cs | 18 +++++- src/e-k/ForceIndex/Kvo.Common (1).cs | 19 ------- src/e-k/Fractal/Fractal.Api.cs | 27 --------- src/e-k/Fractal/Fractal.Common.cs | 19 ------- src/e-k/Fractal/Fractal.StaticSeries.cs | 26 ++++++--- src/e-k/Fractal/Fractal.Utilities.cs | 18 +++++- src/e-k/Gator/Gator.Api.cs | 37 ------------ src/e-k/Gator/Gator.StaticSeries.cs | 26 ++++++++- src/e-k/Gator/Gator.Utilities.cs | 8 ++- src/e-k/HeikinAshi/HeikinAshi.Api.cs | 14 ----- src/e-k/HeikinAshi/HeikinAshi.StaticSeries.cs | 14 +++-- src/e-k/Hma/Hma.Api.cs | 14 ----- src/e-k/Hma/Hma.Common.cs | 19 ------- src/e-k/Hma/Hma.StaticSeries.cs | 16 +++--- src/e-k/Hma/Hma.Utilities.cs | 20 +++---- src/e-k/HtTrendline/HtTrendline.Api.cs | 26 --------- src/e-k/HtTrendline/HtTrendline.Common.cs | 10 ---- .../HtTrendline/HtTrendline.StaticSeries.cs | 22 +++++++- src/e-k/HtTrendline/HtTrendline.Utilities.cs | 9 ++- src/e-k/Hurst/Hurst.Api.cs | 14 ----- src/e-k/Hurst/Hurst.Common.cs | 19 ------- src/e-k/Hurst/Hurst.StaticSeries.cs | 11 ++-- src/e-k/Hurst/Hurst.Utilities.cs | 18 +++++- src/e-k/Ichimoku/Ichimoku.Api.cs | 56 ------------------- src/e-k/Ichimoku/Ichimoku.Common.cs | 40 ------------- src/e-k/Ichimoku/Ichimoku.StaticSeries.cs | 47 +++++++++++++++- src/e-k/Ichimoku/Ichimoku.Utilities.cs | 41 +++++++++++++- src/e-k/Kama/Kama.Api.cs | 17 ------ src/e-k/Kama/Kama.StaticSeries.cs | 13 +++-- src/e-k/Kama/Kama.Utilities.cs | 4 +- src/e-k/Keltner/Keltner.Api.cs | 17 ------ src/e-k/Keltner/Keltner.Common.cs | 33 ----------- src/e-k/Keltner/Keltner.StaticSeries.cs | 11 +++- src/e-k/Keltner/Keltner.Utilities.cs | 34 ++++++++++- src/e-k/Kvo/Kvo.Api.cs | 17 ------ src/e-k/Kvo/Kvo.Common.cs | 33 ----------- src/e-k/Kvo/Kvo.StaticSeries.cs | 11 +++- src/e-k/Kvo/Kvo.Utilities.cs | 32 ++++++++++- .../MaEnvelopes/MaEnvelopes.StaticSeries.cs | 10 ++-- src/m-r/MaEnvelopes/MaEnvelopes.Utilities.cs | 2 +- src/m-r/Macd/Macd.Utilities.cs | 2 +- src/m-r/Mama/Mama.Utilities.cs | 2 +- src/m-r/Marubozu/Marubozu.Api.cs | 2 +- src/m-r/Mfi/Mfi.Api.cs | 2 +- src/m-r/Mfi/Mfi.Utilities.cs | 2 +- src/m-r/Obv/Obv.Api.cs | 2 +- src/m-r/ParabolicSar/ParabolicSar.Api.cs | 4 +- .../ParabolicSar/ParabolicSar.Utilities.cs | 2 +- src/m-r/PivotPoints/PivotPoints.Api.cs | 2 +- src/m-r/PivotPoints/PivotPoints.Utilities.cs | 2 +- src/m-r/Pivots/Pivots.Api.cs | 18 ------ src/m-r/Pivots/Pivots.Common.cs | 34 ----------- src/m-r/Pivots/Pivots.StaticSeries.cs | 27 ++++----- src/m-r/Pivots/Pivots.Utilities.cs | 34 ++++++++++- src/m-r/Pmo/Pmo.Utilities.cs | 2 +- src/m-r/Pvo/Pvo.Api.cs | 2 +- src/m-r/Pvo/Pvo.Utilities.cs | 2 +- src/m-r/Renko/Renko.Api.cs | 2 +- src/m-r/RenkoAtr/RenkoAtr.Api.cs | 2 +- src/m-r/Roc/Roc.Utilities.cs | 2 +- src/m-r/RocWb/RocWb.Utilities.cs | 2 +- src/m-r/RollingPivots/RollingPivots.Api.cs | 2 +- .../RollingPivots/RollingPivots.Utilities.cs | 2 +- src/m-r/Rsi/Rsi.Api.cs | 14 ----- src/m-r/Rsi/Rsi.Common.cs | 19 ------- src/m-r/Rsi/Rsi.StaticSeries.cs | 11 ++-- src/m-r/Rsi/Rsi.Utilities.cs | 18 +++++- src/s-z/Slope/Slope.Api.cs | 14 ----- src/s-z/Slope/Slope.Common.cs | 19 ------- src/s-z/Slope/Slope.StaticSeries.cs | 10 ++-- src/s-z/Slope/Slope.Utilities.cs | 22 ++++---- src/s-z/Smi/Smi.Api.cs | 2 +- src/s-z/Smi/Smi.Utilities.cs | 2 +- src/s-z/Smma/Smma.Utilities.cs | 2 +- src/s-z/StarcBands/StarcBands.Api.cs | 2 +- src/s-z/StarcBands/StarcBands.Utilities.cs | 4 +- src/s-z/Stc/Stc.Utilities.cs | 2 +- src/s-z/StdDev/StdDev.Utilities.cs | 2 +- .../StdDevChannels.StaticSeries.cs | 4 +- .../StdDevChannels.Utilities.cs | 4 +- src/s-z/Stoch/Stoch.Api.cs | 4 +- src/s-z/Stoch/Stoch.Utilities.cs | 2 +- src/s-z/StochRsi/StochRsi.StaticSeries.cs | 4 +- src/s-z/StochRsi/StochRsi.Utilities.cs | 2 +- src/s-z/SuperTrend/SuperTrend.Api.cs | 2 +- src/s-z/SuperTrend/SuperTrend.Utilities.cs | 4 +- src/s-z/Tema/Tema.Utilities.cs | 2 +- src/s-z/Tr/Tr.Api.cs | 2 +- src/s-z/Trix/Trix.Utilities.cs | 2 +- src/s-z/Tsi/Tsi.Utilities.cs | 2 +- src/s-z/UlcerIndex/UlcerIndex.Utilities.cs | 2 +- src/s-z/Ultimate/Ultimate.Api.cs | 2 +- src/s-z/Ultimate/Ultimate.Utilities.cs | 2 +- src/s-z/VolatilityStop/VolatilityStop.Api.cs | 2 +- .../VolatilityStop.Utilities.cs | 2 +- src/s-z/Vortex/Vortex.Api.cs | 2 +- src/s-z/Vortex/Vortex.Utilities.cs | 4 +- src/s-z/Vwap/Vwap.Api.cs | 2 +- src/s-z/Vwap/Vwap.Utilities.cs | 2 +- src/s-z/Vwma/Vwma.Api.cs | 2 +- src/s-z/Vwma/Vwma.Utilities.cs | 2 +- src/s-z/WilliamsR/WilliamsR.Api.cs | 2 +- src/s-z/WilliamsR/WilliamsR.Utilities.cs | 2 +- src/s-z/Wma/Wma.Api.cs | 14 ----- src/s-z/Wma/Wma.Common.cs | 19 ------- src/s-z/Wma/Wma.StaticSeries.cs | 9 +-- src/s-z/Wma/Wma.Utilities.cs | 20 +++---- src/s-z/ZigZag/ZigZag.Api.cs | 2 +- src/s-z/ZigZag/ZigZag.Utilities.cs | 2 +- .../e-k/Fractal/Fractal.StaticSeries.Tests.cs | 2 +- .../e-k/Gator/Gator.StaticSeries.Tests.cs | 2 +- .../HtTrendline.StaticSeries.Tests.cs | 2 +- .../ParabolicSar.StaticSeries.Tests.cs | 13 +++-- .../PivotPoints.StaticSeries.Tests.cs | 15 +++-- .../RollingPivots.StaticSeries.Tests.cs | 6 +- .../SuperTrend.StaticSeries.Tests.cs | 2 +- .../s-z/Vwap/Vwap.StaticSeries.Tests.cs | 5 +- .../s-z/ZigZag/ZigZag.StaticSeries.Tests.cs | 15 +++-- 137 files changed, 638 insertions(+), 980 deletions(-) delete mode 100644 src/e-k/ElderRay/ElderRay.Api.cs delete mode 100644 src/e-k/ElderRay/ElderRay.Common.cs delete mode 100644 src/e-k/Ema/Ema.Api.cs delete mode 100644 src/e-k/Epma/Epma.Api.cs delete mode 100644 src/e-k/Epma/Epma.Common.cs delete mode 100644 src/e-k/Fcb/Fcb.Api.cs delete mode 100644 src/e-k/Fcb/Fcb.Common.cs delete mode 100644 src/e-k/FisherTransform/FisherTransform.Api.cs rename src/e-k/FisherTransform/{FisherTransform.Common.cs => FisherTransform.Utilities.cs} (84%) delete mode 100644 src/e-k/ForceIndex/ForceIndex.Api.cs delete mode 100644 src/e-k/ForceIndex/Kvo.Common (1).cs delete mode 100644 src/e-k/Fractal/Fractal.Api.cs delete mode 100644 src/e-k/Fractal/Fractal.Common.cs delete mode 100644 src/e-k/Gator/Gator.Api.cs delete mode 100644 src/e-k/HeikinAshi/HeikinAshi.Api.cs delete mode 100644 src/e-k/Hma/Hma.Api.cs delete mode 100644 src/e-k/Hma/Hma.Common.cs delete mode 100644 src/e-k/HtTrendline/HtTrendline.Api.cs delete mode 100644 src/e-k/HtTrendline/HtTrendline.Common.cs delete mode 100644 src/e-k/Hurst/Hurst.Api.cs delete mode 100644 src/e-k/Hurst/Hurst.Common.cs delete mode 100644 src/e-k/Ichimoku/Ichimoku.Api.cs delete mode 100644 src/e-k/Ichimoku/Ichimoku.Common.cs delete mode 100644 src/e-k/Kama/Kama.Api.cs delete mode 100644 src/e-k/Keltner/Keltner.Api.cs delete mode 100644 src/e-k/Keltner/Keltner.Common.cs delete mode 100644 src/e-k/Kvo/Kvo.Api.cs delete mode 100644 src/e-k/Kvo/Kvo.Common.cs delete mode 100644 src/m-r/Pivots/Pivots.Api.cs delete mode 100644 src/m-r/Pivots/Pivots.Common.cs delete mode 100644 src/m-r/Rsi/Rsi.Api.cs delete mode 100644 src/m-r/Rsi/Rsi.Common.cs delete mode 100644 src/s-z/Slope/Slope.Api.cs delete mode 100644 src/s-z/Slope/Slope.Common.cs delete mode 100644 src/s-z/Wma/Wma.Api.cs delete mode 100644 src/s-z/Wma/Wma.Common.cs diff --git a/src/e-k/ElderRay/ElderRay.Api.cs b/src/e-k/ElderRay/ElderRay.Api.cs deleted file mode 100644 index fbc8f4a7a..000000000 --- a/src/e-k/ElderRay/ElderRay.Api.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Skender.Stock.Indicators; - -// ELDER-RAY (API) -public static partial class Indicator -{ - // SERIES, from TQuote - /// - /// - public static IReadOnlyList ToElderRay( - this IEnumerable quotes, - int lookbackPeriods = 13) - where TQuote : IQuote => quotes - .ToQuoteDList() - .CalcElderRay(lookbackPeriods); -} diff --git a/src/e-k/ElderRay/ElderRay.Common.cs b/src/e-k/ElderRay/ElderRay.Common.cs deleted file mode 100644 index 76e73e10a..000000000 --- a/src/e-k/ElderRay/ElderRay.Common.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Skender.Stock.Indicators; - -// ELDER-RAY (COMMON) - -public static class ElderRay -{ - // parameter validation - internal static void Validate( - int lookbackPeriods) - { - // check parameter arguments - if (lookbackPeriods <= 0) - { - throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, - "Lookback periods must be greater than 0 for Elder-ray Index."); - } - } - -} diff --git a/src/e-k/ElderRay/ElderRay.StaticSeries.cs b/src/e-k/ElderRay/ElderRay.StaticSeries.cs index 3935caa6a..499b6cca4 100644 --- a/src/e-k/ElderRay/ElderRay.StaticSeries.cs +++ b/src/e-k/ElderRay/ElderRay.StaticSeries.cs @@ -2,14 +2,21 @@ namespace Skender.Stock.Indicators; // ELDER-RAY (SERIES) -public static partial class Indicator +public static partial class ElderRay { + public static IReadOnlyList ToElderRay( + this IReadOnlyList quotes, + int lookbackPeriods = 13) + where TQuote : IQuote => quotes + .ToQuoteDList() + .CalcElderRay(lookbackPeriods); + private static List CalcElderRay( this List source, int lookbackPeriods) { // check parameter arguments - ElderRay.Validate(lookbackPeriods); + Validate(lookbackPeriods); // initialize int length = source.Count; diff --git a/src/e-k/ElderRay/ElderRay.Utilities.cs b/src/e-k/ElderRay/ElderRay.Utilities.cs index 052844eea..5e789103b 100644 --- a/src/e-k/ElderRay/ElderRay.Utilities.cs +++ b/src/e-k/ElderRay/ElderRay.Utilities.cs @@ -1,9 +1,11 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// ELDER-RAY (UTILITIES) + +public static partial class ElderRay { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( this IReadOnlyList results) { @@ -13,4 +15,16 @@ public static IReadOnlyList RemoveWarmupPeriods( return results.Remove(n + 100); } + + // parameter validation + internal static void Validate( + int lookbackPeriods) + { + // check parameter arguments + if (lookbackPeriods <= 0) + { + throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, + "Lookback periods must be greater than 0 for Elder-ray Index."); + } + } } diff --git a/src/e-k/Ema/Ema.Api.cs b/src/e-k/Ema/Ema.Api.cs deleted file mode 100644 index bf9d82f37..000000000 --- a/src/e-k/Ema/Ema.Api.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Skender.Stock.Indicators; - -// EXPONENTIAL MOVING AVERAGE (API) - -public static partial class Ema -{ - // HUB, from Chain Provider - public static EmaHub ToEma( - this IChainProvider chainProvider, - int lookbackPeriods) - where T : IReusable - => new(chainProvider, lookbackPeriods); -} - -public interface IEma -{ - int LookbackPeriods { get; } - double K { get; } -} diff --git a/src/e-k/Ema/Ema.StreamHub.cs b/src/e-k/Ema/Ema.StreamHub.cs index 80996e16c..c66697259 100644 --- a/src/e-k/Ema/Ema.StreamHub.cs +++ b/src/e-k/Ema/Ema.StreamHub.cs @@ -2,6 +2,25 @@ namespace Skender.Stock.Indicators; // EXPONENTIAL MOVING AVERAGE (STREAM HUB) +#region hub interface and initializer + +public interface IEma +{ + int LookbackPeriods { get; } + double K { get; } +} + +public static partial class Ema +{ + // HUB, from Chain Provider + public static EmaHub ToEma( + this IChainProvider chainProvider, + int lookbackPeriods) + where T : IReusable + => new(chainProvider, lookbackPeriods); +} +#endregion + public class EmaHub : ChainProvider, IEma where TIn : IReusable diff --git a/src/e-k/Epma/Epma.Api.cs b/src/e-k/Epma/Epma.Api.cs deleted file mode 100644 index 6136f921a..000000000 --- a/src/e-k/Epma/Epma.Api.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Skender.Stock.Indicators; - -// ENDPOINT MOVING AVERAGE (API) -public static partial class Indicator -{ - // SERIES, from CHAIN - public static IReadOnlyList ToEpma( - this IReadOnlyList results, - int lookbackPeriods) - where T : IReusable - => results - .ToSortedList() - .CalcEpma(lookbackPeriods); -} diff --git a/src/e-k/Epma/Epma.Common.cs b/src/e-k/Epma/Epma.Common.cs deleted file mode 100644 index 84cdab2ac..000000000 --- a/src/e-k/Epma/Epma.Common.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Skender.Stock.Indicators; - -// ENDPOINT MOVING AVERAGE (COMMON) - -public static class Epma -{ - // parameter validation - internal static void Validate( - int lookbackPeriods) - { - // check parameter arguments - if (lookbackPeriods <= 0) - { - throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, - "Lookback periods must be greater than 0 for Epma."); - } - } - -} diff --git a/src/e-k/Epma/Epma.StaticSeries.cs b/src/e-k/Epma/Epma.StaticSeries.cs index 0319b6d7b..131d601be 100644 --- a/src/e-k/Epma/Epma.StaticSeries.cs +++ b/src/e-k/Epma/Epma.StaticSeries.cs @@ -2,23 +2,23 @@ namespace Skender.Stock.Indicators; // ENDPOINT MOVING AVERAGE (SERIES) -public static partial class Indicator +public static partial class Epma { - // calculate series - private static List CalcEpma( - this List source, + public static IReadOnlyList ToEpma( + this IReadOnlyList source, int lookbackPeriods) where T : IReusable { // check parameter arguments - Epma.Validate(lookbackPeriods); + ArgumentNullException.ThrowIfNull(source); + Validate(lookbackPeriods); // initialize int length = source.Count; List results = new(length); IReadOnlyList slope - = source.CalcSlope(lookbackPeriods); + = source.ToSlope(lookbackPeriods); // roll through source values for (int i = 0; i < length; i++) diff --git a/src/e-k/Epma/Epma.Utilities.cs b/src/e-k/Epma/Epma.Utilities.cs index b0e7bbdf1..49bfc8370 100644 --- a/src/e-k/Epma/Epma.Utilities.cs +++ b/src/e-k/Epma/Epma.Utilities.cs @@ -1,9 +1,11 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// ENDPOINT MOVING AVERAGE (UTILITIES) + +public static partial class Epma { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( this IReadOnlyList results) { @@ -13,4 +15,16 @@ public static IReadOnlyList RemoveWarmupPeriods( return results.Remove(removePeriods); } + + // parameter validation + internal static void Validate( + int lookbackPeriods) + { + // check parameter arguments + if (lookbackPeriods <= 0) + { + throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, + "Lookback periods must be greater than 0 for Epma."); + } + } } diff --git a/src/e-k/Fcb/Fcb.Api.cs b/src/e-k/Fcb/Fcb.Api.cs deleted file mode 100644 index 1345e3a9a..000000000 --- a/src/e-k/Fcb/Fcb.Api.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Skender.Stock.Indicators; - -// FRACTAL CHAOS BANDS (API) -public static partial class Indicator -{ - // SERIES, from TQuote - /// - /// - public static IReadOnlyList ToFcb( - this IEnumerable quotes, - int windowSpan = 2) - where TQuote : IQuote => quotes - .ToSortedList() - .CalcFcb(windowSpan); -} diff --git a/src/e-k/Fcb/Fcb.Common.cs b/src/e-k/Fcb/Fcb.Common.cs deleted file mode 100644 index 4535c746a..000000000 --- a/src/e-k/Fcb/Fcb.Common.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Skender.Stock.Indicators; - -// FRACTAL CHAOS BANDS (COMMON) - -public static class Fcb -{ - // parameter validation - internal static void Validate( - int windowSpan) - { - // check parameter arguments - if (windowSpan < 2) - { - throw new ArgumentOutOfRangeException(nameof(windowSpan), windowSpan, - "Window span must be at least 2 for FCB."); - } - } - -} diff --git a/src/e-k/Fcb/Fcb.StaticSeries.cs b/src/e-k/Fcb/Fcb.StaticSeries.cs index 0eac52d52..36ca6553e 100644 --- a/src/e-k/Fcb/Fcb.StaticSeries.cs +++ b/src/e-k/Fcb/Fcb.StaticSeries.cs @@ -2,22 +2,23 @@ namespace Skender.Stock.Indicators; // FRACTAL CHAOS BANDS (SERIES) -public static partial class Indicator +public static partial class Fcb { - private static List CalcFcb( - this List quotesList, - int windowSpan) + public static IReadOnlyList ToFcb( + this IReadOnlyList quotes, + int windowSpan = 2) where TQuote : IQuote { // check parameter arguments - Fcb.Validate(windowSpan); + ArgumentNullException.ThrowIfNull(quotes); + Validate(windowSpan); // initialize - int length = quotesList.Count; + int length = quotes.Count; List results = new(length); - List fractals = quotesList - .CalcFractal(windowSpan, windowSpan, EndType.HighLow); + IReadOnlyList fractals = quotes + .ToFractal(windowSpan, windowSpan, EndType.HighLow); decimal? upperLine = null; decimal? lowerLine = null; diff --git a/src/e-k/Fcb/Fcb.Utilities.cs b/src/e-k/Fcb/Fcb.Utilities.cs index b1ac461a7..6a3dc52b4 100644 --- a/src/e-k/Fcb/Fcb.Utilities.cs +++ b/src/e-k/Fcb/Fcb.Utilities.cs @@ -1,9 +1,10 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// FRACTAL CHAOS BANDS (UTILITIES) + +public static partial class Fcb { - // CONDENSE (REMOVE null results) - /// + /// public static IReadOnlyList Condense( this IReadOnlyList results) { @@ -17,8 +18,7 @@ public static IReadOnlyList Condense( return resultsList.ToSortedList(); } - // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( this IReadOnlyList results) { @@ -28,4 +28,16 @@ public static IReadOnlyList RemoveWarmupPeriods( return results.Remove(removePeriods); } + + // parameter validation + internal static void Validate( + int windowSpan) + { + // check parameter arguments + if (windowSpan < 2) + { + throw new ArgumentOutOfRangeException(nameof(windowSpan), windowSpan, + "Window span must be at least 2 for FCB."); + } + } } diff --git a/src/e-k/FisherTransform/FisherTransform.Api.cs b/src/e-k/FisherTransform/FisherTransform.Api.cs deleted file mode 100644 index db9488809..000000000 --- a/src/e-k/FisherTransform/FisherTransform.Api.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Skender.Stock.Indicators; - -// FISHER TRANSFORM (API) -public static partial class Indicator -{ - // SERIES, from CHAIN - public static IReadOnlyList ToFisherTransform( - this IReadOnlyList results, - int lookbackPeriods = 10) - where T : IReusable - => results - .ToSortedList(CandlePart.HL2) - .CalcFisherTransform(lookbackPeriods); -} diff --git a/src/e-k/FisherTransform/FisherTransform.StaticSeries.cs b/src/e-k/FisherTransform/FisherTransform.StaticSeries.cs index daa6afd92..04ac97f81 100644 --- a/src/e-k/FisherTransform/FisherTransform.StaticSeries.cs +++ b/src/e-k/FisherTransform/FisherTransform.StaticSeries.cs @@ -2,8 +2,16 @@ namespace Skender.Stock.Indicators; // FISHER TRANSFORM (SERIES) -public static partial class Indicator +public static partial class FisherTransform { + public static IReadOnlyList ToFisherTransform( + this IReadOnlyList results, + int lookbackPeriods = 10) + where T : IReusable + => results + .ToSortedList(CandlePart.HL2) + .CalcFisherTransform(lookbackPeriods); + private static List CalcFisherTransform( this List source, int lookbackPeriods) diff --git a/src/e-k/FisherTransform/FisherTransform.Common.cs b/src/e-k/FisherTransform/FisherTransform.Utilities.cs similarity index 84% rename from src/e-k/FisherTransform/FisherTransform.Common.cs rename to src/e-k/FisherTransform/FisherTransform.Utilities.cs index 71e6f016c..8d192b5db 100644 --- a/src/e-k/FisherTransform/FisherTransform.Common.cs +++ b/src/e-k/FisherTransform/FisherTransform.Utilities.cs @@ -1,8 +1,8 @@ namespace Skender.Stock.Indicators; -// FISHER TRANSFORM (COMMON) +// FISHER TRANSFORM (UTILITIES) -public static class FisherTransform +public static partial class FisherTransform { // parameter validation internal static void Validate( @@ -15,5 +15,4 @@ internal static void Validate( "Lookback periods must be greater than 0 for Fisher Transform."); } } - } diff --git a/src/e-k/ForceIndex/ForceIndex.Api.cs b/src/e-k/ForceIndex/ForceIndex.Api.cs deleted file mode 100644 index 34bf5ab9d..000000000 --- a/src/e-k/ForceIndex/ForceIndex.Api.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Skender.Stock.Indicators; - -// FORCE INDEX (API) -public static partial class Indicator -{ - // SERIES, from TQuote - /// - /// - public static IReadOnlyList ToForceIndex( - this IEnumerable quotes, - int lookbackPeriods = 2) - where TQuote : IQuote => quotes - .ToQuoteDList() - .CalcForceIndex(lookbackPeriods); -} diff --git a/src/e-k/ForceIndex/ForceIndex.StaticSeries.cs b/src/e-k/ForceIndex/ForceIndex.StaticSeries.cs index 8374def9c..9b76b1eca 100644 --- a/src/e-k/ForceIndex/ForceIndex.StaticSeries.cs +++ b/src/e-k/ForceIndex/ForceIndex.StaticSeries.cs @@ -2,8 +2,15 @@ namespace Skender.Stock.Indicators; // FORCE INDEX (SERIES) -public static partial class Indicator +public static partial class ForceIndex { + public static IReadOnlyList ToForceIndex( + this IReadOnlyList quotes, + int lookbackPeriods = 2) + where TQuote : IQuote => quotes + .ToQuoteDList() + .CalcForceIndex(lookbackPeriods); + private static List CalcForceIndex( this List source, int lookbackPeriods) diff --git a/src/e-k/ForceIndex/ForceIndex.Utilities.cs b/src/e-k/ForceIndex/ForceIndex.Utilities.cs index 9c8ce8899..025c244ca 100644 --- a/src/e-k/ForceIndex/ForceIndex.Utilities.cs +++ b/src/e-k/ForceIndex/ForceIndex.Utilities.cs @@ -1,9 +1,11 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// FORCE INDEX (UTILITIES) + +public static partial class ForceIndex { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( this IReadOnlyList results) { @@ -13,4 +15,16 @@ public static IReadOnlyList RemoveWarmupPeriods( return results.Remove(n + 100); } + + // parameter validation + internal static void Validate( + int lookbackPeriods) + { + // check parameter arguments + if (lookbackPeriods <= 0) + { + throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, + "Lookback periods must be greater than 0 for Force Index."); + } + } } diff --git a/src/e-k/ForceIndex/Kvo.Common (1).cs b/src/e-k/ForceIndex/Kvo.Common (1).cs deleted file mode 100644 index a694b6633..000000000 --- a/src/e-k/ForceIndex/Kvo.Common (1).cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Skender.Stock.Indicators; - -// FORCE INDEX (COMMON) - -public static class ForceIndex -{ - // parameter validation - internal static void Validate( - int lookbackPeriods) - { - // check parameter arguments - if (lookbackPeriods <= 0) - { - throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, - "Lookback periods must be greater than 0 for Force Index."); - } - } - -} diff --git a/src/e-k/Fractal/Fractal.Api.cs b/src/e-k/Fractal/Fractal.Api.cs deleted file mode 100644 index 82e1c436e..000000000 --- a/src/e-k/Fractal/Fractal.Api.cs +++ /dev/null @@ -1,27 +0,0 @@ -namespace Skender.Stock.Indicators; - -// WILLIAMS FRACTAL (API) -public static partial class Indicator -{ - /// - /// - public static IReadOnlyList ToFractal( - this IEnumerable quotes, - int windowSpan = 2, - EndType endType = EndType.HighLow) - where TQuote : IQuote => quotes - .ToSortedList() - .CalcFractal(windowSpan, windowSpan, endType); - - // more configurable version (undocumented) - /// - /// - public static IReadOnlyList GetFractal( - this IEnumerable quotes, - int leftSpan, - int rightSpan, - EndType endType = EndType.HighLow) - where TQuote : IQuote => quotes - .ToSortedList() - .CalcFractal(leftSpan, rightSpan, endType); -} diff --git a/src/e-k/Fractal/Fractal.Common.cs b/src/e-k/Fractal/Fractal.Common.cs deleted file mode 100644 index 33f2f69ea..000000000 --- a/src/e-k/Fractal/Fractal.Common.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Skender.Stock.Indicators; - -// WILLIAMS FRACTAL (COMMON) - -public static class Fractal -{ - // parameter validation - internal static void Validate( - int windowSpan) - { - // check parameter arguments - if (windowSpan < 2) - { - throw new ArgumentOutOfRangeException(nameof(windowSpan), windowSpan, - "Window span must be at least 2 for Fractal."); - } - } - -} diff --git a/src/e-k/Fractal/Fractal.StaticSeries.cs b/src/e-k/Fractal/Fractal.StaticSeries.cs index 9d15456b7..2dd3b1615 100644 --- a/src/e-k/Fractal/Fractal.StaticSeries.cs +++ b/src/e-k/Fractal/Fractal.StaticSeries.cs @@ -2,30 +2,38 @@ namespace Skender.Stock.Indicators; // WILLIAMS FRACTAL (SERIES) -public static partial class Indicator +public static partial class Fractal { - private static List CalcFractal( - this List quotesList, + public static IReadOnlyList ToFractal( + this IReadOnlyList quotes, + int windowSpan = 2, + EndType endType = EndType.HighLow) + where TQuote : IQuote => quotes + .ToFractal(windowSpan, windowSpan, endType); + + public static IReadOnlyList ToFractal( + this IReadOnlyList quotes, int leftSpan, int rightSpan, - EndType endType) + EndType endType = EndType.HighLow) where TQuote : IQuote { // check parameter arguments - Fractal.Validate(Math.Min(leftSpan, rightSpan)); + ArgumentNullException.ThrowIfNull(quotes); + Validate(Math.Min(leftSpan, rightSpan)); // initialize - int length = quotesList.Count; + int length = quotes.Count; List results = new(length); // roll through source values for (int i = 0; i < length; i++) { - TQuote q = quotesList[i]; + TQuote q = quotes[i]; decimal? fractalBear = null; decimal? fractalBull = null; - if (i + 1 > leftSpan && i + 1 <= quotesList.Count - rightSpan) + if (i + 1 > leftSpan && i + 1 <= length - rightSpan) { bool isHigh = true; bool isLow = true; @@ -46,7 +54,7 @@ private static List CalcFractal( } // evaluate wing periods - TQuote wing = quotesList[p]; + TQuote wing = quotes[p]; decimal wingHigh = endType == EndType.Close ? wing.Close : wing.High; diff --git a/src/e-k/Fractal/Fractal.Utilities.cs b/src/e-k/Fractal/Fractal.Utilities.cs index be6e56385..9e36b3105 100644 --- a/src/e-k/Fractal/Fractal.Utilities.cs +++ b/src/e-k/Fractal/Fractal.Utilities.cs @@ -1,9 +1,11 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// WILLIAMS FRACTAL (UTILITIES) + +public static partial class Fractal { // CONDENSE (REMOVE null results) - /// + /// public static IReadOnlyList Condense( this IReadOnlyList results) { @@ -16,4 +18,16 @@ public static IReadOnlyList Condense( return resultsList.ToSortedList(); } + + // parameter validation + internal static void Validate( + int windowSpan) + { + // check parameter arguments + if (windowSpan < 2) + { + throw new ArgumentOutOfRangeException(nameof(windowSpan), windowSpan, + "Window span must be at least 2 for Fractal."); + } + } } diff --git a/src/e-k/Gator/Gator.Api.cs b/src/e-k/Gator/Gator.Api.cs deleted file mode 100644 index 384112566..000000000 --- a/src/e-k/Gator/Gator.Api.cs +++ /dev/null @@ -1,37 +0,0 @@ -namespace Skender.Stock.Indicators; - -// GATOR OSCILLATOR (API) -public static partial class Indicator -{ - // SERIES, from CHAIN (or QUOTES) - /// - /// Gator Oscillator is an expanded view of Williams Alligator. - /// - /// See - /// documentation - /// for more information. - /// - /// - /// - /// - /// - /// T must be or type - /// - /// Time-series values to transform. - /// Time series of Gator values. - - // See Alligator API for explanation of unusual setup. - public static IReadOnlyList ToGator( - this IEnumerable source) - where T : IReusable - => source - .ToAlligator() - .GetGator(); - - // SERIES, from [custom] Alligator - public static IReadOnlyList GetGator( - this IEnumerable alligator) - => alligator - .ToList() - .CalcGator(); -} diff --git a/src/e-k/Gator/Gator.StaticSeries.cs b/src/e-k/Gator/Gator.StaticSeries.cs index 12d502632..66fe5353b 100644 --- a/src/e-k/Gator/Gator.StaticSeries.cs +++ b/src/e-k/Gator/Gator.StaticSeries.cs @@ -2,11 +2,31 @@ namespace Skender.Stock.Indicators; // GATOR OSCILLATOR (SERIES) -public static partial class Indicator +public static partial class Gator { - private static List CalcGator( - this List alligator) + /// + /// Gator Oscillator is an expanded view of Williams Alligator. + /// + /// + /// + /// + /// T must be or type + /// + /// Time-series values to transform. + /// Time series of Gator values. + public static IReadOnlyList ToGator( + this IReadOnlyList source) + where T : IReusable + => source + .ToAlligator() + .ToGator(); + + // from [custom] Alligator + public static IReadOnlyList ToGator( + this IReadOnlyList alligator) { + ArgumentNullException.ThrowIfNull(alligator); + // initialize int length = alligator.Count; List results = []; diff --git a/src/e-k/Gator/Gator.Utilities.cs b/src/e-k/Gator/Gator.Utilities.cs index d2ce6e2a6..a9b97545a 100644 --- a/src/e-k/Gator/Gator.Utilities.cs +++ b/src/e-k/Gator/Gator.Utilities.cs @@ -1,9 +1,11 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// GATOR OSCILLATOR (UTILITIES) + +public static partial class Gator { // CONDENSE (REMOVE null results) - /// + /// public static IReadOnlyList Condense( this IReadOnlyList results) { @@ -18,7 +20,7 @@ public static IReadOnlyList Condense( } // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( this IReadOnlyList results) => results.Remove(150); } diff --git a/src/e-k/HeikinAshi/HeikinAshi.Api.cs b/src/e-k/HeikinAshi/HeikinAshi.Api.cs deleted file mode 100644 index f46747dee..000000000 --- a/src/e-k/HeikinAshi/HeikinAshi.Api.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Skender.Stock.Indicators; - -// HEIKIN-ASHI (API) -public static partial class Indicator -{ - // SERIES, from TQuote - /// - /// - public static IReadOnlyList ToHeikinAshi( - this IEnumerable quotes) - where TQuote : IQuote => quotes - .ToSortedList() - .CalcHeikinAshi(); -} diff --git a/src/e-k/HeikinAshi/HeikinAshi.StaticSeries.cs b/src/e-k/HeikinAshi/HeikinAshi.StaticSeries.cs index 295303089..946cb94eb 100644 --- a/src/e-k/HeikinAshi/HeikinAshi.StaticSeries.cs +++ b/src/e-k/HeikinAshi/HeikinAshi.StaticSeries.cs @@ -2,14 +2,16 @@ namespace Skender.Stock.Indicators; // HEIKIN-ASHI (SERIES) -public static partial class Indicator +public static class HeikinAshi { - private static List CalcHeikinAshi( - this List quotesList) + public static IReadOnlyList ToHeikinAshi( + this IReadOnlyList quotes) where TQuote : IQuote { + ArgumentNullException.ThrowIfNull(quotes); + // initialize - int length = quotesList.Count; + int length = quotes.Count; List results = new(length); decimal prevOpen = decimal.MinValue; @@ -17,7 +19,7 @@ private static List CalcHeikinAshi( if (length > 0) { - TQuote q = quotesList[0]; + TQuote q = quotes[0]; prevOpen = q.Open; prevClose = q.Close; } @@ -25,7 +27,7 @@ private static List CalcHeikinAshi( // roll through source values for (int i = 0; i < length; i++) { - TQuote q = quotesList[i]; + TQuote q = quotes[i]; // close decimal close = (q.Open + q.High + q.Low + q.Close) / 4; diff --git a/src/e-k/Hma/Hma.Api.cs b/src/e-k/Hma/Hma.Api.cs deleted file mode 100644 index c5c247fa8..000000000 --- a/src/e-k/Hma/Hma.Api.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Skender.Stock.Indicators; - -// HULL MOVING AVERAGE (API) -public static partial class Indicator -{ - // SERIES, from CHAIN - public static IReadOnlyList ToHma( - this IReadOnlyList results, - int lookbackPeriods) - where T : IReusable - => results - .ToSortedList() - .CalcHma(lookbackPeriods); -} diff --git a/src/e-k/Hma/Hma.Common.cs b/src/e-k/Hma/Hma.Common.cs deleted file mode 100644 index d3d98190f..000000000 --- a/src/e-k/Hma/Hma.Common.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Skender.Stock.Indicators; - -// HULL MOVING AVERAGE (COMMON) - -public static class Hma -{ - // parameter validation - internal static void Validate( - int lookbackPeriods) - { - // check parameter arguments - if (lookbackPeriods <= 1) - { - throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, - "Lookback periods must be greater than 1 for HMA."); - } - } - -} diff --git a/src/e-k/Hma/Hma.StaticSeries.cs b/src/e-k/Hma/Hma.StaticSeries.cs index d06a74c98..a4c02ba66 100644 --- a/src/e-k/Hma/Hma.StaticSeries.cs +++ b/src/e-k/Hma/Hma.StaticSeries.cs @@ -2,16 +2,16 @@ namespace Skender.Stock.Indicators; // HULL MOVING AVERAGE (SERIES) -public static partial class Indicator +public static partial class Hma { - // calculate series - private static List CalcHma( - this List source, + public static IReadOnlyList ToHma( + this IReadOnlyList source, int lookbackPeriods) where T : IReusable { // check parameter arguments - Hma.Validate(lookbackPeriods); + ArgumentNullException.ThrowIfNull(source); + Validate(lookbackPeriods); // initialize int length = source.Count; @@ -19,10 +19,10 @@ private static List CalcHma( List synthHistory = []; IReadOnlyList wmaN1 - = source.CalcWma(lookbackPeriods); + = source.ToWma(lookbackPeriods); IReadOnlyList wmaN2 - = source.CalcWma(lookbackPeriods / 2); + = source.ToWma(lookbackPeriods / 2); // roll through source values, to get interim synthetic quotes for (int i = 0; i < length; i++) @@ -53,7 +53,7 @@ IReadOnlyList wmaN2 .ToList(); // calculate final HMA = WMA with period SQRT(n) - List hmaResults = synthHistory.CalcWma(sqN) + List hmaResults = synthHistory.ToWma(sqN) .Select(x => new HmaResult( Timestamp: x.Timestamp, Hma: x.Wma diff --git a/src/e-k/Hma/Hma.Utilities.cs b/src/e-k/Hma/Hma.Utilities.cs index bbed74d40..2cb778625 100644 --- a/src/e-k/Hma/Hma.Utilities.cs +++ b/src/e-k/Hma/Hma.Utilities.cs @@ -1,16 +1,16 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +public static partial class Hma { - // remove recommended periods - /// - public static IReadOnlyList RemoveWarmupPeriods( - this IReadOnlyList results) + // parameter validation + internal static void Validate( + int lookbackPeriods) { - int removePeriods = results - .ToList() - .FindIndex(x => x.Hma != null); - - return results.Remove(removePeriods); + // check parameter arguments + if (lookbackPeriods <= 1) + { + throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, + "Lookback periods must be greater than 1 for HMA."); + } } } diff --git a/src/e-k/HtTrendline/HtTrendline.Api.cs b/src/e-k/HtTrendline/HtTrendline.Api.cs deleted file mode 100644 index 4f70cec5f..000000000 --- a/src/e-k/HtTrendline/HtTrendline.Api.cs +++ /dev/null @@ -1,26 +0,0 @@ -namespace Skender.Stock.Indicators; - -// HILBERT TRANSFORM - INSTANTANEOUS TRENDLINE (API) -public static partial class Indicator -{ - // SERIES, from CHAIN - /// - /// Hilbert Transform Instantaneous Trendline(HTL) is a 5-period trendline of high/low price that uses signal processing to reduce noise. - /// - /// See - /// documentation - /// for more information. - /// - /// - /// - /// T must be or type - /// - /// Time-series values to transform. - /// Time series of HTL values and smoothed price. - public static IReadOnlyList ToHtTrendline( - this IEnumerable source) - where T : IReusable - => source - .ToSortedList(CandlePart.HL2) - .CalcHtTrendline(); -} diff --git a/src/e-k/HtTrendline/HtTrendline.Common.cs b/src/e-k/HtTrendline/HtTrendline.Common.cs deleted file mode 100644 index e81fee576..000000000 --- a/src/e-k/HtTrendline/HtTrendline.Common.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Skender.Stock.Indicators; - -// Htl (COMMON) - -public static class Htl -{ - // parameter validation - internal static void Validate() => throw new NotImplementedException(); - -} diff --git a/src/e-k/HtTrendline/HtTrendline.StaticSeries.cs b/src/e-k/HtTrendline/HtTrendline.StaticSeries.cs index a27f2b747..fa40755b2 100644 --- a/src/e-k/HtTrendline/HtTrendline.StaticSeries.cs +++ b/src/e-k/HtTrendline/HtTrendline.StaticSeries.cs @@ -1,10 +1,28 @@ namespace Skender.Stock.Indicators; // HILBERT TRANSFORM - INSTANTANEOUS TRENDLINE (SERIES) -public static partial class Indicator + +public static partial class HtTrendline { + // SERIES, from CHAIN + /// + /// Hilbert Transform Instantaneous Trendline(HTL) is a 5-period trendline + /// of high/low price that uses signal processing to reduce noise. + /// + /// + /// T must be type + /// + /// Time-series values to transform. + /// Time series of HTL values and smoothed price. + public static IReadOnlyList ToHtTrendline( + this IReadOnlyList source) + where T : IReusable + => source + .ToSortedList(CandlePart.HL2) + .CalcHtTrendline(); + private static List CalcHtTrendline( - this List source) + this IReadOnlyList source) where T : IReusable { // initialize diff --git a/src/e-k/HtTrendline/HtTrendline.Utilities.cs b/src/e-k/HtTrendline/HtTrendline.Utilities.cs index ad7ef3c75..6ca015ee2 100644 --- a/src/e-k/HtTrendline/HtTrendline.Utilities.cs +++ b/src/e-k/HtTrendline/HtTrendline.Utilities.cs @@ -1,9 +1,12 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// HILBERT TRANSFORM - INSTANTANEOUS TRENDLINE (UTILITIES) + +public static partial class HtTrendline { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( - this IReadOnlyList results) => results.Remove(100); + this IReadOnlyList results) + => results.Remove(100); } diff --git a/src/e-k/Hurst/Hurst.Api.cs b/src/e-k/Hurst/Hurst.Api.cs deleted file mode 100644 index cc50f6ca5..000000000 --- a/src/e-k/Hurst/Hurst.Api.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Skender.Stock.Indicators; - -// HURST EXPONENT (API) -public static partial class Indicator -{ - // SERIES, from CHAIN - public static IReadOnlyList ToHurst( - this IReadOnlyList results, - int lookbackPeriods = 100) - where T : IReusable - => results - .ToSortedList() - .CalcHurst(lookbackPeriods); -} diff --git a/src/e-k/Hurst/Hurst.Common.cs b/src/e-k/Hurst/Hurst.Common.cs deleted file mode 100644 index 523e1f2d4..000000000 --- a/src/e-k/Hurst/Hurst.Common.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Skender.Stock.Indicators; - -// HURST EXPONENT (COMMON) - -public static class Hurst -{ - // parameter validation - internal static void Validate( - int lookbackPeriods) - { - // check parameter arguments - if (lookbackPeriods < 20) - { - throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, - "Lookback periods must be at least 20 for Hurst Exponent."); - } - } - -} diff --git a/src/e-k/Hurst/Hurst.StaticSeries.cs b/src/e-k/Hurst/Hurst.StaticSeries.cs index 940e25452..3b2ff650d 100644 --- a/src/e-k/Hurst/Hurst.StaticSeries.cs +++ b/src/e-k/Hurst/Hurst.StaticSeries.cs @@ -2,15 +2,16 @@ namespace Skender.Stock.Indicators; // HURST EXPONENT (SERIES) -public static partial class Indicator +public static partial class Hurst { - private static List CalcHurst( - this List source, - int lookbackPeriods) + public static IReadOnlyList ToHurst( + this IReadOnlyList source, + int lookbackPeriods = 100) where T : IReusable { // check parameter arguments - Hurst.Validate(lookbackPeriods); + ArgumentNullException.ThrowIfNull(source); + Validate(lookbackPeriods); // initialize int length = source.Count; diff --git a/src/e-k/Hurst/Hurst.Utilities.cs b/src/e-k/Hurst/Hurst.Utilities.cs index bbce8e52a..92fc16415 100644 --- a/src/e-k/Hurst/Hurst.Utilities.cs +++ b/src/e-k/Hurst/Hurst.Utilities.cs @@ -1,9 +1,11 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// HURST EXPONENT (UTILITIES) + +public static partial class Hurst { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( this IReadOnlyList results) { @@ -13,4 +15,16 @@ public static IReadOnlyList RemoveWarmupPeriods( return results.Remove(removePeriods); } + + // parameter validation + internal static void Validate( + int lookbackPeriods) + { + // check parameter arguments + if (lookbackPeriods < 20) + { + throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, + "Lookback periods must be at least 20 for Hurst Exponent."); + } + } } diff --git a/src/e-k/Ichimoku/Ichimoku.Api.cs b/src/e-k/Ichimoku/Ichimoku.Api.cs deleted file mode 100644 index 818d5d2e8..000000000 --- a/src/e-k/Ichimoku/Ichimoku.Api.cs +++ /dev/null @@ -1,56 +0,0 @@ -namespace Skender.Stock.Indicators; - -// ICHIMOKU CLOUD (API) -public static partial class Indicator -{ - /// - /// - public static IReadOnlyList ToIchimoku( - this IEnumerable quotes, - int tenkanPeriods = 9, - int kijunPeriods = 26, - int senkouBPeriods = 52) - where TQuote : IQuote => quotes - .ToSortedList() - .CalcIchimoku( - tenkanPeriods, - kijunPeriods, - senkouBPeriods, - kijunPeriods, - kijunPeriods); - - /// - /// - public static IReadOnlyList GetIchimoku( - this IEnumerable quotes, - int tenkanPeriods, - int kijunPeriods, - int senkouBPeriods, - int offsetPeriods) - where TQuote : IQuote => quotes - .ToSortedList() - .CalcIchimoku( - tenkanPeriods, - kijunPeriods, - senkouBPeriods, - offsetPeriods, - offsetPeriods); - - /// - /// - public static IReadOnlyList GetIchimoku( - this IEnumerable quotes, - int tenkanPeriods, - int kijunPeriods, - int senkouBPeriods, - int senkouOffset, - int chikouOffset) - where TQuote : IQuote => quotes - .ToSortedList() - .CalcIchimoku( - tenkanPeriods, - kijunPeriods, - senkouBPeriods, - senkouOffset, - chikouOffset); -} diff --git a/src/e-k/Ichimoku/Ichimoku.Common.cs b/src/e-k/Ichimoku/Ichimoku.Common.cs deleted file mode 100644 index 2430de584..000000000 --- a/src/e-k/Ichimoku/Ichimoku.Common.cs +++ /dev/null @@ -1,40 +0,0 @@ -namespace Skender.Stock.Indicators; - -// ICHIMOKU CLOUD (COMMON) - -public static class Ichimoku -{ - internal static void Validate( - int tenkanPeriods, - int kijunPeriods, - int senkouBPeriods, - int senkouOffset, - int chikouOffset) - { - // check parameter arguments - if (tenkanPeriods <= 0) - { - throw new ArgumentOutOfRangeException(nameof(tenkanPeriods), tenkanPeriods, - "Tenkan periods must be greater than 0 for Ichimoku Cloud."); - } - - if (kijunPeriods <= 0) - { - throw new ArgumentOutOfRangeException(nameof(kijunPeriods), kijunPeriods, - "Kijun periods must be greater than 0 for Ichimoku Cloud."); - } - - if (senkouBPeriods <= kijunPeriods) - { - throw new ArgumentOutOfRangeException(nameof(senkouBPeriods), senkouBPeriods, - "Senkou B periods must be greater than Kijun periods for Ichimoku Cloud."); - } - - if (senkouOffset < 0 || chikouOffset < 0) - { - throw new ArgumentOutOfRangeException(nameof(senkouOffset), senkouOffset, - "Senkou and Chikou offset periods must be non-negative for Ichimoku Cloud."); - } - } - -} diff --git a/src/e-k/Ichimoku/Ichimoku.StaticSeries.cs b/src/e-k/Ichimoku/Ichimoku.StaticSeries.cs index da334180d..2949c15f4 100644 --- a/src/e-k/Ichimoku/Ichimoku.StaticSeries.cs +++ b/src/e-k/Ichimoku/Ichimoku.StaticSeries.cs @@ -2,8 +2,53 @@ namespace Skender.Stock.Indicators; // ICHIMOKU CLOUD (SERIES) -public static partial class Indicator +public static partial class Ichimoku { + public static IReadOnlyList ToIchimoku( + this IReadOnlyList quotes, + int tenkanPeriods = 9, + int kijunPeriods = 26, + int senkouBPeriods = 52) + where TQuote : IQuote => quotes + .ToSortedList() + .CalcIchimoku( + tenkanPeriods, + kijunPeriods, + senkouBPeriods, + kijunPeriods, + kijunPeriods); + + public static IReadOnlyList GetIchimoku( + this IReadOnlyList quotes, + int tenkanPeriods, + int kijunPeriods, + int senkouBPeriods, + int offsetPeriods) + where TQuote : IQuote => quotes + .ToSortedList() + .CalcIchimoku( + tenkanPeriods, + kijunPeriods, + senkouBPeriods, + offsetPeriods, + offsetPeriods); + + public static IReadOnlyList GetIchimoku( + this IReadOnlyList quotes, + int tenkanPeriods, + int kijunPeriods, + int senkouBPeriods, + int senkouOffset, + int chikouOffset) + where TQuote : IQuote => quotes + .ToSortedList() + .CalcIchimoku( + tenkanPeriods, + kijunPeriods, + senkouBPeriods, + senkouOffset, + chikouOffset); + private static List CalcIchimoku( this List quotesList, int tenkanPeriods, diff --git a/src/e-k/Ichimoku/Ichimoku.Utilities.cs b/src/e-k/Ichimoku/Ichimoku.Utilities.cs index b09b048f0..5a09101db 100644 --- a/src/e-k/Ichimoku/Ichimoku.Utilities.cs +++ b/src/e-k/Ichimoku/Ichimoku.Utilities.cs @@ -1,9 +1,11 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// ICHIMOKU CLOUD (UTILITIES) + +public static partial class Ichimoku { - // CONDENSE (REMOVE null results) - /// + // remove null results + /// public static IReadOnlyList Condense( this IReadOnlyList results) { @@ -20,4 +22,37 @@ x.TenkanSen is null return resultsList.ToSortedList(); } + + // validate parameters + internal static void Validate( + int tenkanPeriods, + int kijunPeriods, + int senkouBPeriods, + int senkouOffset, + int chikouOffset) + { + if (tenkanPeriods <= 0) + { + throw new ArgumentOutOfRangeException(nameof(tenkanPeriods), tenkanPeriods, + "Tenkan periods must be greater than 0 for Ichimoku Cloud."); + } + + if (kijunPeriods <= 0) + { + throw new ArgumentOutOfRangeException(nameof(kijunPeriods), kijunPeriods, + "Kijun periods must be greater than 0 for Ichimoku Cloud."); + } + + if (senkouBPeriods <= kijunPeriods) + { + throw new ArgumentOutOfRangeException(nameof(senkouBPeriods), senkouBPeriods, + "Senkou B periods must be greater than Kijun periods for Ichimoku Cloud."); + } + + if (senkouOffset < 0 || chikouOffset < 0) + { + throw new ArgumentOutOfRangeException(nameof(senkouOffset), senkouOffset, + "Senkou and Chikou offset periods must be non-negative for Ichimoku Cloud."); + } + } } diff --git a/src/e-k/Kama/Kama.Api.cs b/src/e-k/Kama/Kama.Api.cs deleted file mode 100644 index 3edfeaa42..000000000 --- a/src/e-k/Kama/Kama.Api.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace Skender.Stock.Indicators; - -// KAUFMAN's ADAPTIVE MOVING AVERAGE (API) - -public static partial class Kama -{ - // SERIES, from CHAIN - public static IReadOnlyList ToKama( - this IEnumerable source, - int erPeriods = 10, - int fastPeriods = 2, - int slowPeriods = 30) - where T : IReusable - => source - .ToSortedList() - .CalcKama(erPeriods, fastPeriods, slowPeriods); -} diff --git a/src/e-k/Kama/Kama.StaticSeries.cs b/src/e-k/Kama/Kama.StaticSeries.cs index e98e34034..b321d4cbf 100644 --- a/src/e-k/Kama/Kama.StaticSeries.cs +++ b/src/e-k/Kama/Kama.StaticSeries.cs @@ -4,15 +4,16 @@ namespace Skender.Stock.Indicators; public static partial class Kama { - private static List CalcKama( - this List source, - int erPeriods, - int fastPeriods, - int slowPeriods) + public static IReadOnlyList ToKama( + this IReadOnlyList source, + int erPeriods = 10, + int fastPeriods = 2, + int slowPeriods = 30) where T : IReusable { // check parameter arguments - Kama.Validate(erPeriods, fastPeriods, slowPeriods); + ArgumentNullException.ThrowIfNull(source); + Validate(erPeriods, fastPeriods, slowPeriods); // initialize int length = source.Count; diff --git a/src/e-k/Kama/Kama.Utilities.cs b/src/e-k/Kama/Kama.Utilities.cs index ec2dada62..93af9a74a 100644 --- a/src/e-k/Kama/Kama.Utilities.cs +++ b/src/e-k/Kama/Kama.Utilities.cs @@ -1,9 +1,11 @@ namespace Skender.Stock.Indicators; +// KAUFMAN's ADAPTIVE MOVING AVERAGE (UTILITIES) + public static partial class Kama { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( this IReadOnlyList results) { diff --git a/src/e-k/Keltner/Keltner.Api.cs b/src/e-k/Keltner/Keltner.Api.cs deleted file mode 100644 index e5ec5722b..000000000 --- a/src/e-k/Keltner/Keltner.Api.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace Skender.Stock.Indicators; - -// KELTNER CHANNELS (API) -public static partial class Indicator -{ - // SERIES, from TQuote - /// - /// - public static IReadOnlyList ToKeltner( - this IEnumerable quotes, - int emaPeriods = 20, - double multiplier = 2, - int atrPeriods = 10) - where TQuote : IQuote => quotes - .ToQuoteDList() - .CalcKeltner(emaPeriods, multiplier, atrPeriods); -} diff --git a/src/e-k/Keltner/Keltner.Common.cs b/src/e-k/Keltner/Keltner.Common.cs deleted file mode 100644 index 3238ee6d5..000000000 --- a/src/e-k/Keltner/Keltner.Common.cs +++ /dev/null @@ -1,33 +0,0 @@ -namespace Skender.Stock.Indicators; - -// KELTNER CHANNELS (COMMON) - -public static class Keltner -{ - // parameter validation - internal static void Validate( - int emaPeriods, - double multiplier, - int atrPeriods) - { - // check parameter arguments - if (emaPeriods <= 1) - { - throw new ArgumentOutOfRangeException(nameof(emaPeriods), emaPeriods, - "EMA periods must be greater than 1 for Keltner Channel."); - } - - if (atrPeriods <= 1) - { - throw new ArgumentOutOfRangeException(nameof(atrPeriods), atrPeriods, - "ATR periods must be greater than 1 for Keltner Channel."); - } - - if (multiplier <= 0) - { - throw new ArgumentOutOfRangeException(nameof(multiplier), multiplier, - "Multiplier must be greater than 0 for Keltner Channel."); - } - } - -} diff --git a/src/e-k/Keltner/Keltner.StaticSeries.cs b/src/e-k/Keltner/Keltner.StaticSeries.cs index f9fabdee9..1a4940caf 100644 --- a/src/e-k/Keltner/Keltner.StaticSeries.cs +++ b/src/e-k/Keltner/Keltner.StaticSeries.cs @@ -2,8 +2,17 @@ namespace Skender.Stock.Indicators; // KELTNER CHANNELS (SERIES) -public static partial class Indicator +public static partial class Keltner { + public static IReadOnlyList ToKeltner( + this IReadOnlyList quotes, + int emaPeriods = 20, + double multiplier = 2, + int atrPeriods = 10) + where TQuote : IQuote => quotes + .ToQuoteDList() + .CalcKeltner(emaPeriods, multiplier, atrPeriods); + private static List CalcKeltner( this List source, int emaPeriods, diff --git a/src/e-k/Keltner/Keltner.Utilities.cs b/src/e-k/Keltner/Keltner.Utilities.cs index 450152548..992bf4f5e 100644 --- a/src/e-k/Keltner/Keltner.Utilities.cs +++ b/src/e-k/Keltner/Keltner.Utilities.cs @@ -1,9 +1,11 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// KELTNER CHANNELS (UTILITIES) + +public static partial class Keltner { // CONDENSE (REMOVE null results) - /// + /// public static IReadOnlyList Condense( this IReadOnlyList results) { @@ -18,7 +20,7 @@ public static IReadOnlyList Condense( } // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( this IReadOnlyList results) { @@ -28,4 +30,30 @@ public static IReadOnlyList RemoveWarmupPeriods( return results.Remove(Math.Max(2 * n, n + 100)); } + + // parameter validation + internal static void Validate( + int emaPeriods, + double multiplier, + int atrPeriods) + { + // check parameter arguments + if (emaPeriods <= 1) + { + throw new ArgumentOutOfRangeException(nameof(emaPeriods), emaPeriods, + "EMA periods must be greater than 1 for Keltner Channel."); + } + + if (atrPeriods <= 1) + { + throw new ArgumentOutOfRangeException(nameof(atrPeriods), atrPeriods, + "ATR periods must be greater than 1 for Keltner Channel."); + } + + if (multiplier <= 0) + { + throw new ArgumentOutOfRangeException(nameof(multiplier), multiplier, + "Multiplier must be greater than 0 for Keltner Channel."); + } + } } diff --git a/src/e-k/Kvo/Kvo.Api.cs b/src/e-k/Kvo/Kvo.Api.cs deleted file mode 100644 index 961b6e4db..000000000 --- a/src/e-k/Kvo/Kvo.Api.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace Skender.Stock.Indicators; - -// KLINGER VOLUME OSCILLATOR (API) -public static partial class Indicator -{ - // SERIES, from TQuote - /// - /// - public static IReadOnlyList ToKvo( - this IEnumerable quotes, - int fastPeriods = 34, - int slowPeriods = 55, - int signalPeriods = 13) - where TQuote : IQuote => quotes - .ToQuoteDList() - .CalcKvo(fastPeriods, slowPeriods, signalPeriods); -} diff --git a/src/e-k/Kvo/Kvo.Common.cs b/src/e-k/Kvo/Kvo.Common.cs deleted file mode 100644 index 74ca3645e..000000000 --- a/src/e-k/Kvo/Kvo.Common.cs +++ /dev/null @@ -1,33 +0,0 @@ -namespace Skender.Stock.Indicators; - -// KLINGER VOLUME OSCILLATOR (COMMON) - -public static class Kvo -{ - // parameter validation - internal static void Validate( - int fastPeriods, - int slowPeriods, - int signalPeriods) - { - // check parameter arguments - if (fastPeriods <= 2) - { - throw new ArgumentOutOfRangeException(nameof(fastPeriods), fastPeriods, - "Fast (short) Periods must be greater than 2 for Klinger Oscillator."); - } - - if (slowPeriods <= fastPeriods) - { - throw new ArgumentOutOfRangeException(nameof(slowPeriods), slowPeriods, - "Slow (long) Periods must be greater than Fast Periods for Klinger Oscillator."); - } - - if (signalPeriods <= 0) - { - throw new ArgumentOutOfRangeException(nameof(signalPeriods), signalPeriods, - "Signal Periods must be greater than 0 for Klinger Oscillator."); - } - } - -} diff --git a/src/e-k/Kvo/Kvo.StaticSeries.cs b/src/e-k/Kvo/Kvo.StaticSeries.cs index 94af60d03..26b36cf81 100644 --- a/src/e-k/Kvo/Kvo.StaticSeries.cs +++ b/src/e-k/Kvo/Kvo.StaticSeries.cs @@ -2,8 +2,17 @@ namespace Skender.Stock.Indicators; // KLINGER VOLUME OSCILLATOR (SERIES) -public static partial class Indicator +public static partial class Kvo { + public static IReadOnlyList ToKvo( + this IReadOnlyList quotes, + int fastPeriods = 34, + int slowPeriods = 55, + int signalPeriods = 13) + where TQuote : IQuote => quotes + .ToQuoteDList() + .CalcKvo(fastPeriods, slowPeriods, signalPeriods); + private static List CalcKvo( this List source, int fastPeriods, diff --git a/src/e-k/Kvo/Kvo.Utilities.cs b/src/e-k/Kvo/Kvo.Utilities.cs index 35d18ee9b..022893924 100644 --- a/src/e-k/Kvo/Kvo.Utilities.cs +++ b/src/e-k/Kvo/Kvo.Utilities.cs @@ -1,9 +1,11 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// KLINGER VOLUME OSCILLATOR (UTILIITES) + +public static partial class Kvo { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( this IReadOnlyList results) { @@ -13,4 +15,30 @@ public static IReadOnlyList RemoveWarmupPeriods( return results.Remove(l + 150); } + + // parameter validation + internal static void Validate( + int fastPeriods, + int slowPeriods, + int signalPeriods) + { + // check parameter arguments + if (fastPeriods <= 2) + { + throw new ArgumentOutOfRangeException(nameof(fastPeriods), fastPeriods, + "Fast (short) Periods must be greater than 2 for Klinger Oscillator."); + } + + if (slowPeriods <= fastPeriods) + { + throw new ArgumentOutOfRangeException(nameof(slowPeriods), slowPeriods, + "Slow (long) Periods must be greater than Fast Periods for Klinger Oscillator."); + } + + if (signalPeriods <= 0) + { + throw new ArgumentOutOfRangeException(nameof(signalPeriods), signalPeriods, + "Signal Periods must be greater than 0 for Klinger Oscillator."); + } + } } diff --git a/src/m-r/MaEnvelopes/MaEnvelopes.StaticSeries.cs b/src/m-r/MaEnvelopes/MaEnvelopes.StaticSeries.cs index 41736bb0e..472689745 100644 --- a/src/m-r/MaEnvelopes/MaEnvelopes.StaticSeries.cs +++ b/src/m-r/MaEnvelopes/MaEnvelopes.StaticSeries.cs @@ -48,7 +48,7 @@ private static IEnumerable MaEnvAlma( int lookbackPeriods, double offsetRatio) where T : IReusable - => source.CalcAlma(lookbackPeriods, offset: 0.85, sigma: 6) + => source.ToAlma(lookbackPeriods, offset: 0.85, sigma: 6) .Select(x => new MaEnvelopeResult( Timestamp: x.Timestamp, Centerline: x.Alma, @@ -60,7 +60,7 @@ private static IEnumerable MaEnvDema( int lookbackPeriods, double offsetRatio) where T : IReusable - => source.CalcDema(lookbackPeriods) + => source.ToDema(lookbackPeriods) .Select(x => new MaEnvelopeResult( Timestamp: x.Timestamp, Centerline: x.Dema, @@ -84,7 +84,7 @@ private static IEnumerable MaEnvEpma( int lookbackPeriods, double offsetRatio) where T : IReusable - => source.CalcEpma(lookbackPeriods) + => source.ToEpma(lookbackPeriods) .Select(x => new MaEnvelopeResult( Timestamp: x.Timestamp, Centerline: x.Epma, @@ -96,7 +96,7 @@ private static IEnumerable MaEnvHma( int lookbackPeriods, double offsetRatio) where T : IReusable - => source.CalcHma(lookbackPeriods) + => source.ToHma(lookbackPeriods) .Select(x => new MaEnvelopeResult( Timestamp: x.Timestamp, Centerline: x.Hma, @@ -144,7 +144,7 @@ private static IEnumerable MaEnvWma( int lookbackPeriods, double offsetRatio) where T : IReusable - => source.CalcWma(lookbackPeriods) + => source.ToWma(lookbackPeriods) .Select(x => new MaEnvelopeResult( Timestamp: x.Timestamp, Centerline: x.Wma, diff --git a/src/m-r/MaEnvelopes/MaEnvelopes.Utilities.cs b/src/m-r/MaEnvelopes/MaEnvelopes.Utilities.cs index e2f6bdca5..5b21710bb 100644 --- a/src/m-r/MaEnvelopes/MaEnvelopes.Utilities.cs +++ b/src/m-r/MaEnvelopes/MaEnvelopes.Utilities.cs @@ -3,7 +3,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // CONDENSE (REMOVE null results) - /// + /// public static IReadOnlyList Condense( this IReadOnlyList results) { diff --git a/src/m-r/Macd/Macd.Utilities.cs b/src/m-r/Macd/Macd.Utilities.cs index 981a844a7..4b1791d84 100644 --- a/src/m-r/Macd/Macd.Utilities.cs +++ b/src/m-r/Macd/Macd.Utilities.cs @@ -3,7 +3,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( this IReadOnlyList results) { diff --git a/src/m-r/Mama/Mama.Utilities.cs b/src/m-r/Mama/Mama.Utilities.cs index 6ccb00e26..48ceb027c 100644 --- a/src/m-r/Mama/Mama.Utilities.cs +++ b/src/m-r/Mama/Mama.Utilities.cs @@ -3,7 +3,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( this IReadOnlyList results) => results.Remove(50); } diff --git a/src/m-r/Marubozu/Marubozu.Api.cs b/src/m-r/Marubozu/Marubozu.Api.cs index 5b91b90af..aaee83029 100644 --- a/src/m-r/Marubozu/Marubozu.Api.cs +++ b/src/m-r/Marubozu/Marubozu.Api.cs @@ -7,7 +7,7 @@ public static partial class Indicator /// /// public static IReadOnlyList ToMarubozu( - this IEnumerable quotes, + this IReadOnlyList quotes, double minBodyPercent = 95) where TQuote : IQuote => quotes .ToSortedList() diff --git a/src/m-r/Mfi/Mfi.Api.cs b/src/m-r/Mfi/Mfi.Api.cs index 502e4f090..4466a5db3 100644 --- a/src/m-r/Mfi/Mfi.Api.cs +++ b/src/m-r/Mfi/Mfi.Api.cs @@ -7,7 +7,7 @@ public static partial class Indicator /// /// public static IReadOnlyList ToMfi( - this IEnumerable quotes, + this IReadOnlyList quotes, int lookbackPeriods = 14) where TQuote : IQuote => quotes .ToQuoteDList() diff --git a/src/m-r/Mfi/Mfi.Utilities.cs b/src/m-r/Mfi/Mfi.Utilities.cs index a3e420448..78a09203e 100644 --- a/src/m-r/Mfi/Mfi.Utilities.cs +++ b/src/m-r/Mfi/Mfi.Utilities.cs @@ -3,7 +3,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( this IReadOnlyList results) { diff --git a/src/m-r/Obv/Obv.Api.cs b/src/m-r/Obv/Obv.Api.cs index 0431a263a..a34e329f9 100644 --- a/src/m-r/Obv/Obv.Api.cs +++ b/src/m-r/Obv/Obv.Api.cs @@ -7,7 +7,7 @@ public static partial class Indicator /// /// public static IReadOnlyList ToObv( - this IEnumerable quotes) + this IReadOnlyList quotes) where TQuote : IQuote => quotes .ToQuoteDList() .CalcObv(); diff --git a/src/m-r/ParabolicSar/ParabolicSar.Api.cs b/src/m-r/ParabolicSar/ParabolicSar.Api.cs index f43fd562d..27c9527ac 100644 --- a/src/m-r/ParabolicSar/ParabolicSar.Api.cs +++ b/src/m-r/ParabolicSar/ParabolicSar.Api.cs @@ -7,7 +7,7 @@ public static partial class Indicator /// /// public static IReadOnlyList ToParabolicSar( - this IEnumerable quotes, + this IReadOnlyList quotes, double accelerationStep = 0.02, double maxAccelerationFactor = 0.2) where TQuote : IQuote => quotes @@ -21,7 +21,7 @@ public static IReadOnlyList ToParabolicSar( /// /// public static IReadOnlyList GetParabolicSar( - this IEnumerable quotes, + this IReadOnlyList quotes, double accelerationStep, double maxAccelerationFactor, double initialFactor) diff --git a/src/m-r/ParabolicSar/ParabolicSar.Utilities.cs b/src/m-r/ParabolicSar/ParabolicSar.Utilities.cs index e08d805dd..b9d229d71 100644 --- a/src/m-r/ParabolicSar/ParabolicSar.Utilities.cs +++ b/src/m-r/ParabolicSar/ParabolicSar.Utilities.cs @@ -3,7 +3,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( this IReadOnlyList results) { diff --git a/src/m-r/PivotPoints/PivotPoints.Api.cs b/src/m-r/PivotPoints/PivotPoints.Api.cs index c6d715677..72caf4131 100644 --- a/src/m-r/PivotPoints/PivotPoints.Api.cs +++ b/src/m-r/PivotPoints/PivotPoints.Api.cs @@ -7,7 +7,7 @@ public static partial class Indicator /// /// public static IReadOnlyList ToPivotPoints( - this IEnumerable quotes, + this IReadOnlyList quotes, PeriodSize windowSize, PivotPointType pointType = PivotPointType.Standard) where TQuote : IQuote => quotes diff --git a/src/m-r/PivotPoints/PivotPoints.Utilities.cs b/src/m-r/PivotPoints/PivotPoints.Utilities.cs index 56ef7fd2e..cd80c9b43 100644 --- a/src/m-r/PivotPoints/PivotPoints.Utilities.cs +++ b/src/m-r/PivotPoints/PivotPoints.Utilities.cs @@ -4,7 +4,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( this IReadOnlyList results) { diff --git a/src/m-r/Pivots/Pivots.Api.cs b/src/m-r/Pivots/Pivots.Api.cs deleted file mode 100644 index 551159008..000000000 --- a/src/m-r/Pivots/Pivots.Api.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace Skender.Stock.Indicators; - -// PIVOTS (API) -public static partial class Indicator -{ - // SERIES, from TQuote - /// - /// - public static IReadOnlyList ToPivots( - this IEnumerable quotes, - int leftSpan = 2, - int rightSpan = 2, - int maxTrendPeriods = 20, - EndType endType = EndType.HighLow) - where TQuote : IQuote => quotes - .ToSortedList() - .CalcPivots(leftSpan, rightSpan, maxTrendPeriods, endType); -} diff --git a/src/m-r/Pivots/Pivots.Common.cs b/src/m-r/Pivots/Pivots.Common.cs deleted file mode 100644 index b244c836a..000000000 --- a/src/m-r/Pivots/Pivots.Common.cs +++ /dev/null @@ -1,34 +0,0 @@ -namespace Skender.Stock.Indicators; - -// PIVOTS (COMMON) - -public static class Pivots -{ - // parameter validation - internal static void Validate( - int leftSpan, - int rightSpan, - int maxTrendPeriods, - string caller = "Pivots") - { - // check parameter arguments - if (rightSpan < 2) - { - throw new ArgumentOutOfRangeException(nameof(rightSpan), rightSpan, - $"Right span must be at least 2 for {caller}."); - } - - if (leftSpan < 2) - { - throw new ArgumentOutOfRangeException(nameof(leftSpan), leftSpan, - $"Left span must be at least 2 for {caller}."); - } - - if (maxTrendPeriods <= leftSpan) - { - throw new ArgumentOutOfRangeException(nameof(leftSpan), leftSpan, - $"Lookback periods must be greater than the Left window span for {caller}."); - } - } - -} diff --git a/src/m-r/Pivots/Pivots.StaticSeries.cs b/src/m-r/Pivots/Pivots.StaticSeries.cs index 6a2672123..00a833b10 100644 --- a/src/m-r/Pivots/Pivots.StaticSeries.cs +++ b/src/m-r/Pivots/Pivots.StaticSeries.cs @@ -2,21 +2,22 @@ namespace Skender.Stock.Indicators; // PIVOTS (SERIES) -public static partial class Indicator +public static partial class Pivots { - private static List CalcPivots( - this List quotesList, - int leftSpan, - int rightSpan, - int maxTrendPeriods, - EndType endType) + public static IReadOnlyList ToPivots( + this IReadOnlyList quotes, + int leftSpan = 2, + int rightSpan = 2, + int maxTrendPeriods = 20, + EndType endType = EndType.HighLow) where TQuote : IQuote { // check parameter arguments - Pivots.Validate(leftSpan, rightSpan, maxTrendPeriods); + ArgumentNullException.ThrowIfNull(quotes); + Validate(leftSpan, rightSpan, maxTrendPeriods); // initialize - int length = quotesList.Count; + int length = quotes.Count; decimal?[] highLine = new decimal?[length]; PivotTrend?[] highTrend = new PivotTrend?[length]; @@ -24,9 +25,9 @@ private static List CalcPivots( decimal?[] lowLine = new decimal?[length]; PivotTrend?[] lowTrend = new PivotTrend?[length]; - List<(decimal? highPoint, decimal? lowPoint)> fractals - = quotesList - .CalcFractal(leftSpan, rightSpan, endType) + IReadOnlyList<(decimal? highPoint, decimal? lowPoint)> fractals + = quotes + .ToFractal(leftSpan, rightSpan, endType) .Select(f => (f.FractalBear, f.FractalBull)) .ToList(); @@ -117,7 +118,7 @@ private static List CalcPivots( for (int i = 0; i < length; i++) { - TQuote q = quotesList[i]; + TQuote q = quotes[i]; (decimal? highPoint, decimal? lowPoint) = fractals[i]; decimal? hl = highLine[i]; diff --git a/src/m-r/Pivots/Pivots.Utilities.cs b/src/m-r/Pivots/Pivots.Utilities.cs index 620d15622..4030ac0a0 100644 --- a/src/m-r/Pivots/Pivots.Utilities.cs +++ b/src/m-r/Pivots/Pivots.Utilities.cs @@ -1,9 +1,10 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// PIVOTS (UTILITIES) + +public static partial class Pivots { - // CONDENSE (REMOVE null results) - /// + /// public static IReadOnlyList Condense( this IReadOnlyList results) { @@ -16,4 +17,31 @@ public static IReadOnlyList Condense( return resultsList.ToSortedList(); } + + // parameter validation + internal static void Validate( + int leftSpan, + int rightSpan, + int maxTrendPeriods, + string caller = "Pivots") + { + // check parameter arguments + if (rightSpan < 2) + { + throw new ArgumentOutOfRangeException(nameof(rightSpan), rightSpan, + $"Right span must be at least 2 for {caller}."); + } + + if (leftSpan < 2) + { + throw new ArgumentOutOfRangeException(nameof(leftSpan), leftSpan, + $"Left span must be at least 2 for {caller}."); + } + + if (maxTrendPeriods <= leftSpan) + { + throw new ArgumentOutOfRangeException(nameof(leftSpan), leftSpan, + $"Lookback periods must be greater than the Left window span for {caller}."); + } + } } diff --git a/src/m-r/Pmo/Pmo.Utilities.cs b/src/m-r/Pmo/Pmo.Utilities.cs index 02e0e10c0..b4e97ee07 100644 --- a/src/m-r/Pmo/Pmo.Utilities.cs +++ b/src/m-r/Pmo/Pmo.Utilities.cs @@ -3,7 +3,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( this IReadOnlyList results) { diff --git a/src/m-r/Pvo/Pvo.Api.cs b/src/m-r/Pvo/Pvo.Api.cs index 321f7b018..0238806eb 100644 --- a/src/m-r/Pvo/Pvo.Api.cs +++ b/src/m-r/Pvo/Pvo.Api.cs @@ -7,7 +7,7 @@ public static partial class Indicator /// /// public static IReadOnlyList ToPvo( - this IEnumerable quotes, + this IReadOnlyList quotes, int fastPeriods = 12, int slowPeriods = 26, int signalPeriods = 9) diff --git a/src/m-r/Pvo/Pvo.Utilities.cs b/src/m-r/Pvo/Pvo.Utilities.cs index efd19f3ee..d5fffbcb0 100644 --- a/src/m-r/Pvo/Pvo.Utilities.cs +++ b/src/m-r/Pvo/Pvo.Utilities.cs @@ -3,7 +3,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( this IReadOnlyList results) { diff --git a/src/m-r/Renko/Renko.Api.cs b/src/m-r/Renko/Renko.Api.cs index a70e86b5a..177fa9f3e 100644 --- a/src/m-r/Renko/Renko.Api.cs +++ b/src/m-r/Renko/Renko.Api.cs @@ -6,7 +6,7 @@ public static partial class Renko { // SERIES, from TQuote public static IReadOnlyList ToRenko( - this IEnumerable quotes, + this IReadOnlyList quotes, decimal brickSize, EndType endType = EndType.Close) where TQuote : IQuote => quotes diff --git a/src/m-r/RenkoAtr/RenkoAtr.Api.cs b/src/m-r/RenkoAtr/RenkoAtr.Api.cs index 2c3cf775c..72fd61676 100644 --- a/src/m-r/RenkoAtr/RenkoAtr.Api.cs +++ b/src/m-r/RenkoAtr/RenkoAtr.Api.cs @@ -4,7 +4,7 @@ namespace Skender.Stock.Indicators; public static partial class RenkoAtr { public static IReadOnlyList GetRenkoAtr( - this IEnumerable quotes, + this IReadOnlyList quotes, int atrPeriods, EndType endType = EndType.Close) where TQuote : IQuote => quotes diff --git a/src/m-r/Roc/Roc.Utilities.cs b/src/m-r/Roc/Roc.Utilities.cs index a16969444..d39e40061 100644 --- a/src/m-r/Roc/Roc.Utilities.cs +++ b/src/m-r/Roc/Roc.Utilities.cs @@ -3,7 +3,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( this IReadOnlyList results) { diff --git a/src/m-r/RocWb/RocWb.Utilities.cs b/src/m-r/RocWb/RocWb.Utilities.cs index c2f0321bc..747a64928 100644 --- a/src/m-r/RocWb/RocWb.Utilities.cs +++ b/src/m-r/RocWb/RocWb.Utilities.cs @@ -3,7 +3,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( this IReadOnlyList results) { diff --git a/src/m-r/RollingPivots/RollingPivots.Api.cs b/src/m-r/RollingPivots/RollingPivots.Api.cs index 2adb3b664..e9e23962a 100644 --- a/src/m-r/RollingPivots/RollingPivots.Api.cs +++ b/src/m-r/RollingPivots/RollingPivots.Api.cs @@ -7,7 +7,7 @@ public static partial class Indicator /// /// public static IReadOnlyList ToRollingPivots( - this IEnumerable quotes, + this IReadOnlyList quotes, int windowPeriods, int offsetPeriods, PivotPointType pointType = PivotPointType.Standard) diff --git a/src/m-r/RollingPivots/RollingPivots.Utilities.cs b/src/m-r/RollingPivots/RollingPivots.Utilities.cs index 43ad0a3d7..d3609c5df 100644 --- a/src/m-r/RollingPivots/RollingPivots.Utilities.cs +++ b/src/m-r/RollingPivots/RollingPivots.Utilities.cs @@ -3,7 +3,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( this IReadOnlyList results) { diff --git a/src/m-r/Rsi/Rsi.Api.cs b/src/m-r/Rsi/Rsi.Api.cs deleted file mode 100644 index 1023e4b8e..000000000 --- a/src/m-r/Rsi/Rsi.Api.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Skender.Stock.Indicators; - -// RELATIVE STRENGTH INDEX (API) -public static partial class Indicator -{ - // SERIES, from CHAIN - public static IReadOnlyList ToRsi( - this IReadOnlyList results, - int lookbackPeriods = 14) - where T : IReusable - => results - .ToSortedList() - .CalcRsi(lookbackPeriods); -} diff --git a/src/m-r/Rsi/Rsi.Common.cs b/src/m-r/Rsi/Rsi.Common.cs deleted file mode 100644 index 70d11e5cb..000000000 --- a/src/m-r/Rsi/Rsi.Common.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Skender.Stock.Indicators; - -// RELATIVE STRENGTH INDEX (COMMON) - -public static class Rsi -{ - // parameter validation - internal static void Validate( - int lookbackPeriods) - { - // check parameter arguments - if (lookbackPeriods < 1) - { - throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, - "Lookback periods must be greater than 0 for RSI."); - } - } - -} diff --git a/src/m-r/Rsi/Rsi.StaticSeries.cs b/src/m-r/Rsi/Rsi.StaticSeries.cs index 71c88f55f..66d3eba99 100644 --- a/src/m-r/Rsi/Rsi.StaticSeries.cs +++ b/src/m-r/Rsi/Rsi.StaticSeries.cs @@ -2,14 +2,15 @@ namespace Skender.Stock.Indicators; // RELATIVE STRENGTH INDEX (SERIES) -public static partial class Indicator +public static partial class Rsi { - private static List CalcRsi( - this List source, - int lookbackPeriods) + public static IReadOnlyList ToRsi( + this IReadOnlyList source, + int lookbackPeriods = 14) where T : IReusable { // check parameter arguments + ArgumentNullException.ThrowIfNull(source); Rsi.Validate(lookbackPeriods); // initialize @@ -46,7 +47,7 @@ private static List CalcRsi( double? rsi = null; prevValue = s.Value; - // initialize average gain + // re/initialize average gain if (i >= lookbackPeriods && (double.IsNaN(avgGain) || double.IsNaN(avgLoss))) { double sumGain = 0; diff --git a/src/m-r/Rsi/Rsi.Utilities.cs b/src/m-r/Rsi/Rsi.Utilities.cs index 25ecc15ca..c82bab854 100644 --- a/src/m-r/Rsi/Rsi.Utilities.cs +++ b/src/m-r/Rsi/Rsi.Utilities.cs @@ -1,9 +1,11 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// RELATIVE STRENGTH INDEX (UTILITIES) + +public static partial class Rsi { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( this IReadOnlyList results) { @@ -13,4 +15,16 @@ public static IReadOnlyList RemoveWarmupPeriods( return results.Remove(10 * n); } + + // parameter validation + internal static void Validate( + int lookbackPeriods) + { + // check parameter arguments + if (lookbackPeriods < 1) + { + throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, + "Lookback periods must be greater than 0 for RSI."); + } + } } diff --git a/src/s-z/Slope/Slope.Api.cs b/src/s-z/Slope/Slope.Api.cs deleted file mode 100644 index 8a2df0575..000000000 --- a/src/s-z/Slope/Slope.Api.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Skender.Stock.Indicators; - -// SLOPE AND LINEAR REGRESSION (API) -public static partial class Indicator -{ - // SERIES, from CHAIN - public static IReadOnlyList ToSlope( - this IReadOnlyList results, - int lookbackPeriods) - where T : IReusable - => results - .ToSortedList() - .CalcSlope(lookbackPeriods); -} diff --git a/src/s-z/Slope/Slope.Common.cs b/src/s-z/Slope/Slope.Common.cs deleted file mode 100644 index 375aa15f4..000000000 --- a/src/s-z/Slope/Slope.Common.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Skender.Stock.Indicators; - -// SLOPE AND LINEAR REGRESSION (COMMON) - -public static class Slope -{ - // parameter validation - internal static void Validate( - int lookbackPeriods) - { - // check parameter arguments - if (lookbackPeriods <= 1) - { - throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, - "Lookback periods must be greater than 1 for Slope/Linear Regression."); - } - } - -} diff --git a/src/s-z/Slope/Slope.StaticSeries.cs b/src/s-z/Slope/Slope.StaticSeries.cs index f50694867..6082405ed 100644 --- a/src/s-z/Slope/Slope.StaticSeries.cs +++ b/src/s-z/Slope/Slope.StaticSeries.cs @@ -2,16 +2,16 @@ namespace Skender.Stock.Indicators; // SLOPE AND LINEAR REGRESSION (SERIES) -public static partial class Indicator +public static partial class Slope { - // calculate series - private static List CalcSlope( - this List source, + public static IReadOnlyList ToSlope( + this IReadOnlyList source, int lookbackPeriods) where T : IReusable { // check parameter arguments - Slope.Validate(lookbackPeriods); + ArgumentNullException.ThrowIfNull(source); + Validate(lookbackPeriods); // initialize int length = source.Count; diff --git a/src/s-z/Slope/Slope.Utilities.cs b/src/s-z/Slope/Slope.Utilities.cs index 99ce32fd9..f04ed9b5e 100644 --- a/src/s-z/Slope/Slope.Utilities.cs +++ b/src/s-z/Slope/Slope.Utilities.cs @@ -1,16 +1,18 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// SLOPE AND LINEAR REGRESSION (UTILITIES) + +public static partial class Slope { - // remove recommended periods - /// - public static IReadOnlyList RemoveWarmupPeriods( - this IReadOnlyList results) + // parameter validation + internal static void Validate( + int lookbackPeriods) { - int removePeriods = results - .ToList() - .FindIndex(x => x.Slope != null); - - return results.Remove(removePeriods); + // check parameter arguments + if (lookbackPeriods <= 1) + { + throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, + "Lookback periods must be greater than 1 for Slope/Linear Regression."); + } } } diff --git a/src/s-z/Smi/Smi.Api.cs b/src/s-z/Smi/Smi.Api.cs index a6abdc0c2..927ffbd24 100644 --- a/src/s-z/Smi/Smi.Api.cs +++ b/src/s-z/Smi/Smi.Api.cs @@ -7,7 +7,7 @@ public static partial class Indicator /// /// public static IReadOnlyList ToSmi( - this IEnumerable quotes, + this IReadOnlyList quotes, int lookbackPeriods = 13, int firstSmoothPeriods = 25, int secondSmoothPeriods = 2, diff --git a/src/s-z/Smi/Smi.Utilities.cs b/src/s-z/Smi/Smi.Utilities.cs index 3b4b3a5af..1d67cb99d 100644 --- a/src/s-z/Smi/Smi.Utilities.cs +++ b/src/s-z/Smi/Smi.Utilities.cs @@ -3,7 +3,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( this IReadOnlyList results) { diff --git a/src/s-z/Smma/Smma.Utilities.cs b/src/s-z/Smma/Smma.Utilities.cs index f77205627..87f246467 100644 --- a/src/s-z/Smma/Smma.Utilities.cs +++ b/src/s-z/Smma/Smma.Utilities.cs @@ -3,7 +3,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( this IReadOnlyList results) { diff --git a/src/s-z/StarcBands/StarcBands.Api.cs b/src/s-z/StarcBands/StarcBands.Api.cs index 9ce66033b..dc046ac1d 100644 --- a/src/s-z/StarcBands/StarcBands.Api.cs +++ b/src/s-z/StarcBands/StarcBands.Api.cs @@ -7,7 +7,7 @@ public static partial class Indicator /// /// public static IReadOnlyList ToStarcBands( - this IEnumerable quotes, + this IReadOnlyList quotes, int smaPeriods, double multiplier = 2, int atrPeriods = 10) diff --git a/src/s-z/StarcBands/StarcBands.Utilities.cs b/src/s-z/StarcBands/StarcBands.Utilities.cs index 92e05adc5..06ad39e46 100644 --- a/src/s-z/StarcBands/StarcBands.Utilities.cs +++ b/src/s-z/StarcBands/StarcBands.Utilities.cs @@ -3,7 +3,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // CONDENSE (REMOVE null results) - /// + /// public static IReadOnlyList Condense( this IReadOnlyList results) { @@ -18,7 +18,7 @@ public static IReadOnlyList Condense( } // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( this IReadOnlyList results) { diff --git a/src/s-z/Stc/Stc.Utilities.cs b/src/s-z/Stc/Stc.Utilities.cs index 390492324..a39b0180d 100644 --- a/src/s-z/Stc/Stc.Utilities.cs +++ b/src/s-z/Stc/Stc.Utilities.cs @@ -3,7 +3,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( this IReadOnlyList results) { diff --git a/src/s-z/StdDev/StdDev.Utilities.cs b/src/s-z/StdDev/StdDev.Utilities.cs index 7f519e639..6b316d1d3 100644 --- a/src/s-z/StdDev/StdDev.Utilities.cs +++ b/src/s-z/StdDev/StdDev.Utilities.cs @@ -3,7 +3,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( this IReadOnlyList results) { diff --git a/src/s-z/StdDevChannels/StdDevChannels.StaticSeries.cs b/src/s-z/StdDevChannels/StdDevChannels.StaticSeries.cs index 2e8bece73..78a03d6d4 100644 --- a/src/s-z/StdDevChannels/StdDevChannels.StaticSeries.cs +++ b/src/s-z/StdDevChannels/StdDevChannels.StaticSeries.cs @@ -19,8 +19,8 @@ private static List CalcStdDevChannels( // initialize int length = source.Count; - List slopeResults = source - .CalcSlope((int)lookbackPeriods); + IReadOnlyList slopeResults = source + .ToSlope((int)lookbackPeriods); List results = slopeResults .Select(x => new StdDevChannelsResult(x.Timestamp)) diff --git a/src/s-z/StdDevChannels/StdDevChannels.Utilities.cs b/src/s-z/StdDevChannels/StdDevChannels.Utilities.cs index 228ff78d4..350ab8f77 100644 --- a/src/s-z/StdDevChannels/StdDevChannels.Utilities.cs +++ b/src/s-z/StdDevChannels/StdDevChannels.Utilities.cs @@ -3,7 +3,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // CONDENSE (REMOVE null results) - /// + /// public static IReadOnlyList Condense( this IReadOnlyList results) { @@ -21,7 +21,7 @@ x.UpperChannel is null } // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( this IReadOnlyList results) { diff --git a/src/s-z/Stoch/Stoch.Api.cs b/src/s-z/Stoch/Stoch.Api.cs index 4cba11ab3..936420892 100644 --- a/src/s-z/Stoch/Stoch.Api.cs +++ b/src/s-z/Stoch/Stoch.Api.cs @@ -7,7 +7,7 @@ public static partial class Indicator /// /// public static IReadOnlyList ToStoch( - this IEnumerable quotes, + this IReadOnlyList quotes, int lookbackPeriods = 14, int signalPeriods = 3, int smoothPeriods = 3) @@ -22,7 +22,7 @@ public static IReadOnlyList ToStoch( /// /// public static IReadOnlyList ToStoch( - this IEnumerable quotes, + this IReadOnlyList quotes, int lookbackPeriods, int signalPeriods, int smoothPeriods, diff --git a/src/s-z/Stoch/Stoch.Utilities.cs b/src/s-z/Stoch/Stoch.Utilities.cs index 5b3eb2806..4a1548f68 100644 --- a/src/s-z/Stoch/Stoch.Utilities.cs +++ b/src/s-z/Stoch/Stoch.Utilities.cs @@ -3,7 +3,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( this IReadOnlyList results) { diff --git a/src/s-z/StochRsi/StochRsi.StaticSeries.cs b/src/s-z/StochRsi/StochRsi.StaticSeries.cs index 9afe0b389..d8ce9ea09 100644 --- a/src/s-z/StochRsi/StochRsi.StaticSeries.cs +++ b/src/s-z/StochRsi/StochRsi.StaticSeries.cs @@ -30,8 +30,8 @@ private static List CalcStochRsi( // get Stochastic of RSI List stoResults = source - .CalcRsi(rsiPeriods) - .Remove(Math.Min(rsiPeriods, length)) // TODO: still need to Remove() here? + .ToRsi(rsiPeriods) + .Remove(Math.Min(rsiPeriods, length)) // TODO: still need to Remove() here, or auto-healing? .Select(x => new QuoteD( Timestamp: x.Timestamp, Open: 0, diff --git a/src/s-z/StochRsi/StochRsi.Utilities.cs b/src/s-z/StochRsi/StochRsi.Utilities.cs index 00dd324b4..b092f3e48 100644 --- a/src/s-z/StochRsi/StochRsi.Utilities.cs +++ b/src/s-z/StochRsi/StochRsi.Utilities.cs @@ -3,7 +3,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( this IReadOnlyList results) { diff --git a/src/s-z/SuperTrend/SuperTrend.Api.cs b/src/s-z/SuperTrend/SuperTrend.Api.cs index cc9ddb23f..056c2adb6 100644 --- a/src/s-z/SuperTrend/SuperTrend.Api.cs +++ b/src/s-z/SuperTrend/SuperTrend.Api.cs @@ -7,7 +7,7 @@ public static partial class Indicator /// /// public static IReadOnlyList ToSuperTrend( - this IEnumerable quotes, + this IReadOnlyList quotes, int lookbackPeriods = 10, double multiplier = 3) where TQuote : IQuote => quotes diff --git a/src/s-z/SuperTrend/SuperTrend.Utilities.cs b/src/s-z/SuperTrend/SuperTrend.Utilities.cs index d5bf857dc..93ae76e77 100644 --- a/src/s-z/SuperTrend/SuperTrend.Utilities.cs +++ b/src/s-z/SuperTrend/SuperTrend.Utilities.cs @@ -3,7 +3,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // CONDENSE (REMOVE null results) - /// + /// public static IReadOnlyList Condense( this IReadOnlyList results) { @@ -18,7 +18,7 @@ public static IReadOnlyList Condense( } // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( this IReadOnlyList results) { diff --git a/src/s-z/Tema/Tema.Utilities.cs b/src/s-z/Tema/Tema.Utilities.cs index e0a559dc3..3d1117b27 100644 --- a/src/s-z/Tema/Tema.Utilities.cs +++ b/src/s-z/Tema/Tema.Utilities.cs @@ -3,7 +3,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( this IReadOnlyList results) { diff --git a/src/s-z/Tr/Tr.Api.cs b/src/s-z/Tr/Tr.Api.cs index 3999229d1..eaeee9561 100644 --- a/src/s-z/Tr/Tr.Api.cs +++ b/src/s-z/Tr/Tr.Api.cs @@ -8,7 +8,7 @@ public static partial class Tr /// /// public static IReadOnlyList ToTr( - this IEnumerable quotes) + this IReadOnlyList quotes) where TQuote : IQuote => quotes .ToQuoteDList() .CalcTr(); diff --git a/src/s-z/Trix/Trix.Utilities.cs b/src/s-z/Trix/Trix.Utilities.cs index 8aeaac921..e2661bed9 100644 --- a/src/s-z/Trix/Trix.Utilities.cs +++ b/src/s-z/Trix/Trix.Utilities.cs @@ -3,7 +3,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( this IReadOnlyList results) { diff --git a/src/s-z/Tsi/Tsi.Utilities.cs b/src/s-z/Tsi/Tsi.Utilities.cs index 1d8921bd2..a78af3e0c 100644 --- a/src/s-z/Tsi/Tsi.Utilities.cs +++ b/src/s-z/Tsi/Tsi.Utilities.cs @@ -3,7 +3,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( this IReadOnlyList results) { diff --git a/src/s-z/UlcerIndex/UlcerIndex.Utilities.cs b/src/s-z/UlcerIndex/UlcerIndex.Utilities.cs index eb66129de..421fa0099 100644 --- a/src/s-z/UlcerIndex/UlcerIndex.Utilities.cs +++ b/src/s-z/UlcerIndex/UlcerIndex.Utilities.cs @@ -3,7 +3,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( this IReadOnlyList results) { diff --git a/src/s-z/Ultimate/Ultimate.Api.cs b/src/s-z/Ultimate/Ultimate.Api.cs index 8b6cc2844..b75449711 100644 --- a/src/s-z/Ultimate/Ultimate.Api.cs +++ b/src/s-z/Ultimate/Ultimate.Api.cs @@ -7,7 +7,7 @@ public static partial class Indicator /// /// public static IReadOnlyList ToUltimate( - this IEnumerable quotes, + this IReadOnlyList quotes, int shortPeriods = 7, int middlePeriods = 14, int longPeriods = 28) diff --git a/src/s-z/Ultimate/Ultimate.Utilities.cs b/src/s-z/Ultimate/Ultimate.Utilities.cs index 187318b1f..6c37ba72f 100644 --- a/src/s-z/Ultimate/Ultimate.Utilities.cs +++ b/src/s-z/Ultimate/Ultimate.Utilities.cs @@ -3,7 +3,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( this IReadOnlyList results) { diff --git a/src/s-z/VolatilityStop/VolatilityStop.Api.cs b/src/s-z/VolatilityStop/VolatilityStop.Api.cs index 4c551ada7..90e5dd2ee 100644 --- a/src/s-z/VolatilityStop/VolatilityStop.Api.cs +++ b/src/s-z/VolatilityStop/VolatilityStop.Api.cs @@ -7,7 +7,7 @@ public static partial class Indicator /// /// public static IReadOnlyList ToVolatilityStop( - this IEnumerable quotes, + this IReadOnlyList quotes, int lookbackPeriods = 7, double multiplier = 3) where TQuote : IQuote => quotes diff --git a/src/s-z/VolatilityStop/VolatilityStop.Utilities.cs b/src/s-z/VolatilityStop/VolatilityStop.Utilities.cs index 203926f57..6213ab213 100644 --- a/src/s-z/VolatilityStop/VolatilityStop.Utilities.cs +++ b/src/s-z/VolatilityStop/VolatilityStop.Utilities.cs @@ -3,7 +3,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( this IReadOnlyList results) { diff --git a/src/s-z/Vortex/Vortex.Api.cs b/src/s-z/Vortex/Vortex.Api.cs index 837067dce..761dd2d72 100644 --- a/src/s-z/Vortex/Vortex.Api.cs +++ b/src/s-z/Vortex/Vortex.Api.cs @@ -7,7 +7,7 @@ public static partial class Indicator /// /// public static IReadOnlyList ToVortex( - this IEnumerable quotes, + this IReadOnlyList quotes, int lookbackPeriods) where TQuote : IQuote => quotes .ToQuoteDList() diff --git a/src/s-z/Vortex/Vortex.Utilities.cs b/src/s-z/Vortex/Vortex.Utilities.cs index db723ca83..85907c47a 100644 --- a/src/s-z/Vortex/Vortex.Utilities.cs +++ b/src/s-z/Vortex/Vortex.Utilities.cs @@ -3,7 +3,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // CONDENSE (REMOVE null results) - /// + /// public static IReadOnlyList Condense( this IReadOnlyList results) { @@ -18,7 +18,7 @@ public static IReadOnlyList Condense( } // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( this IReadOnlyList results) { diff --git a/src/s-z/Vwap/Vwap.Api.cs b/src/s-z/Vwap/Vwap.Api.cs index bf28da1bc..2e1cc8081 100644 --- a/src/s-z/Vwap/Vwap.Api.cs +++ b/src/s-z/Vwap/Vwap.Api.cs @@ -7,7 +7,7 @@ public static partial class Indicator /// /// public static IReadOnlyList ToVwap( - this IEnumerable quotes, + this IReadOnlyList quotes, DateTime? startDate = null) where TQuote : IQuote => quotes .ToQuoteDList() diff --git a/src/s-z/Vwap/Vwap.Utilities.cs b/src/s-z/Vwap/Vwap.Utilities.cs index 1b2de2b61..b8a3836bd 100644 --- a/src/s-z/Vwap/Vwap.Utilities.cs +++ b/src/s-z/Vwap/Vwap.Utilities.cs @@ -3,7 +3,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( this IReadOnlyList results) { diff --git a/src/s-z/Vwma/Vwma.Api.cs b/src/s-z/Vwma/Vwma.Api.cs index edc82abf3..6a265cdbb 100644 --- a/src/s-z/Vwma/Vwma.Api.cs +++ b/src/s-z/Vwma/Vwma.Api.cs @@ -7,7 +7,7 @@ public static partial class Indicator /// /// public static IReadOnlyList ToVwma( - this IEnumerable quotes, + this IReadOnlyList quotes, int lookbackPeriods) where TQuote : IQuote => quotes .ToQuoteDList() diff --git a/src/s-z/Vwma/Vwma.Utilities.cs b/src/s-z/Vwma/Vwma.Utilities.cs index dcb253ac3..de20abfce 100644 --- a/src/s-z/Vwma/Vwma.Utilities.cs +++ b/src/s-z/Vwma/Vwma.Utilities.cs @@ -3,7 +3,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( this IReadOnlyList results) { diff --git a/src/s-z/WilliamsR/WilliamsR.Api.cs b/src/s-z/WilliamsR/WilliamsR.Api.cs index 21b8e4a80..10fc6971a 100644 --- a/src/s-z/WilliamsR/WilliamsR.Api.cs +++ b/src/s-z/WilliamsR/WilliamsR.Api.cs @@ -7,7 +7,7 @@ public static partial class Indicator /// /// public static IReadOnlyList ToWilliamsR( - this IEnumerable quotes, + this IReadOnlyList quotes, int lookbackPeriods = 14) where TQuote : IQuote => quotes .ToQuoteDList() diff --git a/src/s-z/WilliamsR/WilliamsR.Utilities.cs b/src/s-z/WilliamsR/WilliamsR.Utilities.cs index ab1d51037..cd5f5cb19 100644 --- a/src/s-z/WilliamsR/WilliamsR.Utilities.cs +++ b/src/s-z/WilliamsR/WilliamsR.Utilities.cs @@ -3,7 +3,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // remove recommended periods - /// + /// public static IReadOnlyList RemoveWarmupPeriods( this IReadOnlyList results) { diff --git a/src/s-z/Wma/Wma.Api.cs b/src/s-z/Wma/Wma.Api.cs deleted file mode 100644 index 209e4f1fd..000000000 --- a/src/s-z/Wma/Wma.Api.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Skender.Stock.Indicators; - -// WEIGHTED MOVING AVERAGE (API) -public static partial class Indicator -{ - // SERIES, from CHAIN - public static IReadOnlyList ToWma( - this IReadOnlyList results, - int lookbackPeriods) - where T : IReusable - => results - .ToSortedList() - .CalcWma(lookbackPeriods); -} diff --git a/src/s-z/Wma/Wma.Common.cs b/src/s-z/Wma/Wma.Common.cs deleted file mode 100644 index fd0d6b64a..000000000 --- a/src/s-z/Wma/Wma.Common.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Skender.Stock.Indicators; - -// WEIGHTED MOVING AVERAGE (COMMON) - -public static class Wma -{ - // parameter validation - internal static void Validate( - int lookbackPeriods) - { - // check parameter arguments - if (lookbackPeriods <= 0) - { - throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, - "Lookback periods must be greater than 0 for WMA."); - } - } - -} diff --git a/src/s-z/Wma/Wma.StaticSeries.cs b/src/s-z/Wma/Wma.StaticSeries.cs index 19e3efd4b..95fcc8aac 100644 --- a/src/s-z/Wma/Wma.StaticSeries.cs +++ b/src/s-z/Wma/Wma.StaticSeries.cs @@ -2,15 +2,16 @@ namespace Skender.Stock.Indicators; // WEIGHTED MOVING AVERAGE (SERIES) -public static partial class Indicator +public static partial class Wma { - private static List CalcWma( - this List source, + public static IReadOnlyList ToWma( + this IReadOnlyList source, int lookbackPeriods) where T : IReusable { // check parameter arguments - Wma.Validate(lookbackPeriods); + ArgumentNullException.ThrowIfNull(source); + Validate(lookbackPeriods); // initialize int length = source.Count; diff --git a/src/s-z/Wma/Wma.Utilities.cs b/src/s-z/Wma/Wma.Utilities.cs index 44c72b402..341abf976 100644 --- a/src/s-z/Wma/Wma.Utilities.cs +++ b/src/s-z/Wma/Wma.Utilities.cs @@ -1,16 +1,16 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +public static partial class Wma { - // remove recommended periods - /// - public static IReadOnlyList RemoveWarmupPeriods( - this IReadOnlyList results) + // parameter validation + internal static void Validate( + int lookbackPeriods) { - int removePeriods = results - .ToList() - .FindIndex(x => x.Wma != null); - - return results.Remove(removePeriods); + // check parameter arguments + if (lookbackPeriods <= 0) + { + throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, + "Lookback periods must be greater than 0 for WMA."); + } } } diff --git a/src/s-z/ZigZag/ZigZag.Api.cs b/src/s-z/ZigZag/ZigZag.Api.cs index 531d2b7bf..65c747017 100644 --- a/src/s-z/ZigZag/ZigZag.Api.cs +++ b/src/s-z/ZigZag/ZigZag.Api.cs @@ -7,7 +7,7 @@ public static partial class Indicator /// /// public static IReadOnlyList ToZigZag( - this IEnumerable quotes, + this IReadOnlyList quotes, EndType endType = EndType.Close, decimal percentChange = 5) where TQuote : IQuote => quotes diff --git a/src/s-z/ZigZag/ZigZag.Utilities.cs b/src/s-z/ZigZag/ZigZag.Utilities.cs index 5bd39608a..2973679e1 100644 --- a/src/s-z/ZigZag/ZigZag.Utilities.cs +++ b/src/s-z/ZigZag/ZigZag.Utilities.cs @@ -3,7 +3,7 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { // CONDENSE (REMOVE null results) - /// + /// public static IReadOnlyList Condense( this IReadOnlyList results) { diff --git a/tests/indicators/e-k/Fractal/Fractal.StaticSeries.Tests.cs b/tests/indicators/e-k/Fractal/Fractal.StaticSeries.Tests.cs index 20e7a52dc..6085d67b7 100644 --- a/tests/indicators/e-k/Fractal/Fractal.StaticSeries.Tests.cs +++ b/tests/indicators/e-k/Fractal/Fractal.StaticSeries.Tests.cs @@ -44,7 +44,7 @@ public override void Standard() // Span 2 public void StandardSpan4() { IReadOnlyList results = Quotes - .GetFractal(4, 4); + .ToFractal(4, 4); // proper quantities Assert.AreEqual(502, results.Count); diff --git a/tests/indicators/e-k/Gator/Gator.StaticSeries.Tests.cs b/tests/indicators/e-k/Gator/Gator.StaticSeries.Tests.cs index 994f1026a..3c448b971 100644 --- a/tests/indicators/e-k/Gator/Gator.StaticSeries.Tests.cs +++ b/tests/indicators/e-k/Gator/Gator.StaticSeries.Tests.cs @@ -77,7 +77,7 @@ public void FromAlligator() { IReadOnlyList results = Quotes .ToAlligator() - .GetGator(); + .ToGator(); // proper quantities Assert.AreEqual(502, results.Count); diff --git a/tests/indicators/e-k/HtTrendline/HtTrendline.StaticSeries.Tests.cs b/tests/indicators/e-k/HtTrendline/HtTrendline.StaticSeries.Tests.cs index d3ce7c5fd..e15b2268c 100644 --- a/tests/indicators/e-k/HtTrendline/HtTrendline.StaticSeries.Tests.cs +++ b/tests/indicators/e-k/HtTrendline/HtTrendline.StaticSeries.Tests.cs @@ -117,7 +117,7 @@ public void Removed() [TestMethod] public void PennyData() { - IEnumerable penny = Data.GetPenny(); + IReadOnlyList penny = Data.GetPenny(); IReadOnlyList r = penny .ToHtTrendline(); diff --git a/tests/indicators/m-r/ParabolicSar/ParabolicSar.StaticSeries.Tests.cs b/tests/indicators/m-r/ParabolicSar/ParabolicSar.StaticSeries.Tests.cs index bdadbe5a1..e8eea6afa 100644 --- a/tests/indicators/m-r/ParabolicSar/ParabolicSar.StaticSeries.Tests.cs +++ b/tests/indicators/m-r/ParabolicSar/ParabolicSar.StaticSeries.Tests.cs @@ -9,7 +9,7 @@ public override void Standard() double acclerationStep = 0.02; double maxAccelerationFactor = 0.2; - IReadOnlyList results = + List results = Quotes.ToParabolicSar(acclerationStep, maxAccelerationFactor) .ToList(); @@ -42,7 +42,7 @@ public void Extended() double maxAccelerationFactor = 0.2; double initialStep = 0.01; - IReadOnlyList results = + List results = Quotes.GetParabolicSar( acclerationStep, maxAccelerationFactor, initialStep) .ToList(); @@ -90,13 +90,14 @@ public void InsufficientQuotes() double acclerationStep = 0.02; double maxAccelerationFactor = 0.2; - IEnumerable insufficientQuotes = Data.GetDefault() + List insufficientQuotes = Data.GetDefault() .OrderBy(x => x.Timestamp) - .Take(10); + .Take(10) + .ToList(); IReadOnlyList results = - insufficientQuotes.ToParabolicSar(acclerationStep, maxAccelerationFactor) - .ToList(); + insufficientQuotes + .ToParabolicSar(acclerationStep, maxAccelerationFactor); // assertions diff --git a/tests/indicators/m-r/PivotPoints/PivotPoints.StaticSeries.Tests.cs b/tests/indicators/m-r/PivotPoints/PivotPoints.StaticSeries.Tests.cs index 26fd5e7e6..91e7d739b 100644 --- a/tests/indicators/m-r/PivotPoints/PivotPoints.StaticSeries.Tests.cs +++ b/tests/indicators/m-r/PivotPoints/PivotPoints.StaticSeries.Tests.cs @@ -90,8 +90,9 @@ public void Camarilla() PeriodSize periodSize = PeriodSize.Week; PivotPointType pointType = PivotPointType.Camarilla; - IEnumerable h = Data.GetDefault(38); - IReadOnlyList results = h.ToPivotPoints(periodSize, pointType); + IReadOnlyList h = Data.GetDefault(38); + IReadOnlyList results + = h.ToPivotPoints(periodSize, pointType); // proper quantities Assert.AreEqual(38, results.Count); @@ -245,8 +246,9 @@ public void Fibonacci() PeriodSize periodSize = PeriodSize.OneHour; PivotPointType pointType = PivotPointType.Fibonacci; - IEnumerable h = Data.GetIntraday(300); - IReadOnlyList results = h.ToPivotPoints(periodSize, pointType); + IReadOnlyList h = Data.GetIntraday(300); + IReadOnlyList results + = h.ToPivotPoints(periodSize, pointType); // proper quantities Assert.AreEqual(300, results.Count); @@ -316,8 +318,9 @@ public void Woodie() PeriodSize periodSize = PeriodSize.Day; PivotPointType pointType = PivotPointType.Woodie; - IEnumerable h = Data.GetIntraday(); - IReadOnlyList results = h.ToPivotPoints(periodSize, pointType); + IReadOnlyList h = Data.GetIntraday(); + IReadOnlyList results + = h.ToPivotPoints(periodSize, pointType); // proper quantities Assert.AreEqual(1564, results.Count); diff --git a/tests/indicators/m-r/RollingPivots/RollingPivots.StaticSeries.Tests.cs b/tests/indicators/m-r/RollingPivots/RollingPivots.StaticSeries.Tests.cs index 456ea905d..7874751ca 100644 --- a/tests/indicators/m-r/RollingPivots/RollingPivots.StaticSeries.Tests.cs +++ b/tests/indicators/m-r/RollingPivots/RollingPivots.StaticSeries.Tests.cs @@ -81,7 +81,7 @@ public void Camarilla() int offsetPeriods = 0; PivotPointType pointType = PivotPointType.Camarilla; - IEnumerable h = Data.GetDefault(38); + IReadOnlyList h = Data.GetDefault(38); IReadOnlyList results = h .ToRollingPivots(windowPeriods, offsetPeriods, pointType); @@ -236,7 +236,7 @@ public void Fibonacci() int offsetPeriods = 15; PivotPointType pointType = PivotPointType.Fibonacci; - IEnumerable h = Data.GetIntraday(300); + IReadOnlyList h = Data.GetIntraday(300); IReadOnlyList results = h.ToRollingPivots(windowPeriods, offsetPeriods, pointType); @@ -310,7 +310,7 @@ public void Woodie() int offsetPeriods = 16; PivotPointType pointType = PivotPointType.Woodie; - IEnumerable h = Data.GetIntraday(); + IReadOnlyList h = Data.GetIntraday(); IReadOnlyList results = h .ToRollingPivots(windowPeriods, offsetPeriods, pointType); diff --git a/tests/indicators/s-z/SuperTrend/SuperTrend.StaticSeries.Tests.cs b/tests/indicators/s-z/SuperTrend/SuperTrend.StaticSeries.Tests.cs index 0732cab82..3b652b756 100644 --- a/tests/indicators/s-z/SuperTrend/SuperTrend.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/SuperTrend/SuperTrend.StaticSeries.Tests.cs @@ -51,7 +51,7 @@ public override void Standard() [TestMethod] public void Bitcoin() { - IEnumerable h = Data.GetBitcoin(); + IReadOnlyList h = Data.GetBitcoin(); IReadOnlyList results = h .ToSuperTrend(); diff --git a/tests/indicators/s-z/Vwap/Vwap.StaticSeries.Tests.cs b/tests/indicators/s-z/Vwap/Vwap.StaticSeries.Tests.cs index 998368ce2..df7973627 100644 --- a/tests/indicators/s-z/Vwap/Vwap.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/Vwap/Vwap.StaticSeries.Tests.cs @@ -3,9 +3,10 @@ namespace StaticSeries; [TestClass] public class Vwap : StaticSeriesTestBase { - private readonly IEnumerable intraday = Data.GetIntraday() + private static readonly IReadOnlyList intraday = Data.GetIntraday() .OrderBy(x => x.Timestamp) - .Take(391); + .Take(391) + .ToList(); [TestMethod] public override void Standard() diff --git a/tests/indicators/s-z/ZigZag/ZigZag.StaticSeries.Tests.cs b/tests/indicators/s-z/ZigZag/ZigZag.StaticSeries.Tests.cs index 3994d2863..30c5e0300 100644 --- a/tests/indicators/s-z/ZigZag/ZigZag.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/ZigZag/ZigZag.StaticSeries.Tests.cs @@ -124,8 +124,9 @@ public void NoEntry() // thresholds are never met string json = File.ReadAllText("./s-z/ZigZag/data.ethusdt.json"); - IReadOnlyCollection quotes = JsonConvert - .DeserializeObject>(json); + IReadOnlyList quotes = JsonConvert + .DeserializeObject>(json) + .ToList(); IReadOnlyList results = quotes .ToZigZag(); @@ -139,8 +140,9 @@ public void Issue632() // thresholds are never met string json = File.ReadAllText("./s-z/ZigZag/data.issue632.json"); - IReadOnlyCollection quotesList = JsonConvert - .DeserializeObject>(json); + IReadOnlyList quotesList = JsonConvert + .DeserializeObject>(json) + .ToList(); IReadOnlyList resultsList = quotesList .ToZigZag(); @@ -192,9 +194,10 @@ public void SchrodingerScenario() { string json = File.ReadAllText("./s-z/ZigZag/data.schrodinger.json"); - IOrderedEnumerable h = JsonConvert + IReadOnlyList h = JsonConvert .DeserializeObject>(json) - .OrderBy(x => x.Timestamp); + .OrderBy(x => x.Timestamp) + .ToList(); IReadOnlyList r1 = h.ToZigZag(EndType.Close, 0.25m).ToList(); Assert.AreEqual(342, r1.Count); From 8412ffc56b4b94888203756297e63ea8df26076a Mon Sep 17 00:00:00 2001 From: Dave Skender <8432125+DaveSkender@users.noreply.github.com> Date: Mon, 14 Oct 2024 18:27:58 -0400 Subject: [PATCH 32/38] fix: invariant culture in tests --- src/_common/Quotes/Quote.Converters.cs | 2 -- src/_common/Quotes/Quote.Validation.cs | 13 +++++-- tests/indicators/TestBase.cs | 4 +-- .../_common/Candles/Candles.Tests.cs | 6 ++-- .../_common/Generics/Sorting.Tests.cs | 20 +++++------ .../_common/Math/Numerical.Tests.cs | 4 +-- .../_common/Quotes/Quote.Aggregates.Tests.cs | 18 +++++----- .../_common/Quotes/Quote.Converters.Tests.cs | 12 +++---- .../_common/Quotes/Quote.Validation.Tests.cs | 33 ++++++++--------- .../Reusable/Reusable.Utilities.Tests.cs | 2 +- .../QuotePart.StaticSeries.Tests.cs | 2 +- .../QuotePart.Utilities.Tests.cs | 4 +-- .../a-d/Beta/Beta.StaticSeries.Tests.cs | 36 +++++++++---------- .../a-d/Dpo/Dpo.StaticSeries.Tests.cs | 2 +- .../s-z/Sma/Sma.StaticSeries.Tests.cs | 2 +- .../s-z/Vwap/Vwap.StaticSeries.Tests.cs | 6 ++-- 16 files changed, 87 insertions(+), 79 deletions(-) diff --git a/src/_common/Quotes/Quote.Converters.cs b/src/_common/Quotes/Quote.Converters.cs index f7186f683..0a03e5e13 100644 --- a/src/_common/Quotes/Quote.Converters.cs +++ b/src/_common/Quotes/Quote.Converters.cs @@ -1,5 +1,3 @@ -using System.Globalization; - namespace Skender.Stock.Indicators; // QUOTE UTILITIES (CONVERTERS) diff --git a/src/_common/Quotes/Quote.Validation.cs b/src/_common/Quotes/Quote.Validation.cs index 04318e83b..382c955bb 100644 --- a/src/_common/Quotes/Quote.Validation.cs +++ b/src/_common/Quotes/Quote.Validation.cs @@ -1,9 +1,14 @@ +using System.Globalization; + namespace Skender.Stock.Indicators; // QUOTE UTILITIES: VALIDATION public static partial class Quotes { + private static readonly CultureInfo invariantCulture + = CultureInfo.InvariantCulture; + /// /// Check that quotes are valid and in ascending order. /// @@ -34,13 +39,17 @@ public static IReadOnlyList Validate( if (lastDate == currentDate) { - string msg = $"Duplicate date found on {currentDate}."; + string msg = + $"Duplicate date found on {currentDate.ToString("MM/dd/yyyy", invariantCulture)}."; + throw new InvalidQuotesException(nameof(quotes), msg); } if (lastDate > currentDate) { - string msg = $"Quotes are out of sequence on {currentDate}."; + string msg = + $"Quotes are out of sequence on {currentDate.ToString("MM/dd/yyyy", invariantCulture)}."; + throw new InvalidQuotesException(nameof(quotes), msg); } diff --git a/tests/indicators/TestBase.cs b/tests/indicators/TestBase.cs index d0d11019f..5486c5f0e 100644 --- a/tests/indicators/TestBase.cs +++ b/tests/indicators/TestBase.cs @@ -12,7 +12,7 @@ namespace Test.Data; public abstract class TestBase // base for all tests { - internal static readonly CultureInfo englishCulture = new("en-US", false); + internal static readonly CultureInfo invariantCulture = CultureInfo.InvariantCulture; internal static readonly IReadOnlyList Quotes = Data.GetDefault(); internal static readonly IReadOnlyList OtherQuotes = Data.GetCompare(); @@ -29,7 +29,7 @@ namespace Test.Data; protected static readonly double DoublePrecision = 1E-13; protected static readonly DateTime EvalDate - = DateTime.ParseExact("12/31/2018", "MM/dd/yyyy", englishCulture); + = DateTime.ParseExact("12/31/2018", "MM/dd/yyyy", invariantCulture); } /// diff --git a/tests/indicators/_common/Candles/Candles.Tests.cs b/tests/indicators/_common/Candles/Candles.Tests.cs index 85d6fe6e3..a23c94202 100644 --- a/tests/indicators/_common/Candles/Candles.Tests.cs +++ b/tests/indicators/_common/Candles/Candles.Tests.cs @@ -16,13 +16,13 @@ public void SortCandles() Assert.AreEqual(502, candles.Count); // sample values - DateTime firstDate = DateTime.ParseExact("01/18/2016", "MM/dd/yyyy", englishCulture); + DateTime firstDate = DateTime.ParseExact("01/18/2016", "MM/dd/yyyy", invariantCulture); Assert.AreEqual(firstDate, candles[0].Timestamp); - DateTime lastDate = DateTime.ParseExact("12/31/2018", "MM/dd/yyyy", englishCulture); + DateTime lastDate = DateTime.ParseExact("12/31/2018", "MM/dd/yyyy", invariantCulture); Assert.AreEqual(lastDate, candles[^1].Timestamp); - DateTime spotDate = DateTime.ParseExact("03/16/2017", "MM/dd/yyyy", englishCulture); + DateTime spotDate = DateTime.ParseExact("03/16/2017", "MM/dd/yyyy", invariantCulture); Assert.AreEqual(spotDate, candles[50].Timestamp); } diff --git a/tests/indicators/_common/Generics/Sorting.Tests.cs b/tests/indicators/_common/Generics/Sorting.Tests.cs index 77aa0c223..d89adf62f 100644 --- a/tests/indicators/_common/Generics/Sorting.Tests.cs +++ b/tests/indicators/_common/Generics/Sorting.Tests.cs @@ -11,15 +11,15 @@ public void ToSortedCollection() // baseline for comparison IReadOnlyList baseline = [ - new(Timestamp: DateTime.Parse("1/1/2000", englishCulture), Sma: null), - new(Timestamp: DateTime.Parse("1/2/2000", englishCulture), Sma: null), - new(Timestamp: DateTime.Parse("1/9/2000", englishCulture), Sma: null), - new(Timestamp: DateTime.Parse("1/3/2000", englishCulture), Sma: 3), - new(Timestamp: DateTime.Parse("1/4/2000", englishCulture), Sma: 4), - new(Timestamp: DateTime.Parse("1/5/2000", englishCulture), Sma: 5), - new(Timestamp: DateTime.Parse("1/6/2000", englishCulture), Sma: 6), - new(Timestamp: DateTime.Parse("1/7/2000", englishCulture), Sma: 7), - new(Timestamp: DateTime.Parse("1/8/2000", englishCulture), Sma: double.NaN) + new(Timestamp: DateTime.Parse("1/1/2000", invariantCulture), Sma: null), + new(Timestamp: DateTime.Parse("1/2/2000", invariantCulture), Sma: null), + new(Timestamp: DateTime.Parse("1/9/2000", invariantCulture), Sma: null), + new(Timestamp: DateTime.Parse("1/3/2000", invariantCulture), Sma: 3), + new(Timestamp: DateTime.Parse("1/4/2000", invariantCulture), Sma: 4), + new(Timestamp: DateTime.Parse("1/5/2000", invariantCulture), Sma: 5), + new(Timestamp: DateTime.Parse("1/6/2000", invariantCulture), Sma: 6), + new(Timestamp: DateTime.Parse("1/7/2000", invariantCulture), Sma: 7), + new(Timestamp: DateTime.Parse("1/8/2000", invariantCulture), Sma: double.NaN) ]; // PUBLIC VARIANT, generic sorted Collection @@ -27,6 +27,6 @@ public void ToSortedCollection() .ToSortedCollection(); Assert.AreEqual(5, sortResults[4].Sma); - Assert.AreEqual(DateTime.Parse("1/9/2000", englishCulture), sortResults.LastOrDefault().Timestamp); + Assert.AreEqual(DateTime.Parse("1/9/2000", invariantCulture), sortResults.LastOrDefault().Timestamp); } } diff --git a/tests/indicators/_common/Math/Numerical.Tests.cs b/tests/indicators/_common/Math/Numerical.Tests.cs index 4f0e1f939..e116fe11f 100644 --- a/tests/indicators/_common/Math/Numerical.Tests.cs +++ b/tests/indicators/_common/Math/Numerical.Tests.cs @@ -54,10 +54,10 @@ public void SlopeMismatch() public void RoundDownDate() { TimeSpan interval = PeriodSize.OneHour.ToTimeSpan(); - DateTime evDate = DateTime.Parse("2020-12-15 09:35:45", englishCulture); + DateTime evDate = DateTime.Parse("2020-12-15 09:35:45", invariantCulture); DateTime rnDate = evDate.RoundDown(interval); - DateTime exDate = DateTime.Parse("2020-12-15 09:00:00", englishCulture); + DateTime exDate = DateTime.Parse("2020-12-15 09:00:00", invariantCulture); Assert.AreEqual(exDate, rnDate); } diff --git a/tests/indicators/_common/Quotes/Quote.Aggregates.Tests.cs b/tests/indicators/_common/Quotes/Quote.Aggregates.Tests.cs index 0f9a4b449..9cb91b204 100644 --- a/tests/indicators/_common/Quotes/Quote.Aggregates.Tests.cs +++ b/tests/indicators/_common/Quotes/Quote.Aggregates.Tests.cs @@ -18,7 +18,7 @@ public void Aggregate() // sample values Quote r0 = results[0]; - Assert.AreEqual(DateTime.Parse("2020-12-15 09:30", englishCulture), r0.Timestamp); + Assert.AreEqual(DateTime.Parse("2020-12-15 09:30", TestBase.invariantCulture), r0.Timestamp); Assert.AreEqual(367.40m, r0.Open); Assert.AreEqual(367.775m, r0.High); Assert.AreEqual(367.02m, r0.Low); @@ -26,7 +26,7 @@ public void Aggregate() Assert.AreEqual(2401786m, r0.Volume); Quote r1 = results[1]; - Assert.AreEqual(DateTime.Parse("2020-12-15 09:45", englishCulture), r1.Timestamp); + Assert.AreEqual(DateTime.Parse("2020-12-15 09:45", TestBase.invariantCulture), r1.Timestamp); Assert.AreEqual(367.25m, r1.Open); Assert.AreEqual(367.44m, r1.High); Assert.AreEqual(366.69m, r1.Low); @@ -34,7 +34,7 @@ public void Aggregate() Assert.AreEqual(1669983m, r1.Volume); Quote r2 = results[2]; - Assert.AreEqual(DateTime.Parse("2020-12-15 10:00", englishCulture), r2.Timestamp); + Assert.AreEqual(DateTime.Parse("2020-12-15 10:00", TestBase.invariantCulture), r2.Timestamp); Assert.AreEqual(366.85m, r2.Open); Assert.AreEqual(367.17m, r2.High); Assert.AreEqual(366.57m, r2.Low); @@ -61,7 +61,7 @@ public void AggregateTimeSpan() // sample values Quote r0 = results[0]; - Assert.AreEqual(DateTime.Parse("2020-12-15 09:30", englishCulture), r0.Timestamp); + Assert.AreEqual(DateTime.Parse("2020-12-15 09:30", TestBase.invariantCulture), r0.Timestamp); Assert.AreEqual(367.40m, r0.Open); Assert.AreEqual(367.775m, r0.High); Assert.AreEqual(367.02m, r0.Low); @@ -69,7 +69,7 @@ public void AggregateTimeSpan() Assert.AreEqual(2401786m, r0.Volume); Quote r1 = results[1]; - Assert.AreEqual(DateTime.Parse("2020-12-15 09:45", englishCulture), r1.Timestamp); + Assert.AreEqual(DateTime.Parse("2020-12-15 09:45", TestBase.invariantCulture), r1.Timestamp); Assert.AreEqual(367.25m, r1.Open); Assert.AreEqual(367.44m, r1.High); Assert.AreEqual(366.69m, r1.Low); @@ -77,7 +77,7 @@ public void AggregateTimeSpan() Assert.AreEqual(1669983m, r1.Volume); Quote r2 = results[2]; - Assert.AreEqual(DateTime.Parse("2020-12-15 10:00", englishCulture), r2.Timestamp); + Assert.AreEqual(DateTime.Parse("2020-12-15 10:00", TestBase.invariantCulture), r2.Timestamp); Assert.AreEqual(366.85m, r2.Open); Assert.AreEqual(367.17m, r2.High); Assert.AreEqual(366.57m, r2.Low); @@ -102,7 +102,7 @@ public void AggregateMonth() // sample values Quote r0 = results[0]; - Assert.AreEqual(DateTime.Parse("2017-01-01", englishCulture), r0.Timestamp); + Assert.AreEqual(DateTime.Parse("2017-01-01", TestBase.invariantCulture), r0.Timestamp); Assert.AreEqual(212.61m, r0.Open); Assert.AreEqual(217.02m, r0.High); Assert.AreEqual(211.52m, r0.Low); @@ -110,7 +110,7 @@ public void AggregateMonth() Assert.AreEqual(1569087580m, r0.Volume); Quote r1 = results[1]; - Assert.AreEqual(DateTime.Parse("2017-02-01", englishCulture), r1.Timestamp); + Assert.AreEqual(DateTime.Parse("2017-02-01", TestBase.invariantCulture), r1.Timestamp); Assert.AreEqual(215.65m, r1.Open); Assert.AreEqual(224.20m, r1.High); Assert.AreEqual(214.29m, r1.Low); @@ -118,7 +118,7 @@ public void AggregateMonth() Assert.AreEqual(1444958340m, r1.Volume); Quote r23 = results[23]; - Assert.AreEqual(DateTime.Parse("2018-12-01", englishCulture), r23.Timestamp); + Assert.AreEqual(DateTime.Parse("2018-12-01", TestBase.invariantCulture), r23.Timestamp); Assert.AreEqual(273.47m, r23.Open); Assert.AreEqual(273.59m, r23.High); Assert.AreEqual(229.42m, r23.Low); diff --git a/tests/indicators/_common/Quotes/Quote.Converters.Tests.cs b/tests/indicators/_common/Quotes/Quote.Converters.Tests.cs index 6e10aadc9..704f4096b 100644 --- a/tests/indicators/_common/Quotes/Quote.Converters.Tests.cs +++ b/tests/indicators/_common/Quotes/Quote.Converters.Tests.cs @@ -18,15 +18,15 @@ public void ToSortedCollection() Assert.AreEqual(502, h.Count); // check first date - DateTime firstDate = DateTime.ParseExact("01/18/2016", "MM/dd/yyyy", englishCulture); + DateTime firstDate = DateTime.ParseExact("01/18/2016", "MM/dd/yyyy", TestBase.invariantCulture); Assert.AreEqual(firstDate, h[0].Timestamp); // check last date - DateTime lastDate = DateTime.ParseExact("12/31/2018", "MM/dd/yyyy", englishCulture); + DateTime lastDate = DateTime.ParseExact("12/31/2018", "MM/dd/yyyy", TestBase.invariantCulture); Assert.AreEqual(lastDate, h.LastOrDefault().Timestamp); // spot check an out of sequence date - DateTime spotDate = DateTime.ParseExact("03/16/2017", "MM/dd/yyyy", englishCulture); + DateTime spotDate = DateTime.ParseExact("03/16/2017", "MM/dd/yyyy", TestBase.invariantCulture); Assert.AreEqual(spotDate, h[50].Timestamp); } @@ -41,15 +41,15 @@ public void ToSortedList() Assert.AreEqual(502, h.Count); // check first date - DateTime firstDate = DateTime.ParseExact("01/18/2016", "MM/dd/yyyy", englishCulture); + DateTime firstDate = DateTime.ParseExact("01/18/2016", "MM/dd/yyyy", TestBase.invariantCulture); Assert.AreEqual(firstDate, h[0].Timestamp); // check last date - DateTime lastDate = DateTime.ParseExact("12/31/2018", "MM/dd/yyyy", englishCulture); + DateTime lastDate = DateTime.ParseExact("12/31/2018", "MM/dd/yyyy", TestBase.invariantCulture); Assert.AreEqual(lastDate, h[^1].Timestamp); // spot check an out of sequence date - DateTime spotDate = DateTime.ParseExact("03/16/2017", "MM/dd/yyyy", englishCulture); + DateTime spotDate = DateTime.ParseExact("03/16/2017", "MM/dd/yyyy", TestBase.invariantCulture); Assert.AreEqual(spotDate, h[50].Timestamp); } } diff --git a/tests/indicators/_common/Quotes/Quote.Validation.Tests.cs b/tests/indicators/_common/Quotes/Quote.Validation.Tests.cs index d5af907a5..b4526b8cd 100644 --- a/tests/indicators/_common/Quotes/Quote.Validation.Tests.cs +++ b/tests/indicators/_common/Quotes/Quote.Validation.Tests.cs @@ -1,3 +1,5 @@ +using System.Globalization; + namespace Utilities; // quote validation @@ -15,10 +17,10 @@ public void Validate() Assert.AreEqual(502, h.Count); // sample values - DateTime lastDate = DateTime.ParseExact("12/31/2018", "MM/dd/yyyy", englishCulture); + DateTime lastDate = DateTime.ParseExact("12/31/2018", "MM/dd/yyyy", invariantCulture); Assert.AreEqual(lastDate, h[501].Timestamp); - DateTime spotDate = DateTime.ParseExact("02/01/2017", "MM/dd/yyyy", englishCulture); + DateTime spotDate = DateTime.ParseExact("02/01/2017", "MM/dd/yyyy", invariantCulture); Assert.AreEqual(spotDate, h[20].Timestamp); } @@ -31,7 +33,7 @@ public void ValidateLong() Assert.AreEqual(5285, h.Count); // sample values - DateTime lastDate = DateTime.ParseExact("09/04/2020", "MM/dd/yyyy", englishCulture); + DateTime lastDate = DateTime.ParseExact("09/04/2020", "MM/dd/yyyy", invariantCulture); Assert.AreEqual(lastDate, h[5284].Timestamp); } @@ -80,11 +82,11 @@ public void ValidateDuplicates() { IReadOnlyList dupQuotes = new List { - new(Timestamp: DateTime.ParseExact("2017-01-03", "yyyy-MM-dd", englishCulture), Open: 214.86m, High: 220.33m, Low: 210.96m, Close: 216.99m, Volume: 5923254), - new(Timestamp: DateTime.ParseExact("2017-01-04", "yyyy-MM-dd", englishCulture), Open: 214.75m, High: 228.00m, Low: 214.31m, Close: 226.99m, Volume: 11213471), - new(Timestamp: DateTime.ParseExact("2017-01-05", "yyyy-MM-dd", englishCulture), Open: 226.42m, High: 227.48m, Low: 221.95m, Close: 226.75m, Volume: 5911695), - new(Timestamp: DateTime.ParseExact("2017-01-06", "yyyy-MM-dd", englishCulture), Open: 226.93m, High: 230.31m, Low: 225.45m, Close: 229.01m, Volume: 5527893), - new(Timestamp: DateTime.ParseExact("2017-01-06", "yyyy-MM-dd", englishCulture), Open: 228.97m, High: 231.92m, Low: 228.00m, Close: 231.28m, Volume: 3979484) + new(Timestamp: DateTime.ParseExact("2017-01-03", "yyyy-MM-dd", invariantCulture), Open: 214.86m, High: 220.33m, Low: 210.96m, Close: 216.99m, Volume: 5923254), + new(Timestamp: DateTime.ParseExact("2017-01-04", "yyyy-MM-dd", invariantCulture), Open: 214.75m, High: 228.00m, Low: 214.31m, Close: 226.99m, Volume: 11213471), + new(Timestamp: DateTime.ParseExact("2017-01-05", "yyyy-MM-dd", invariantCulture), Open: 226.42m, High: 227.48m, Low: 221.95m, Close: 226.75m, Volume: 5911695), + new(Timestamp: DateTime.ParseExact("2017-01-06", "yyyy-MM-dd", invariantCulture), Open: 226.93m, High: 230.31m, Low: 225.45m, Close: 229.01m, Volume: 5527893), + new(Timestamp: DateTime.ParseExact("2017-01-06", "yyyy-MM-dd", invariantCulture), Open: 228.97m, High: 231.92m, Low: 228.00m, Close: 231.28m, Volume: 3979484) }; InvalidQuotesException dx @@ -92,7 +94,7 @@ InvalidQuotesException dx () => dupQuotes.Validate()); dx.Message.Should() - .Be("Duplicate date found on 1/6/2017 12:00:00 AM. (Parameter 'quotes')"); + .Be("Duplicate date found on 01/06/2017. (Parameter 'quotes')"); } [TestMethod] @@ -100,11 +102,11 @@ public void ValidateOutOfSequence() { IReadOnlyList unorderedQuotes = new List { - new(Timestamp: DateTime.ParseExact("2017-01-03", "yyyy-MM-dd", englishCulture), Open: 214.86m, High: 220.33m, Low: 210.96m, Close: 216.99m, Volume: 5923254), - new(Timestamp: DateTime.ParseExact("2017-01-04", "yyyy-MM-dd", englishCulture), Open: 214.75m, High: 228.00m, Low: 214.31m, Close: 226.99m, Volume: 11213471), - new(Timestamp: DateTime.ParseExact("2017-01-06", "yyyy-MM-dd", englishCulture), Open: 228.97m, High: 231.92m, Low: 228.00m, Close: 231.28m, Volume: 3979484), - new(Timestamp: DateTime.ParseExact("2017-01-05", "yyyy-MM-dd", englishCulture), Open: 226.42m, High: 227.48m, Low: 221.95m, Close: 226.75m, Volume: 5911695), - new(Timestamp: DateTime.ParseExact("2017-01-06", "yyyy-MM-dd", englishCulture), Open: 226.93m, High: 230.31m, Low: 225.45m, Close: 229.01m, Volume: 5527893) + new(Timestamp: DateTime.ParseExact("2017-01-03", "yyyy-MM-dd", invariantCulture), Open: 214.86m, High: 220.33m, Low: 210.96m, Close: 216.99m, Volume: 5923254), + new(Timestamp: DateTime.ParseExact("2017-01-04", "yyyy-MM-dd", invariantCulture), Open: 214.75m, High: 228.00m, Low: 214.31m, Close: 226.99m, Volume: 11213471), + new(Timestamp: DateTime.ParseExact("2017-01-06", "yyyy-MM-dd", invariantCulture), Open: 228.97m, High: 231.92m, Low: 228.00m, Close: 231.28m, Volume: 3979484), + new(Timestamp: DateTime.ParseExact("2017-01-05", "yyyy-MM-dd", invariantCulture), Open: 226.42m, High: 227.48m, Low: 221.95m, Close: 226.75m, Volume: 5911695), + new(Timestamp: DateTime.ParseExact("2017-01-06", "yyyy-MM-dd", invariantCulture), Open: 226.93m, High: 230.31m, Low: 225.45m, Close: 229.01m, Volume: 5527893) }; InvalidQuotesException dx @@ -112,7 +114,6 @@ InvalidQuotesException dx () => unorderedQuotes.Validate()); dx.Message.Should() - .Be("Quotes are out of sequence on 1/5/2017 12:00:00 AM. (Parameter 'quotes')"); + .Be("Quotes are out of sequence on 01/05/2017. (Parameter 'quotes')"); } - } diff --git a/tests/indicators/_common/Reusable/Reusable.Utilities.Tests.cs b/tests/indicators/_common/Reusable/Reusable.Utilities.Tests.cs index 72c8433e6..f8bba07d7 100644 --- a/tests/indicators/_common/Reusable/Reusable.Utilities.Tests.cs +++ b/tests/indicators/_common/Reusable/Reusable.Utilities.Tests.cs @@ -41,7 +41,7 @@ public void ToReusableList() [TestMethod] public void QuoteToReusable() { - DateTime t = DateTime.Parse("5/5/2055", englishCulture); + DateTime t = DateTime.Parse("5/5/2055", invariantCulture); decimal l = 111111111111111m; decimal o = 222222222222222m; diff --git a/tests/indicators/_common/Use (QuotePart)/QuotePart.StaticSeries.Tests.cs b/tests/indicators/_common/Use (QuotePart)/QuotePart.StaticSeries.Tests.cs index 720328894..72c57b1a2 100644 --- a/tests/indicators/_common/Use (QuotePart)/QuotePart.StaticSeries.Tests.cs +++ b/tests/indicators/_common/Use (QuotePart)/QuotePart.StaticSeries.Tests.cs @@ -34,7 +34,7 @@ public override void Standard() QuotePart rohlc = ohlc[501]; // proper last date - DateTime lastDate = DateTime.ParseExact("12/31/2018", "MM/dd/yyyy", englishCulture); + DateTime lastDate = DateTime.ParseExact("12/31/2018", "MM/dd/yyyy", invariantCulture); Assert.AreEqual(lastDate, rc.Timestamp); // last values should be correct diff --git a/tests/indicators/_common/Use (QuotePart)/QuotePart.Utilities.Tests.cs b/tests/indicators/_common/Use (QuotePart)/QuotePart.Utilities.Tests.cs index ed7fe3524..bbf643f4b 100644 --- a/tests/indicators/_common/Use (QuotePart)/QuotePart.Utilities.Tests.cs +++ b/tests/indicators/_common/Use (QuotePart)/QuotePart.Utilities.Tests.cs @@ -22,7 +22,7 @@ public void ConvertQuote() QuotePart ohlc = Quotes[501].ToQuotePart(CandlePart.OHLC4); // proper last date - DateTime lastDate = DateTime.ParseExact("12/31/2018", "MM/dd/yyyy", englishCulture); + DateTime lastDate = DateTime.ParseExact("12/31/2018", "MM/dd/yyyy", invariantCulture); Assert.AreEqual(lastDate, c.Timestamp); // last values should be correct @@ -70,7 +70,7 @@ public void ConvertList() QuotePart rohlc = ohlc[501]; // proper last date - DateTime lastDate = DateTime.ParseExact("12/31/2018", "MM/dd/yyyy", englishCulture); + DateTime lastDate = DateTime.ParseExact("12/31/2018", "MM/dd/yyyy", invariantCulture); Assert.AreEqual(lastDate, rc.Timestamp); // last values should be correct diff --git a/tests/indicators/a-d/Beta/Beta.StaticSeries.Tests.cs b/tests/indicators/a-d/Beta/Beta.StaticSeries.Tests.cs index f2797f1c7..c8214d024 100644 --- a/tests/indicators/a-d/Beta/Beta.StaticSeries.Tests.cs +++ b/tests/indicators/a-d/Beta/Beta.StaticSeries.Tests.cs @@ -227,28 +227,28 @@ public void NoMatch() { IReadOnlyList quoteA = [ - new(DateTime.Parse("1/1/2020", englishCulture), 0, 0, 0, 1234, 0), - new(DateTime.Parse("1/2/2020", englishCulture), 0, 0, 0, 1234, 0), - new(DateTime.Parse("1/3/2020", englishCulture), 0, 0, 0, 1234, 0), - new(DateTime.Parse("1/4/2020", englishCulture), 0, 0, 0, 1234, 0), - new(DateTime.Parse("1/5/2020", englishCulture), 0, 0, 0, 1234, 0), - new(DateTime.Parse("1/6/2020", englishCulture), 0, 0, 0, 1234, 0), - new(DateTime.Parse("1/7/2020", englishCulture), 0, 0, 0, 1234, 0), - new(DateTime.Parse("1/8/2020", englishCulture), 0, 0, 0, 1234, 0), - new(DateTime.Parse("1/9/2020", englishCulture), 0, 0, 0, 1234, 0) + new(DateTime.Parse("1/1/2020", invariantCulture), 0, 0, 0, 1234, 0), + new(DateTime.Parse("1/2/2020", invariantCulture), 0, 0, 0, 1234, 0), + new(DateTime.Parse("1/3/2020", invariantCulture), 0, 0, 0, 1234, 0), + new(DateTime.Parse("1/4/2020", invariantCulture), 0, 0, 0, 1234, 0), + new(DateTime.Parse("1/5/2020", invariantCulture), 0, 0, 0, 1234, 0), + new(DateTime.Parse("1/6/2020", invariantCulture), 0, 0, 0, 1234, 0), + new(DateTime.Parse("1/7/2020", invariantCulture), 0, 0, 0, 1234, 0), + new(DateTime.Parse("1/8/2020", invariantCulture), 0, 0, 0, 1234, 0), + new(DateTime.Parse("1/9/2020", invariantCulture), 0, 0, 0, 1234, 0) ]; IReadOnlyList quoteB = [ - new(DateTime.Parse("1/1/2020", englishCulture), 0, 0, 0, 1234, 0), - new(DateTime.Parse("1/2/2020", englishCulture), 0, 0, 0, 1234, 0), - new(DateTime.Parse("1/3/2020", englishCulture), 0, 0, 0, 1234, 0), - new(DateTime.Parse("2/4/2020", englishCulture), 0, 0, 0, 1234, 0), // abberrant - new(DateTime.Parse("1/5/2020", englishCulture), 0, 0, 0, 1234, 0), - new(DateTime.Parse("1/6/2020", englishCulture), 0, 0, 0, 1234, 0), - new(DateTime.Parse("1/7/2020", englishCulture), 0, 0, 0, 1234, 0), - new(DateTime.Parse("1/8/2020", englishCulture), 0, 0, 0, 1234, 0), - new(DateTime.Parse("1/9/2020", englishCulture), 0, 0, 0, 1234, 0) + new(DateTime.Parse("1/1/2020", invariantCulture), 0, 0, 0, 1234, 0), + new(DateTime.Parse("1/2/2020", invariantCulture), 0, 0, 0, 1234, 0), + new(DateTime.Parse("1/3/2020", invariantCulture), 0, 0, 0, 1234, 0), + new(DateTime.Parse("2/4/2020", invariantCulture), 0, 0, 0, 1234, 0), // abberrant + new(DateTime.Parse("1/5/2020", invariantCulture), 0, 0, 0, 1234, 0), + new(DateTime.Parse("1/6/2020", invariantCulture), 0, 0, 0, 1234, 0), + new(DateTime.Parse("1/7/2020", invariantCulture), 0, 0, 0, 1234, 0), + new(DateTime.Parse("1/8/2020", invariantCulture), 0, 0, 0, 1234, 0), + new(DateTime.Parse("1/9/2020", invariantCulture), 0, 0, 0, 1234, 0) ]; Assert.ThrowsException(() diff --git a/tests/indicators/a-d/Dpo/Dpo.StaticSeries.Tests.cs b/tests/indicators/a-d/Dpo/Dpo.StaticSeries.Tests.cs index f6a3c71b3..08628d406 100644 --- a/tests/indicators/a-d/Dpo/Dpo.StaticSeries.Tests.cs +++ b/tests/indicators/a-d/Dpo/Dpo.StaticSeries.Tests.cs @@ -17,7 +17,7 @@ public override void Standard() for (int i = 0; i < csvData.Count; i++) { string[] csv = csvData[i].Split(","); - DateTime date = Convert.ToDateTime(csv[1], englishCulture); + DateTime date = Convert.ToDateTime(csv[1], invariantCulture); qot.Add(new Quote(date, 0, 0, 0, Close: csv[5].ToDecimal(), 0)); exp.Add(new(date, csv[7].ToDoubleNull(), csv[6].ToDoubleNull())); diff --git a/tests/indicators/s-z/Sma/Sma.StaticSeries.Tests.cs b/tests/indicators/s-z/Sma/Sma.StaticSeries.Tests.cs index beb01d021..d66fe61ff 100644 --- a/tests/indicators/s-z/Sma/Sma.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/Sma/Sma.StaticSeries.Tests.cs @@ -59,7 +59,7 @@ public void CandlePartVolume() Assert.AreEqual(157958070.8, r290.Sma); SmaResult r501 = results[501]; - Assert.AreEqual(DateTime.ParseExact("12/31/2018", "MM/dd/yyyy", englishCulture), r501.Timestamp); + Assert.AreEqual(DateTime.ParseExact("12/31/2018", "MM/dd/yyyy", invariantCulture), r501.Timestamp); Assert.AreEqual(163695200, r501.Sma); } diff --git a/tests/indicators/s-z/Vwap/Vwap.StaticSeries.Tests.cs b/tests/indicators/s-z/Vwap/Vwap.StaticSeries.Tests.cs index df7973627..cb07abc66 100644 --- a/tests/indicators/s-z/Vwap/Vwap.StaticSeries.Tests.cs +++ b/tests/indicators/s-z/Vwap/Vwap.StaticSeries.Tests.cs @@ -35,7 +35,7 @@ public override void Standard() public void WithStartDate() { DateTime startDate = - DateTime.ParseExact("2020-12-15 10:00", "yyyy-MM-dd h:mm", englishCulture); + DateTime.ParseExact("2020-12-15 10:00", "yyyy-MM-dd h:mm", invariantCulture); IReadOnlyList results = intraday .ToVwap(startDate); @@ -109,7 +109,7 @@ public void Removed() // with start date DateTime startDate = - DateTime.ParseExact("2020-12-15 10:00", "yyyy-MM-dd h:mm", englishCulture); + DateTime.ParseExact("2020-12-15 10:00", "yyyy-MM-dd h:mm", invariantCulture); IReadOnlyList sdResults = intraday .ToVwap(startDate) @@ -127,7 +127,7 @@ public void Exceptions() { // bad SMA period DateTime startDate = - DateTime.ParseExact("2000-12-15", "yyyy-MM-dd", englishCulture); + DateTime.ParseExact("2000-12-15", "yyyy-MM-dd", invariantCulture); Assert.ThrowsException(() => Quotes.ToVwap(startDate)); From 797d117807556d1dc88aa5e226e9e13c8eb63390 Mon Sep 17 00:00:00 2001 From: Dave Skender <8432125+DaveSkender@users.noreply.github.com> Date: Sun, 27 Oct 2024 11:07:03 -0400 Subject: [PATCH 33/38] rename Increment interfaces --- src/_common/Incrementals/IIncremental.cs | 4 ++-- src/e-k/Ema/Ema.Increments.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/_common/Incrementals/IIncremental.cs b/src/_common/Incrementals/IIncremental.cs index 5014c1f53..269316e08 100644 --- a/src/_common/Incrementals/IIncremental.cs +++ b/src/_common/Incrementals/IIncremental.cs @@ -1,6 +1,6 @@ namespace Skender.Stock.Indicators; -public interface IIncrementReusable +public interface IAddReusable { /// /// Converts an incremental value into @@ -30,7 +30,7 @@ public interface IIncrementReusable void Add(IReadOnlyList values); } -public interface IIncrementQuote +public interface IAddQuote { /// /// Converts an incremental quote into diff --git a/src/e-k/Ema/Ema.Increments.cs b/src/e-k/Ema/Ema.Increments.cs index 59d4a4c7d..0df4706d5 100644 --- a/src/e-k/Ema/Ema.Increments.cs +++ b/src/e-k/Ema/Ema.Increments.cs @@ -6,7 +6,7 @@ namespace Skender.Stock.Indicators; /// Exponential Moving Average (EMA) /// from incremental reusable values. /// -public class EmaList : List, IEma, IIncrementQuote, IIncrementReusable +public class EmaList : List, IEma, IAddQuote, IAddReusable { private readonly Queue _buffer; private double _bufferSum; From e10c32176b59e41f467e35365865420a08ce311a Mon Sep 17 00:00:00 2001 From: Dave Skender <8432125+DaveSkender@users.noreply.github.com> Date: Sun, 27 Oct 2024 14:45:44 -0400 Subject: [PATCH 34/38] refactor: use readonly list input m-r --- src/_common/Globals.cs | 17 -- src/a-d/Adl/Adl.StreamHub.cs | 1 - src/a-d/Alligator/Alligator.StreamHub.cs | 4 +- src/a-d/Atr/Atr.StaticSeries.cs | 4 +- src/m-r/MaEnvelopes/MaEnvelopes.Api.cs | 16 -- src/m-r/MaEnvelopes/MaEnvelopes.Common.cs | 19 --- .../MaEnvelopes/MaEnvelopes.StaticSeries.cs | 38 ++--- src/m-r/MaEnvelopes/MaEnvelopes.Utilities.cs | 16 +- src/m-r/Macd/Macd.Common.cs | 33 ---- src/m-r/Macd/Macd.Models.cs | 2 +- src/m-r/Macd/Macd.StaticSeries.cs | 15 +- src/m-r/Macd/Macd.Utilities.cs | 30 +++- src/m-r/Macd/MacdApi.cs | 16 -- src/m-r/Mama/Mama.Api.cs | 15 -- src/m-r/Mama/Mama.Common.cs | 26 ---- src/m-r/Mama/Mama.StaticSeries.cs | 12 +- src/m-r/Mama/Mama.Utilities.cs | 23 ++- src/m-r/Marubozu/Marubozu.Api.cs | 15 -- src/m-r/Marubozu/Marubozu.StaticSeries.cs | 15 +- ...rubozu.Common.cs => Marubozu.Utilities.cs} | 5 +- src/m-r/Mfi/Mfi.Api.cs | 15 -- src/m-r/Mfi/Mfi.Common.cs | 19 --- src/m-r/Mfi/Mfi.StaticSeries.cs | 7 + src/m-r/Mfi/Mfi.Utilities.cs | 16 +- src/m-r/Obv/Obv.Api.cs | 14 -- src/m-r/Obv/Obv.StaticSeries.cs | 8 +- src/m-r/ParabolicSar/ParabolicSar.Api.cs | 34 ---- src/m-r/ParabolicSar/ParabolicSar.Common.cs | 47 ------ .../ParabolicSar/ParabolicSar.StaticSeries.cs | 25 ++- .../ParabolicSar/ParabolicSar.Utilities.cs | 48 ++++-- src/m-r/PivotPoints/PivotPoints.Api.cs | 16 -- .../PivotPoints/PivotPoints.StaticSeries.cs | 146 +++++++++--------- src/m-r/PivotPoints/PivotPoints.Utilities.cs | 18 ++- src/m-r/Pmo/Pmo.Api.cs | 16 -- src/m-r/Pmo/Pmo.Common.cs | 33 ---- src/m-r/Pmo/Pmo.StaticSeries.cs | 21 +-- src/m-r/Pmo/Pmo.Utilities.cs | 30 +++- src/m-r/Prs/Prs.Api.cs | 16 -- src/m-r/Prs/Prs.StaticSeries.cs | 24 +-- .../Prs/{Prs.Common.cs => Prs.Utilities.cs} | 14 +- src/m-r/Pvo/Pvo.Api.cs | 20 --- src/m-r/Pvo/Pvo.Common.cs | 33 ---- src/m-r/Pvo/Pvo.StaticSeries.cs | 15 +- src/m-r/Pvo/Pvo.Utilities.cs | 30 +++- src/m-r/Renko/Renko.Api.cs | 23 --- src/m-r/Renko/Renko.StaticSeries.cs | 13 +- src/m-r/Renko/Renko.StreamHub.cs | 12 +- src/m-r/RenkoAtr/RenkoAtr.Api.cs | 13 -- src/m-r/RenkoAtr/RenkoAtr.StaticSeries.cs | 10 +- src/m-r/Roc/Roc.Api.cs | 14 -- src/m-r/Roc/Roc.Common.cs | 19 --- src/m-r/Roc/Roc.StaticSeries.cs | 9 +- src/m-r/Roc/Roc.Utilities.cs | 22 +-- src/m-r/RocWb/RocWb.Api.cs | 16 -- src/m-r/RocWb/RocWb.Common.cs | 33 ---- src/m-r/RocWb/RocWb.StaticSeries.cs | 16 +- src/m-r/RocWb/RocWb.Utilities.cs | 30 +++- src/m-r/RollingPivots/RollingPivots.Api.cs | 17 -- src/m-r/RollingPivots/RollingPivots.Common.cs | 26 ---- .../RollingPivots.StaticSeries.cs | 23 +-- .../RollingPivots/RollingPivots.Utilities.cs | 23 ++- src/m-r/Rsi/Rsi.StaticSeries.cs | 2 +- src/s-z/Smma/Smma.Api.cs | 14 -- src/s-z/Smma/Smma.Common.cs | 19 --- src/s-z/Smma/Smma.StaticSeries.cs | 10 +- src/s-z/Smma/Smma.Utilities.cs | 14 +- src/s-z/Stc/Stc.StaticSeries.cs | 2 +- src/s-z/Tema/Tema.Api.cs | 14 -- src/s-z/Tema/Tema.Common.cs | 19 --- src/s-z/Tema/Tema.StaticSeries.cs | 9 +- src/s-z/Tema/Tema.Utilities.cs | 14 +- .../PivotPoints.StaticSeries.Tests.cs | 4 +- 72 files changed, 553 insertions(+), 874 deletions(-) delete mode 100644 src/m-r/MaEnvelopes/MaEnvelopes.Api.cs delete mode 100644 src/m-r/MaEnvelopes/MaEnvelopes.Common.cs delete mode 100644 src/m-r/Macd/Macd.Common.cs delete mode 100644 src/m-r/Macd/MacdApi.cs delete mode 100644 src/m-r/Mama/Mama.Api.cs delete mode 100644 src/m-r/Mama/Mama.Common.cs delete mode 100644 src/m-r/Marubozu/Marubozu.Api.cs rename src/m-r/Marubozu/{Marubozu.Common.cs => Marubozu.Utilities.cs} (92%) delete mode 100644 src/m-r/Mfi/Mfi.Api.cs delete mode 100644 src/m-r/Mfi/Mfi.Common.cs delete mode 100644 src/m-r/Obv/Obv.Api.cs delete mode 100644 src/m-r/ParabolicSar/ParabolicSar.Api.cs delete mode 100644 src/m-r/ParabolicSar/ParabolicSar.Common.cs delete mode 100644 src/m-r/PivotPoints/PivotPoints.Api.cs delete mode 100644 src/m-r/Pmo/Pmo.Api.cs delete mode 100644 src/m-r/Pmo/Pmo.Common.cs delete mode 100644 src/m-r/Prs/Prs.Api.cs rename src/m-r/Prs/{Prs.Common.cs => Prs.Utilities.cs} (80%) delete mode 100644 src/m-r/Pvo/Pvo.Api.cs delete mode 100644 src/m-r/Pvo/Pvo.Common.cs delete mode 100644 src/m-r/Renko/Renko.Api.cs delete mode 100644 src/m-r/RenkoAtr/RenkoAtr.Api.cs delete mode 100644 src/m-r/Roc/Roc.Api.cs delete mode 100644 src/m-r/Roc/Roc.Common.cs delete mode 100644 src/m-r/RocWb/RocWb.Api.cs delete mode 100644 src/m-r/RocWb/RocWb.Common.cs delete mode 100644 src/m-r/RollingPivots/RollingPivots.Api.cs delete mode 100644 src/m-r/RollingPivots/RollingPivots.Common.cs delete mode 100644 src/s-z/Smma/Smma.Api.cs delete mode 100644 src/s-z/Smma/Smma.Common.cs delete mode 100644 src/s-z/Tema/Tema.Api.cs delete mode 100644 src/s-z/Tema/Tema.Common.cs diff --git a/src/_common/Globals.cs b/src/_common/Globals.cs index 072c2ce43..3cdac175f 100644 --- a/src/_common/Globals.cs +++ b/src/_common/Globals.cs @@ -1,4 +1,3 @@ -using System.Globalization; using System.Runtime.CompilerServices; [assembly: CLSCompliant(true)] @@ -6,19 +5,3 @@ [assembly: InternalsVisibleTo("Tests.Performance")] namespace Skender.Stock.Indicators; - -/// Technical indicators and overlays. See -/// -/// the Guide for more information. -public static partial class Indicator -{ - private static readonly CultureInfo invCulture = CultureInfo.InvariantCulture; - private static readonly Calendar invCalendar = invCulture.Calendar; - - // Gets the DTFI properties required by GetWeekOfYear. - private static readonly CalendarWeekRule invCalendarWeekRule - = invCulture.DateTimeFormat.CalendarWeekRule; - - private static readonly DayOfWeek invFirstDayOfWeek - = invCulture.DateTimeFormat.FirstDayOfWeek; -} diff --git a/src/a-d/Adl/Adl.StreamHub.cs b/src/a-d/Adl/Adl.StreamHub.cs index 279a07bf1..e336e51b3 100644 --- a/src/a-d/Adl/Adl.StreamHub.cs +++ b/src/a-d/Adl/Adl.StreamHub.cs @@ -6,7 +6,6 @@ namespace Skender.Stock.Indicators; public static partial class Adl { - // OBSERVER, from Quote Provider public static AdlHub ToAdl( this IQuoteProvider quoteProvider) where TIn : IQuote diff --git a/src/a-d/Alligator/Alligator.StreamHub.cs b/src/a-d/Alligator/Alligator.StreamHub.cs index 960548d9f..8ade9b1ac 100644 --- a/src/a-d/Alligator/Alligator.StreamHub.cs +++ b/src/a-d/Alligator/Alligator.StreamHub.cs @@ -38,8 +38,8 @@ public static AlligatorHub ToAlligator( #endregion public class AlligatorHub -: StreamHub, IAlligatorHub -where TIn : IReusable + : StreamHub, IAlligatorHub + where TIn : IReusable { #region constructors diff --git a/src/a-d/Atr/Atr.StaticSeries.cs b/src/a-d/Atr/Atr.StaticSeries.cs index 8e4b50ada..10db80315 100644 --- a/src/a-d/Atr/Atr.StaticSeries.cs +++ b/src/a-d/Atr/Atr.StaticSeries.cs @@ -4,7 +4,6 @@ namespace Skender.Stock.Indicators; public static partial class Atr { - // SERIES, from TQuote public static IReadOnlyList ToAtr( this IReadOnlyList quotes, int lookbackPeriods = 14) @@ -12,9 +11,8 @@ public static IReadOnlyList ToAtr( .ToQuoteDList() .CalcAtr(lookbackPeriods); - // calculate series internal static List CalcAtr( - this List source, + this IReadOnlyList source, int lookbackPeriods) { // check parameter arguments diff --git a/src/m-r/MaEnvelopes/MaEnvelopes.Api.cs b/src/m-r/MaEnvelopes/MaEnvelopes.Api.cs deleted file mode 100644 index b68d153a8..000000000 --- a/src/m-r/MaEnvelopes/MaEnvelopes.Api.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace Skender.Stock.Indicators; - -// MOVING AVERAGE ENVELOPES (API) -public static partial class Indicator -{ - // SERIES, from CHAIN - public static IReadOnlyList ToMaEnvelopes( - this IReadOnlyList results, - int lookbackPeriods, - double percentOffset = 2.5, - MaType movingAverageType = MaType.SMA) - where T : IReusable - => results - .ToSortedList() - .CalcMaEnvelopes(lookbackPeriods, percentOffset, movingAverageType); -} diff --git a/src/m-r/MaEnvelopes/MaEnvelopes.Common.cs b/src/m-r/MaEnvelopes/MaEnvelopes.Common.cs deleted file mode 100644 index c894dc624..000000000 --- a/src/m-r/MaEnvelopes/MaEnvelopes.Common.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Skender.Stock.Indicators; - -// MOVING AVERAGE ENVELOPES (COMMON) - -public static class MaEnvelopes -{ - // parameter validation - internal static void Validate( - double percentOffset) - { - // check parameter arguments - if (percentOffset <= 0) - { - throw new ArgumentOutOfRangeException(nameof(percentOffset), percentOffset, - "Percent Offset must be greater than 0 for Moving Average Envelopes."); - } - } - -} diff --git a/src/m-r/MaEnvelopes/MaEnvelopes.StaticSeries.cs b/src/m-r/MaEnvelopes/MaEnvelopes.StaticSeries.cs index e553820ba..52942bbbd 100644 --- a/src/m-r/MaEnvelopes/MaEnvelopes.StaticSeries.cs +++ b/src/m-r/MaEnvelopes/MaEnvelopes.StaticSeries.cs @@ -1,20 +1,22 @@ +using System.Globalization; + namespace Skender.Stock.Indicators; // MOVING AVERAGE ENVELOPES (SERIES) -public static partial class Indicator +public static partial class MaEnvelopes { // calculate series - private static List CalcMaEnvelopes( - this List source, + public static IReadOnlyList ToMaEnvelopes( + this IReadOnlyList source, int lookbackPeriods, - double percentOffset, - MaType movingAverageType) + double percentOffset = 2.5, + MaType movingAverageType = MaType.SMA) where T : IReusable { // check parameter arguments // note: most validations are done in variant methods - MaEnvelopes.Validate(percentOffset); + Validate(percentOffset); // initialize double offsetRatio = percentOffset / 100d; @@ -35,7 +37,7 @@ private static List CalcMaEnvelopes( _ => throw new ArgumentOutOfRangeException( nameof(movingAverageType), movingAverageType, string.Format( - invCulture, + CultureInfo.InvariantCulture, "Moving Average Envelopes does not support {0}.", Enum.GetName(typeof(MaType), movingAverageType))) }; @@ -44,7 +46,7 @@ private static List CalcMaEnvelopes( } private static IEnumerable MaEnvAlma( - this List source, + this IReadOnlyList source, int lookbackPeriods, double offsetRatio) where T : IReusable @@ -56,7 +58,7 @@ private static IEnumerable MaEnvAlma( LowerEnvelope: x.Alma - (x.Alma * offsetRatio))); private static IEnumerable MaEnvDema( - this List source, + this IReadOnlyList source, int lookbackPeriods, double offsetRatio) where T : IReusable @@ -68,7 +70,7 @@ private static IEnumerable MaEnvDema( LowerEnvelope: x.Dema - (x.Dema * offsetRatio))); private static IEnumerable MaEnvEma( - this List source, + this IReadOnlyList source, int lookbackPeriods, double offsetRatio) where T : IReusable @@ -80,7 +82,7 @@ private static IEnumerable MaEnvEma( LowerEnvelope: x.Ema - (x.Ema * offsetRatio))); private static IEnumerable MaEnvEpma( - this List source, + this IReadOnlyList source, int lookbackPeriods, double offsetRatio) where T : IReusable @@ -92,7 +94,7 @@ private static IEnumerable MaEnvEpma( LowerEnvelope: x.Epma - (x.Epma * offsetRatio))); private static IEnumerable MaEnvHma( - this List source, + this IReadOnlyList source, int lookbackPeriods, double offsetRatio) where T : IReusable @@ -104,7 +106,7 @@ private static IEnumerable MaEnvHma( LowerEnvelope: x.Hma - (x.Hma * offsetRatio))); private static IEnumerable MaEnvSma( - this List source, + this IReadOnlyList source, int lookbackPeriods, double offsetRatio) where T : IReusable @@ -116,11 +118,11 @@ private static IEnumerable MaEnvSma( LowerEnvelope: x.Sma - (x.Sma * offsetRatio))); private static IEnumerable MaEnvSmma( - this List source, + this IReadOnlyList source, int lookbackPeriods, double offsetRatio) where T : IReusable - => source.CalcSmma(lookbackPeriods) + => source.ToSmma(lookbackPeriods) .Select(x => new MaEnvelopeResult( Timestamp: x.Timestamp, Centerline: x.Smma, @@ -128,11 +130,11 @@ private static IEnumerable MaEnvSmma( LowerEnvelope: x.Smma - (x.Smma * offsetRatio))); private static IEnumerable MaEnvTema( - this List source, + this IReadOnlyList source, int lookbackPeriods, double offsetRatio) where T : IReusable - => source.CalcTema(lookbackPeriods) + => source.ToTema(lookbackPeriods) .Select(x => new MaEnvelopeResult( Timestamp: x.Timestamp, Centerline: x.Tema, @@ -140,7 +142,7 @@ private static IEnumerable MaEnvTema( LowerEnvelope: x.Tema - (x.Tema * offsetRatio))); private static IEnumerable MaEnvWma( - this List source, + this IReadOnlyList source, int lookbackPeriods, double offsetRatio) where T : IReusable diff --git a/src/m-r/MaEnvelopes/MaEnvelopes.Utilities.cs b/src/m-r/MaEnvelopes/MaEnvelopes.Utilities.cs index 5b21710bb..07b314c46 100644 --- a/src/m-r/MaEnvelopes/MaEnvelopes.Utilities.cs +++ b/src/m-r/MaEnvelopes/MaEnvelopes.Utilities.cs @@ -1,6 +1,8 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// MOVING AVERAGE ENVELOPES (UTILITIES) + +public static partial class MaEnvelopes { // CONDENSE (REMOVE null results) /// @@ -16,4 +18,16 @@ public static IReadOnlyList Condense( return resultsList.ToSortedList(); } + + // parameter validation + internal static void Validate( + double percentOffset) + { + // check parameter arguments + if (percentOffset <= 0) + { + throw new ArgumentOutOfRangeException(nameof(percentOffset), percentOffset, + "Percent Offset must be greater than 0 for Moving Average Envelopes."); + } + } } diff --git a/src/m-r/Macd/Macd.Common.cs b/src/m-r/Macd/Macd.Common.cs deleted file mode 100644 index f01a1a63e..000000000 --- a/src/m-r/Macd/Macd.Common.cs +++ /dev/null @@ -1,33 +0,0 @@ -namespace Skender.Stock.Indicators; - -// MOVING AVERAGE CONVERGENCE/DIVERGENCE (MACD) OSCILLATOR (COMMON) - -public static class Macd -{ - // parameter validation - internal static void Validate( - int fastPeriods, - int slowPeriods, - int signalPeriods) - { - // check parameter arguments - if (fastPeriods <= 0) - { - throw new ArgumentOutOfRangeException(nameof(fastPeriods), fastPeriods, - "Fast periods must be greater than 0 for MACD."); - } - - if (signalPeriods < 0) - { - throw new ArgumentOutOfRangeException(nameof(signalPeriods), signalPeriods, - "Signal periods must be greater than or equal to 0 for MACD."); - } - - if (slowPeriods <= fastPeriods) - { - throw new ArgumentOutOfRangeException(nameof(slowPeriods), slowPeriods, - "Slow periods must be greater than the fast period for MACD."); - } - } - -} diff --git a/src/m-r/Macd/Macd.Models.cs b/src/m-r/Macd/Macd.Models.cs index 343ec3ec4..c6b48ff1e 100644 --- a/src/m-r/Macd/Macd.Models.cs +++ b/src/m-r/Macd/Macd.Models.cs @@ -7,7 +7,7 @@ public record MacdResult double? Signal, double? Histogram, - // extra interim data + // extra/interim data double? FastEma, double? SlowEma diff --git a/src/m-r/Macd/Macd.StaticSeries.cs b/src/m-r/Macd/Macd.StaticSeries.cs index 8eedf8bc3..45c4628d6 100644 --- a/src/m-r/Macd/Macd.StaticSeries.cs +++ b/src/m-r/Macd/Macd.StaticSeries.cs @@ -2,17 +2,18 @@ namespace Skender.Stock.Indicators; // MOVING AVERAGE CONVERGENCE/DIVERGENCE (MACD) OSCILLATOR (SERIES) -public static partial class Indicator +public static partial class Macd { - private static List CalcMacd( - this List source, - int fastPeriods, - int slowPeriods, - int signalPeriods) + public static IReadOnlyList ToMacd( + this IReadOnlyList source, + int fastPeriods = 12, + int slowPeriods = 26, + int signalPeriods = 9) where T : IReusable { // check parameter arguments - Macd.Validate(fastPeriods, slowPeriods, signalPeriods); + ArgumentNullException.ThrowIfNull(source); + Validate(fastPeriods, slowPeriods, signalPeriods); // initialize int length = source.Count; diff --git a/src/m-r/Macd/Macd.Utilities.cs b/src/m-r/Macd/Macd.Utilities.cs index 4b1791d84..4326aac2d 100644 --- a/src/m-r/Macd/Macd.Utilities.cs +++ b/src/m-r/Macd/Macd.Utilities.cs @@ -1,6 +1,8 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// MOVING AVERAGE CONVERGENCE/DIVERGENCE (MACD) OSCILLATOR (UTILITIES) + +public static partial class Macd { // remove recommended periods /// @@ -13,4 +15,30 @@ public static IReadOnlyList RemoveWarmupPeriods( return results.Remove(n + 250); } + + // parameter validation + internal static void Validate( + int fastPeriods, + int slowPeriods, + int signalPeriods) + { + // check parameter arguments + if (fastPeriods <= 0) + { + throw new ArgumentOutOfRangeException(nameof(fastPeriods), fastPeriods, + "Fast periods must be greater than 0 for MACD."); + } + + if (signalPeriods < 0) + { + throw new ArgumentOutOfRangeException(nameof(signalPeriods), signalPeriods, + "Signal periods must be greater than or equal to 0 for MACD."); + } + + if (slowPeriods <= fastPeriods) + { + throw new ArgumentOutOfRangeException(nameof(slowPeriods), slowPeriods, + "Slow periods must be greater than the fast period for MACD."); + } + } } diff --git a/src/m-r/Macd/MacdApi.cs b/src/m-r/Macd/MacdApi.cs deleted file mode 100644 index 502edebf0..000000000 --- a/src/m-r/Macd/MacdApi.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace Skender.Stock.Indicators; - -// MOVING AVERAGE CONVERGENCE/DIVERGENCE (MACD) OSCILLATOR (API) -public static partial class Indicator -{ - // SERIES, from CHAIN - public static IReadOnlyList ToMacd( - this IReadOnlyList results, - int fastPeriods = 12, - int slowPeriods = 26, - int signalPeriods = 9) - where T : IReusable - => results - .ToSortedList() - .CalcMacd(fastPeriods, slowPeriods, signalPeriods); -} diff --git a/src/m-r/Mama/Mama.Api.cs b/src/m-r/Mama/Mama.Api.cs deleted file mode 100644 index f9c6d57b4..000000000 --- a/src/m-r/Mama/Mama.Api.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Skender.Stock.Indicators; - -// MOTHER of ADAPTIVE MOVING AVERAGES - MAMA (API) -public static partial class Indicator -{ - // SERIES, from CHAIN - public static IReadOnlyList ToMama( - this IReadOnlyList results, - double fastLimit = 0.5, - double slowLimit = 0.05) - where T : IReusable - => results - .ToSortedList(CandlePart.HL2) - .CalcMama(fastLimit, slowLimit); -} diff --git a/src/m-r/Mama/Mama.Common.cs b/src/m-r/Mama/Mama.Common.cs deleted file mode 100644 index 9fca3e44f..000000000 --- a/src/m-r/Mama/Mama.Common.cs +++ /dev/null @@ -1,26 +0,0 @@ -namespace Skender.Stock.Indicators; - -// MOTHER of ADAPTIVE MOVING AVERAGES (COMMON) - -public static class Mama -{ - // parameter validation - internal static void Validate( - double fastLimit, - double slowLimit) - { - // check parameter arguments - if (fastLimit <= slowLimit || fastLimit >= 1) - { - throw new ArgumentOutOfRangeException(nameof(fastLimit), fastLimit, - "Fast Limit must be greater than Slow Limit and less than 1 for MAMA."); - } - - if (slowLimit <= 0) - { - throw new ArgumentOutOfRangeException(nameof(slowLimit), slowLimit, - "Slow Limit must be greater than 0 for MAMA."); - } - } - -} diff --git a/src/m-r/Mama/Mama.StaticSeries.cs b/src/m-r/Mama/Mama.StaticSeries.cs index 0aa73ce54..be955973b 100644 --- a/src/m-r/Mama/Mama.StaticSeries.cs +++ b/src/m-r/Mama/Mama.StaticSeries.cs @@ -1,8 +1,18 @@ namespace Skender.Stock.Indicators; // MOTHER of ADAPTIVE MOVING AVERAGES (SERIES) -public static partial class Indicator + +public static partial class Mama { + public static IReadOnlyList ToMama( + this IReadOnlyList results, + double fastLimit = 0.5, + double slowLimit = 0.05) + where T : IReusable + => results + .ToSortedList(CandlePart.HL2) + .CalcMama(fastLimit, slowLimit); + private static List CalcMama( this List source, double fastLimit, diff --git a/src/m-r/Mama/Mama.Utilities.cs b/src/m-r/Mama/Mama.Utilities.cs index 48ceb027c..2b9a21126 100644 --- a/src/m-r/Mama/Mama.Utilities.cs +++ b/src/m-r/Mama/Mama.Utilities.cs @@ -1,9 +1,30 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// MOTHER of ADAPTIVE MOVING AVERAGES (UTILITIES) + +public static partial class Mama { // remove recommended periods /// public static IReadOnlyList RemoveWarmupPeriods( this IReadOnlyList results) => results.Remove(50); + + // parameter validation + internal static void Validate( + double fastLimit, + double slowLimit) + { + // check parameter arguments + if (fastLimit <= slowLimit || fastLimit >= 1) + { + throw new ArgumentOutOfRangeException(nameof(fastLimit), fastLimit, + "Fast Limit must be greater than Slow Limit and less than 1 for MAMA."); + } + + if (slowLimit <= 0) + { + throw new ArgumentOutOfRangeException(nameof(slowLimit), slowLimit, + "Slow Limit must be greater than 0 for MAMA."); + } + } } diff --git a/src/m-r/Marubozu/Marubozu.Api.cs b/src/m-r/Marubozu/Marubozu.Api.cs deleted file mode 100644 index aaee83029..000000000 --- a/src/m-r/Marubozu/Marubozu.Api.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Skender.Stock.Indicators; - -// MARUBOZU (API) -public static partial class Indicator -{ - // SERIES, from TQuote - /// - /// - public static IReadOnlyList ToMarubozu( - this IReadOnlyList quotes, - double minBodyPercent = 95) - where TQuote : IQuote => quotes - .ToSortedList() - .CalcMarubozu(minBodyPercent); -} diff --git a/src/m-r/Marubozu/Marubozu.StaticSeries.cs b/src/m-r/Marubozu/Marubozu.StaticSeries.cs index 59f3ca219..6cf34e122 100644 --- a/src/m-r/Marubozu/Marubozu.StaticSeries.cs +++ b/src/m-r/Marubozu/Marubozu.StaticSeries.cs @@ -2,18 +2,19 @@ namespace Skender.Stock.Indicators; // MARUBOZU (SERIES) -public static partial class Indicator +public static partial class Marubozu { - private static List CalcMarubozu( - this List quotesList, - double minBodyPercent) + public static IReadOnlyList ToMarubozu( + this IReadOnlyList quotes, + double minBodyPercent = 95) where TQuote : IQuote { // check parameter arguments - Marubozu.Validate(minBodyPercent); + ArgumentNullException.ThrowIfNull(quotes); + Validate(minBodyPercent); // initialize - int length = quotesList.Count; + int length = quotes.Count; List results = new(length); minBodyPercent /= 100; @@ -21,7 +22,7 @@ private static List CalcMarubozu( // roll through candles for (int i = 0; i < length; i++) { - TQuote q = quotesList[i]; + TQuote q = quotes[i]; decimal? matchPrice = null; Match matchType = Match.None; CandleProperties candle = q.ToCandle(); diff --git a/src/m-r/Marubozu/Marubozu.Common.cs b/src/m-r/Marubozu/Marubozu.Utilities.cs similarity index 92% rename from src/m-r/Marubozu/Marubozu.Common.cs rename to src/m-r/Marubozu/Marubozu.Utilities.cs index 1b882334c..7d859c14c 100644 --- a/src/m-r/Marubozu/Marubozu.Common.cs +++ b/src/m-r/Marubozu/Marubozu.Utilities.cs @@ -1,8 +1,8 @@ namespace Skender.Stock.Indicators; -// MARUBOZU (COMMON) +// MARUBOZU (UTILITIES) -public static class Marubozu +public static partial class Marubozu { // parameter validation internal static void Validate( @@ -25,5 +25,4 @@ internal static void Validate( "for Marubozu and is usually greater than 90 (90%)."); } } - } diff --git a/src/m-r/Mfi/Mfi.Api.cs b/src/m-r/Mfi/Mfi.Api.cs deleted file mode 100644 index 4466a5db3..000000000 --- a/src/m-r/Mfi/Mfi.Api.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Skender.Stock.Indicators; - -// MONEY FLOW INDEX (API) -public static partial class Indicator -{ - // SERIES, from TQuote - /// - /// - public static IReadOnlyList ToMfi( - this IReadOnlyList quotes, - int lookbackPeriods = 14) - where TQuote : IQuote => quotes - .ToQuoteDList() - .CalcMfi(lookbackPeriods); -} diff --git a/src/m-r/Mfi/Mfi.Common.cs b/src/m-r/Mfi/Mfi.Common.cs deleted file mode 100644 index b1f6b8ad5..000000000 --- a/src/m-r/Mfi/Mfi.Common.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Skender.Stock.Indicators; - -// MONEY FLOW INDEX (COMMON) - -public static class Mfi -{ - // parameter validation - internal static void Validate( - int lookbackPeriods) - { - // check parameter arguments - if (lookbackPeriods <= 1) - { - throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, - "Lookback periods must be greater than 1 for MFI."); - } - } - -} diff --git a/src/m-r/Mfi/Mfi.StaticSeries.cs b/src/m-r/Mfi/Mfi.StaticSeries.cs index e6d434aea..50286dc8e 100644 --- a/src/m-r/Mfi/Mfi.StaticSeries.cs +++ b/src/m-r/Mfi/Mfi.StaticSeries.cs @@ -4,6 +4,13 @@ namespace Skender.Stock.Indicators; public static partial class Indicator { + public static IReadOnlyList ToMfi( + this IReadOnlyList quotes, + int lookbackPeriods = 14) + where TQuote : IQuote => quotes + .ToQuoteDList() + .CalcMfi(lookbackPeriods); + private static List CalcMfi( this List source, int lookbackPeriods) diff --git a/src/m-r/Mfi/Mfi.Utilities.cs b/src/m-r/Mfi/Mfi.Utilities.cs index 78a09203e..e4768b450 100644 --- a/src/m-r/Mfi/Mfi.Utilities.cs +++ b/src/m-r/Mfi/Mfi.Utilities.cs @@ -1,6 +1,8 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// MONEY FLOW INDEX (UTILITIES) + +public static partial class Mfi { // remove recommended periods /// @@ -13,4 +15,16 @@ public static IReadOnlyList RemoveWarmupPeriods( return results.Remove(removePeriods); } + + // parameter validation + internal static void Validate( + int lookbackPeriods) + { + // check parameter arguments + if (lookbackPeriods <= 1) + { + throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, + "Lookback periods must be greater than 1 for MFI."); + } + } } diff --git a/src/m-r/Obv/Obv.Api.cs b/src/m-r/Obv/Obv.Api.cs deleted file mode 100644 index a34e329f9..000000000 --- a/src/m-r/Obv/Obv.Api.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Skender.Stock.Indicators; - -// ON-BALANCE VOLUME (API) -public static partial class Indicator -{ - // SERIES, from TQuote - /// - /// - public static IReadOnlyList ToObv( - this IReadOnlyList quotes) - where TQuote : IQuote => quotes - .ToQuoteDList() - .CalcObv(); -} diff --git a/src/m-r/Obv/Obv.StaticSeries.cs b/src/m-r/Obv/Obv.StaticSeries.cs index 9c9754eec..d4bf3cd61 100644 --- a/src/m-r/Obv/Obv.StaticSeries.cs +++ b/src/m-r/Obv/Obv.StaticSeries.cs @@ -2,8 +2,14 @@ namespace Skender.Stock.Indicators; // ON-BALANCE VOLUME (SERIES) -public static partial class Indicator +public static partial class Obv { + public static IReadOnlyList ToObv( + this IReadOnlyList quotes) + where TQuote : IQuote => quotes + .ToQuoteDList() + .CalcObv(); + private static List CalcObv( this List source) { diff --git a/src/m-r/ParabolicSar/ParabolicSar.Api.cs b/src/m-r/ParabolicSar/ParabolicSar.Api.cs deleted file mode 100644 index 27c9527ac..000000000 --- a/src/m-r/ParabolicSar/ParabolicSar.Api.cs +++ /dev/null @@ -1,34 +0,0 @@ -namespace Skender.Stock.Indicators; - -// PARABOLIC SAR (API) -public static partial class Indicator -{ - // SERIES, from TQuote - /// - /// - public static IReadOnlyList ToParabolicSar( - this IReadOnlyList quotes, - double accelerationStep = 0.02, - double maxAccelerationFactor = 0.2) - where TQuote : IQuote => quotes - .ToQuoteDList() - .CalcParabolicSar( - accelerationStep, - maxAccelerationFactor, - accelerationStep); - - // SERIES, from TQuote (alt) - /// - /// - public static IReadOnlyList GetParabolicSar( - this IReadOnlyList quotes, - double accelerationStep, - double maxAccelerationFactor, - double initialFactor) - where TQuote : IQuote => quotes - .ToQuoteDList() - .CalcParabolicSar( - accelerationStep, - maxAccelerationFactor, - initialFactor); -} diff --git a/src/m-r/ParabolicSar/ParabolicSar.Common.cs b/src/m-r/ParabolicSar/ParabolicSar.Common.cs deleted file mode 100644 index e6a51ab8a..000000000 --- a/src/m-r/ParabolicSar/ParabolicSar.Common.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System.Globalization; - -namespace Skender.Stock.Indicators; - -// PARABOLIC SAR (COMMON) - -public static class ParabolicSar -{ - private static readonly CultureInfo EnglishCulture = new("en-US", false); - - // parameter validation - internal static void Validate( - double accelerationStep, - double maxAccelerationFactor, - double initialFactor) - { - // check parameter arguments - if (accelerationStep <= 0) - { - throw new ArgumentOutOfRangeException(nameof(accelerationStep), accelerationStep, - "Acceleration Step must be greater than 0 for Parabolic SAR."); - } - - if (maxAccelerationFactor <= 0) - { - throw new ArgumentOutOfRangeException(nameof(maxAccelerationFactor), maxAccelerationFactor, - "Max Acceleration Factor must be greater than 0 for Parabolic SAR."); - } - - if (accelerationStep > maxAccelerationFactor) - { - string message = string.Format( - EnglishCulture, - "Acceleration Step cannot be larger than the Max Acceleration Factor ({0}) for Parabolic SAR.", - maxAccelerationFactor); - - throw new ArgumentOutOfRangeException(nameof(accelerationStep), accelerationStep, message); - } - - if (initialFactor <= 0 || initialFactor > maxAccelerationFactor) - { - throw new ArgumentOutOfRangeException(nameof(initialFactor), initialFactor, - "Initial Factor must be greater than 0 and not larger than Max Acceleration Factor for Parabolic SAR."); - } - } - -} diff --git a/src/m-r/ParabolicSar/ParabolicSar.StaticSeries.cs b/src/m-r/ParabolicSar/ParabolicSar.StaticSeries.cs index 4016fea11..99c3e9da0 100644 --- a/src/m-r/ParabolicSar/ParabolicSar.StaticSeries.cs +++ b/src/m-r/ParabolicSar/ParabolicSar.StaticSeries.cs @@ -2,8 +2,31 @@ namespace Skender.Stock.Indicators; // PARABOLIC SAR (SERIES) -public static partial class Indicator +public static partial class ParabolicSar { + public static IReadOnlyList ToParabolicSar( + this IReadOnlyList quotes, + double accelerationStep = 0.02, + double maxAccelerationFactor = 0.2) + where TQuote : IQuote => quotes + .ToQuoteDList() + .CalcParabolicSar( + accelerationStep, + maxAccelerationFactor, + accelerationStep); + + public static IReadOnlyList GetParabolicSar( + this IReadOnlyList quotes, + double accelerationStep, + double maxAccelerationFactor, + double initialFactor) + where TQuote : IQuote => quotes + .ToQuoteDList() + .CalcParabolicSar( + accelerationStep, + maxAccelerationFactor, + initialFactor); + private static List CalcParabolicSar( this List source, double accelerationStep, diff --git a/src/m-r/ParabolicSar/ParabolicSar.Utilities.cs b/src/m-r/ParabolicSar/ParabolicSar.Utilities.cs index b9d229d71..afa732021 100644 --- a/src/m-r/ParabolicSar/ParabolicSar.Utilities.cs +++ b/src/m-r/ParabolicSar/ParabolicSar.Utilities.cs @@ -1,16 +1,46 @@ +using System.Globalization; + namespace Skender.Stock.Indicators; -public static partial class Indicator +// PARABOLIC SAR (UTILITIES) + +public static partial class ParabolicSar { - // remove recommended periods - /// - public static IReadOnlyList RemoveWarmupPeriods( - this IReadOnlyList results) + private static readonly CultureInfo invariantCulture = CultureInfo.InvariantCulture; + + // parameter validation + internal static void Validate( + double accelerationStep, + double maxAccelerationFactor, + double initialFactor) { - int removePeriods = results - .ToList() - .FindIndex(x => x.Sar != null); + // check parameter arguments + if (accelerationStep <= 0) + { + throw new ArgumentOutOfRangeException(nameof(accelerationStep), accelerationStep, + "Acceleration Step must be greater than 0 for Parabolic SAR."); + } + + if (maxAccelerationFactor <= 0) + { + throw new ArgumentOutOfRangeException(nameof(maxAccelerationFactor), maxAccelerationFactor, + "Max Acceleration Factor must be greater than 0 for Parabolic SAR."); + } + + if (accelerationStep > maxAccelerationFactor) + { + string message = string.Format( + invariantCulture, + "Acceleration Step cannot be larger than the Max Acceleration Factor ({0}) for Parabolic SAR.", + maxAccelerationFactor); + + throw new ArgumentOutOfRangeException(nameof(accelerationStep), accelerationStep, message); + } - return results.Remove(removePeriods); + if (initialFactor <= 0 || initialFactor > maxAccelerationFactor) + { + throw new ArgumentOutOfRangeException(nameof(initialFactor), initialFactor, + "Initial Factor must be greater than 0 and not larger than Max Acceleration Factor for Parabolic SAR."); + } } } diff --git a/src/m-r/PivotPoints/PivotPoints.Api.cs b/src/m-r/PivotPoints/PivotPoints.Api.cs deleted file mode 100644 index 72caf4131..000000000 --- a/src/m-r/PivotPoints/PivotPoints.Api.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace Skender.Stock.Indicators; - -// PIVOT POINTS (API) -public static partial class Indicator -{ - // SERIES, from TQuote - /// - /// - public static IReadOnlyList ToPivotPoints( - this IReadOnlyList quotes, - PeriodSize windowSize, - PivotPointType pointType = PivotPointType.Standard) - where TQuote : IQuote => quotes - .ToSortedList() - .CalcPivotPoints(windowSize, pointType); -} diff --git a/src/m-r/PivotPoints/PivotPoints.StaticSeries.cs b/src/m-r/PivotPoints/PivotPoints.StaticSeries.cs index 058649e93..7b540b12f 100644 --- a/src/m-r/PivotPoints/PivotPoints.StaticSeries.cs +++ b/src/m-r/PivotPoints/PivotPoints.StaticSeries.cs @@ -2,16 +2,18 @@ namespace Skender.Stock.Indicators; // PIVOT POINTS (SERIES) -public static partial class Indicator +public static partial class PivotPoints { - private static List CalcPivotPoints( - this List quotesList, + public static IReadOnlyList ToPivotPoints( + this IReadOnlyList quotes, PeriodSize windowSize, - PivotPointType pointType) + PivotPointType pointType = PivotPointType.Standard) where TQuote : IQuote { + ArgumentNullException.ThrowIfNull(quotes); + // initialize - int length = quotesList.Count; + int length = quotes.Count; List results = new(length); WindowPoint windowPoint = new(); @@ -21,7 +23,7 @@ private static List CalcPivotPoints( return results; } - TQuote h0 = quotesList[0]; + TQuote h0 = quotes[0]; int windowId = GetWindowNumber(h0.Timestamp, windowSize); @@ -35,7 +37,7 @@ private static List CalcPivotPoints( // roll through source values for (int i = 0; i < length; i++) { - TQuote q = quotesList[i]; + TQuote q = quotes[i]; // new window evaluation int windowEval = GetWindowNumber(q.Timestamp, windowSize); @@ -97,7 +99,43 @@ PivotPointsResult r return results; } - // internals + // pivot point lookup + internal static WindowPoint GetPivotPoint( + PivotPointType pointType, decimal open, decimal high, decimal low, decimal close) + => pointType switch { + + PivotPointType.Standard => GetPivotPointStandard(high, low, close), + PivotPointType.Camarilla => GetPivotPointCamarilla(high, low, close), + PivotPointType.Demark => GetPivotPointDemark(open, high, low, close), + PivotPointType.Fibonacci => GetPivotPointFibonacci(high, low, close), + PivotPointType.Woodie => GetPivotPointWoodie(open, high, low), + + _ => throw new ArgumentOutOfRangeException( + nameof(pointType), pointType, "Invalid pointType provided.") + }; + + // window size lookup + private static int GetWindowNumber(DateTime d, PeriodSize windowSize) + => windowSize switch { + + PeriodSize.Month => d.Month, + + PeriodSize.Week => calendar.GetWeekOfYear( + d, calendarWeekRule, firstDayOfWeek), + + PeriodSize.Day => d.Day, + PeriodSize.OneHour => d.Hour, + + _ => throw new ArgumentOutOfRangeException( + nameof(windowSize), windowSize, + string.Format( + invariantCulture, + "Pivot Points does not support PeriodSize of {0}. " + + "See documentation for valid options.", + Enum.GetName(typeof(PeriodSize), windowSize))) + }; + + // pivot point variants private static WindowPoint GetPivotPointStandard( decimal high, decimal low, decimal close) { @@ -105,12 +143,12 @@ private static WindowPoint GetPivotPointStandard( return new() { PP = pp, - S1 = pp * 2 - high, + S1 = (pp * 2) - high, S2 = pp - (high - low), - S3 = low - 2 * (high - pp), - R1 = pp * 2 - low, + S3 = low - (2 * (high - pp)), + R1 = (pp * 2) - low, R2 = pp + (high - low), - R3 = high + 2 * (pp - low) + R3 = high + (2 * (pp - low)) }; } @@ -118,29 +156,29 @@ private static WindowPoint GetPivotPointCamarilla( decimal high, decimal low, decimal close) => new() { PP = close, - S1 = close - 1.1m / 12 * (high - low), - S2 = close - 1.1m / 6 * (high - low), - S3 = close - 1.1m / 4 * (high - low), - S4 = close - 1.1m / 2 * (high - low), - R1 = close + 1.1m / 12 * (high - low), - R2 = close + 1.1m / 6 * (high - low), - R3 = close + 1.1m / 4 * (high - low), - R4 = close + 1.1m / 2 * (high - low) + S1 = close - (1.1m / 12 * (high - low)), + S2 = close - (1.1m / 6 * (high - low)), + S3 = close - (1.1m / 4 * (high - low)), + S4 = close - (1.1m / 2 * (high - low)), + R1 = close + (1.1m / 12 * (high - low)), + R2 = close + (1.1m / 6 * (high - low)), + R3 = close + (1.1m / 4 * (high - low)), + R4 = close + (1.1m / 2 * (high - low)) }; internal static WindowPoint GetPivotPointDemark( decimal open, decimal high, decimal low, decimal close) { decimal x = close < open - ? high + 2 * low + close + ? high + (2 * low) + close : close > open - ? 2 * high + low + close - : high + low + 2 * close; + ? (2 * high) + low + close + : high + low + (2 * close); return new() { PP = x / 4, - S1 = x / 2 - high, - R1 = x / 2 - low + S1 = (x / 2) - high, + R1 = (x / 2) - low }; } @@ -151,64 +189,28 @@ private static WindowPoint GetPivotPointFibonacci( return new() { PP = pp, - S1 = pp - 0.382m * (high - low), - S2 = pp - 0.618m * (high - low), - S3 = pp - 1.000m * (high - low), - R1 = pp + 0.382m * (high - low), - R2 = pp + 0.618m * (high - low), - R3 = pp + 1.000m * (high - low) + S1 = pp - (0.382m * (high - low)), + S2 = pp - (0.618m * (high - low)), + S3 = pp - (1.000m * (high - low)), + R1 = pp + (0.382m * (high - low)), + R2 = pp + (0.618m * (high - low)), + R3 = pp + (1.000m * (high - low)) }; } private static WindowPoint GetPivotPointWoodie( decimal currentOpen, decimal high, decimal low) { - decimal pp = (high + low + 2 * currentOpen) / 4; + decimal pp = (high + low + (2 * currentOpen)) / 4; return new() { PP = pp, - S1 = pp * 2 - high, + S1 = (pp * 2) - high, S2 = pp - high + low, - S3 = low - 2 * (high - pp), - R1 = pp * 2 - low, + S3 = low - (2 * (high - pp)), + R1 = (pp * 2) - low, R2 = pp + high - low, - R3 = high + 2 * (pp - low) + R3 = high + (2 * (pp - low)) }; } - - // pivot type lookup - private static WindowPoint GetPivotPoint( - PivotPointType pointType, decimal open, decimal high, decimal low, decimal close) - => pointType switch { - - PivotPointType.Standard => GetPivotPointStandard(high, low, close), - PivotPointType.Camarilla => GetPivotPointCamarilla(high, low, close), - PivotPointType.Demark => GetPivotPointDemark(open, high, low, close), - PivotPointType.Fibonacci => GetPivotPointFibonacci(high, low, close), - PivotPointType.Woodie => GetPivotPointWoodie(open, high, low), - - _ => throw new ArgumentOutOfRangeException( - nameof(pointType), pointType, "Invalid pointType provided.") - }; - - // window size lookup - private static int GetWindowNumber(DateTime d, PeriodSize windowSize) - => windowSize switch { - - PeriodSize.Month => d.Month, - - PeriodSize.Week => invCalendar.GetWeekOfYear( - d, invCalendarWeekRule, invFirstDayOfWeek), - - PeriodSize.Day => d.Day, - PeriodSize.OneHour => d.Hour, - - _ => throw new ArgumentOutOfRangeException( - nameof(windowSize), windowSize, - string.Format( - invCulture, - "Pivot Points does not support PeriodSize of {0}. " + - "See documentation for valid options.", - Enum.GetName(typeof(PeriodSize), windowSize))) - }; } diff --git a/src/m-r/PivotPoints/PivotPoints.Utilities.cs b/src/m-r/PivotPoints/PivotPoints.Utilities.cs index cd80c9b43..c562b0da9 100644 --- a/src/m-r/PivotPoints/PivotPoints.Utilities.cs +++ b/src/m-r/PivotPoints/PivotPoints.Utilities.cs @@ -1,15 +1,29 @@ +using System.Globalization; + namespace Skender.Stock.Indicators; // PIVOT POINTS (UTILITIES) -public static partial class Indicator + +public static partial class PivotPoints { + private static readonly CultureInfo invariantCulture = CultureInfo.InvariantCulture; + + private static readonly Calendar calendar = invariantCulture.Calendar; + + // Gets the DTFI properties required by GetWeekOfYear. + private static readonly CalendarWeekRule calendarWeekRule + = invariantCulture.DateTimeFormat.CalendarWeekRule; + + private static readonly DayOfWeek firstDayOfWeek + = invariantCulture.DateTimeFormat.FirstDayOfWeek; + // remove recommended periods /// public static IReadOnlyList RemoveWarmupPeriods( this IReadOnlyList results) { int removePeriods = results - .ToList() + .ToList() // TODO: is there a no-copy way to do this? Many places. .FindIndex(x => x.PP != null); return results.Remove(removePeriods); diff --git a/src/m-r/Pmo/Pmo.Api.cs b/src/m-r/Pmo/Pmo.Api.cs deleted file mode 100644 index fcf815367..000000000 --- a/src/m-r/Pmo/Pmo.Api.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace Skender.Stock.Indicators; - -// PRICE MOMENTUM OSCILLATOR (API) -public static partial class Indicator -{ - // SERIES, from CHAIN - public static IReadOnlyList ToPmo( - this IReadOnlyList results, - int timePeriods = 35, - int smoothPeriods = 20, - int signalPeriods = 10) - where T : IReusable - => results - .ToSortedList() - .CalcPmo(timePeriods, smoothPeriods, signalPeriods); -} diff --git a/src/m-r/Pmo/Pmo.Common.cs b/src/m-r/Pmo/Pmo.Common.cs deleted file mode 100644 index 1fab8c121..000000000 --- a/src/m-r/Pmo/Pmo.Common.cs +++ /dev/null @@ -1,33 +0,0 @@ -namespace Skender.Stock.Indicators; - -// PRICE MOMENTUM OSCILLATOR (COMMON) - -public static class Pmo -{ - // parameter validation - internal static void Validate( - int timePeriods, - int smoothPeriods, - int signalPeriods) - { - // check parameter arguments - if (timePeriods <= 1) - { - throw new ArgumentOutOfRangeException(nameof(timePeriods), timePeriods, - "Time periods must be greater than 1 for PMO."); - } - - if (smoothPeriods <= 0) - { - throw new ArgumentOutOfRangeException(nameof(smoothPeriods), smoothPeriods, - "Smoothing periods must be greater than 0 for PMO."); - } - - if (signalPeriods <= 0) - { - throw new ArgumentOutOfRangeException(nameof(signalPeriods), signalPeriods, - "Signal periods must be greater than 0 for PMO."); - } - } - -} diff --git a/src/m-r/Pmo/Pmo.StaticSeries.cs b/src/m-r/Pmo/Pmo.StaticSeries.cs index adaffec49..feaea3a64 100644 --- a/src/m-r/Pmo/Pmo.StaticSeries.cs +++ b/src/m-r/Pmo/Pmo.StaticSeries.cs @@ -2,17 +2,18 @@ namespace Skender.Stock.Indicators; // PRICE MOMENTUM OSCILLATOR (SERIES) -public static partial class Indicator +public static partial class Pmo { - private static List CalcPmo( - this List source, - int timePeriods, - int smoothPeriods, - int signalPeriods) + public static IReadOnlyList ToPmo( + this IReadOnlyList source, + int timePeriods = 35, + int smoothPeriods = 20, + int signalPeriods = 10) where T : IReusable { // check parameter arguments - Pmo.Validate(timePeriods, smoothPeriods, signalPeriods); + ArgumentNullException.ThrowIfNull(source); + Validate(timePeriods, smoothPeriods, signalPeriods); // initialize int length = source.Count; @@ -36,7 +37,7 @@ private static List CalcPmo( T s = source[i]; // rate of change (ROC) - rc[i] = prevPrice == 0 ? double.NaN : 100 * (s.Value / prevPrice - 1); + rc[i] = prevPrice == 0 ? double.NaN : 100 * ((s.Value / prevPrice) - 1); prevPrice = s.Value; // ROC smoothed moving average @@ -53,7 +54,7 @@ private static List CalcPmo( } else { - rocEma = prevRocEma + smoothingConstant2 * (rc[i] - prevRocEma); + rocEma = prevRocEma + (smoothingConstant2 * (rc[i] - prevRocEma)); } re[i] = rocEma * 10; @@ -73,7 +74,7 @@ private static List CalcPmo( } else { - pmo = prevPmo + smoothingConstant1 * (re[i] - prevPmo); + pmo = prevPmo + (smoothingConstant1 * (re[i] - prevPmo)); } prevPmo = pm[i] = pmo; diff --git a/src/m-r/Pmo/Pmo.Utilities.cs b/src/m-r/Pmo/Pmo.Utilities.cs index b4e97ee07..3ca068f94 100644 --- a/src/m-r/Pmo/Pmo.Utilities.cs +++ b/src/m-r/Pmo/Pmo.Utilities.cs @@ -1,6 +1,8 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// PRICE MOMENTUM OSCILLATOR (UTILITIES) + +public static partial class Pmo { // remove recommended periods /// @@ -13,4 +15,30 @@ public static IReadOnlyList RemoveWarmupPeriods( return results.Remove(ts + 250); } + + // parameter validation + internal static void Validate( + int timePeriods, + int smoothPeriods, + int signalPeriods) + { + // check parameter arguments + if (timePeriods <= 1) + { + throw new ArgumentOutOfRangeException(nameof(timePeriods), timePeriods, + "Time periods must be greater than 1 for PMO."); + } + + if (smoothPeriods <= 0) + { + throw new ArgumentOutOfRangeException(nameof(smoothPeriods), smoothPeriods, + "Smoothing periods must be greater than 0 for PMO."); + } + + if (signalPeriods <= 0) + { + throw new ArgumentOutOfRangeException(nameof(signalPeriods), signalPeriods, + "Signal periods must be greater than 0 for PMO."); + } + } } diff --git a/src/m-r/Prs/Prs.Api.cs b/src/m-r/Prs/Prs.Api.cs deleted file mode 100644 index 347e0709a..000000000 --- a/src/m-r/Prs/Prs.Api.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace Skender.Stock.Indicators; - -// PRICE RELATIVE STRENGTH (API) -public static partial class Indicator -{ - // SERIES, from CHAINS (both inputs reusable) - public static IReadOnlyList ToPrs( - this IEnumerable quotesEval, - IEnumerable quotesBase, - int? lookbackPeriods = null) - where T : IReusable - => CalcPrs( - quotesEval.ToSortedList(), - quotesBase.ToSortedList(), - lookbackPeriods); -} diff --git a/src/m-r/Prs/Prs.StaticSeries.cs b/src/m-r/Prs/Prs.StaticSeries.cs index 197590345..40a6ab70d 100644 --- a/src/m-r/Prs/Prs.StaticSeries.cs +++ b/src/m-r/Prs/Prs.StaticSeries.cs @@ -2,31 +2,33 @@ namespace Skender.Stock.Indicators; // PRICE RELATIVE STRENGTH (SERIES) -public static partial class Indicator +public static partial class Prs { - private static List CalcPrs( - List listEval, - List listBase, + public static IReadOnlyList ToPrs( + this IReadOnlyList sourceEval, + IReadOnlyList sourceBase, int? lookbackPeriods = null) where T : IReusable { // check parameter arguments - Prs.Validate(listEval, listBase, lookbackPeriods); + ArgumentNullException.ThrowIfNull(sourceEval); + ArgumentNullException.ThrowIfNull(sourceBase); + Validate(sourceEval, sourceBase, lookbackPeriods); // initialize - int length = listEval.Count; + int length = sourceEval.Count; List results = new(length); // roll through source values for (int i = 0; i < length; i++) { - T b = listBase[i]; - T e = listEval[i]; + T b = sourceBase[i]; + T e = sourceEval[i]; if (e.Timestamp != b.Timestamp) { throw new InvalidQuotesException( - nameof(listEval), e.Timestamp, + nameof(sourceEval), e.Timestamp, "Timestamp sequence does not match. " + "Price Relative requires matching dates in provided histories."); } @@ -35,8 +37,8 @@ private static List CalcPrs( if (lookbackPeriods is not null && i > lookbackPeriods - 1) { - T bo = listBase[i - (int)lookbackPeriods]; - T eo = listEval[i - (int)lookbackPeriods]; + T bo = sourceBase[i - (int)lookbackPeriods]; + T eo = sourceEval[i - (int)lookbackPeriods]; if (bo.Value != 0 && eo.Value != 0) { diff --git a/src/m-r/Prs/Prs.Common.cs b/src/m-r/Prs/Prs.Utilities.cs similarity index 80% rename from src/m-r/Prs/Prs.Common.cs rename to src/m-r/Prs/Prs.Utilities.cs index 55e71e8ee..497f2e649 100644 --- a/src/m-r/Prs/Prs.Common.cs +++ b/src/m-r/Prs/Prs.Utilities.cs @@ -2,18 +2,18 @@ namespace Skender.Stock.Indicators; -// PRICE RELATIVE STRENGTH (COMMON) +// PRICE RELATIVE STRENGTH (UTILITIES) -public static class Prs +public static partial class Prs { - private static readonly CultureInfo EnglishCulture = new("en-US", false); + private static readonly CultureInfo invariantCulture = CultureInfo.InvariantCulture; // parameter validation internal static void Validate( - List quotesEval, - List quotesBase, + IReadOnlyList quotesEval, + IReadOnlyList quotesBase, int? lookbackPeriods) - where T : ISeries + where T : IReusable { // check parameter arguments if (lookbackPeriods is <= 0) @@ -31,7 +31,7 @@ internal static void Validate( { string message = "Insufficient quotes provided for Price Relative Strength. " + string.Format( - EnglishCulture, + invariantCulture, "You provided {0} periods of quotes when at least {1} are required.", qtyHistoryEval, lookbackPeriods); diff --git a/src/m-r/Pvo/Pvo.Api.cs b/src/m-r/Pvo/Pvo.Api.cs deleted file mode 100644 index 0238806eb..000000000 --- a/src/m-r/Pvo/Pvo.Api.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace Skender.Stock.Indicators; - -// PRICE VOLUME OSCILLATOR (API) -public static partial class Indicator -{ - // SERIES, from TQuote - /// - /// - public static IReadOnlyList ToPvo( - this IReadOnlyList quotes, - int fastPeriods = 12, - int slowPeriods = 26, - int signalPeriods = 9) - where TQuote : IQuote => quotes - .Use(CandlePart.Volume) - .ToList() - .CalcPvo(fastPeriods, slowPeriods, signalPeriods); - - // given that this is volume-based, other chaining is moot -} diff --git a/src/m-r/Pvo/Pvo.Common.cs b/src/m-r/Pvo/Pvo.Common.cs deleted file mode 100644 index 8119da987..000000000 --- a/src/m-r/Pvo/Pvo.Common.cs +++ /dev/null @@ -1,33 +0,0 @@ -namespace Skender.Stock.Indicators; - -// PRICE VOLUME OSCILLATOR (COMMON) - -public static class Pvo -{ - // parameter validation - internal static void Validate( - int fastPeriods, - int slowPeriods, - int signalPeriods) - { - // check parameter arguments - if (fastPeriods <= 0) - { - throw new ArgumentOutOfRangeException(nameof(fastPeriods), fastPeriods, - "Fast periods must be greater than 0 for PVO."); - } - - if (signalPeriods < 0) - { - throw new ArgumentOutOfRangeException(nameof(signalPeriods), signalPeriods, - "Signal periods must be greater than or equal to 0 for PVO."); - } - - if (slowPeriods <= fastPeriods) - { - throw new ArgumentOutOfRangeException(nameof(slowPeriods), slowPeriods, - "Slow periods must be greater than the fast period for PVO."); - } - } - -} diff --git a/src/m-r/Pvo/Pvo.StaticSeries.cs b/src/m-r/Pvo/Pvo.StaticSeries.cs index eff18d84b..4f02630e7 100644 --- a/src/m-r/Pvo/Pvo.StaticSeries.cs +++ b/src/m-r/Pvo/Pvo.StaticSeries.cs @@ -2,17 +2,26 @@ namespace Skender.Stock.Indicators; // PRICE VOLUME OSCILLATOR (SERIES) -public static partial class Indicator +public static partial class Pvo { + public static IReadOnlyList ToPvo( + this IReadOnlyList quotes, + int fastPeriods = 12, + int slowPeriods = 26, + int signalPeriods = 9) + where TQuote : IQuote => quotes + .Use(CandlePart.Volume) + .CalcPvo(fastPeriods, slowPeriods, signalPeriods); + private static List CalcPvo( - this List source, // volume + this IReadOnlyList source, // volume int fastPeriods, int slowPeriods, int signalPeriods) where T : IReusable { // check parameter arguments - Pvo.Validate(fastPeriods, slowPeriods, signalPeriods); + Validate(fastPeriods, slowPeriods, signalPeriods); // initialize int length = source.Count; diff --git a/src/m-r/Pvo/Pvo.Utilities.cs b/src/m-r/Pvo/Pvo.Utilities.cs index d5fffbcb0..3731ccb5d 100644 --- a/src/m-r/Pvo/Pvo.Utilities.cs +++ b/src/m-r/Pvo/Pvo.Utilities.cs @@ -1,6 +1,8 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// PRICE VOLUME OSCILLATOR (UTILITIES) + +public static partial class Pvo { // remove recommended periods /// @@ -13,4 +15,30 @@ public static IReadOnlyList RemoveWarmupPeriods( return results.Remove(n + 250); } + + // parameter validation + internal static void Validate( + int fastPeriods, + int slowPeriods, + int signalPeriods) + { + // check parameter arguments + if (fastPeriods <= 0) + { + throw new ArgumentOutOfRangeException(nameof(fastPeriods), fastPeriods, + "Fast periods must be greater than 0 for PVO."); + } + + if (signalPeriods < 0) + { + throw new ArgumentOutOfRangeException(nameof(signalPeriods), signalPeriods, + "Signal periods must be greater than or equal to 0 for PVO."); + } + + if (slowPeriods <= fastPeriods) + { + throw new ArgumentOutOfRangeException(nameof(slowPeriods), slowPeriods, + "Slow periods must be greater than the fast period for PVO."); + } + } } diff --git a/src/m-r/Renko/Renko.Api.cs b/src/m-r/Renko/Renko.Api.cs deleted file mode 100644 index 177fa9f3e..000000000 --- a/src/m-r/Renko/Renko.Api.cs +++ /dev/null @@ -1,23 +0,0 @@ -namespace Skender.Stock.Indicators; - -// RENKO CHART (API) - -public static partial class Renko -{ - // SERIES, from TQuote - public static IReadOnlyList ToRenko( - this IReadOnlyList quotes, - decimal brickSize, - EndType endType = EndType.Close) - where TQuote : IQuote => quotes - .ToSortedList() - .CalcRenko(brickSize, endType); - - // OBSERVER, from Quote Provider - public static RenkoHub ToRenko( - this IQuoteProvider quoteProvider, - decimal brickSize, - EndType endType = EndType.Close) - where TIn : IQuote - => new(quoteProvider, brickSize, endType); -} diff --git a/src/m-r/Renko/Renko.StaticSeries.cs b/src/m-r/Renko/Renko.StaticSeries.cs index 89c95cd8d..6aaa45bc5 100644 --- a/src/m-r/Renko/Renko.StaticSeries.cs +++ b/src/m-r/Renko/Renko.StaticSeries.cs @@ -4,17 +4,18 @@ namespace Skender.Stock.Indicators; public static partial class Renko { - internal static List CalcRenko( - this List quotesList, + public static IReadOnlyList ToRenko( + this IReadOnlyList quotes, decimal brickSize, - EndType endType) + EndType endType = EndType.Close) where TQuote : IQuote { // check parameter arguments + ArgumentNullException.ThrowIfNull(quotes); Validate(brickSize); // initialize - int length = quotesList.Count; + int length = quotes.Count; List results = new(length); if (length == 0) @@ -23,7 +24,7 @@ internal static List CalcRenko( } // first brick baseline - TQuote q0 = quotesList[0]; + TQuote q0 = quotes[0]; int decimals = brickSize.GetDecimalPlaces(); decimal baseline = Math.Round(q0.Close, Math.Max(decimals - 1, 0)); @@ -41,7 +42,7 @@ internal static List CalcRenko( // roll through source values for (int i = 1; i < length; i++) { - TQuote q = quotesList[i]; + TQuote q = quotes[i]; // track high/low/volume between bricks h = Math.Max(h, q.High); diff --git a/src/m-r/Renko/Renko.StreamHub.cs b/src/m-r/Renko/Renko.StreamHub.cs index 0ffc4e3b2..8486bf51f 100644 --- a/src/m-r/Renko/Renko.StreamHub.cs +++ b/src/m-r/Renko/Renko.StreamHub.cs @@ -2,13 +2,23 @@ namespace Skender.Stock.Indicators; // RENKO CHART (STREAM HUB) -#region hub interface +#region hub interface and initializer public interface IRenkoHub { decimal BrickSize { get; } EndType EndType { get; } } + +public static partial class Renko +{ + public static RenkoHub ToRenko( + this IQuoteProvider quoteProvider, + decimal brickSize, + EndType endType = EndType.Close) + where TIn : IQuote + => new(quoteProvider, brickSize, endType); +} #endregion public class RenkoHub diff --git a/src/m-r/RenkoAtr/RenkoAtr.Api.cs b/src/m-r/RenkoAtr/RenkoAtr.Api.cs deleted file mode 100644 index 72fd61676..000000000 --- a/src/m-r/RenkoAtr/RenkoAtr.Api.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Skender.Stock.Indicators; - -// RENKO CHART - ATR (API) -public static partial class RenkoAtr -{ - public static IReadOnlyList GetRenkoAtr( - this IReadOnlyList quotes, - int atrPeriods, - EndType endType = EndType.Close) - where TQuote : IQuote => quotes - .ToSortedList() - .CalcRenkoAtr(atrPeriods, endType); -} diff --git a/src/m-r/RenkoAtr/RenkoAtr.StaticSeries.cs b/src/m-r/RenkoAtr/RenkoAtr.StaticSeries.cs index 142191b05..479278122 100644 --- a/src/m-r/RenkoAtr/RenkoAtr.StaticSeries.cs +++ b/src/m-r/RenkoAtr/RenkoAtr.StaticSeries.cs @@ -2,16 +2,16 @@ namespace Skender.Stock.Indicators; // RENKO CHART - ATR (SERIES) -public static partial class RenkoAtr +public static partial class Renko { - private static List CalcRenkoAtr( - this List quotesList, + public static IReadOnlyList GetRenkoAtr( + this IReadOnlyList quotes, int atrPeriods, EndType endType = EndType.Close) where TQuote : IQuote { // initialize - List atrResults = quotesList + List atrResults = quotes .ToQuoteDList() .CalcAtr(atrPeriods); @@ -20,6 +20,6 @@ private static List CalcRenkoAtr( return brickSize == 0 ? [] - : quotesList.CalcRenko(brickSize, endType); + : quotes.ToRenko(brickSize, endType); } } diff --git a/src/m-r/Roc/Roc.Api.cs b/src/m-r/Roc/Roc.Api.cs deleted file mode 100644 index 43fda5055..000000000 --- a/src/m-r/Roc/Roc.Api.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Skender.Stock.Indicators; - -// RATE OF CHANGE (API) -public static partial class Indicator -{ - // SERIES, from CHAIN - public static IReadOnlyList ToRoc( - this IReadOnlyList results, - int lookbackPeriods) - where T : IReusable - => results - .ToSortedList() - .CalcRoc(lookbackPeriods); -} diff --git a/src/m-r/Roc/Roc.Common.cs b/src/m-r/Roc/Roc.Common.cs deleted file mode 100644 index 3c3131afc..000000000 --- a/src/m-r/Roc/Roc.Common.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Skender.Stock.Indicators; - -// RATE OF CHANGE (COMMON) - -public static class Roc -{ - // parameter validation - internal static void Validate( - int lookbackPeriods) - { - // check parameter arguments - if (lookbackPeriods <= 0) - { - throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, - "Lookback periods must be greater than 0 for ROC."); - } - } - -} diff --git a/src/m-r/Roc/Roc.StaticSeries.cs b/src/m-r/Roc/Roc.StaticSeries.cs index 570fbdc44..aacfbf368 100644 --- a/src/m-r/Roc/Roc.StaticSeries.cs +++ b/src/m-r/Roc/Roc.StaticSeries.cs @@ -2,15 +2,16 @@ namespace Skender.Stock.Indicators; // RATE OF CHANGE (SERIES) -public static partial class Indicator +public static partial class Roc { - private static List CalcRoc( - this List source, + public static IReadOnlyList ToRoc( + this IReadOnlyList source, int lookbackPeriods) where T : IReusable { // check parameter arguments - Roc.Validate(lookbackPeriods); + ArgumentNullException.ThrowIfNull(source); + Validate(lookbackPeriods); // initialize int length = source.Count; diff --git a/src/m-r/Roc/Roc.Utilities.cs b/src/m-r/Roc/Roc.Utilities.cs index d39e40061..2256c42ec 100644 --- a/src/m-r/Roc/Roc.Utilities.cs +++ b/src/m-r/Roc/Roc.Utilities.cs @@ -1,16 +1,18 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// RATE OF CHANGE (UTILITIES) + +public static partial class Roc { - // remove recommended periods - /// - public static IReadOnlyList RemoveWarmupPeriods( - this IReadOnlyList results) + // parameter validation + internal static void Validate( + int lookbackPeriods) { - int removePeriods = results - .ToList() - .FindIndex(x => x.Roc != null); - - return results.Remove(removePeriods); + // check parameter arguments + if (lookbackPeriods <= 0) + { + throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, + "Lookback periods must be greater than 0 for ROC."); + } } } diff --git a/src/m-r/RocWb/RocWb.Api.cs b/src/m-r/RocWb/RocWb.Api.cs deleted file mode 100644 index 94f3e65c9..000000000 --- a/src/m-r/RocWb/RocWb.Api.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace Skender.Stock.Indicators; - -// RATE OF CHANGE (ROC) WITH BANDS (API) -public static partial class Indicator -{ - // SERIES, from CHAIN - public static IReadOnlyList ToRocWb( - this IReadOnlyList results, - int lookbackPeriods, - int emaPeriods, - int stdDevPeriods) - where T : IReusable - => results - .ToSortedList() - .CalcRocWb(lookbackPeriods, emaPeriods, stdDevPeriods); -} diff --git a/src/m-r/RocWb/RocWb.Common.cs b/src/m-r/RocWb/RocWb.Common.cs deleted file mode 100644 index 6178f926b..000000000 --- a/src/m-r/RocWb/RocWb.Common.cs +++ /dev/null @@ -1,33 +0,0 @@ -namespace Skender.Stock.Indicators; - -// RocWb (COMMON) - -public static class RocWb -{ - // parameter validation - internal static void Validate( - int lookbackPeriods, - int emaPeriods, - int stdDevPeriods) - { - // check parameter arguments - if (lookbackPeriods <= 0) - { - throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, - "Lookback periods must be greater than 0 for ROC with Bands."); - } - - if (emaPeriods <= 0) - { - throw new ArgumentOutOfRangeException(nameof(emaPeriods), emaPeriods, - "EMA periods must be greater than 0 for ROC."); - } - - if (stdDevPeriods <= 0 || stdDevPeriods > lookbackPeriods) - { - throw new ArgumentOutOfRangeException(nameof(stdDevPeriods), stdDevPeriods, - "Standard Deviation periods must be greater than 0 and less than lookback period for ROC with Bands."); - } - } - -} diff --git a/src/m-r/RocWb/RocWb.StaticSeries.cs b/src/m-r/RocWb/RocWb.StaticSeries.cs index eee59d16b..5fa46b88f 100644 --- a/src/m-r/RocWb/RocWb.StaticSeries.cs +++ b/src/m-r/RocWb/RocWb.StaticSeries.cs @@ -1,17 +1,19 @@ namespace Skender.Stock.Indicators; // RATE OF CHANGE (ROC) WITH BANDS (SERIES) -public static partial class Indicator + +public static partial class RocWb { - private static List CalcRocWb( - this List source, + public static IReadOnlyList ToRocWb( + this IReadOnlyList source, int lookbackPeriods, int emaPeriods, int stdDevPeriods) where T : IReusable { // check parameter arguments - RocWb.Validate(lookbackPeriods, emaPeriods, stdDevPeriods); + ArgumentNullException.ThrowIfNull(source); + Validate(lookbackPeriods, emaPeriods, stdDevPeriods); // initialize int length = source.Count; @@ -20,10 +22,8 @@ private static List CalcRocWb( double k = 2d / (emaPeriods + 1); double prevEma = double.NaN; - List ogRoc = source - .CalcRoc(lookbackPeriods) - .Cast() - .ToSortedList(); + IReadOnlyList ogRoc = source + .ToRoc(lookbackPeriods); double[] rocSq = ogRoc .Select(x => x.Value * x.Value) diff --git a/src/m-r/RocWb/RocWb.Utilities.cs b/src/m-r/RocWb/RocWb.Utilities.cs index 747a64928..3b94d7257 100644 --- a/src/m-r/RocWb/RocWb.Utilities.cs +++ b/src/m-r/RocWb/RocWb.Utilities.cs @@ -1,6 +1,8 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// RATE OF CHANGE (ROC) WITH BANDS (UTILITIES) + +public static partial class RocWb { // remove recommended periods /// @@ -13,4 +15,30 @@ public static IReadOnlyList RemoveWarmupPeriods( return results.Remove(n + 100); } + + // parameter validation + internal static void Validate( + int lookbackPeriods, + int emaPeriods, + int stdDevPeriods) + { + // check parameter arguments + if (lookbackPeriods <= 0) + { + throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, + "Lookback periods must be greater than 0 for ROC with Bands."); + } + + if (emaPeriods <= 0) + { + throw new ArgumentOutOfRangeException(nameof(emaPeriods), emaPeriods, + "EMA periods must be greater than 0 for ROC."); + } + + if (stdDevPeriods <= 0 || stdDevPeriods > lookbackPeriods) + { + throw new ArgumentOutOfRangeException(nameof(stdDevPeriods), stdDevPeriods, + "Standard Deviation periods must be greater than 0 and less than lookback period for ROC with Bands."); + } + } } diff --git a/src/m-r/RollingPivots/RollingPivots.Api.cs b/src/m-r/RollingPivots/RollingPivots.Api.cs deleted file mode 100644 index e9e23962a..000000000 --- a/src/m-r/RollingPivots/RollingPivots.Api.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace Skender.Stock.Indicators; - -// ROLLING PIVOT POINTS (API) -public static partial class Indicator -{ - // SERIES, from TQuote - /// - /// - public static IReadOnlyList ToRollingPivots( - this IReadOnlyList quotes, - int windowPeriods, - int offsetPeriods, - PivotPointType pointType = PivotPointType.Standard) - where TQuote : IQuote => quotes - .ToSortedList() - .CalcRollingPivots(windowPeriods, offsetPeriods, pointType); -} diff --git a/src/m-r/RollingPivots/RollingPivots.Common.cs b/src/m-r/RollingPivots/RollingPivots.Common.cs deleted file mode 100644 index d0a3c8fa4..000000000 --- a/src/m-r/RollingPivots/RollingPivots.Common.cs +++ /dev/null @@ -1,26 +0,0 @@ -namespace Skender.Stock.Indicators; - -// ROLLING PIVOT POINTS (COMMON) - -public static class RollingPivots -{ - // parameter validation - internal static void Validate( - int windowPeriods, - int offsetPeriods) - { - // check parameter arguments - if (windowPeriods <= 0) - { - throw new ArgumentOutOfRangeException(nameof(windowPeriods), windowPeriods, - "Window periods must be greater than 0 for Rolling Pivot Points."); - } - - if (offsetPeriods < 0) - { - throw new ArgumentOutOfRangeException(nameof(offsetPeriods), offsetPeriods, - "Offset periods must be greater than or equal to 0 for Rolling Pivot Points."); - } - } - -} diff --git a/src/m-r/RollingPivots/RollingPivots.StaticSeries.cs b/src/m-r/RollingPivots/RollingPivots.StaticSeries.cs index 75ba6df3b..efbc07fde 100644 --- a/src/m-r/RollingPivots/RollingPivots.StaticSeries.cs +++ b/src/m-r/RollingPivots/RollingPivots.StaticSeries.cs @@ -2,26 +2,27 @@ namespace Skender.Stock.Indicators; // ROLLING PIVOT POINTS (SERIES) -public static partial class Indicator +public static partial class RollingPivots { - private static List CalcRollingPivots( - this List quotesList, + public static IReadOnlyList ToRollingPivots( + this IReadOnlyList quotes, int windowPeriods, int offsetPeriods, - PivotPointType pointType) + PivotPointType pointType = PivotPointType.Standard) where TQuote : IQuote { // check parameter arguments - RollingPivots.Validate(windowPeriods, offsetPeriods); + ArgumentNullException.ThrowIfNull(quotes); + Validate(windowPeriods, offsetPeriods); // initialize - int length = quotesList.Count; + int length = quotes.Count; List results = new(length); // roll through source values for (int i = 0; i < length; i++) { - TQuote q = quotesList[i]; + TQuote q = quotes[i]; RollingPivotsResult r; @@ -29,21 +30,21 @@ private static List CalcRollingPivots( { // window values int s = i - windowPeriods - offsetPeriods; - TQuote hi = quotesList[s]; + TQuote hi = quotes[s]; decimal windowHigh = hi.High; decimal windowLow = hi.Low; - decimal windowClose = quotesList[i - offsetPeriods - 1].Close; + decimal windowClose = quotes[i - offsetPeriods - 1].Close; for (int p = s; p <= i - offsetPeriods - 1; p++) { - TQuote d = quotesList[p]; + TQuote d = quotes[p]; windowHigh = d.High > windowHigh ? d.High : windowHigh; windowLow = d.Low < windowLow ? d.Low : windowLow; } // pivot points - WindowPoint wp = GetPivotPoint( + WindowPoint wp = PivotPoints.GetPivotPoint( pointType, q.Open, windowHigh, windowLow, windowClose); r = new() { diff --git a/src/m-r/RollingPivots/RollingPivots.Utilities.cs b/src/m-r/RollingPivots/RollingPivots.Utilities.cs index d3609c5df..95a88b44b 100644 --- a/src/m-r/RollingPivots/RollingPivots.Utilities.cs +++ b/src/m-r/RollingPivots/RollingPivots.Utilities.cs @@ -1,6 +1,8 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// ROLLING PIVOT POINTS (UTILITIES) + +public static partial class RollingPivots { // remove recommended periods /// @@ -13,4 +15,23 @@ public static IReadOnlyList RemoveWarmupPeriods( return results.Remove(removePeriods); } + + // parameter validation + internal static void Validate( + int windowPeriods, + int offsetPeriods) + { + // check parameter arguments + if (windowPeriods <= 0) + { + throw new ArgumentOutOfRangeException(nameof(windowPeriods), windowPeriods, + "Window periods must be greater than 0 for Rolling Pivot Points."); + } + + if (offsetPeriods < 0) + { + throw new ArgumentOutOfRangeException(nameof(offsetPeriods), offsetPeriods, + "Offset periods must be greater than or equal to 0 for Rolling Pivot Points."); + } + } } diff --git a/src/m-r/Rsi/Rsi.StaticSeries.cs b/src/m-r/Rsi/Rsi.StaticSeries.cs index 66d3eba99..fe0163cdf 100644 --- a/src/m-r/Rsi/Rsi.StaticSeries.cs +++ b/src/m-r/Rsi/Rsi.StaticSeries.cs @@ -11,7 +11,7 @@ public static IReadOnlyList ToRsi( { // check parameter arguments ArgumentNullException.ThrowIfNull(source); - Rsi.Validate(lookbackPeriods); + Validate(lookbackPeriods); // initialize int length = source.Count; diff --git a/src/s-z/Smma/Smma.Api.cs b/src/s-z/Smma/Smma.Api.cs deleted file mode 100644 index 88eb1c5c8..000000000 --- a/src/s-z/Smma/Smma.Api.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Skender.Stock.Indicators; - -// SMOOTHED MOVING AVERAGE (API) -public static partial class Indicator -{ - // SERIES, from CHAIN - public static IReadOnlyList ToSmma( - this IReadOnlyList results, - int lookbackPeriods) - where T : IReusable - => results - .ToSortedList() - .CalcSmma(lookbackPeriods); -} diff --git a/src/s-z/Smma/Smma.Common.cs b/src/s-z/Smma/Smma.Common.cs deleted file mode 100644 index af39121b2..000000000 --- a/src/s-z/Smma/Smma.Common.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Skender.Stock.Indicators; - -// SMOOTHED MOVING AVERAGE (COMMON) - -public static class Smma -{ - // parameter validation - internal static void Validate( - int lookbackPeriods) - { - // check parameter arguments - if (lookbackPeriods <= 0) - { - throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, - "Lookback periods must be greater than 0 for SMMA."); - } - } - -} diff --git a/src/s-z/Smma/Smma.StaticSeries.cs b/src/s-z/Smma/Smma.StaticSeries.cs index 65c91e02d..e2503ef6c 100644 --- a/src/s-z/Smma/Smma.StaticSeries.cs +++ b/src/s-z/Smma/Smma.StaticSeries.cs @@ -2,16 +2,16 @@ namespace Skender.Stock.Indicators; // SMOOTHED MOVING AVERAGE (SERIES) -public static partial class Indicator +public static partial class Smma { - // calculate series - private static List CalcSmma( - this List source, + public static IReadOnlyList ToSmma( + this IReadOnlyList source, int lookbackPeriods) where T : IReusable { // check parameter arguments - Smma.Validate(lookbackPeriods); + ArgumentNullException.ThrowIfNull(source); + Validate(lookbackPeriods); // initialize int length = source.Count; diff --git a/src/s-z/Smma/Smma.Utilities.cs b/src/s-z/Smma/Smma.Utilities.cs index 87f246467..5951bcbac 100644 --- a/src/s-z/Smma/Smma.Utilities.cs +++ b/src/s-z/Smma/Smma.Utilities.cs @@ -1,6 +1,6 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +public static partial class Smma { // remove recommended periods /// @@ -13,4 +13,16 @@ public static IReadOnlyList RemoveWarmupPeriods( return results.Remove(n + 100); } + + // parameter validation + internal static void Validate( + int lookbackPeriods) + { + // check parameter arguments + if (lookbackPeriods <= 0) + { + throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, + "Lookback periods must be greater than 0 for SMMA."); + } + } } diff --git a/src/s-z/Stc/Stc.StaticSeries.cs b/src/s-z/Stc/Stc.StaticSeries.cs index 5873af1a9..7af49241e 100644 --- a/src/s-z/Stc/Stc.StaticSeries.cs +++ b/src/s-z/Stc/Stc.StaticSeries.cs @@ -20,7 +20,7 @@ private static List CalcStc( // get stochastic of macd IReadOnlyList stochMacd = source - .CalcMacd(fastPeriods, slowPeriods, 1) + .ToMacd(fastPeriods, slowPeriods, 1) .Select(x => new QuoteD( x.Timestamp, 0, x.Macd.Null2NaN(), diff --git a/src/s-z/Tema/Tema.Api.cs b/src/s-z/Tema/Tema.Api.cs deleted file mode 100644 index 50965ec0c..000000000 --- a/src/s-z/Tema/Tema.Api.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Skender.Stock.Indicators; - -// TRIPLE EXPONENTIAL MOVING AVERAGE - TEMA (API) -public static partial class Indicator -{ - // SERIES, from CHAIN - public static IReadOnlyList ToTema( - this IReadOnlyList results, - int lookbackPeriods) - where T : IReusable - => results - .ToSortedList() - .CalcTema(lookbackPeriods); -} diff --git a/src/s-z/Tema/Tema.Common.cs b/src/s-z/Tema/Tema.Common.cs deleted file mode 100644 index 8cf6417b6..000000000 --- a/src/s-z/Tema/Tema.Common.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Skender.Stock.Indicators; - -// TRIPLE EXPONENTIAL MOVING AVERAGE (COMMON) - -public static class Tema -{ - // parameter validation - internal static void Validate( - int lookbackPeriods) - { - // check parameter arguments - if (lookbackPeriods <= 0) - { - throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, - "Lookback periods must be greater than 0 for TEMA."); - } - } - -} diff --git a/src/s-z/Tema/Tema.StaticSeries.cs b/src/s-z/Tema/Tema.StaticSeries.cs index 29514baef..f14a28512 100644 --- a/src/s-z/Tema/Tema.StaticSeries.cs +++ b/src/s-z/Tema/Tema.StaticSeries.cs @@ -2,16 +2,17 @@ namespace Skender.Stock.Indicators; // TRIPLE EXPONENTIAL MOVING AVERAGE (SERIES) -public static partial class Indicator +public static partial class Tema { // calculate series - private static List CalcTema( - this List source, + public static IReadOnlyList ToTema( + this IReadOnlyList source, int lookbackPeriods) where T : IReusable { // check parameter arguments - Tema.Validate(lookbackPeriods); + ArgumentNullException.ThrowIfNull(source); + Validate(lookbackPeriods); // initialize int length = source.Count; diff --git a/src/s-z/Tema/Tema.Utilities.cs b/src/s-z/Tema/Tema.Utilities.cs index 3d1117b27..3e9946637 100644 --- a/src/s-z/Tema/Tema.Utilities.cs +++ b/src/s-z/Tema/Tema.Utilities.cs @@ -1,6 +1,6 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +public static partial class Tema { // remove recommended periods /// @@ -13,4 +13,16 @@ public static IReadOnlyList RemoveWarmupPeriods( return results.Remove(3 * n + 100); } + + // parameter validation + internal static void Validate( + int lookbackPeriods) + { + // check parameter arguments + if (lookbackPeriods <= 0) + { + throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, + "Lookback periods must be greater than 0 for TEMA."); + } + } } diff --git a/tests/indicators/m-r/PivotPoints/PivotPoints.StaticSeries.Tests.cs b/tests/indicators/m-r/PivotPoints/PivotPoints.StaticSeries.Tests.cs index 91e7d739b..56ad3e87d 100644 --- a/tests/indicators/m-r/PivotPoints/PivotPoints.StaticSeries.Tests.cs +++ b/tests/indicators/m-r/PivotPoints/PivotPoints.StaticSeries.Tests.cs @@ -1,7 +1,7 @@ namespace StaticSeries; [TestClass] -public class PivotPoints : StaticSeriesTestBase +public class PivotPointz : StaticSeriesTestBase { [TestMethod] public override void Standard() @@ -236,7 +236,7 @@ public void Demark() Assert.AreEqual(null, r6.S4); // special Demark case: test close = open - WindowPoint d1 = Indicator.GetPivotPointDemark(125, 200, 100, 125); + WindowPoint d1 = PivotPoints.GetPivotPointDemark(125, 200, 100, 125); Assert.AreEqual(550m / 4, d1.PP); } From b110de34f3a4b094655c190f25286821938152bb Mon Sep 17 00:00:00 2001 From: Dave Skender <8432125+DaveSkender@users.noreply.github.com> Date: Sun, 27 Oct 2024 15:46:40 -0400 Subject: [PATCH 35/38] refactor: use readonly list input s-z --- src/_common/ObsoleteV3.cs | 4 +- src/a-d/Adx/Adx.StaticSeries.cs | 2 +- src/a-d/Aroon/Aroon.StaticSeries.cs | 2 +- src/a-d/AtrStop/AtrStop.StaticSeries.cs | 2 +- src/a-d/Bop/Bop.StaticSeries.cs | 4 +- src/a-d/Cci/Cci.StaticSeries.cs | 4 +- src/a-d/Chandelier/Chandelier.StaticSeries.cs | 2 +- src/a-d/Chop/Chop.StaticSeries.cs | 4 +- src/e-k/ElderRay/ElderRay.StaticSeries.cs | 2 +- .../FisherTransform.StaticSeries.cs | 2 +- src/e-k/ForceIndex/ForceIndex.StaticSeries.cs | 4 +- src/e-k/Ichimoku/Ichimoku.StaticSeries.cs | 2 +- src/e-k/Keltner/Keltner.StaticSeries.cs | 4 +- src/e-k/Kvo/Kvo.StaticSeries.cs | 4 +- src/m-r/Mama/Mama.StaticSeries.cs | 2 +- src/m-r/Mfi/Mfi.StaticSeries.cs | 6 +-- src/m-r/Obv/Obv.StaticSeries.cs | 2 +- .../ParabolicSar/ParabolicSar.StaticSeries.cs | 4 +- src/s-z/Sma/Sma.Api.cs | 13 ----- src/s-z/Sma/Sma.Incremental.cs | 36 ------------- src/s-z/Sma/Sma.StreamHub.cs | 12 ++++- src/s-z/Sma/Sma.Utilities.cs | 36 +++++++++++++ src/s-z/SmaAnalysis/SmaAnalysis.Api.cs | 16 ------ .../SmaAnalysis/SmaAnalysis.StaticSeries.cs | 7 +-- src/s-z/Smi/Smi.Api.cs | 22 -------- src/s-z/Smi/Smi.Common.cs | 40 -------------- src/s-z/Smi/Smi.StaticSeries.cs | 20 +++++-- src/s-z/Smi/Smi.Utilities.cs | 37 ++++++++++++- src/s-z/Smma/Smma.Utilities.cs | 2 + src/s-z/StarcBands/StarcBands.Api.cs | 17 ------ src/s-z/StarcBands/StarcBands.Common.cs | 33 ------------ src/s-z/StarcBands/StarcBands.StaticSeries.cs | 15 ++++-- src/s-z/StarcBands/StarcBands.Utilities.cs | 30 ++++++++++- src/s-z/Stc/Stc.Api.cs | 16 ------ src/s-z/Stc/Stc.Common.cs | 33 ------------ src/s-z/Stc/Stc.StaticSeries.cs | 15 +++--- src/s-z/Stc/Stc.Utilities.cs | 30 ++++++++++- src/s-z/StdDev/StdDev.Api.cs | 14 ----- src/s-z/StdDev/StdDev.Common.cs | 19 ------- src/s-z/StdDev/StdDev.StaticSeries.cs | 9 ++-- src/s-z/StdDev/StdDev.Utilities.cs | 22 ++++---- src/s-z/StdDevChannels/StdDevChannels.Api.cs | 15 ------ .../StdDevChannels/StdDevChannels.Common.cs | 26 --------- .../StdDevChannels.StaticSeries.cs | 19 ++++--- .../StdDevChannels.Utilities.cs | 23 +++++++- src/s-z/Stoch/Stoch.Api.cs | 41 -------------- src/s-z/Stoch/Stoch.Common.cs | 54 ------------------- src/s-z/Stoch/Stoch.Models.cs | 2 - src/s-z/Stoch/Stoch.StaticSeries.cs | 44 ++++++++++++--- src/s-z/Stoch/Stoch.Utilities.cs | 51 +++++++++++++++++- src/s-z/StochRsi/StochRsi.Api.cs | 21 -------- src/s-z/StochRsi/StochRsi.Common.cs | 40 -------------- src/s-z/StochRsi/StochRsi.StaticSeries.cs | 11 ++-- src/s-z/StochRsi/StochRsi.Utilities.cs | 37 ++++++++++++- src/s-z/SuperTrend/SuperTrend.Api.cs | 16 ------ src/s-z/SuperTrend/SuperTrend.Common.cs | 26 --------- src/s-z/SuperTrend/SuperTrend.StaticSeries.cs | 14 +++-- src/s-z/SuperTrend/SuperTrend.Utilities.cs | 23 +++++++- src/s-z/T3/T3.Api.cs | 15 ------ src/s-z/T3/T3.StaticSeries.cs | 13 ++--- src/s-z/T3/{T3.Common.cs => T3.Utilities.cs} | 5 +- src/s-z/Tema/Tema.Utilities.cs | 2 + src/s-z/Tr/Tr.Api.cs | 21 -------- src/s-z/Tr/Tr.StaticSeries.cs | 9 +++- src/s-z/Tr/Tr.StreamHub.cs | 11 ++++ src/s-z/Tr/Tr.Utilities.cs | 5 -- src/s-z/Trix/Trix.Api.cs | 14 ----- src/s-z/Trix/Trix.Common.cs | 19 ------- src/s-z/Trix/Trix.StaticSeries.cs | 9 ++-- src/s-z/Trix/Trix.Utilities.cs | 16 +++++- src/s-z/Tsi/Tsi.Api.cs | 16 ------ src/s-z/Tsi/Tsi.Common.cs | 33 ------------ src/s-z/Tsi/Tsi.StaticSeries.cs | 15 +++--- src/s-z/Tsi/Tsi.Utilities.cs | 30 ++++++++++- src/s-z/UlcerIndex/UlcerIndex.Api.cs | 14 ----- src/s-z/UlcerIndex/UlcerIndex.Common.cs | 19 ------- src/s-z/UlcerIndex/UlcerIndex.StaticSeries.cs | 11 ++-- src/s-z/UlcerIndex/UlcerIndex.Utilities.cs | 22 ++++---- src/s-z/Ultimate/Ultimate.Api.cs | 17 ------ src/s-z/Ultimate/Ultimate.Common.cs | 27 ---------- src/s-z/Ultimate/Ultimate.StaticSeries.cs | 15 ++++-- src/s-z/Ultimate/Ultimate.Utilities.cs | 28 ++++++---- src/s-z/VolatilityStop/VolatilityStop.Api.cs | 16 ------ .../VolatilityStop/VolatilityStop.Common.cs | 26 --------- .../VolatilityStop.StaticSeries.cs | 14 +++-- .../VolatilityStop.Utilities.cs | 23 +++++++- src/s-z/Vortex/Vortex.Api.cs | 15 ------ src/s-z/Vortex/Vortex.Common.cs | 19 ------- src/s-z/Vortex/Vortex.StaticSeries.cs | 13 +++-- src/s-z/Vortex/Vortex.Utilities.cs | 16 +++++- src/s-z/Vwap/Vwap.Api.cs | 15 ------ src/s-z/Vwap/Vwap.Common.cs | 26 --------- src/s-z/Vwap/Vwap.StaticSeries.cs | 13 +++-- src/s-z/Vwap/Vwap.Utilities.cs | 23 +++++++- src/s-z/Vwma/Vwma.Api.cs | 15 ------ src/s-z/Vwma/Vwma.Common.cs | 19 ------- src/s-z/Vwma/Vwma.StaticSeries.cs | 13 +++-- src/s-z/Vwma/Vwma.Utilities.cs | 22 ++++---- src/s-z/WilliamsR/WilliamsR.Api.cs | 15 ------ src/s-z/WilliamsR/WilliamsR.Common.cs | 19 ------- src/s-z/WilliamsR/WilliamsR.StaticSeries.cs | 13 +++-- src/s-z/WilliamsR/WilliamsR.Utilities.cs | 22 ++++---- src/s-z/Wma/Wma.Utilities.cs | 2 + src/s-z/ZigZag/ZigZag.Api.cs | 16 ------ src/s-z/ZigZag/ZigZag.Common.cs | 19 ------- src/s-z/ZigZag/ZigZag.StaticSeries.cs | 25 ++++----- src/s-z/ZigZag/ZigZag.Utilities.cs | 16 +++++- 107 files changed, 721 insertions(+), 1113 deletions(-) delete mode 100644 src/s-z/Sma/Sma.Api.cs delete mode 100644 src/s-z/Sma/Sma.Incremental.cs delete mode 100644 src/s-z/SmaAnalysis/SmaAnalysis.Api.cs delete mode 100644 src/s-z/Smi/Smi.Api.cs delete mode 100644 src/s-z/Smi/Smi.Common.cs delete mode 100644 src/s-z/StarcBands/StarcBands.Api.cs delete mode 100644 src/s-z/StarcBands/StarcBands.Common.cs delete mode 100644 src/s-z/Stc/Stc.Api.cs delete mode 100644 src/s-z/Stc/Stc.Common.cs delete mode 100644 src/s-z/StdDev/StdDev.Api.cs delete mode 100644 src/s-z/StdDev/StdDev.Common.cs delete mode 100644 src/s-z/StdDevChannels/StdDevChannels.Api.cs delete mode 100644 src/s-z/StdDevChannels/StdDevChannels.Common.cs delete mode 100644 src/s-z/Stoch/Stoch.Api.cs delete mode 100644 src/s-z/Stoch/Stoch.Common.cs delete mode 100644 src/s-z/StochRsi/StochRsi.Api.cs delete mode 100644 src/s-z/StochRsi/StochRsi.Common.cs delete mode 100644 src/s-z/SuperTrend/SuperTrend.Api.cs delete mode 100644 src/s-z/SuperTrend/SuperTrend.Common.cs delete mode 100644 src/s-z/T3/T3.Api.cs rename src/s-z/T3/{T3.Common.cs => T3.Utilities.cs} (89%) delete mode 100644 src/s-z/Tr/Tr.Api.cs delete mode 100644 src/s-z/Trix/Trix.Api.cs delete mode 100644 src/s-z/Trix/Trix.Common.cs delete mode 100644 src/s-z/Tsi/Tsi.Api.cs delete mode 100644 src/s-z/Tsi/Tsi.Common.cs delete mode 100644 src/s-z/UlcerIndex/UlcerIndex.Api.cs delete mode 100644 src/s-z/UlcerIndex/UlcerIndex.Common.cs delete mode 100644 src/s-z/Ultimate/Ultimate.Api.cs delete mode 100644 src/s-z/Ultimate/Ultimate.Common.cs delete mode 100644 src/s-z/VolatilityStop/VolatilityStop.Api.cs delete mode 100644 src/s-z/VolatilityStop/VolatilityStop.Common.cs delete mode 100644 src/s-z/Vortex/Vortex.Api.cs delete mode 100644 src/s-z/Vortex/Vortex.Common.cs delete mode 100644 src/s-z/Vwap/Vwap.Api.cs delete mode 100644 src/s-z/Vwap/Vwap.Common.cs delete mode 100644 src/s-z/Vwma/Vwma.Api.cs delete mode 100644 src/s-z/Vwma/Vwma.Common.cs delete mode 100644 src/s-z/WilliamsR/WilliamsR.Api.cs delete mode 100644 src/s-z/WilliamsR/WilliamsR.Common.cs delete mode 100644 src/s-z/ZigZag/ZigZag.Api.cs delete mode 100644 src/s-z/ZigZag/ZigZag.Common.cs diff --git a/src/_common/ObsoleteV3.cs b/src/_common/ObsoleteV3.cs index c7f4152ed..a6f751868 100644 --- a/src/_common/ObsoleteV3.cs +++ b/src/_common/ObsoleteV3.cs @@ -75,14 +75,14 @@ public static IEnumerable GetRoc( public static IEnumerable GetStdDev( this IReadOnlyList quotes, int lookbackPeriods, int smaPeriods) where TQuote : IQuote - => quotes.Use(CandlePart.Close).ToList().CalcStdDev(lookbackPeriods); + => quotes.Use(CandlePart.Close).ToStdDev(lookbackPeriods); [ExcludeFromCodeCoverage] [Obsolete("Use a chained `results.GetSma(smaPeriods)` to generate a moving average.", true)] // v3.0.0 public static IEnumerable GetTrix( this IReadOnlyList quotes, int lookbackPeriods, int smaPeriods) where TQuote : IQuote - => quotes.Use(CandlePart.Close).ToList().CalcTrix(lookbackPeriods); + => quotes.Use(CandlePart.Close).ToTrix(lookbackPeriods); // UTILITIES diff --git a/src/a-d/Adx/Adx.StaticSeries.cs b/src/a-d/Adx/Adx.StaticSeries.cs index 4cb309c05..45839098a 100644 --- a/src/a-d/Adx/Adx.StaticSeries.cs +++ b/src/a-d/Adx/Adx.StaticSeries.cs @@ -12,7 +12,7 @@ public static IReadOnlyList ToAdx( .CalcAdx(lookbackPeriods); private static List CalcAdx( - this List source, + this IReadOnlyList source, int lookbackPeriods = 14) { // check parameter arguments diff --git a/src/a-d/Aroon/Aroon.StaticSeries.cs b/src/a-d/Aroon/Aroon.StaticSeries.cs index 4111c2111..4fcdbe3be 100644 --- a/src/a-d/Aroon/Aroon.StaticSeries.cs +++ b/src/a-d/Aroon/Aroon.StaticSeries.cs @@ -12,7 +12,7 @@ public static IReadOnlyList ToAroon( .CalcAroon(lookbackPeriods); private static List CalcAroon( - this List source, + this IReadOnlyList source, int lookbackPeriods) { // check parameter arguments diff --git a/src/a-d/AtrStop/AtrStop.StaticSeries.cs b/src/a-d/AtrStop/AtrStop.StaticSeries.cs index 1334e4902..b4b840f48 100644 --- a/src/a-d/AtrStop/AtrStop.StaticSeries.cs +++ b/src/a-d/AtrStop/AtrStop.StaticSeries.cs @@ -14,7 +14,7 @@ public static IReadOnlyList ToAtrStop( .CalcAtrStop(lookbackPeriods, multiplier, endType); private static List CalcAtrStop( - this List source, + this IReadOnlyList source, int lookbackPeriods, double multiplier, EndType endType) diff --git a/src/a-d/Bop/Bop.StaticSeries.cs b/src/a-d/Bop/Bop.StaticSeries.cs index 86e75f669..37a1c7b7c 100644 --- a/src/a-d/Bop/Bop.StaticSeries.cs +++ b/src/a-d/Bop/Bop.StaticSeries.cs @@ -12,11 +12,11 @@ public static IReadOnlyList ToBop( .CalcBop(smoothPeriods); private static List CalcBop( - this List source, + this IReadOnlyList source, int smoothPeriods) { // check parameter arguments - Bop.Validate(smoothPeriods); + Validate(smoothPeriods); // initialize int length = source.Count; diff --git a/src/a-d/Cci/Cci.StaticSeries.cs b/src/a-d/Cci/Cci.StaticSeries.cs index 277ee46d2..e854ce386 100644 --- a/src/a-d/Cci/Cci.StaticSeries.cs +++ b/src/a-d/Cci/Cci.StaticSeries.cs @@ -12,11 +12,11 @@ public static IReadOnlyList ToCci( .CalcCci(lookbackPeriods); private static List CalcCci( - this List source, + this IReadOnlyList source, int lookbackPeriods) { // check parameter arguments - Cci.Validate(lookbackPeriods); + Validate(lookbackPeriods); // initialize int length = source.Count; diff --git a/src/a-d/Chandelier/Chandelier.StaticSeries.cs b/src/a-d/Chandelier/Chandelier.StaticSeries.cs index 42c833f26..8f13ebeb8 100644 --- a/src/a-d/Chandelier/Chandelier.StaticSeries.cs +++ b/src/a-d/Chandelier/Chandelier.StaticSeries.cs @@ -14,7 +14,7 @@ public static IReadOnlyList ToChandelier( .CalcChandelier(lookbackPeriods, multiplier, type); private static List CalcChandelier( - this List source, + this IReadOnlyList source, int lookbackPeriods, double multiplier, ChandelierType type) diff --git a/src/a-d/Chop/Chop.StaticSeries.cs b/src/a-d/Chop/Chop.StaticSeries.cs index 7452b4800..2237f86c1 100644 --- a/src/a-d/Chop/Chop.StaticSeries.cs +++ b/src/a-d/Chop/Chop.StaticSeries.cs @@ -12,11 +12,11 @@ public static IReadOnlyList ToChop( .CalcChop(lookbackPeriods); private static List CalcChop( - this List source, + this IReadOnlyList source, int lookbackPeriods) { // check parameter arguments - Chop.Validate(lookbackPeriods); + Validate(lookbackPeriods); // initialize int length = source.Count; diff --git a/src/e-k/ElderRay/ElderRay.StaticSeries.cs b/src/e-k/ElderRay/ElderRay.StaticSeries.cs index 499b6cca4..785223db6 100644 --- a/src/e-k/ElderRay/ElderRay.StaticSeries.cs +++ b/src/e-k/ElderRay/ElderRay.StaticSeries.cs @@ -12,7 +12,7 @@ public static IReadOnlyList ToElderRay( .CalcElderRay(lookbackPeriods); private static List CalcElderRay( - this List source, + this IReadOnlyList source, int lookbackPeriods) { // check parameter arguments diff --git a/src/e-k/FisherTransform/FisherTransform.StaticSeries.cs b/src/e-k/FisherTransform/FisherTransform.StaticSeries.cs index 04ac97f81..01b81dcfe 100644 --- a/src/e-k/FisherTransform/FisherTransform.StaticSeries.cs +++ b/src/e-k/FisherTransform/FisherTransform.StaticSeries.cs @@ -18,7 +18,7 @@ private static List CalcFisherTransform( where T : IReusable { // check parameter arguments - FisherTransform.Validate(lookbackPeriods); + Validate(lookbackPeriods); // initialize int length = source.Count; diff --git a/src/e-k/ForceIndex/ForceIndex.StaticSeries.cs b/src/e-k/ForceIndex/ForceIndex.StaticSeries.cs index 9b76b1eca..1bea16987 100644 --- a/src/e-k/ForceIndex/ForceIndex.StaticSeries.cs +++ b/src/e-k/ForceIndex/ForceIndex.StaticSeries.cs @@ -12,11 +12,11 @@ public static IReadOnlyList ToForceIndex( .CalcForceIndex(lookbackPeriods); private static List CalcForceIndex( - this List source, + this IReadOnlyList source, int lookbackPeriods) { // check parameter arguments - ForceIndex.Validate(lookbackPeriods); + Validate(lookbackPeriods); // initialize int length = source.Count; diff --git a/src/e-k/Ichimoku/Ichimoku.StaticSeries.cs b/src/e-k/Ichimoku/Ichimoku.StaticSeries.cs index 2949c15f4..3fcf3cabe 100644 --- a/src/e-k/Ichimoku/Ichimoku.StaticSeries.cs +++ b/src/e-k/Ichimoku/Ichimoku.StaticSeries.cs @@ -59,7 +59,7 @@ private static List CalcIchimoku( where TQuote : IQuote { // check parameter arguments - Ichimoku.Validate( + Validate( tenkanPeriods, kijunPeriods, senkouBPeriods, diff --git a/src/e-k/Keltner/Keltner.StaticSeries.cs b/src/e-k/Keltner/Keltner.StaticSeries.cs index 1a4940caf..baa1ba676 100644 --- a/src/e-k/Keltner/Keltner.StaticSeries.cs +++ b/src/e-k/Keltner/Keltner.StaticSeries.cs @@ -14,13 +14,13 @@ public static IReadOnlyList ToKeltner( .CalcKeltner(emaPeriods, multiplier, atrPeriods); private static List CalcKeltner( - this List source, + this IReadOnlyList source, int emaPeriods, double multiplier, int atrPeriods) { // check parameter arguments - Keltner.Validate(emaPeriods, multiplier, atrPeriods); + Validate(emaPeriods, multiplier, atrPeriods); // initialize int length = source.Count; diff --git a/src/e-k/Kvo/Kvo.StaticSeries.cs b/src/e-k/Kvo/Kvo.StaticSeries.cs index 26b36cf81..1b735fe2d 100644 --- a/src/e-k/Kvo/Kvo.StaticSeries.cs +++ b/src/e-k/Kvo/Kvo.StaticSeries.cs @@ -14,13 +14,13 @@ public static IReadOnlyList ToKvo( .CalcKvo(fastPeriods, slowPeriods, signalPeriods); private static List CalcKvo( - this List source, + this IReadOnlyList source, int fastPeriods, int slowPeriods, int signalPeriods) { // check parameter arguments - Kvo.Validate(fastPeriods, slowPeriods, signalPeriods); + Validate(fastPeriods, slowPeriods, signalPeriods); // initialize int length = source.Count; diff --git a/src/m-r/Mama/Mama.StaticSeries.cs b/src/m-r/Mama/Mama.StaticSeries.cs index be955973b..4bded7fcd 100644 --- a/src/m-r/Mama/Mama.StaticSeries.cs +++ b/src/m-r/Mama/Mama.StaticSeries.cs @@ -20,7 +20,7 @@ private static List CalcMama( where T : IReusable { // check parameter arguments - Mama.Validate(fastLimit, slowLimit); + Validate(fastLimit, slowLimit); // initialize int length = source.Count; diff --git a/src/m-r/Mfi/Mfi.StaticSeries.cs b/src/m-r/Mfi/Mfi.StaticSeries.cs index 50286dc8e..2d9043a7c 100644 --- a/src/m-r/Mfi/Mfi.StaticSeries.cs +++ b/src/m-r/Mfi/Mfi.StaticSeries.cs @@ -2,7 +2,7 @@ namespace Skender.Stock.Indicators; // MONEY FLOW INDEX (SERIES) -public static partial class Indicator +public static partial class Mfi { public static IReadOnlyList ToMfi( this IReadOnlyList quotes, @@ -12,11 +12,11 @@ public static IReadOnlyList ToMfi( .CalcMfi(lookbackPeriods); private static List CalcMfi( - this List source, + this IReadOnlyList source, int lookbackPeriods) { // check parameter arguments - Mfi.Validate(lookbackPeriods); + Validate(lookbackPeriods); // initialize int length = source.Count; diff --git a/src/m-r/Obv/Obv.StaticSeries.cs b/src/m-r/Obv/Obv.StaticSeries.cs index d4bf3cd61..48456b11d 100644 --- a/src/m-r/Obv/Obv.StaticSeries.cs +++ b/src/m-r/Obv/Obv.StaticSeries.cs @@ -11,7 +11,7 @@ public static IReadOnlyList ToObv( .CalcObv(); private static List CalcObv( - this List source) + this IReadOnlyList source) { // initialize int length = source.Count; diff --git a/src/m-r/ParabolicSar/ParabolicSar.StaticSeries.cs b/src/m-r/ParabolicSar/ParabolicSar.StaticSeries.cs index 99c3e9da0..f19618e1c 100644 --- a/src/m-r/ParabolicSar/ParabolicSar.StaticSeries.cs +++ b/src/m-r/ParabolicSar/ParabolicSar.StaticSeries.cs @@ -28,13 +28,13 @@ public static IReadOnlyList GetParabolicSar( initialFactor); private static List CalcParabolicSar( - this List source, + this IReadOnlyList source, double accelerationStep, double maxAccelerationFactor, double initialFactor) { // check parameter arguments - ParabolicSar.Validate( + Validate( accelerationStep, maxAccelerationFactor, initialFactor); // initialize diff --git a/src/s-z/Sma/Sma.Api.cs b/src/s-z/Sma/Sma.Api.cs deleted file mode 100644 index e1eaf6712..000000000 --- a/src/s-z/Sma/Sma.Api.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Skender.Stock.Indicators; - -// SIMPLE MOVING AVERAGE (API) - -public static partial class Sma -{ - // OBSERVER, from Chain Provider - public static SmaHub ToSma( - this IChainProvider chainProvider, - int lookbackPeriods) - where TIn : IReusable - => new(chainProvider, lookbackPeriods); -} diff --git a/src/s-z/Sma/Sma.Incremental.cs b/src/s-z/Sma/Sma.Incremental.cs deleted file mode 100644 index 3f7c1807d..000000000 --- a/src/s-z/Sma/Sma.Incremental.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Numerics; - -namespace Skender.Stock.Indicators; - -public static partial class Sma -{ - internal static double[] CalcSma(this double[] prices, int period) - { - int count = prices.Length - period + 1; - double[] sma = new double[count]; - - int simdWidth = Vector.Count; - for (int i = 0; i < count; i++) - { - Vector sumVector = Vector.Zero; - - int j; - for (j = 0; j <= period - simdWidth; j += simdWidth) - { - Vector priceVector = new(prices, i + j); - sumVector += priceVector; - } - - double sum = 0; - for (; j < period; j++) // remainder loop - { - sum += prices[i + j]; - } - sum += Vector.Dot(sumVector, Vector.One); - - sma[i] = sum / period; - } - - return sma; - } -} diff --git a/src/s-z/Sma/Sma.StreamHub.cs b/src/s-z/Sma/Sma.StreamHub.cs index 7cc4636b4..150609bb2 100644 --- a/src/s-z/Sma/Sma.StreamHub.cs +++ b/src/s-z/Sma/Sma.StreamHub.cs @@ -2,11 +2,21 @@ namespace Skender.Stock.Indicators; // SIMPLE MOVING AVERAGE (STREAM HUB) -#region hub interface +#region hub interface and initializer + public interface ISmaHub { int LookbackPeriods { get; } } + +public static partial class Sma +{ + public static SmaHub ToSma( + this IChainProvider chainProvider, + int lookbackPeriods) + where TIn : IReusable + => new(chainProvider, lookbackPeriods); +} #endregion public class SmaHub diff --git a/src/s-z/Sma/Sma.Utilities.cs b/src/s-z/Sma/Sma.Utilities.cs index b67923dd8..f8700d185 100644 --- a/src/s-z/Sma/Sma.Utilities.cs +++ b/src/s-z/Sma/Sma.Utilities.cs @@ -1,5 +1,9 @@ +using System.Numerics; + namespace Skender.Stock.Indicators; +// SIMPLE MOVING AVERAGE (UTILITIES) + public static partial class Sma { /// @@ -65,6 +69,38 @@ internal static double Increment( // TODO: apply this SMA increment method more widely in other indicators (see EMA example) } + internal static double[] Increment(this double[] prices, int period) + { + // TODO: is this used (probably just an experiment, has rounding errors) + + int count = prices.Length - period + 1; + double[] sma = new double[count]; + + int simdWidth = Vector.Count; + for (int i = 0; i < count; i++) + { + Vector sumVector = Vector.Zero; + + int j; + for (j = 0; j <= period - simdWidth; j += simdWidth) + { + Vector priceVector = new(prices, i + j); + sumVector += priceVector; + } + + double sum = 0; + for (; j < period; j++) // remainder loop + { + sum += prices[i + j]; + } + sum += Vector.Dot(sumVector, Vector.One); + + sma[i] = sum / period; + } + + return sma; + } + // parameter validation internal static void Validate( int lookbackPeriods) diff --git a/src/s-z/SmaAnalysis/SmaAnalysis.Api.cs b/src/s-z/SmaAnalysis/SmaAnalysis.Api.cs deleted file mode 100644 index fb9cd3a88..000000000 --- a/src/s-z/SmaAnalysis/SmaAnalysis.Api.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace Skender.Stock.Indicators; - -// SIMPLE MOVING AVERAGE (API) -// with extended analysis - -public static partial class Indicator -{ - // ANALYSIS, from CHAIN - public static IReadOnlyList ToSmaAnalysis( - this IEnumerable source, - int lookbackPeriods) - where T : IReusable - => source - .ToSortedList() - .CalcSmaAnalysis(lookbackPeriods); -} diff --git a/src/s-z/SmaAnalysis/SmaAnalysis.StaticSeries.cs b/src/s-z/SmaAnalysis/SmaAnalysis.StaticSeries.cs index b52cc6c08..d43770795 100644 --- a/src/s-z/SmaAnalysis/SmaAnalysis.StaticSeries.cs +++ b/src/s-z/SmaAnalysis/SmaAnalysis.StaticSeries.cs @@ -1,10 +1,11 @@ namespace Skender.Stock.Indicators; // SIMPLE MOVING AVERAGE (ANALYSIS) -public static partial class Indicator + +public static partial class Sma { - private static List CalcSmaAnalysis( - this List source, + public static IReadOnlyList ToSmaAnalysis( + this IReadOnlyList source, int lookbackPeriods) where T : IReusable { diff --git a/src/s-z/Smi/Smi.Api.cs b/src/s-z/Smi/Smi.Api.cs deleted file mode 100644 index 927ffbd24..000000000 --- a/src/s-z/Smi/Smi.Api.cs +++ /dev/null @@ -1,22 +0,0 @@ -namespace Skender.Stock.Indicators; - -// STOCHASTIC MOMENTUM INDEX (API) -public static partial class Indicator -{ - // SERIES, from TQuote - /// - /// - public static IReadOnlyList ToSmi( - this IReadOnlyList quotes, - int lookbackPeriods = 13, - int firstSmoothPeriods = 25, - int secondSmoothPeriods = 2, - int signalPeriods = 3) - where TQuote : IQuote => quotes - .ToQuoteDList() - .CalcSmi( - lookbackPeriods, - firstSmoothPeriods, - secondSmoothPeriods, - signalPeriods); -} diff --git a/src/s-z/Smi/Smi.Common.cs b/src/s-z/Smi/Smi.Common.cs deleted file mode 100644 index 0549703fe..000000000 --- a/src/s-z/Smi/Smi.Common.cs +++ /dev/null @@ -1,40 +0,0 @@ -namespace Skender.Stock.Indicators; - -// STOCHASTIC MOMENTUM INDEX (COMMON) - -public static class Smi -{ - // parameter validation - internal static void Validate( - int lookbackPeriods, - int firstSmoothPeriods, - int secondSmoothPeriods, - int signalPeriods) - { - // check parameter arguments - if (lookbackPeriods <= 0) - { - throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, - "Lookback periods must be greater than 0 for SMI."); - } - - if (firstSmoothPeriods <= 0) - { - throw new ArgumentOutOfRangeException(nameof(firstSmoothPeriods), firstSmoothPeriods, - "Smoothing periods must be greater than 0 for SMI."); - } - - if (secondSmoothPeriods <= 0) - { - throw new ArgumentOutOfRangeException(nameof(secondSmoothPeriods), secondSmoothPeriods, - "Smoothing periods must be greater than 0 for SMI."); - } - - if (signalPeriods <= 0) - { - throw new ArgumentOutOfRangeException(nameof(signalPeriods), signalPeriods, - "Signal periods must be greater than 0 for SMI."); - } - } - -} diff --git a/src/s-z/Smi/Smi.StaticSeries.cs b/src/s-z/Smi/Smi.StaticSeries.cs index bd7fe49ef..9d80f0be2 100644 --- a/src/s-z/Smi/Smi.StaticSeries.cs +++ b/src/s-z/Smi/Smi.StaticSeries.cs @@ -2,17 +2,31 @@ namespace Skender.Stock.Indicators; // STOCHASTIC MOMENTUM INDEX (SERIES) -public static partial class Indicator +public static partial class Smi { + public static IReadOnlyList ToSmi( + this IReadOnlyList quotes, + int lookbackPeriods = 13, + int firstSmoothPeriods = 25, + int secondSmoothPeriods = 2, + int signalPeriods = 3) + where TQuote : IQuote => quotes + .ToQuoteDList() + .CalcSmi( + lookbackPeriods, + firstSmoothPeriods, + secondSmoothPeriods, + signalPeriods); + private static List CalcSmi( - this List source, + this IReadOnlyList source, int lookbackPeriods, int firstSmoothPeriods, int secondSmoothPeriods, int signalPeriods) { // check parameter arguments - Smi.Validate( + Validate( lookbackPeriods, firstSmoothPeriods, secondSmoothPeriods, diff --git a/src/s-z/Smi/Smi.Utilities.cs b/src/s-z/Smi/Smi.Utilities.cs index 1d67cb99d..b22632495 100644 --- a/src/s-z/Smi/Smi.Utilities.cs +++ b/src/s-z/Smi/Smi.Utilities.cs @@ -1,6 +1,8 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// STOCHASTIC MOMENTUM INDEX (UTILITIES) + +public static partial class Smi { // remove recommended periods /// @@ -13,4 +15,37 @@ public static IReadOnlyList RemoveWarmupPeriods( return results.Remove(removePeriods + 2 + 100); } + + // parameter validation + internal static void Validate( + int lookbackPeriods, + int firstSmoothPeriods, + int secondSmoothPeriods, + int signalPeriods) + { + // check parameter arguments + if (lookbackPeriods <= 0) + { + throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, + "Lookback periods must be greater than 0 for SMI."); + } + + if (firstSmoothPeriods <= 0) + { + throw new ArgumentOutOfRangeException(nameof(firstSmoothPeriods), firstSmoothPeriods, + "Smoothing periods must be greater than 0 for SMI."); + } + + if (secondSmoothPeriods <= 0) + { + throw new ArgumentOutOfRangeException(nameof(secondSmoothPeriods), secondSmoothPeriods, + "Smoothing periods must be greater than 0 for SMI."); + } + + if (signalPeriods <= 0) + { + throw new ArgumentOutOfRangeException(nameof(signalPeriods), signalPeriods, + "Signal periods must be greater than 0 for SMI."); + } + } } diff --git a/src/s-z/Smma/Smma.Utilities.cs b/src/s-z/Smma/Smma.Utilities.cs index 5951bcbac..5b5336023 100644 --- a/src/s-z/Smma/Smma.Utilities.cs +++ b/src/s-z/Smma/Smma.Utilities.cs @@ -1,5 +1,7 @@ namespace Skender.Stock.Indicators; +// SMOOTHED MOVING AVERAGE (UTILITIES) + public static partial class Smma { // remove recommended periods diff --git a/src/s-z/StarcBands/StarcBands.Api.cs b/src/s-z/StarcBands/StarcBands.Api.cs deleted file mode 100644 index dc046ac1d..000000000 --- a/src/s-z/StarcBands/StarcBands.Api.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace Skender.Stock.Indicators; - -// STARC BANDS (API) -public static partial class Indicator -{ - // SERIES, from TQuote - /// - /// - public static IReadOnlyList ToStarcBands( - this IReadOnlyList quotes, - int smaPeriods, - double multiplier = 2, - int atrPeriods = 10) - where TQuote : IQuote => quotes - .ToQuoteDList() - .CalcStarcBands(smaPeriods, multiplier, atrPeriods); -} diff --git a/src/s-z/StarcBands/StarcBands.Common.cs b/src/s-z/StarcBands/StarcBands.Common.cs deleted file mode 100644 index 861f3d783..000000000 --- a/src/s-z/StarcBands/StarcBands.Common.cs +++ /dev/null @@ -1,33 +0,0 @@ -namespace Skender.Stock.Indicators; - -// STARC BANDS (COMMON) - -public static class StarcBands -{ - // parameter validation - internal static void Validate( - int smaPeriods, - double multiplier, - int atrPeriods) - { - // check parameter arguments - if (smaPeriods <= 1) - { - throw new ArgumentOutOfRangeException(nameof(smaPeriods), smaPeriods, - "EMA periods must be greater than 1 for STARC Bands."); - } - - if (atrPeriods <= 1) - { - throw new ArgumentOutOfRangeException(nameof(atrPeriods), atrPeriods, - "ATR periods must be greater than 1 for STARC Bands."); - } - - if (multiplier <= 0) - { - throw new ArgumentOutOfRangeException(nameof(multiplier), multiplier, - "Multiplier must be greater than 0 for STARC Bands."); - } - } - -} diff --git a/src/s-z/StarcBands/StarcBands.StaticSeries.cs b/src/s-z/StarcBands/StarcBands.StaticSeries.cs index 106f5f753..3a28837e4 100644 --- a/src/s-z/StarcBands/StarcBands.StaticSeries.cs +++ b/src/s-z/StarcBands/StarcBands.StaticSeries.cs @@ -2,16 +2,25 @@ namespace Skender.Stock.Indicators; // STARC BANDS (SERIES) -public static partial class Indicator +public static partial class StarcBands { + public static IReadOnlyList ToStarcBands( + this IReadOnlyList quotes, + int smaPeriods, + double multiplier = 2, + int atrPeriods = 10) + where TQuote : IQuote => quotes + .ToQuoteDList() + .CalcStarcBands(smaPeriods, multiplier, atrPeriods); + private static List CalcStarcBands( - this List source, + this IReadOnlyList source, int smaPeriods, double multiplier, int atrPeriods) { // check parameter arguments - StarcBands.Validate(smaPeriods, multiplier, atrPeriods); + Validate(smaPeriods, multiplier, atrPeriods); // initialize int length = source.Count; diff --git a/src/s-z/StarcBands/StarcBands.Utilities.cs b/src/s-z/StarcBands/StarcBands.Utilities.cs index 06ad39e46..c30e4d801 100644 --- a/src/s-z/StarcBands/StarcBands.Utilities.cs +++ b/src/s-z/StarcBands/StarcBands.Utilities.cs @@ -1,6 +1,8 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// STARC BANDS (UTILITIES) + +public static partial class StarcBands { // CONDENSE (REMOVE null results) /// @@ -28,4 +30,30 @@ public static IReadOnlyList RemoveWarmupPeriods( return results.Remove(n + 150); } + + // parameter validation + internal static void Validate( + int smaPeriods, + double multiplier, + int atrPeriods) + { + // check parameter arguments + if (smaPeriods <= 1) + { + throw new ArgumentOutOfRangeException(nameof(smaPeriods), smaPeriods, + "EMA periods must be greater than 1 for STARC Bands."); + } + + if (atrPeriods <= 1) + { + throw new ArgumentOutOfRangeException(nameof(atrPeriods), atrPeriods, + "ATR periods must be greater than 1 for STARC Bands."); + } + + if (multiplier <= 0) + { + throw new ArgumentOutOfRangeException(nameof(multiplier), multiplier, + "Multiplier must be greater than 0 for STARC Bands."); + } + } } diff --git a/src/s-z/Stc/Stc.Api.cs b/src/s-z/Stc/Stc.Api.cs deleted file mode 100644 index 2da7c4075..000000000 --- a/src/s-z/Stc/Stc.Api.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace Skender.Stock.Indicators; - -// SCHAFF TREND CYCLE (API) -public static partial class Indicator -{ - // SERIES, from CHAIN - public static IReadOnlyList ToStc( - this IReadOnlyList results, - int cyclePeriods = 10, - int fastPeriods = 23, - int slowPeriods = 50) - where T : IReusable - => results - .ToSortedList() - .CalcStc(cyclePeriods, fastPeriods, slowPeriods); -} diff --git a/src/s-z/Stc/Stc.Common.cs b/src/s-z/Stc/Stc.Common.cs deleted file mode 100644 index 762caa2e4..000000000 --- a/src/s-z/Stc/Stc.Common.cs +++ /dev/null @@ -1,33 +0,0 @@ -namespace Skender.Stock.Indicators; - -// SCHAFF TREND CYCLE (COMMON) - -public static class Stc -{ - // parameter validation - internal static void Validate( - int cyclePeriods, - int fastPeriods, - int slowPeriods) - { - // check parameter arguments - if (cyclePeriods < 0) - { - throw new ArgumentOutOfRangeException(nameof(cyclePeriods), cyclePeriods, - "Trend Cycle periods must be greater than or equal to 0 for STC."); - } - - if (fastPeriods <= 0) - { - throw new ArgumentOutOfRangeException(nameof(fastPeriods), fastPeriods, - "Fast periods must be greater than 0 for STC."); - } - - if (slowPeriods <= fastPeriods) - { - throw new ArgumentOutOfRangeException(nameof(slowPeriods), slowPeriods, - "Slow periods must be greater than the fast period for STC."); - } - } - -} diff --git a/src/s-z/Stc/Stc.StaticSeries.cs b/src/s-z/Stc/Stc.StaticSeries.cs index 7af49241e..bb103d5bb 100644 --- a/src/s-z/Stc/Stc.StaticSeries.cs +++ b/src/s-z/Stc/Stc.StaticSeries.cs @@ -2,17 +2,18 @@ namespace Skender.Stock.Indicators; // SCHAFF TREND CYCLE (SERIES) -public static partial class Indicator +public static partial class Stc { - private static List CalcStc( - this List source, - int cyclePeriods, - int fastPeriods, - int slowPeriods) + public static IReadOnlyList ToStc( + this IReadOnlyList source, + int cyclePeriods = 10, + int fastPeriods = 23, + int slowPeriods = 50) where T : IReusable { // check parameter arguments - Stc.Validate(cyclePeriods, fastPeriods, slowPeriods); + ArgumentNullException.ThrowIfNull(source); + Validate(cyclePeriods, fastPeriods, slowPeriods); // initialize results int length = source.Count; diff --git a/src/s-z/Stc/Stc.Utilities.cs b/src/s-z/Stc/Stc.Utilities.cs index a39b0180d..ecc8a0004 100644 --- a/src/s-z/Stc/Stc.Utilities.cs +++ b/src/s-z/Stc/Stc.Utilities.cs @@ -1,6 +1,8 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// SCHAFF TREND CYCLE (UTILITIES) + +public static partial class Stc { // remove recommended periods /// @@ -13,4 +15,30 @@ public static IReadOnlyList RemoveWarmupPeriods( return results.Remove(n + 250); } + + // parameter validation + internal static void Validate( + int cyclePeriods, + int fastPeriods, + int slowPeriods) + { + // check parameter arguments + if (cyclePeriods < 0) + { + throw new ArgumentOutOfRangeException(nameof(cyclePeriods), cyclePeriods, + "Trend Cycle periods must be greater than or equal to 0 for STC."); + } + + if (fastPeriods <= 0) + { + throw new ArgumentOutOfRangeException(nameof(fastPeriods), fastPeriods, + "Fast periods must be greater than 0 for STC."); + } + + if (slowPeriods <= fastPeriods) + { + throw new ArgumentOutOfRangeException(nameof(slowPeriods), slowPeriods, + "Slow periods must be greater than the fast period for STC."); + } + } } diff --git a/src/s-z/StdDev/StdDev.Api.cs b/src/s-z/StdDev/StdDev.Api.cs deleted file mode 100644 index 05ef0f06e..000000000 --- a/src/s-z/StdDev/StdDev.Api.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Skender.Stock.Indicators; - -// STANDARD DEVIATION (API) -public static partial class Indicator -{ - // SERIES, from CHAIN - public static IReadOnlyList ToStdDev( - this IReadOnlyList results, - int lookbackPeriods) - where T : IReusable - => results - .ToSortedList() - .CalcStdDev(lookbackPeriods); -} diff --git a/src/s-z/StdDev/StdDev.Common.cs b/src/s-z/StdDev/StdDev.Common.cs deleted file mode 100644 index 2224d9f4c..000000000 --- a/src/s-z/StdDev/StdDev.Common.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Skender.Stock.Indicators; - -// STANDARD DEVIATION (COMMON) - -public static class StdDev -{ - // parameter validation - internal static void Validate( - int lookbackPeriods) - { - // check parameter arguments - if (lookbackPeriods <= 1) - { - throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, - "Lookback periods must be greater than 1 for Standard Deviation."); - } - } - -} diff --git a/src/s-z/StdDev/StdDev.StaticSeries.cs b/src/s-z/StdDev/StdDev.StaticSeries.cs index 6bc8bc173..f1a9aba47 100644 --- a/src/s-z/StdDev/StdDev.StaticSeries.cs +++ b/src/s-z/StdDev/StdDev.StaticSeries.cs @@ -2,15 +2,16 @@ namespace Skender.Stock.Indicators; // STANDARD DEVIATION (SERIES) -public static partial class Indicator +public static partial class StdDev { - private static List CalcStdDev( - this List source, + public static IReadOnlyList ToStdDev( + this IReadOnlyList source, int lookbackPeriods) where T : IReusable { // check parameter arguments - StdDev.Validate(lookbackPeriods); + ArgumentNullException.ThrowIfNull(source); + Validate(lookbackPeriods); // initialize int length = source.Count; diff --git a/src/s-z/StdDev/StdDev.Utilities.cs b/src/s-z/StdDev/StdDev.Utilities.cs index 6b316d1d3..bd42630e0 100644 --- a/src/s-z/StdDev/StdDev.Utilities.cs +++ b/src/s-z/StdDev/StdDev.Utilities.cs @@ -1,16 +1,18 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// STANDARD DEVIATION (UTILITIES) + +public static partial class StdDev { - // remove recommended periods - /// - public static IReadOnlyList RemoveWarmupPeriods( - this IReadOnlyList results) + // parameter validation + internal static void Validate( + int lookbackPeriods) { - int removePeriods = results - .ToList() - .FindIndex(x => x.StdDev != null); - - return results.Remove(removePeriods); + // check parameter arguments + if (lookbackPeriods <= 1) + { + throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, + "Lookback periods must be greater than 1 for Standard Deviation."); + } } } diff --git a/src/s-z/StdDevChannels/StdDevChannels.Api.cs b/src/s-z/StdDevChannels/StdDevChannels.Api.cs deleted file mode 100644 index 6851171dd..000000000 --- a/src/s-z/StdDevChannels/StdDevChannels.Api.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Skender.Stock.Indicators; - -// STANDARD DEVIATION CHANNELS (API) -public static partial class Indicator -{ - // SERIES, from CHAIN - public static IReadOnlyList ToStdDevChannels( - this IReadOnlyList results, - int? lookbackPeriods = 20, - double stdDeviations = 2) - where T : IReusable - => results - .ToSortedList() - .CalcStdDevChannels(lookbackPeriods, stdDeviations); -} diff --git a/src/s-z/StdDevChannels/StdDevChannels.Common.cs b/src/s-z/StdDevChannels/StdDevChannels.Common.cs deleted file mode 100644 index bf56037f5..000000000 --- a/src/s-z/StdDevChannels/StdDevChannels.Common.cs +++ /dev/null @@ -1,26 +0,0 @@ -namespace Skender.Stock.Indicators; - -// STANDARD DEVIATION CHANNELS (COMMON) - -public static class StdDevChannels -{ - // parameter validation - internal static void Validate( - int? lookbackPeriods, - double stdDeviations) - { - // check parameter arguments - if (lookbackPeriods <= 1) - { - throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, - "Lookback periods must be greater than 1 for Standard Deviation Channels."); - } - - if (stdDeviations <= 0) - { - throw new ArgumentOutOfRangeException(nameof(stdDeviations), stdDeviations, - "Standard Deviations must be greater than 0 for Standard Deviation Channels."); - } - } - -} diff --git a/src/s-z/StdDevChannels/StdDevChannels.StaticSeries.cs b/src/s-z/StdDevChannels/StdDevChannels.StaticSeries.cs index 78a03d6d4..067c32127 100644 --- a/src/s-z/StdDevChannels/StdDevChannels.StaticSeries.cs +++ b/src/s-z/StdDevChannels/StdDevChannels.StaticSeries.cs @@ -1,22 +1,21 @@ namespace Skender.Stock.Indicators; -// STANDARD DEVIATION CHANNELS +// STANDARD DEVIATION CHANNELS (SERIES) -public static partial class Indicator +public static partial class StdDevChannels { - private static List CalcStdDevChannels( - this List source, - int? lookbackPeriods, - double stdDeviations) + public static IReadOnlyList ToStdDevChannels( + this IReadOnlyList source, + int? lookbackPeriods = 20, + double stdDeviations = 2) where T : IReusable { - // assume whole quotes when lookback is null - lookbackPeriods ??= source.Count; - // check parameter arguments - StdDevChannels.Validate(lookbackPeriods, stdDeviations); + ArgumentNullException.ThrowIfNull(source); + Validate(lookbackPeriods, stdDeviations); // initialize + lookbackPeriods ??= source.Count; // assume whole quotes when null int length = source.Count; IReadOnlyList slopeResults = source diff --git a/src/s-z/StdDevChannels/StdDevChannels.Utilities.cs b/src/s-z/StdDevChannels/StdDevChannels.Utilities.cs index 350ab8f77..70d382c48 100644 --- a/src/s-z/StdDevChannels/StdDevChannels.Utilities.cs +++ b/src/s-z/StdDevChannels/StdDevChannels.Utilities.cs @@ -1,6 +1,8 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// STANDARD DEVIATION CHANNELS (UTILITIES) + +public static partial class StdDevChannels { // CONDENSE (REMOVE null results) /// @@ -31,4 +33,23 @@ public static IReadOnlyList RemoveWarmupPeriods( return results.Remove(removePeriods); } + + // parameter validation + internal static void Validate( + int? lookbackPeriods, + double stdDeviations) + { + // check parameter arguments + if (lookbackPeriods <= 1) + { + throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, + "Lookback periods must be greater than 1 for Standard Deviation Channels."); + } + + if (stdDeviations <= 0) + { + throw new ArgumentOutOfRangeException(nameof(stdDeviations), stdDeviations, + "Standard Deviations must be greater than 0 for Standard Deviation Channels."); + } + } } diff --git a/src/s-z/Stoch/Stoch.Api.cs b/src/s-z/Stoch/Stoch.Api.cs deleted file mode 100644 index 936420892..000000000 --- a/src/s-z/Stoch/Stoch.Api.cs +++ /dev/null @@ -1,41 +0,0 @@ -namespace Skender.Stock.Indicators; - -// STOCHASTIC OSCILLATOR (API) -public static partial class Indicator -{ - // SERIES, from TQuote (standard) - /// - /// - public static IReadOnlyList ToStoch( - this IReadOnlyList quotes, - int lookbackPeriods = 14, - int signalPeriods = 3, - int smoothPeriods = 3) - where TQuote : IQuote => quotes - .ToQuoteDList() - .CalcStoch( - lookbackPeriods, - signalPeriods, - smoothPeriods, 3, 2, MaType.SMA); - - // SERIES, from TQuote (extended) - /// - /// - public static IReadOnlyList ToStoch( - this IReadOnlyList quotes, - int lookbackPeriods, - int signalPeriods, - int smoothPeriods, - double kFactor, - double dFactor, - MaType movingAverageType) - where TQuote : IQuote => quotes - .ToQuoteDList() - .CalcStoch( - lookbackPeriods, - signalPeriods, - smoothPeriods, - kFactor, - dFactor, - movingAverageType); -} diff --git a/src/s-z/Stoch/Stoch.Common.cs b/src/s-z/Stoch/Stoch.Common.cs deleted file mode 100644 index dbe45afd3..000000000 --- a/src/s-z/Stoch/Stoch.Common.cs +++ /dev/null @@ -1,54 +0,0 @@ -namespace Skender.Stock.Indicators; - -// STOCHASTIC OSCILLATOR (COMMON) - -public static class Stoch -{ - // parameter validation - internal static void Validate( - int lookbackPeriods, - int signalPeriods, - int smoothPeriods, - double kFactor, - double dFactor, - MaType movingAverageType) - { - // check parameter arguments - if (lookbackPeriods <= 0) - { - throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, - "Lookback periods must be greater than 0 for Stochastic."); - } - - if (signalPeriods <= 0) - { - throw new ArgumentOutOfRangeException(nameof(signalPeriods), signalPeriods, - "Signal periods must be greater than 0 for Stochastic."); - } - - if (smoothPeriods <= 0) - { - throw new ArgumentOutOfRangeException(nameof(smoothPeriods), smoothPeriods, - "Smooth periods must be greater than 0 for Stochastic."); - } - - if (kFactor <= 0) - { - throw new ArgumentOutOfRangeException(nameof(kFactor), kFactor, - "kFactor must be greater than 0 for Stochastic."); - } - - if (dFactor <= 0) - { - throw new ArgumentOutOfRangeException(nameof(dFactor), dFactor, - "dFactor must be greater than 0 for Stochastic."); - } - - if (movingAverageType is not MaType.SMA and not MaType.SMMA) - { - throw new ArgumentOutOfRangeException(nameof(dFactor), dFactor, - "Stochastic only supports SMA and SMMA moving average types."); - } - } - -} diff --git a/src/s-z/Stoch/Stoch.Models.cs b/src/s-z/Stoch/Stoch.Models.cs index 11798b267..4e060a287 100644 --- a/src/s-z/Stoch/Stoch.Models.cs +++ b/src/s-z/Stoch/Stoch.Models.cs @@ -1,7 +1,5 @@ namespace Skender.Stock.Indicators; -/// -/// public record StochResult ( DateTime Timestamp, diff --git a/src/s-z/Stoch/Stoch.StaticSeries.cs b/src/s-z/Stoch/Stoch.StaticSeries.cs index 83f3e441d..b272dfb4a 100644 --- a/src/s-z/Stoch/Stoch.StaticSeries.cs +++ b/src/s-z/Stoch/Stoch.StaticSeries.cs @@ -2,10 +2,40 @@ namespace Skender.Stock.Indicators; // STOCHASTIC OSCILLATOR (SERIES) -public static partial class Indicator +public static partial class Stoch { - private static List CalcStoch( - this List source, + public static IReadOnlyList ToStoch( + this IReadOnlyList quotes, + int lookbackPeriods = 14, + int signalPeriods = 3, + int smoothPeriods = 3) + where TQuote : IQuote => quotes + .ToQuoteDList() + .CalcStoch( + lookbackPeriods, + signalPeriods, + smoothPeriods, 3, 2, MaType.SMA); + + public static IReadOnlyList ToStoch( + this IReadOnlyList quotes, + int lookbackPeriods, + int signalPeriods, + int smoothPeriods, + double kFactor, + double dFactor, + MaType movingAverageType) + where TQuote : IQuote => quotes + .ToQuoteDList() + .CalcStoch( + lookbackPeriods, + signalPeriods, + smoothPeriods, + kFactor, + dFactor, + movingAverageType); + + internal static List CalcStoch( + this IReadOnlyList source, int lookbackPeriods, int signalPeriods, int smoothPeriods, @@ -14,7 +44,7 @@ private static List CalcStoch( MaType movingAverageType) { // check parameter arguments - Stoch.Validate( + Validate( lookbackPeriods, signalPeriods, smoothPeriods, kFactor, dFactor, movingAverageType); @@ -109,7 +139,7 @@ private static List CalcStoch( prevK = o[i]; } - k[i] = (prevK * (smoothPeriods - 1) + o[i]) / smoothPeriods; + k[i] = ((prevK * (smoothPeriods - 1)) + o[i]) / smoothPeriods; prevK = k[i]; break; } @@ -160,7 +190,7 @@ private static List CalcStoch( prevD = k[i]; } - double d = (prevD * (signalPeriods - 1) + k[i]) / signalPeriods; + double d = ((prevD * (signalPeriods - 1)) + k[i]) / signalPeriods; signal = d; prevD = d; break; @@ -179,7 +209,7 @@ private static List CalcStoch( Timestamp: q.Timestamp, Oscillator: oscillator.NaN2Null(), Signal: signal.NaN2Null(), - PercentJ: (kFactor * oscillator - dFactor * signal).NaN2Null())); + PercentJ: ((kFactor * oscillator) - (dFactor * signal)).NaN2Null())); } return results; } diff --git a/src/s-z/Stoch/Stoch.Utilities.cs b/src/s-z/Stoch/Stoch.Utilities.cs index 4a1548f68..bb1fcc708 100644 --- a/src/s-z/Stoch/Stoch.Utilities.cs +++ b/src/s-z/Stoch/Stoch.Utilities.cs @@ -1,6 +1,8 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// STOCHASTIC OSCILLATOR (UTILITIES) + +public static partial class Stoch { // remove recommended periods /// @@ -13,4 +15,51 @@ public static IReadOnlyList RemoveWarmupPeriods( return results.Remove(removePeriods); } + + // parameter validation + internal static void Validate( + int lookbackPeriods, + int signalPeriods, + int smoothPeriods, + double kFactor, + double dFactor, + MaType movingAverageType) + { + // check parameter arguments + if (lookbackPeriods <= 0) + { + throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, + "Lookback periods must be greater than 0 for Stochastic."); + } + + if (signalPeriods <= 0) + { + throw new ArgumentOutOfRangeException(nameof(signalPeriods), signalPeriods, + "Signal periods must be greater than 0 for Stochastic."); + } + + if (smoothPeriods <= 0) + { + throw new ArgumentOutOfRangeException(nameof(smoothPeriods), smoothPeriods, + "Smooth periods must be greater than 0 for Stochastic."); + } + + if (kFactor <= 0) + { + throw new ArgumentOutOfRangeException(nameof(kFactor), kFactor, + "kFactor must be greater than 0 for Stochastic."); + } + + if (dFactor <= 0) + { + throw new ArgumentOutOfRangeException(nameof(dFactor), dFactor, + "dFactor must be greater than 0 for Stochastic."); + } + + if (movingAverageType is not MaType.SMA and not MaType.SMMA) + { + throw new ArgumentOutOfRangeException(nameof(dFactor), dFactor, + "Stochastic only supports SMA and SMMA moving average types."); + } + } } diff --git a/src/s-z/StochRsi/StochRsi.Api.cs b/src/s-z/StochRsi/StochRsi.Api.cs deleted file mode 100644 index 10853a986..000000000 --- a/src/s-z/StochRsi/StochRsi.Api.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace Skender.Stock.Indicators; - -// STOCHASTIC RSI (API) -public static partial class Indicator -{ - // SERIES, from CHAIN - public static IReadOnlyList ToStochRsi( - this IReadOnlyList results, - int rsiPeriods, - int stochPeriods, - int signalPeriods, - int smoothPeriods = 1) - where T : IReusable - => results - .ToSortedList() - .CalcStochRsi( - rsiPeriods, - stochPeriods, - signalPeriods, - smoothPeriods); -} diff --git a/src/s-z/StochRsi/StochRsi.Common.cs b/src/s-z/StochRsi/StochRsi.Common.cs deleted file mode 100644 index 3f138708b..000000000 --- a/src/s-z/StochRsi/StochRsi.Common.cs +++ /dev/null @@ -1,40 +0,0 @@ -namespace Skender.Stock.Indicators; - -// STOCHASTIC RSI (COMMON) - -public static class StochRsi -{ - // parameter validation - internal static void Validate( - int rsiPeriods, - int stochPeriods, - int signalPeriods, - int smoothPeriods) - { - // check parameter arguments - if (rsiPeriods <= 0) - { - throw new ArgumentOutOfRangeException(nameof(rsiPeriods), rsiPeriods, - "RSI periods must be greater than 0 for Stochastic RSI."); - } - - if (stochPeriods <= 0) - { - throw new ArgumentOutOfRangeException(nameof(stochPeriods), stochPeriods, - "STOCH periods must be greater than 0 for Stochastic RSI."); - } - - if (signalPeriods <= 0) - { - throw new ArgumentOutOfRangeException(nameof(signalPeriods), signalPeriods, - "Signal periods must be greater than 0 for Stochastic RSI."); - } - - if (smoothPeriods <= 0) - { - throw new ArgumentOutOfRangeException(nameof(smoothPeriods), smoothPeriods, - "Smooth periods must be greater than 0 for Stochastic RSI."); - } - } - -} diff --git a/src/s-z/StochRsi/StochRsi.StaticSeries.cs b/src/s-z/StochRsi/StochRsi.StaticSeries.cs index d8ce9ea09..85837f5bf 100644 --- a/src/s-z/StochRsi/StochRsi.StaticSeries.cs +++ b/src/s-z/StochRsi/StochRsi.StaticSeries.cs @@ -2,18 +2,19 @@ namespace Skender.Stock.Indicators; // STOCHASTIC RSI (SERIES) -public static partial class Indicator +public static partial class StochRsi { - private static List CalcStochRsi( - this List source, + public static IReadOnlyList ToStochRsi( + this IReadOnlyList source, int rsiPeriods, int stochPeriods, int signalPeriods, - int smoothPeriods) + int smoothPeriods = 1) where T : IReusable { // check parameter arguments - StochRsi.Validate(rsiPeriods, stochPeriods, signalPeriods, smoothPeriods); + ArgumentNullException.ThrowIfNull(source); + Validate(rsiPeriods, stochPeriods, signalPeriods, smoothPeriods); // initialize results int length = source.Count; diff --git a/src/s-z/StochRsi/StochRsi.Utilities.cs b/src/s-z/StochRsi/StochRsi.Utilities.cs index b092f3e48..d7d71e061 100644 --- a/src/s-z/StochRsi/StochRsi.Utilities.cs +++ b/src/s-z/StochRsi/StochRsi.Utilities.cs @@ -1,6 +1,8 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// STOCHASTIC RSI (UTILITIES) + +public static partial class StochRsi { // remove recommended periods /// @@ -13,4 +15,37 @@ public static IReadOnlyList RemoveWarmupPeriods( return results.Remove(n + 100); } + + // parameter validation + internal static void Validate( + int rsiPeriods, + int stochPeriods, + int signalPeriods, + int smoothPeriods) + { + // check parameter arguments + if (rsiPeriods <= 0) + { + throw new ArgumentOutOfRangeException(nameof(rsiPeriods), rsiPeriods, + "RSI periods must be greater than 0 for Stochastic RSI."); + } + + if (stochPeriods <= 0) + { + throw new ArgumentOutOfRangeException(nameof(stochPeriods), stochPeriods, + "STOCH periods must be greater than 0 for Stochastic RSI."); + } + + if (signalPeriods <= 0) + { + throw new ArgumentOutOfRangeException(nameof(signalPeriods), signalPeriods, + "Signal periods must be greater than 0 for Stochastic RSI."); + } + + if (smoothPeriods <= 0) + { + throw new ArgumentOutOfRangeException(nameof(smoothPeriods), smoothPeriods, + "Smooth periods must be greater than 0 for Stochastic RSI."); + } + } } diff --git a/src/s-z/SuperTrend/SuperTrend.Api.cs b/src/s-z/SuperTrend/SuperTrend.Api.cs deleted file mode 100644 index 056c2adb6..000000000 --- a/src/s-z/SuperTrend/SuperTrend.Api.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace Skender.Stock.Indicators; - -// SUPERTREND (API) -public static partial class Indicator -{ - // SERIES, from TQuote - /// - /// - public static IReadOnlyList ToSuperTrend( - this IReadOnlyList quotes, - int lookbackPeriods = 10, - double multiplier = 3) - where TQuote : IQuote => quotes - .ToQuoteDList() - .CalcSuperTrend(lookbackPeriods, multiplier); -} diff --git a/src/s-z/SuperTrend/SuperTrend.Common.cs b/src/s-z/SuperTrend/SuperTrend.Common.cs deleted file mode 100644 index 3125b29cb..000000000 --- a/src/s-z/SuperTrend/SuperTrend.Common.cs +++ /dev/null @@ -1,26 +0,0 @@ -namespace Skender.Stock.Indicators; - -// SUPERTREND (COMMON) - -public static class SuperTrend -{ - // parameter validation - internal static void Validate( - int lookbackPeriods, - double multiplier) - { - // check parameter arguments - if (lookbackPeriods <= 1) - { - throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, - "Lookback periods must be greater than 1 for SuperTrend."); - } - - if (multiplier <= 0) - { - throw new ArgumentOutOfRangeException(nameof(multiplier), multiplier, - "Multiplier must be greater than 0 for SuperTrend."); - } - } - -} diff --git a/src/s-z/SuperTrend/SuperTrend.StaticSeries.cs b/src/s-z/SuperTrend/SuperTrend.StaticSeries.cs index 9bb2f8265..98e6fbee6 100644 --- a/src/s-z/SuperTrend/SuperTrend.StaticSeries.cs +++ b/src/s-z/SuperTrend/SuperTrend.StaticSeries.cs @@ -2,15 +2,23 @@ namespace Skender.Stock.Indicators; // SUPERTREND (SERIES) -public static partial class Indicator +public static partial class SuperTrend { + public static IReadOnlyList ToSuperTrend( + this IReadOnlyList quotes, + int lookbackPeriods = 10, + double multiplier = 3) + where TQuote : IQuote => quotes + .ToQuoteDList() + .CalcSuperTrend(lookbackPeriods, multiplier); + private static List CalcSuperTrend( - this List source, + this IReadOnlyList source, int lookbackPeriods, double multiplier) { // check parameter arguments - SuperTrend.Validate(lookbackPeriods, multiplier); + Validate(lookbackPeriods, multiplier); // initialize int length = source.Count; diff --git a/src/s-z/SuperTrend/SuperTrend.Utilities.cs b/src/s-z/SuperTrend/SuperTrend.Utilities.cs index 93ae76e77..052d097b9 100644 --- a/src/s-z/SuperTrend/SuperTrend.Utilities.cs +++ b/src/s-z/SuperTrend/SuperTrend.Utilities.cs @@ -1,6 +1,8 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// SUPERTREND (UTILITIES) + +public static partial class SuperTrend { // CONDENSE (REMOVE null results) /// @@ -28,4 +30,23 @@ public static IReadOnlyList RemoveWarmupPeriods( return results.Remove(removePeriods); } + + // parameter validation + internal static void Validate( + int lookbackPeriods, + double multiplier) + { + // check parameter arguments + if (lookbackPeriods <= 1) + { + throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, + "Lookback periods must be greater than 1 for SuperTrend."); + } + + if (multiplier <= 0) + { + throw new ArgumentOutOfRangeException(nameof(multiplier), multiplier, + "Multiplier must be greater than 0 for SuperTrend."); + } + } } diff --git a/src/s-z/T3/T3.Api.cs b/src/s-z/T3/T3.Api.cs deleted file mode 100644 index af3fa182c..000000000 --- a/src/s-z/T3/T3.Api.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Skender.Stock.Indicators; - -// TILLSON T3 MOVING AVERAGE (API) -public static partial class Indicator -{ - // SERIES, from CHAIN - public static IReadOnlyList ToT3( - this IReadOnlyList results, - int lookbackPeriods = 5, - double volumeFactor = 0.7) - where T : IReusable - => results - .ToSortedList() - .CalcT3(lookbackPeriods, volumeFactor); -} diff --git a/src/s-z/T3/T3.StaticSeries.cs b/src/s-z/T3/T3.StaticSeries.cs index f34fc01ed..a85bf64ac 100644 --- a/src/s-z/T3/T3.StaticSeries.cs +++ b/src/s-z/T3/T3.StaticSeries.cs @@ -2,16 +2,17 @@ namespace Skender.Stock.Indicators; // TILLSON T3 MOVING AVERAGE (SERIES) -public static partial class Indicator +public static partial class T3 { - private static List CalcT3( - this List source, - int lookbackPeriods, - double volumeFactor) + public static IReadOnlyList ToT3( + this IReadOnlyList source, + int lookbackPeriods = 5, + double volumeFactor = 0.7) where T : IReusable { // check parameter arguments - T3.Validate(lookbackPeriods, volumeFactor); + ArgumentNullException.ThrowIfNull(source); + Validate(lookbackPeriods, volumeFactor); // initialize int length = source.Count; diff --git a/src/s-z/T3/T3.Common.cs b/src/s-z/T3/T3.Utilities.cs similarity index 89% rename from src/s-z/T3/T3.Common.cs rename to src/s-z/T3/T3.Utilities.cs index 797dee7b6..70c4264aa 100644 --- a/src/s-z/T3/T3.Common.cs +++ b/src/s-z/T3/T3.Utilities.cs @@ -1,8 +1,8 @@ namespace Skender.Stock.Indicators; -// TILLSON T3 MOVING AVERAGE (COMMON) +// TILLSON T3 MOVING AVERAGE (UTILITIES) -public static class T3 +public static partial class T3 { // parameter validation internal static void Validate( @@ -22,5 +22,4 @@ internal static void Validate( "Volume Factor must be greater than 0 for T3."); } } - } diff --git a/src/s-z/Tema/Tema.Utilities.cs b/src/s-z/Tema/Tema.Utilities.cs index 3e9946637..963479cb1 100644 --- a/src/s-z/Tema/Tema.Utilities.cs +++ b/src/s-z/Tema/Tema.Utilities.cs @@ -1,5 +1,7 @@ namespace Skender.Stock.Indicators; +// TRIPLE EXPONENTIAL MOVING AVERAGE (UTILITIES) + public static partial class Tema { // remove recommended periods diff --git a/src/s-z/Tr/Tr.Api.cs b/src/s-z/Tr/Tr.Api.cs deleted file mode 100644 index eaeee9561..000000000 --- a/src/s-z/Tr/Tr.Api.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace Skender.Stock.Indicators; - -// TRUE RANGE (API) - -public static partial class Tr -{ - // SERIES, from TQuote - /// - /// - public static IReadOnlyList ToTr( - this IReadOnlyList quotes) - where TQuote : IQuote => quotes - .ToQuoteDList() - .CalcTr(); - - // OBSERVER, from Quote Provider - public static TrHub ToTr( - this IQuoteProvider quoteProvider) - where TIn : IQuote - => new(quoteProvider); -} diff --git a/src/s-z/Tr/Tr.StaticSeries.cs b/src/s-z/Tr/Tr.StaticSeries.cs index 54100a88e..79fa0dbaf 100644 --- a/src/s-z/Tr/Tr.StaticSeries.cs +++ b/src/s-z/Tr/Tr.StaticSeries.cs @@ -4,9 +4,14 @@ namespace Skender.Stock.Indicators; public static partial class Tr { - // calculate series + public static IReadOnlyList ToTr( + this IReadOnlyList quotes) + where TQuote : IQuote => quotes + .ToQuoteDList() + .CalcTr(); + private static List CalcTr( - this List source) + this IReadOnlyList source) { // initialize int length = source.Count; diff --git a/src/s-z/Tr/Tr.StreamHub.cs b/src/s-z/Tr/Tr.StreamHub.cs index 3d10f2e61..ea0803e9b 100644 --- a/src/s-z/Tr/Tr.StreamHub.cs +++ b/src/s-z/Tr/Tr.StreamHub.cs @@ -2,6 +2,17 @@ namespace Skender.Stock.Indicators; // TRUE RANGE (STREAM HUB) +#region initializer + +public static partial class Tr +{ + public static TrHub ToTr( + this IQuoteProvider quoteProvider) + where TIn : IQuote + => new(quoteProvider); +} +#endregion + public class TrHub : ChainProvider where TIn : IQuote diff --git a/src/s-z/Tr/Tr.Utilities.cs b/src/s-z/Tr/Tr.Utilities.cs index 5e53022cb..d6f9f4d09 100644 --- a/src/s-z/Tr/Tr.Utilities.cs +++ b/src/s-z/Tr/Tr.Utilities.cs @@ -2,13 +2,8 @@ namespace Skender.Stock.Indicators; // TRUE RANGE (UTILITIES) -/// See the -/// Stock Indicators for .NET online guide for more information. public static partial class Tr { - // increment calculation - /// - /// public static double Increment( double high, double low, diff --git a/src/s-z/Trix/Trix.Api.cs b/src/s-z/Trix/Trix.Api.cs deleted file mode 100644 index 0dad6ca8b..000000000 --- a/src/s-z/Trix/Trix.Api.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Skender.Stock.Indicators; - -// TRIPLE EMA OSCILLATOR - TRIX (API) -public static partial class Indicator -{ - // SERIES, from CHAIN - public static IReadOnlyList ToTrix( - this IReadOnlyList results, - int lookbackPeriods) - where T : IReusable - => results - .ToSortedList() - .CalcTrix(lookbackPeriods); -} diff --git a/src/s-z/Trix/Trix.Common.cs b/src/s-z/Trix/Trix.Common.cs deleted file mode 100644 index c9028974f..000000000 --- a/src/s-z/Trix/Trix.Common.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Skender.Stock.Indicators; - -// TRIPLE EMA OSCILLATOR - TRIX (COMMON) - -public static class Trix -{ - // parameter validation - internal static void Validate( - int lookbackPeriods) - { - // check parameter arguments - if (lookbackPeriods <= 0) - { - throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, - "Lookback periods must be greater than 0 for TRIX."); - } - } - -} diff --git a/src/s-z/Trix/Trix.StaticSeries.cs b/src/s-z/Trix/Trix.StaticSeries.cs index 0d8f70380..a94818133 100644 --- a/src/s-z/Trix/Trix.StaticSeries.cs +++ b/src/s-z/Trix/Trix.StaticSeries.cs @@ -2,15 +2,16 @@ namespace Skender.Stock.Indicators; // TRIPLE EMA OSCILLATOR - TRIX (SERIES) -public static partial class Indicator +public static partial class Trix { - private static List CalcTrix( - this List source, + public static IReadOnlyList ToTrix( + this IReadOnlyList source, int lookbackPeriods) where T : IReusable { // check parameter arguments - Trix.Validate(lookbackPeriods); + ArgumentNullException.ThrowIfNull(source); + Validate(lookbackPeriods); // initialize int length = source.Count; diff --git a/src/s-z/Trix/Trix.Utilities.cs b/src/s-z/Trix/Trix.Utilities.cs index e2661bed9..ce869af82 100644 --- a/src/s-z/Trix/Trix.Utilities.cs +++ b/src/s-z/Trix/Trix.Utilities.cs @@ -1,6 +1,8 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// TRIPLE EMA OSCILLATOR - TRIX (UTILITIES) + +public static partial class Trix { // remove recommended periods /// @@ -13,4 +15,16 @@ public static IReadOnlyList RemoveWarmupPeriods( return results.Remove(3 * n + 100); } + + // parameter validation + internal static void Validate( + int lookbackPeriods) + { + // check parameter arguments + if (lookbackPeriods <= 0) + { + throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, + "Lookback periods must be greater than 0 for TRIX."); + } + } } diff --git a/src/s-z/Tsi/Tsi.Api.cs b/src/s-z/Tsi/Tsi.Api.cs deleted file mode 100644 index 137f65929..000000000 --- a/src/s-z/Tsi/Tsi.Api.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace Skender.Stock.Indicators; - -// TRUE STRENGTH INDEX (API) -public static partial class Indicator -{ - // SERIES, from CHAIN - public static IReadOnlyList ToTsi( - this IReadOnlyList results, - int lookbackPeriods = 25, - int smoothPeriods = 13, - int signalPeriods = 7) - where T : IReusable - => results - .ToSortedList() - .CalcTsi(lookbackPeriods, smoothPeriods, signalPeriods); -} diff --git a/src/s-z/Tsi/Tsi.Common.cs b/src/s-z/Tsi/Tsi.Common.cs deleted file mode 100644 index 862d388db..000000000 --- a/src/s-z/Tsi/Tsi.Common.cs +++ /dev/null @@ -1,33 +0,0 @@ -namespace Skender.Stock.Indicators; - -// TRUE STRENGTH INDEX (COMMON) - -public static class Tsi -{ - // parameter validation - internal static void Validate( - int lookbackPeriods, - int smoothPeriods, - int signalPeriods) - { - // check parameter arguments - if (lookbackPeriods <= 0) - { - throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, - "Lookback periods must be greater than 0 for TSI."); - } - - if (smoothPeriods <= 0) - { - throw new ArgumentOutOfRangeException(nameof(smoothPeriods), smoothPeriods, - "Smoothing periods must be greater than 0 for TSI."); - } - - if (signalPeriods < 0) - { - throw new ArgumentOutOfRangeException(nameof(signalPeriods), signalPeriods, - "Signal periods must be greater than or equal to 0 for TSI."); - } - } - -} diff --git a/src/s-z/Tsi/Tsi.StaticSeries.cs b/src/s-z/Tsi/Tsi.StaticSeries.cs index ff76ac646..578f6ab88 100644 --- a/src/s-z/Tsi/Tsi.StaticSeries.cs +++ b/src/s-z/Tsi/Tsi.StaticSeries.cs @@ -2,17 +2,18 @@ namespace Skender.Stock.Indicators; // TRUE STRENGTH INDEX (SERIES) -public static partial class Indicator +public static partial class Tsi { - private static List CalcTsi( - this List source, - int lookbackPeriods, - int smoothPeriods, - int signalPeriods) + public static IReadOnlyList ToTsi( + this IReadOnlyList source, + int lookbackPeriods = 25, + int smoothPeriods = 13, + int signalPeriods = 7) where T : IReusable { // check parameter arguments - Tsi.Validate(lookbackPeriods, smoothPeriods, signalPeriods); + ArgumentNullException.ThrowIfNull(source); + Validate(lookbackPeriods, smoothPeriods, signalPeriods); // initialize int length = source.Count; diff --git a/src/s-z/Tsi/Tsi.Utilities.cs b/src/s-z/Tsi/Tsi.Utilities.cs index a78af3e0c..16b08c8ef 100644 --- a/src/s-z/Tsi/Tsi.Utilities.cs +++ b/src/s-z/Tsi/Tsi.Utilities.cs @@ -1,6 +1,8 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// TRUE STRENGTH INDEX (UTILITIES) + +public static partial class Tsi { // remove recommended periods /// @@ -13,4 +15,30 @@ public static IReadOnlyList RemoveWarmupPeriods( return results.Remove(nm + 250); } + + // parameter validation + internal static void Validate( + int lookbackPeriods, + int smoothPeriods, + int signalPeriods) + { + // check parameter arguments + if (lookbackPeriods <= 0) + { + throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, + "Lookback periods must be greater than 0 for TSI."); + } + + if (smoothPeriods <= 0) + { + throw new ArgumentOutOfRangeException(nameof(smoothPeriods), smoothPeriods, + "Smoothing periods must be greater than 0 for TSI."); + } + + if (signalPeriods < 0) + { + throw new ArgumentOutOfRangeException(nameof(signalPeriods), signalPeriods, + "Signal periods must be greater than or equal to 0 for TSI."); + } + } } diff --git a/src/s-z/UlcerIndex/UlcerIndex.Api.cs b/src/s-z/UlcerIndex/UlcerIndex.Api.cs deleted file mode 100644 index 61248598e..000000000 --- a/src/s-z/UlcerIndex/UlcerIndex.Api.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Skender.Stock.Indicators; - -// ULCER INDEX (API) -public static partial class Indicator -{ - // SERIES, from CHAIN - public static IReadOnlyList ToUlcerIndex( - this IReadOnlyList results, - int lookbackPeriods = 14) - where T : IReusable - => results - .ToSortedList() - .CalcUlcerIndex(lookbackPeriods); -} diff --git a/src/s-z/UlcerIndex/UlcerIndex.Common.cs b/src/s-z/UlcerIndex/UlcerIndex.Common.cs deleted file mode 100644 index 7e203219e..000000000 --- a/src/s-z/UlcerIndex/UlcerIndex.Common.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Skender.Stock.Indicators; - -// ULCER INDEX (COMMON) - -public static class UlcerIndex -{ - // parameter validation - internal static void Validate( - int lookbackPeriods) - { - // check parameter arguments - if (lookbackPeriods <= 0) - { - throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, - "Lookback periods must be greater than 0 for Ulcer Index."); - } - } - -} diff --git a/src/s-z/UlcerIndex/UlcerIndex.StaticSeries.cs b/src/s-z/UlcerIndex/UlcerIndex.StaticSeries.cs index 819a60ebf..29f7a3bc3 100644 --- a/src/s-z/UlcerIndex/UlcerIndex.StaticSeries.cs +++ b/src/s-z/UlcerIndex/UlcerIndex.StaticSeries.cs @@ -2,15 +2,16 @@ namespace Skender.Stock.Indicators; // ULCER INDEX (SERIES) -public static partial class Indicator +public static partial class UlcerIndex { - private static List CalcUlcerIndex( - this List source, - int lookbackPeriods) + public static IReadOnlyList ToUlcerIndex( + this IReadOnlyList source, + int lookbackPeriods = 14) where T : IReusable { // check parameter arguments - UlcerIndex.Validate(lookbackPeriods); + ArgumentNullException.ThrowIfNull(source); + Validate(lookbackPeriods); // initialize int length = source.Count; diff --git a/src/s-z/UlcerIndex/UlcerIndex.Utilities.cs b/src/s-z/UlcerIndex/UlcerIndex.Utilities.cs index 421fa0099..26679c7a6 100644 --- a/src/s-z/UlcerIndex/UlcerIndex.Utilities.cs +++ b/src/s-z/UlcerIndex/UlcerIndex.Utilities.cs @@ -1,16 +1,18 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// ULCER INDEX (UTILITIES) + +public static partial class UlcerIndex { - // remove recommended periods - /// - public static IReadOnlyList RemoveWarmupPeriods( - this IReadOnlyList results) + // parameter validation + internal static void Validate( + int lookbackPeriods) { - int removePeriods = results - .ToList() - .FindIndex(x => x.UlcerIndex != null); - - return results.Remove(removePeriods); + // check parameter arguments + if (lookbackPeriods <= 0) + { + throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, + "Lookback periods must be greater than 0 for Ulcer Index."); + } } } diff --git a/src/s-z/Ultimate/Ultimate.Api.cs b/src/s-z/Ultimate/Ultimate.Api.cs deleted file mode 100644 index b75449711..000000000 --- a/src/s-z/Ultimate/Ultimate.Api.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace Skender.Stock.Indicators; - -// ULTIMATE OSCILLATOR (API) -public static partial class Indicator -{ - // SERIES, from TQuote - /// - /// - public static IReadOnlyList ToUltimate( - this IReadOnlyList quotes, - int shortPeriods = 7, - int middlePeriods = 14, - int longPeriods = 28) - where TQuote : IQuote => quotes - .ToQuoteDList() - .CalcUltimate(shortPeriods, middlePeriods, longPeriods); -} diff --git a/src/s-z/Ultimate/Ultimate.Common.cs b/src/s-z/Ultimate/Ultimate.Common.cs deleted file mode 100644 index 115b0fd1b..000000000 --- a/src/s-z/Ultimate/Ultimate.Common.cs +++ /dev/null @@ -1,27 +0,0 @@ -namespace Skender.Stock.Indicators; - -// ULTIMATE OSCILLATOR (COMMON) - -public static class Ultimate -{ - // parameter validation - internal static void Validate( - int shortPeriods, - int middleAverage, - int longPeriods) - { - // check parameter arguments - if (shortPeriods <= 0 || middleAverage <= 0 || longPeriods <= 0) - { - throw new ArgumentOutOfRangeException(nameof(longPeriods), longPeriods, - "Average periods must be greater than 0 for Ultimate Oscillator."); - } - - if (shortPeriods >= middleAverage || middleAverage >= longPeriods) - { - throw new ArgumentOutOfRangeException(nameof(middleAverage), middleAverage, - "Average periods must be increasingly larger than each other for Ultimate Oscillator."); - } - } - -} diff --git a/src/s-z/Ultimate/Ultimate.StaticSeries.cs b/src/s-z/Ultimate/Ultimate.StaticSeries.cs index e477adaf5..a4978492b 100644 --- a/src/s-z/Ultimate/Ultimate.StaticSeries.cs +++ b/src/s-z/Ultimate/Ultimate.StaticSeries.cs @@ -2,16 +2,25 @@ namespace Skender.Stock.Indicators; // ULTIMATE OSCILLATOR (SERIES) -public static partial class Indicator +public static partial class Ultimate { + public static IReadOnlyList ToUltimate( + this IReadOnlyList quotes, + int shortPeriods = 7, + int middlePeriods = 14, + int longPeriods = 28) + where TQuote : IQuote => quotes + .ToQuoteDList() + .CalcUltimate(shortPeriods, middlePeriods, longPeriods); + private static List CalcUltimate( - this List source, + this IReadOnlyList source, int shortPeriods, int middlePeriods, int longPeriods) { // check parameter arguments - Ultimate.Validate(shortPeriods, middlePeriods, longPeriods); + Validate(shortPeriods, middlePeriods, longPeriods); // initialize int length = source.Count; diff --git a/src/s-z/Ultimate/Ultimate.Utilities.cs b/src/s-z/Ultimate/Ultimate.Utilities.cs index 6c37ba72f..63c6da0ff 100644 --- a/src/s-z/Ultimate/Ultimate.Utilities.cs +++ b/src/s-z/Ultimate/Ultimate.Utilities.cs @@ -1,16 +1,26 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// ULTIMATE OSCILLATOR (UTILITIES) + +public static partial class Ultimate { - // remove recommended periods - /// - public static IReadOnlyList RemoveWarmupPeriods( - this IReadOnlyList results) + // parameter validation + internal static void Validate( + int shortPeriods, + int middleAverage, + int longPeriods) { - int removePeriods = results - .ToList() - .FindIndex(x => x.Ultimate != null); + // check parameter arguments + if (shortPeriods <= 0 || middleAverage <= 0 || longPeriods <= 0) + { + throw new ArgumentOutOfRangeException(nameof(longPeriods), longPeriods, + "Average periods must be greater than 0 for Ultimate Oscillator."); + } - return results.Remove(removePeriods); + if (shortPeriods >= middleAverage || middleAverage >= longPeriods) + { + throw new ArgumentOutOfRangeException(nameof(middleAverage), middleAverage, + "Average periods must be increasingly larger than each other for Ultimate Oscillator."); + } } } diff --git a/src/s-z/VolatilityStop/VolatilityStop.Api.cs b/src/s-z/VolatilityStop/VolatilityStop.Api.cs deleted file mode 100644 index 90e5dd2ee..000000000 --- a/src/s-z/VolatilityStop/VolatilityStop.Api.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace Skender.Stock.Indicators; - -// VOLATILITY SYSTEM/STOP (API) -public static partial class Indicator -{ - // SERIES, from TQuote - /// - /// - public static IReadOnlyList ToVolatilityStop( - this IReadOnlyList quotes, - int lookbackPeriods = 7, - double multiplier = 3) - where TQuote : IQuote => quotes - .ToQuoteDList() - .CalcVolatilityStop(lookbackPeriods, multiplier); -} diff --git a/src/s-z/VolatilityStop/VolatilityStop.Common.cs b/src/s-z/VolatilityStop/VolatilityStop.Common.cs deleted file mode 100644 index 2beb0f8d1..000000000 --- a/src/s-z/VolatilityStop/VolatilityStop.Common.cs +++ /dev/null @@ -1,26 +0,0 @@ -namespace Skender.Stock.Indicators; - -// VOLATILITY SYSTEM/STOP (COMMON) - -public static class VolatilityStop -{ - // parameter validation - internal static void Validate( - int lookbackPeriods, - double multiplier) - { - // check parameter arguments - if (lookbackPeriods <= 1) - { - throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, - "Lookback periods must be greater than 1 for Volatility Stop."); - } - - if (multiplier <= 0) - { - throw new ArgumentOutOfRangeException(nameof(multiplier), multiplier, - "ATR Multiplier must be greater than 0 for Volatility Stop."); - } - } - -} diff --git a/src/s-z/VolatilityStop/VolatilityStop.StaticSeries.cs b/src/s-z/VolatilityStop/VolatilityStop.StaticSeries.cs index bb82e67bb..9b30ea8ea 100644 --- a/src/s-z/VolatilityStop/VolatilityStop.StaticSeries.cs +++ b/src/s-z/VolatilityStop/VolatilityStop.StaticSeries.cs @@ -2,10 +2,18 @@ namespace Skender.Stock.Indicators; // VOLATILITY SYSTEM/STOP (SERIES) -public static partial class Indicator +public static partial class VolatilityStop { + public static IReadOnlyList ToVolatilityStop( + this IReadOnlyList quotes, + int lookbackPeriods = 7, + double multiplier = 3) + where TQuote : IQuote => quotes + .ToQuoteDList() + .CalcVolatilityStop(lookbackPeriods, multiplier); + private static List CalcVolatilityStop( - this List source, + this IReadOnlyList source, int lookbackPeriods, double multiplier) { @@ -15,7 +23,7 @@ private static List CalcVolatilityStop( .ToList(); // check parameter arguments - VolatilityStop.Validate(lookbackPeriods, multiplier); + Validate(lookbackPeriods, multiplier); // initialize int length = source.Count; diff --git a/src/s-z/VolatilityStop/VolatilityStop.Utilities.cs b/src/s-z/VolatilityStop/VolatilityStop.Utilities.cs index 6213ab213..ec65d0404 100644 --- a/src/s-z/VolatilityStop/VolatilityStop.Utilities.cs +++ b/src/s-z/VolatilityStop/VolatilityStop.Utilities.cs @@ -1,6 +1,8 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// VOLATILITY SYSTEM/STOP (UTILITIES) + +public static partial class VolatilityStop { // remove recommended periods /// @@ -15,4 +17,23 @@ public static IReadOnlyList RemoveWarmupPeriods( return results.Remove(removePeriods); } + + // parameter validation + internal static void Validate( + int lookbackPeriods, + double multiplier) + { + // check parameter arguments + if (lookbackPeriods <= 1) + { + throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, + "Lookback periods must be greater than 1 for Volatility Stop."); + } + + if (multiplier <= 0) + { + throw new ArgumentOutOfRangeException(nameof(multiplier), multiplier, + "ATR Multiplier must be greater than 0 for Volatility Stop."); + } + } } diff --git a/src/s-z/Vortex/Vortex.Api.cs b/src/s-z/Vortex/Vortex.Api.cs deleted file mode 100644 index 761dd2d72..000000000 --- a/src/s-z/Vortex/Vortex.Api.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Skender.Stock.Indicators; - -// VORTEX INDICATOR (API) -public static partial class Indicator -{ - // SERIES, from TQuote - /// - /// - public static IReadOnlyList ToVortex( - this IReadOnlyList quotes, - int lookbackPeriods) - where TQuote : IQuote => quotes - .ToQuoteDList() - .CalcVortex(lookbackPeriods); -} diff --git a/src/s-z/Vortex/Vortex.Common.cs b/src/s-z/Vortex/Vortex.Common.cs deleted file mode 100644 index f5d0a7702..000000000 --- a/src/s-z/Vortex/Vortex.Common.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Skender.Stock.Indicators; - -// VORTEX INDICATOR (COMMON) - -public static class Vortex -{ - // parameter validation - internal static void Validate( - int lookbackPeriods) - { - // check parameter arguments - if (lookbackPeriods <= 1) - { - throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, - "Lookback periods must be greater than 1 for VI."); - } - } - -} diff --git a/src/s-z/Vortex/Vortex.StaticSeries.cs b/src/s-z/Vortex/Vortex.StaticSeries.cs index 0e95ecfb9..2d6ce4549 100644 --- a/src/s-z/Vortex/Vortex.StaticSeries.cs +++ b/src/s-z/Vortex/Vortex.StaticSeries.cs @@ -2,14 +2,21 @@ namespace Skender.Stock.Indicators; // VORTEX INDICATOR (SERIES) -public static partial class Indicator +public static partial class Vortex { + public static IReadOnlyList ToVortex( + this IReadOnlyList quotes, + int lookbackPeriods) + where TQuote : IQuote => quotes + .ToQuoteDList() + .CalcVortex(lookbackPeriods); + private static List CalcVortex( - this List source, + this IReadOnlyList source, int lookbackPeriods) { // check parameter arguments - Vortex.Validate(lookbackPeriods); + Validate(lookbackPeriods); // initialize int length = source.Count; diff --git a/src/s-z/Vortex/Vortex.Utilities.cs b/src/s-z/Vortex/Vortex.Utilities.cs index 85907c47a..22e449b50 100644 --- a/src/s-z/Vortex/Vortex.Utilities.cs +++ b/src/s-z/Vortex/Vortex.Utilities.cs @@ -1,6 +1,8 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// VORTEX INDICATOR (UTILITIES) + +public static partial class Vortex { // CONDENSE (REMOVE null results) /// @@ -28,4 +30,16 @@ public static IReadOnlyList RemoveWarmupPeriods( return results.Remove(removePeriods); } + + // parameter validation + internal static void Validate( + int lookbackPeriods) + { + // check parameter arguments + if (lookbackPeriods <= 1) + { + throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, + "Lookback periods must be greater than 1 for VI."); + } + } } diff --git a/src/s-z/Vwap/Vwap.Api.cs b/src/s-z/Vwap/Vwap.Api.cs deleted file mode 100644 index 2e1cc8081..000000000 --- a/src/s-z/Vwap/Vwap.Api.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Skender.Stock.Indicators; - -// VOLUME WEIGHTED AVERAGE PRICE (API) -public static partial class Indicator -{ - // SERIES, from TQuote - /// - /// - public static IReadOnlyList ToVwap( - this IReadOnlyList quotes, - DateTime? startDate = null) - where TQuote : IQuote => quotes - .ToQuoteDList() - .CalcVwap(startDate); -} diff --git a/src/s-z/Vwap/Vwap.Common.cs b/src/s-z/Vwap/Vwap.Common.cs deleted file mode 100644 index f6755a855..000000000 --- a/src/s-z/Vwap/Vwap.Common.cs +++ /dev/null @@ -1,26 +0,0 @@ -namespace Skender.Stock.Indicators; - -// VOLUME WEIGHTED AVERAGE PRICE (COMMON) - -public static class Vwap -{ - // parameter validation - internal static void Validate( - List quotesList, - DateTime? startDate) - { - // nothing to do for 0 length - if (quotesList.Count == 0) - { - return; - } - - // check parameter arguments (intentionally after quotes check) - if (startDate < quotesList[0].Timestamp) - { - throw new ArgumentOutOfRangeException(nameof(startDate), startDate, - "Start Timestamp must be within the quotes range for VWAP."); - } - } - -} diff --git a/src/s-z/Vwap/Vwap.StaticSeries.cs b/src/s-z/Vwap/Vwap.StaticSeries.cs index a4a1e8f5c..0f31b1505 100644 --- a/src/s-z/Vwap/Vwap.StaticSeries.cs +++ b/src/s-z/Vwap/Vwap.StaticSeries.cs @@ -2,14 +2,21 @@ namespace Skender.Stock.Indicators; // VOLUME WEIGHTED AVERAGE PRICE (SERIES) -public static partial class Indicator +public static partial class Vwap { + public static IReadOnlyList ToVwap( + this IReadOnlyList quotes, + DateTime? startDate = null) + where TQuote : IQuote => quotes + .ToQuoteDList() + .CalcVwap(startDate); + private static List CalcVwap( - this List source, + this IReadOnlyList source, DateTime? startDate = null) { // check parameter arguments - Vwap.Validate(source, startDate); + Validate(source, startDate); // initialize int length = source.Count; diff --git a/src/s-z/Vwap/Vwap.Utilities.cs b/src/s-z/Vwap/Vwap.Utilities.cs index b8a3836bd..bf24c9fea 100644 --- a/src/s-z/Vwap/Vwap.Utilities.cs +++ b/src/s-z/Vwap/Vwap.Utilities.cs @@ -1,6 +1,8 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// VOLUME WEIGHTED AVERAGE PRICE (UTILITIES) + +public static partial class Vwap { // remove recommended periods /// @@ -13,4 +15,23 @@ public static IReadOnlyList RemoveWarmupPeriods( return results.Remove(removePeriods); } + + // parameter validation + internal static void Validate( + IReadOnlyList quotes, + DateTime? startDate) + { + // nothing to do for 0 length + if (quotes.Count == 0) + { + return; + } + + // check parameter arguments (intentionally after quotes check) + if (startDate < quotes[0].Timestamp) + { + throw new ArgumentOutOfRangeException(nameof(startDate), startDate, + "Start Timestamp must be within the quotes range for VWAP."); + } + } } diff --git a/src/s-z/Vwma/Vwma.Api.cs b/src/s-z/Vwma/Vwma.Api.cs deleted file mode 100644 index 6a265cdbb..000000000 --- a/src/s-z/Vwma/Vwma.Api.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Skender.Stock.Indicators; - -// VOLUME WEIGHTED MOVING AVERAGE (API) -public static partial class Indicator -{ - // SERIES, from TQuote - /// - /// - public static IReadOnlyList ToVwma( - this IReadOnlyList quotes, - int lookbackPeriods) - where TQuote : IQuote => quotes - .ToQuoteDList() - .CalcVwma(lookbackPeriods); -} diff --git a/src/s-z/Vwma/Vwma.Common.cs b/src/s-z/Vwma/Vwma.Common.cs deleted file mode 100644 index a99db7fce..000000000 --- a/src/s-z/Vwma/Vwma.Common.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Skender.Stock.Indicators; - -// VOLUME WEIGHTED MOVING AVERAGE (COMMON) - -public static class Vwma -{ - // parameter validation - internal static void Validate( - int lookbackPeriods) - { - // check parameter arguments - if (lookbackPeriods <= 0) - { - throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, - "Lookback periods must be greater than 0 for Vwma."); - } - } - -} diff --git a/src/s-z/Vwma/Vwma.StaticSeries.cs b/src/s-z/Vwma/Vwma.StaticSeries.cs index c7ae21839..20c4c689e 100644 --- a/src/s-z/Vwma/Vwma.StaticSeries.cs +++ b/src/s-z/Vwma/Vwma.StaticSeries.cs @@ -2,14 +2,21 @@ namespace Skender.Stock.Indicators; // VOLUME WEIGHTED MOVING AVERAGE (SERIES) -public static partial class Indicator +public static partial class Vwma { + public static IReadOnlyList ToVwma( + this IReadOnlyList quotes, + int lookbackPeriods) + where TQuote : IQuote => quotes + .ToQuoteDList() + .CalcVwma(lookbackPeriods); + private static List CalcVwma( - this List source, + this IReadOnlyList source, int lookbackPeriods) { // check parameter arguments - Vwma.Validate(lookbackPeriods); + Validate(lookbackPeriods); // initialize int length = source.Count; diff --git a/src/s-z/Vwma/Vwma.Utilities.cs b/src/s-z/Vwma/Vwma.Utilities.cs index de20abfce..dd43909b3 100644 --- a/src/s-z/Vwma/Vwma.Utilities.cs +++ b/src/s-z/Vwma/Vwma.Utilities.cs @@ -1,16 +1,18 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// VOLUME WEIGHTED MOVING AVERAGE (UTILITIES) + +public static partial class Vwma { - // remove recommended periods - /// - public static IReadOnlyList RemoveWarmupPeriods( - this IReadOnlyList results) + // parameter validation + internal static void Validate( + int lookbackPeriods) { - int removePeriods = results - .ToList() - .FindIndex(x => x.Vwma != null); - - return results.Remove(removePeriods); + // check parameter arguments + if (lookbackPeriods <= 0) + { + throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, + "Lookback periods must be greater than 0 for Vwma."); + } } } diff --git a/src/s-z/WilliamsR/WilliamsR.Api.cs b/src/s-z/WilliamsR/WilliamsR.Api.cs deleted file mode 100644 index 10fc6971a..000000000 --- a/src/s-z/WilliamsR/WilliamsR.Api.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Skender.Stock.Indicators; - -// WILLIAM %R OSCILLATOR (API) -public static partial class Indicator -{ - // SERIES, from TQuote - /// - /// - public static IReadOnlyList ToWilliamsR( - this IReadOnlyList quotes, - int lookbackPeriods = 14) - where TQuote : IQuote => quotes - .ToQuoteDList() - .CalcWilliamsR(lookbackPeriods); -} diff --git a/src/s-z/WilliamsR/WilliamsR.Common.cs b/src/s-z/WilliamsR/WilliamsR.Common.cs deleted file mode 100644 index 8ef455e8a..000000000 --- a/src/s-z/WilliamsR/WilliamsR.Common.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Skender.Stock.Indicators; - -// WILLIAM %R OSCILLATOR (COMMON) - -public static class WilliamsR -{ - // parameter validation - internal static void Validate( - int lookbackPeriods) - { - // check parameter arguments - if (lookbackPeriods <= 0) - { - throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, - "Lookback periods must be greater than 0 for William %R."); - } - } - -} diff --git a/src/s-z/WilliamsR/WilliamsR.StaticSeries.cs b/src/s-z/WilliamsR/WilliamsR.StaticSeries.cs index bece3f912..23becb293 100644 --- a/src/s-z/WilliamsR/WilliamsR.StaticSeries.cs +++ b/src/s-z/WilliamsR/WilliamsR.StaticSeries.cs @@ -2,14 +2,21 @@ namespace Skender.Stock.Indicators; // WILLIAM %R OSCILLATOR (SERIES) -public static partial class Indicator +public static partial class WilliamsR { + public static IReadOnlyList ToWilliamsR( + this IReadOnlyList quotes, + int lookbackPeriods = 14) + where TQuote : IQuote => quotes + .ToQuoteDList() + .CalcWilliamsR(lookbackPeriods); + private static List CalcWilliamsR( - this List source, + this IReadOnlyList source, int lookbackPeriods) { // check parameter arguments - WilliamsR.Validate(lookbackPeriods); + Validate(lookbackPeriods); // convert Fast Stochastic to William %R return source.CalcStoch(lookbackPeriods, 1, 1, 3, 2, MaType.SMA) diff --git a/src/s-z/WilliamsR/WilliamsR.Utilities.cs b/src/s-z/WilliamsR/WilliamsR.Utilities.cs index cd5f5cb19..49f8d8af1 100644 --- a/src/s-z/WilliamsR/WilliamsR.Utilities.cs +++ b/src/s-z/WilliamsR/WilliamsR.Utilities.cs @@ -1,16 +1,18 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// WILLIAM %R OSCILLATOR (UTILITIES) + +public static partial class WilliamsR { - // remove recommended periods - /// - public static IReadOnlyList RemoveWarmupPeriods( - this IReadOnlyList results) + // parameter validation + internal static void Validate( + int lookbackPeriods) { - int removePeriods = results - .ToList() - .FindIndex(x => x.WilliamsR != null); - - return results.Remove(removePeriods); + // check parameter arguments + if (lookbackPeriods <= 0) + { + throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, + "Lookback periods must be greater than 0 for William %R."); + } } } diff --git a/src/s-z/Wma/Wma.Utilities.cs b/src/s-z/Wma/Wma.Utilities.cs index 341abf976..cd7b65c13 100644 --- a/src/s-z/Wma/Wma.Utilities.cs +++ b/src/s-z/Wma/Wma.Utilities.cs @@ -1,5 +1,7 @@ namespace Skender.Stock.Indicators; +// WEIGHTED MOVING AVERAGE (UTILITIES) + public static partial class Wma { // parameter validation diff --git a/src/s-z/ZigZag/ZigZag.Api.cs b/src/s-z/ZigZag/ZigZag.Api.cs deleted file mode 100644 index 65c747017..000000000 --- a/src/s-z/ZigZag/ZigZag.Api.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace Skender.Stock.Indicators; - -// ZIG ZAG (API) -public static partial class Indicator -{ - // SERIES, from TQuote - /// - /// - public static IReadOnlyList ToZigZag( - this IReadOnlyList quotes, - EndType endType = EndType.Close, - decimal percentChange = 5) - where TQuote : IQuote => quotes - .ToSortedList() - .CalcZigZag(endType, percentChange); -} diff --git a/src/s-z/ZigZag/ZigZag.Common.cs b/src/s-z/ZigZag/ZigZag.Common.cs deleted file mode 100644 index fdcd0bc0a..000000000 --- a/src/s-z/ZigZag/ZigZag.Common.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Skender.Stock.Indicators; - -// ZIG ZAG (COMMON) - -public static class ZigZag -{ - // parameter validation - internal static void Validate( - decimal percentChange) - { - // check parameter arguments - if (percentChange <= 0) - { - throw new ArgumentOutOfRangeException(nameof(percentChange), percentChange, - "Percent change must be greater than 0 for ZIGZAG."); - } - } - -} diff --git a/src/s-z/ZigZag/ZigZag.StaticSeries.cs b/src/s-z/ZigZag/ZigZag.StaticSeries.cs index 39397a269..8d249e916 100644 --- a/src/s-z/ZigZag/ZigZag.StaticSeries.cs +++ b/src/s-z/ZigZag/ZigZag.StaticSeries.cs @@ -2,19 +2,20 @@ namespace Skender.Stock.Indicators; // ZIG ZAG (SERIES) -public static partial class Indicator +public static partial class ZigZag { - private static List CalcZigZag( - this List quotesList, + public static IReadOnlyList ToZigZag( + this IReadOnlyList quotes, EndType endType = EndType.Close, decimal percentChange = 5) where TQuote : IQuote { // check parameter arguments - ZigZag.Validate(percentChange); + ArgumentNullException.ThrowIfNull(quotes); + Validate(percentChange); // initialize - int length = quotesList.Count; + int length = quotes.Count; List results = new(length); if (length == 0) @@ -22,7 +23,7 @@ private static List CalcZigZag( return results; } - TQuote q0 = quotesList[0]; + TQuote q0 = quotes[0]; ZigZagEval eval = GetZigZagEval(endType, 1, q0); decimal changeThreshold = percentChange / 100m; @@ -48,7 +49,7 @@ private static List CalcZigZag( // roll through source values, to find initial trend for (int i = 0; i < length; i++) { - TQuote q = quotesList[i]; + TQuote q = quotes[i]; int index = i + 1; eval = GetZigZagEval(endType, index, q); @@ -88,12 +89,12 @@ private static List CalcZigZag( while (lastPoint.Index < length) { ZigZagPoint nextPoint = EvaluateNextPoint( - quotesList, endType, changeThreshold, lastPoint); + quotes, endType, changeThreshold, lastPoint); string lastDirection = lastPoint.PointType; // draw line (and reset last point) - DrawZigZagLine(results, quotesList, lastPoint, nextPoint); + DrawZigZagLine(results, quotes, lastPoint, nextPoint); // draw retrace line (and reset last high/low point) DrawRetraceLine(results, lastDirection, lastLowPoint, @@ -105,7 +106,7 @@ private static List CalcZigZag( // internals private static ZigZagPoint EvaluateNextPoint( - List quotesList, + IReadOnlyList quotesList, EndType endType, decimal changeThreshold, ZigZagPoint lastPoint) @@ -183,7 +184,7 @@ private static ZigZagPoint EvaluateNextPoint( } private static void DrawZigZagLine( - List results, List quotesList, + List results, IReadOnlyList quotes, ZigZagPoint lastPoint, ZigZagPoint nextPoint) where TQuote : IQuote { @@ -196,7 +197,7 @@ private static void DrawZigZagLine( // add new line segment for (int i = lastPoint.Index; i < nextPoint.Index; i++) { - TQuote q = quotesList[i]; + TQuote q = quotes[i]; int index = i + 1; ZigZagResult result = new( diff --git a/src/s-z/ZigZag/ZigZag.Utilities.cs b/src/s-z/ZigZag/ZigZag.Utilities.cs index 2973679e1..b3af14695 100644 --- a/src/s-z/ZigZag/ZigZag.Utilities.cs +++ b/src/s-z/ZigZag/ZigZag.Utilities.cs @@ -1,6 +1,8 @@ namespace Skender.Stock.Indicators; -public static partial class Indicator +// ZIG ZAG (UTILITIES) + +public static partial class ZigZag { // CONDENSE (REMOVE null results) /// @@ -16,4 +18,16 @@ public static IReadOnlyList Condense( return resultsList.ToSortedList(); } + + // parameter validation + internal static void Validate( + decimal percentChange) + { + // check parameter arguments + if (percentChange <= 0) + { + throw new ArgumentOutOfRangeException(nameof(percentChange), percentChange, + "Percent change must be greater than 0 for ZIGZAG."); + } + } } From 84c8f8ed775bd14917bb10ed4b2fa21d116b5aff Mon Sep 17 00:00:00 2001 From: Dave Skender <8432125+DaveSkender@users.noreply.github.com> Date: Sun, 27 Oct 2024 17:51:26 -0400 Subject: [PATCH 36/38] refactor: IReadOnly for utilities --- .github/ISSUE_TEMPLATE/bug_report.yml | 2 +- docs/_indicators/Beta.md | 2 +- docs/_indicators/Correlation.md | 2 +- docs/pages/guide.md | 12 +++--- docs/pages/utilities.md | 10 ++--- src/_common/Candles/Candles.Utilities.cs | 2 +- src/_common/Generics/Sorting.cs | 18 +-------- src/_common/Globals.cs | 2 - src/_common/Incrementals/IIncremental.cs | 2 +- src/_common/ObsoleteV3.cs | 11 ++++- .../Use (QuotePart)/QuotePart.StaticSeries.cs | 16 ++++++-- .../Use (QuotePart)/QuotePart.Utilities.cs | 31 +++++++------- src/a-d/Alligator/Alligator.StaticSeries.cs | 39 ++++++------------ src/a-d/Atr/Atr.StreamHub.cs | 2 +- src/a-d/Awesome/Awesome.StaticSeries.cs | 17 +++----- src/a-d/Cmf/Cmf.StaticSeries.cs | 2 +- src/a-d/Doji/Doji.StaticSeries.cs | 12 ++---- src/a-d/Donchian/Donchian.StaticSeries.cs | 14 ++----- .../FisherTransform.StaticSeries.cs | 18 ++++----- .../HtTrendline/HtTrendline.StaticSeries.cs | 15 +++---- src/e-k/Ichimoku/Ichimoku.StaticSeries.cs | 28 ++++++------- src/m-r/Mama/Mama.StaticSeries.cs | 19 ++++----- .../_common/Generics/Sorting.Tests.cs | 10 ++--- .../StreamHub.Stackoverflow.Tests.cs | 40 +++++++++---------- .../_common/Quotes/Quote.Aggregates.Tests.cs | 4 +- .../_common/Quotes/Quote.Converters.Tests.cs | 23 ----------- .../_common/Quotes/Quote.StreamHub.Tests.cs | 9 ++--- .../QuotePart.StreamHub.Tests.cs | 6 +-- .../indicators/a-d/Adl/Adl.StreamHub.Tests.cs | 6 +-- .../Alligator/Alligator.StreamHub.Tests.cs | 6 +-- .../indicators/a-d/Atr/Atr.StreamHub.Tests.cs | 6 +-- .../a-d/AtrStop/AtrStop.StreamHub.Tests.cs | 7 ++-- .../a-d/Bop/Bop.StaticSeries.Tests.cs | 2 +- .../indicators/e-k/Ema/Ema.StreamHub.Tests.cs | 9 ++--- .../m-r/Renko/Renko.StreamHub.Tests.cs | 6 +-- .../m-r/Rsi/Rsi.StaticSeries.Tests.cs | 2 +- .../indicators/s-z/Sma/Sma.StreamHub.Tests.cs | 9 ++--- tests/indicators/s-z/Tr/Tr.StreamHub.Tests.cs | 6 +-- tests/other/Custom.Indicator.Tests.cs | 6 +-- tests/other/Custom.Results.Tests.cs | 2 +- tests/other/PublicApi.Interface.Tests.cs | 10 ++--- tests/other/Sut.CustomItems.cs | 4 +- tests/performance/Perf.Utility.cs | 3 -- 43 files changed, 178 insertions(+), 274 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 921dda23d..3b7f7d542 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -23,7 +23,7 @@ body: render: csharp placeholder: | // example (put your own code here) - IEnumerable results = quotes.GetEma(14); + IReadOnlyList results = quotes.GetEma(14); validations: required: false - type: textarea diff --git a/docs/_indicators/Beta.md b/docs/_indicators/Beta.md index 3dc49393e..b41d716cb 100644 --- a/docs/_indicators/Beta.md +++ b/docs/_indicators/Beta.md @@ -22,7 +22,7 @@ IReadOnlyList results = quotesEval ## Parameters -**`quotesMarket`** _`IEnumerable`_ - [Historical quotes]({{site.baseurl}}/guide/#historical-quotes) market data should be at any consistent frequency (day, hour, minute, etc). This `market` quotes will be used to establish the baseline. +**`quotesMarket`** _`IReadOnlyList`_ - [Historical quotes]({{site.baseurl}}/guide/#historical-quotes) market data should be at any consistent frequency (day, hour, minute, etc). This `market` quotes will be used to establish the baseline. **`lookbackPeriods`** _`int`_ - Number of periods (`N`) in the lookback window. Must be greater than 0 to calculate; however we suggest a larger period for statistically appropriate sample size and especially when using Beta +/-. diff --git a/docs/_indicators/Correlation.md b/docs/_indicators/Correlation.md index 70ef31ce4..740374667 100644 --- a/docs/_indicators/Correlation.md +++ b/docs/_indicators/Correlation.md @@ -30,7 +30,7 @@ IReadOnlyList results = You must have at least `N` periods for both versions of `quotes` to cover the warmup periods. Mismatch histories will produce a `InvalidQuotesException`. Historical price quotes should have a consistent frequency (day, hour, minute, etc). -`quotesA` is an `IEnumerable` collection of historical price quotes. It should have a consistent frequency (day, hour, minute, etc). See [the Guide]({{site.baseurl}}/guide/#historical-quotes) for more information. +`quotesA` is an `IReadOnlyList` collection of historical price quotes. It should have a consistent frequency (day, hour, minute, etc). See [the Guide]({{site.baseurl}}/guide/#historical-quotes) for more information. ## Response diff --git a/docs/pages/guide.md b/docs/pages/guide.md index 6344988c6..40b1adad4 100644 --- a/docs/pages/guide.md +++ b/docs/pages/guide.md @@ -43,7 +43,7 @@ Most indicators require that you provide historical quote data and additional co You must get historical quotes from your own market data provider. For clarification, the `GetQuotesFromFeed()` method shown in the example below **is not part of this library**, but rather an example to represent your own acquisition of historical quotes. -Historical price data can be provided as a `List`, `IEnumerable`, or `ICollection` of the `Quote` class ([see below](#historical-quotes)); however, it can also be supplied as a generic [custom TQuote type](#using-custom-quote-classes) if you prefer to use your own quote model. +Historical price data can be provided as a `List`, `IReadOnlyList`, or `ICollection` of the `Quote` class ([see below](#historical-quotes)); however, it can also be supplied as a generic [custom TQuote type](#using-custom-quote-classes) if you prefer to use your own quote model. For additional configuration parameters, default values are provided when there is an industry standard. You can, of course, override these and provide your own values. @@ -57,7 +57,7 @@ using Skender.Stock.Indicators; [..] // fetch historical quotes from your feed (your method) -IEnumerable quotes = GetQuotesFromFeed("MSFT"); +IReadOnlyList quotes = GetQuotesFromFeed("MSFT"); // calculate 20-period SMA IReadOnlyList results = quotes @@ -89,7 +89,7 @@ More examples available: ## Historical quotes -You must provide historical price quotes to the library in the standard OHLCV `IEnumerable` or a compatible `List` or `ICollection` format. It should have a consistent period frequency (day, hour, minute, etc). See [using custom quote classes](#using-custom-quote-classes) if you prefer to use your own quote class. +You must provide historical price quotes to the library in the standard OHLCV `IReadOnlyList` or a compatible `List` or `ICollection` format. It should have a consistent period frequency (day, hour, minute, etc). See [using custom quote classes](#using-custom-quote-classes) if you prefer to use your own quote class. | name | type | notes | -- |-- |-- @@ -194,10 +194,10 @@ public class MyCustomQuote : IQuote ```csharp // USAGE // fetch historical quotes from your favorite feed -IEnumerable myQuotes = GetQuotesFromFeed("MSFT"); +IReadOnlyList myQuotes = GetQuotesFromFeed("MSFT"); // example: get 20-period simple moving average -IEnumerable results = myQuotes.GetSma(20); +IReadOnlyList results = myQuotes.GetSma(20); ``` #### Using custom quote property names @@ -247,7 +247,7 @@ Example: ```csharp // fetch historical quotes from your feed (your method) -IEnumerable quotes = GetQuotesFromFeed("SPY"); +IReadOnlyList quotes = GetQuotesFromFeed("SPY"); // calculate RSI of OBV IReadOnlyList results diff --git a/docs/pages/utilities.md b/docs/pages/utilities.md index 6159b938e..e86794df1 100644 --- a/docs/pages/utilities.md +++ b/docs/pages/utilities.md @@ -30,7 +30,7 @@ var results = quotes ### Sort quotes -`quotes.ToSortedCollection()` sorts any collection of `TQuote` or `ISeries` and returns it as a `Collection` sorted by ascending `Timestamp`. You do not need to sort quotes before using library indicators; however, if you are creating [custom indicators]({{site.baseurl}}/custom-indicators/#content) it's important to analyze `quotes` in a proper sequence. +`quotes.ToSortedList()` sorts any collection of `TQuote` or `ISeries` and returns it as a `IReadOnlyList` sorted by ascending `Timestamp`. You **do need to sort quotes** before using library indicators. ### Resize quote history @@ -38,7 +38,7 @@ var results = quotes ```csharp // aggregate into larger bars -IEnumerable dayBarQuotes = +IReadOnlyList dayBarQuotes = minuteBarQuotes.Aggregate(PeriodSize.Day); ``` @@ -46,7 +46,7 @@ An alternate version of this utility is provided where you can use any native `T ```csharp // alternate usage with TimeSpan -IEnumerable dayBarQuotes = +IReadOnlyList dayBarQuotes = minuteBarQuotes.Aggregate(TimeSpan timeSpan); ``` @@ -87,7 +87,7 @@ IReadOnlyList candles = quotes.ToCandles(); ```csharp // advanced validation -IEnumerable validatedQuotes = quotes.Validate(); +IReadOnlyList validatedQuotes = quotes.Validate(); // and can be used inline with chaining var results = quotes @@ -148,7 +148,7 @@ See [individual indicator pages]({{site.baseurl}}/indicators/#content) for infor ### Sort results -`results.ToSortedCollection()` sorts any collection of indicator results and returns it as a `Collection` sorted by ascending `Timestamp`. Results from the library indicators are already sorted, so you'd only potentially need this if you're creating [custom indicators]({{site.baseurl}}/custom-indicators/#content). +`results.ToSortedList()` sorts any collection of indicator results and returns it as a `IReadOnlyList` sorted by ascending `Timestamp`. Results from the library indicators are already sorted, so you'd only potentially need this if you're creating [custom indicators]({{site.baseurl}}/custom-indicators/#content). ## Utilities for numerical analysis diff --git a/src/_common/Candles/Candles.Utilities.cs b/src/_common/Candles/Candles.Utilities.cs index f8b01e196..82d278637 100644 --- a/src/_common/Candles/Candles.Utilities.cs +++ b/src/_common/Candles/Candles.Utilities.cs @@ -3,7 +3,7 @@ namespace Skender.Stock.Indicators; public static partial class Utility { public static IReadOnlyList Condense( - this IEnumerable candleResults) => candleResults + this IReadOnlyList candleResults) => candleResults .Where(candle => candle.Match != Match.None) .ToList(); diff --git a/src/_common/Generics/Sorting.cs b/src/_common/Generics/Sorting.cs index 6e5ffedf0..cf90af7f8 100644 --- a/src/_common/Generics/Sorting.cs +++ b/src/_common/Generics/Sorting.cs @@ -6,23 +6,7 @@ namespace Skender.Stock.Indicators; public static partial class Utility { - public static Collection ToSortedCollection( - this IEnumerable series) - where TSeries : ISeries - => series - .OrderBy(x => x.Timestamp) - .ToCollection(); - - // TODO: need it? is it a useful public utility? - [Obsolete("new, never implemented")] - public static IReadOnlyList ToSortedReadOnlyList( - this IEnumerable series) - where TSeries : ISeries - => series - .OrderBy(x => x.Timestamp) - .ToList(); - - internal static List ToSortedList( + public static IReadOnlyList ToSortedList( this IEnumerable series) where TSeries : ISeries => series diff --git a/src/_common/Globals.cs b/src/_common/Globals.cs index 3cdac175f..620494b62 100644 --- a/src/_common/Globals.cs +++ b/src/_common/Globals.cs @@ -3,5 +3,3 @@ [assembly: CLSCompliant(true)] [assembly: InternalsVisibleTo("Tests.Indicators")] // these test internals [assembly: InternalsVisibleTo("Tests.Performance")] - -namespace Skender.Stock.Indicators; diff --git a/src/_common/Incrementals/IIncremental.cs b/src/_common/Incrementals/IIncremental.cs index 269316e08..90de40106 100644 --- a/src/_common/Incrementals/IIncremental.cs +++ b/src/_common/Incrementals/IIncremental.cs @@ -25,7 +25,7 @@ public interface IAddReusable /// and added them to the list. /// /// - /// Chronologically ordered batch of IReuslable info + /// Chronologically ordered batch of IReusable info /// void Add(IReadOnlyList values); } diff --git a/src/_common/ObsoleteV3.cs b/src/_common/ObsoleteV3.cs index a6f751868..de35c808b 100644 --- a/src/_common/ObsoleteV3.cs +++ b/src/_common/ObsoleteV3.cs @@ -23,7 +23,7 @@ public static IEnumerable GetAlligator( => priceTuples .Select(t => new QuotePart(t.d, t.v)) .ToList() - .CalcAlligator( + .ToAlligator( jawPeriods, jawOffset, teethPeriods, teethOffset, lipsPeriods, lipsOffset); @@ -93,6 +93,15 @@ public static IEnumerable GetTrix( where TQuote : IQuote => quotes.Select(x => (x.Timestamp, x.Value)); + [ExcludeFromCodeCoverage] + [Obsolete("Refactor to use `ToSortedList()`", true)] // v3.0.0 + public static Collection ToSortedCollection( + this IReadOnlyList series) + where TSeries : ISeries + => series + .OrderBy(x => x.Timestamp) + .ToCollection(); + [ExcludeFromCodeCoverage] [Obsolete("Refactor to use `ToReusable()`", true)] // v3.0.0 public static Collection<(DateTime Timestamp, double Value)> ToTupleChainable( diff --git a/src/_common/Use (QuotePart)/QuotePart.StaticSeries.cs b/src/_common/Use (QuotePart)/QuotePart.StaticSeries.cs index 9382eb58f..53821b9f0 100644 --- a/src/_common/Use (QuotePart)/QuotePart.StaticSeries.cs +++ b/src/_common/Use (QuotePart)/QuotePart.StaticSeries.cs @@ -20,9 +20,17 @@ public static IReadOnlyList ToQuotePart( this IReadOnlyList quotes, CandlePart candlePart) where TQuote : IQuote - => quotes - .Select(q => q.ToQuotePart(candlePart)) - .ToList(); + { + ArgumentNullException.ThrowIfNull(quotes); + int length = quotes.Count; + List result = new(length); + + for (int i = 0; i < length; i++) + { + result.Add(quotes[i].ToQuotePart(candlePart)); + } + return result; + } // QuotePart alias /// @@ -33,5 +41,5 @@ public static IReadOnlyList Use( => ToQuotePart(quotes, candlePart); // TODO: should we deprecate Use in favor of "ToQuotePart"? - // Probably not, this is a fairly simply alias. + // Probably not, this is a fairly simple alias. } diff --git a/src/_common/Use (QuotePart)/QuotePart.Utilities.cs b/src/_common/Use (QuotePart)/QuotePart.Utilities.cs index 3fb863987..487cc7173 100644 --- a/src/_common/Use (QuotePart)/QuotePart.Utilities.cs +++ b/src/_common/Use (QuotePart)/QuotePart.Utilities.cs @@ -60,22 +60,19 @@ internal static double QuotePartOrValue( /// List of IQuote or IReusable items /// /// List of IReusable items - internal static List ToSortedList( - this IReadOnlyList items, CandlePart candlePart) - where T : IReusable - - // TODO: optimize this to avoid double-casting - - => typeof(IQuote).IsAssignableFrom(typeof(T)) - - ? items - .Cast() - .ToList() - .Use(candlePart) - .Cast() - .ToSortedList() + internal static IReadOnlyList ToPreferredList( + this IReadOnlyList items, CandlePart candlePart) + where T : IReusable + { + ArgumentNullException.ThrowIfNull(items); - : items - .Cast() - .ToSortedList(); + if (items is IReadOnlyList quotes) + { + return quotes.ToQuotePart(candlePart); + } + else + { + return items.Cast().ToList(); + } + } } diff --git a/src/a-d/Alligator/Alligator.StaticSeries.cs b/src/a-d/Alligator/Alligator.StaticSeries.cs index 9707d8fb8..f35217b70 100644 --- a/src/a-d/Alligator/Alligator.StaticSeries.cs +++ b/src/a-d/Alligator/Alligator.StaticSeries.cs @@ -33,25 +33,6 @@ public static IReadOnlyList ToAlligator( int lipsPeriods = 5, int lipsOffset = 3) where T : IReusable - => source - .ToSortedList(CandlePart.HL2) - .CalcAlligator( - jawPeriods, - jawOffset, - teethPeriods, - teethOffset, - lipsPeriods, - lipsOffset); - - internal static List CalcAlligator( - this List source, - int jawPeriods, - int jawOffset, - int teethPeriods, - int teethOffset, - int lipsPeriods, - int lipsOffset) - where T : IReusable { // check parameter arguments Validate( @@ -62,8 +43,12 @@ internal static List CalcAlligator( lipsPeriods, lipsOffset); + // prefer HL2 when IQuote + IReadOnlyList values + = source.ToPreferredList(CandlePart.HL2); + // initialize - int length = source.Count; + int length = values.Count; List results = new(length); // roll through source values @@ -82,7 +67,7 @@ internal static List CalcAlligator( double sum = 0; for (int p = i - jawPeriods - jawOffset + 1; p <= i - jawOffset; p++) { - sum += source[p].Value; + sum += values[p].Value; } jaw = sum / jawPeriods; @@ -93,7 +78,7 @@ internal static List CalcAlligator( { double prevJaw = results[i - 1].Jaw.Null2NaN(); - jaw = ((prevJaw * (jawPeriods - 1)) + source[i - jawOffset].Value) / jawPeriods; + jaw = ((prevJaw * (jawPeriods - 1)) + values[i - jawOffset].Value) / jawPeriods; } } @@ -106,7 +91,7 @@ internal static List CalcAlligator( double sum = 0; for (int p = i - teethPeriods - teethOffset + 1; p <= i - teethOffset; p++) { - sum += source[p].Value; + sum += values[p].Value; } teeth = sum / teethPeriods; @@ -117,7 +102,7 @@ internal static List CalcAlligator( { double prevTooth = results[i - 1].Teeth.Null2NaN(); - teeth = ((prevTooth * (teethPeriods - 1)) + source[i - teethOffset].Value) / teethPeriods; + teeth = ((prevTooth * (teethPeriods - 1)) + values[i - teethOffset].Value) / teethPeriods; } } @@ -130,7 +115,7 @@ internal static List CalcAlligator( double sum = 0; for (int p = i - lipsPeriods - lipsOffset + 1; p <= i - lipsOffset; p++) { - sum += source[p].Value; + sum += values[p].Value; } lips = sum / lipsPeriods; @@ -141,13 +126,13 @@ internal static List CalcAlligator( { double prevLips = results[i - 1].Lips.Null2NaN(); - lips = ((prevLips * (lipsPeriods - 1)) + source[i - lipsOffset].Value) / lipsPeriods; + lips = ((prevLips * (lipsPeriods - 1)) + values[i - lipsOffset].Value) / lipsPeriods; } } // result results.Add(new AlligatorResult( - source[i].Timestamp, + values[i].Timestamp, jaw.NaN2Null(), teeth.NaN2Null(), lips.NaN2Null())); diff --git a/src/a-d/Atr/Atr.StreamHub.cs b/src/a-d/Atr/Atr.StreamHub.cs index ead73a8ee..d37d45062 100644 --- a/src/a-d/Atr/Atr.StreamHub.cs +++ b/src/a-d/Atr/Atr.StreamHub.cs @@ -9,7 +9,7 @@ public interface IAtrHub int LookbackPeriods { get; } } -public static partial class Indicator +public static partial class Atr { public static AtrHub ToAtr( this IQuoteProvider quoteProvider, diff --git a/src/a-d/Awesome/Awesome.StaticSeries.cs b/src/a-d/Awesome/Awesome.StaticSeries.cs index c096bf060..b8f38f542 100644 --- a/src/a-d/Awesome/Awesome.StaticSeries.cs +++ b/src/a-d/Awesome/Awesome.StaticSeries.cs @@ -9,28 +9,23 @@ public static IReadOnlyList ToAwesome( int fastPeriods = 5, int slowPeriods = 34) where T : IReusable - => source - .ToSortedList(CandlePart.HL2) - .CalcAwesome(fastPeriods, slowPeriods); - - private static List CalcAwesome( - this List source, - int fastPeriods, - int slowPeriods) - where T : IReusable { // check parameter arguments Validate(fastPeriods, slowPeriods); + // prefer HL2 when IQuote + IReadOnlyList values + = source.ToPreferredList(CandlePart.HL2); + // initialize - int length = source.Count; + int length = values.Count; List results = new(length); double[] pr = new double[length]; // roll through source values for (int i = 0; i < length; i++) { - IReusable s = source[i]; + IReusable s = values[i]; pr[i] = s.Value; double? oscillator = null; diff --git a/src/a-d/Cmf/Cmf.StaticSeries.cs b/src/a-d/Cmf/Cmf.StaticSeries.cs index 0404549f0..063d60b5b 100644 --- a/src/a-d/Cmf/Cmf.StaticSeries.cs +++ b/src/a-d/Cmf/Cmf.StaticSeries.cs @@ -12,7 +12,7 @@ public static IReadOnlyList ToCmf( .CalcCmf(lookbackPeriods); private static List CalcCmf( - this List source, + this IReadOnlyList source, int lookbackPeriods) where TQuote : IQuote { diff --git a/src/a-d/Doji/Doji.StaticSeries.cs b/src/a-d/Doji/Doji.StaticSeries.cs index 44933ce8b..982d4f3eb 100644 --- a/src/a-d/Doji/Doji.StaticSeries.cs +++ b/src/a-d/Doji/Doji.StaticSeries.cs @@ -21,20 +21,14 @@ public static partial class Doji public static IReadOnlyList ToDoji( this IReadOnlyList quotes, double maxPriceChangePercent = 0.1) - where TQuote : IQuote => quotes - .ToSortedList() - .CalcDoji(maxPriceChangePercent); - - private static List CalcDoji( - this List quotesList, - double maxPriceChangePercent) where TQuote : IQuote { // check parameter arguments + ArgumentNullException.ThrowIfNull(quotes); Validate(maxPriceChangePercent); // initialize - int length = quotesList.Count; + int length = quotes.Count; List results = new(length); maxPriceChangePercent /= 100; @@ -42,7 +36,7 @@ private static List CalcDoji( // roll through candles for (int i = 0; i < length; i++) { - TQuote q = quotesList[i]; + TQuote q = quotes[i]; decimal? matchPrice = null; Match matchType = Match.None; diff --git a/src/a-d/Donchian/Donchian.StaticSeries.cs b/src/a-d/Donchian/Donchian.StaticSeries.cs index 0da8f0c62..483ac4a34 100644 --- a/src/a-d/Donchian/Donchian.StaticSeries.cs +++ b/src/a-d/Donchian/Donchian.StaticSeries.cs @@ -7,26 +7,20 @@ public static partial class Donchian public static IReadOnlyList ToDonchian( this IReadOnlyList quotes, int lookbackPeriods = 20) - where TQuote : IQuote => quotes - .ToSortedList() - .CalcDonchian(lookbackPeriods); - - private static List CalcDonchian( - this List quotesList, - int lookbackPeriods) where TQuote : IQuote { // check parameter arguments + ArgumentNullException.ThrowIfNull(quotes); Validate(lookbackPeriods); // initialize - int length = quotesList.Count; + int length = quotes.Count; List results = new(length); // roll through source values for (int i = 0; i < length; i++) { - TQuote q = quotesList[i]; + TQuote q = quotes[i]; if (i >= lookbackPeriods) { @@ -36,7 +30,7 @@ private static List CalcDonchian( // high/low over prior periods for (int p = i - lookbackPeriods; p < i; p++) { - TQuote d = quotesList[p]; + TQuote d = quotes[p]; if (d.High > highHigh) { diff --git a/src/e-k/FisherTransform/FisherTransform.StaticSeries.cs b/src/e-k/FisherTransform/FisherTransform.StaticSeries.cs index 01b81dcfe..a9f542ba8 100644 --- a/src/e-k/FisherTransform/FisherTransform.StaticSeries.cs +++ b/src/e-k/FisherTransform/FisherTransform.StaticSeries.cs @@ -5,23 +5,19 @@ namespace Skender.Stock.Indicators; public static partial class FisherTransform { public static IReadOnlyList ToFisherTransform( - this IReadOnlyList results, + this IReadOnlyList source, int lookbackPeriods = 10) where T : IReusable - => results - .ToSortedList(CandlePart.HL2) - .CalcFisherTransform(lookbackPeriods); - - private static List CalcFisherTransform( - this List source, - int lookbackPeriods) - where T : IReusable { // check parameter arguments Validate(lookbackPeriods); + // prefer HL2 when IQuote + IReadOnlyList values + = source.ToPreferredList(CandlePart.HL2); + // initialize - int length = source.Count; + int length = values.Count; double[] pr = new double[length]; // median price double[] xv = new double[length]; // price transform "value" List results = new(length); @@ -29,7 +25,7 @@ private static List CalcFisherTransform( // roll through source values for (int i = 0; i < length; i++) { - IReusable s = source[i]; + IReusable s = values[i]; pr[i] = s.Value; double minPrice = pr[i]; diff --git a/src/e-k/HtTrendline/HtTrendline.StaticSeries.cs b/src/e-k/HtTrendline/HtTrendline.StaticSeries.cs index fa40755b2..0788b5181 100644 --- a/src/e-k/HtTrendline/HtTrendline.StaticSeries.cs +++ b/src/e-k/HtTrendline/HtTrendline.StaticSeries.cs @@ -15,18 +15,15 @@ public static partial class HtTrendline /// Time-series values to transform. /// Time series of HTL values and smoothed price. public static IReadOnlyList ToHtTrendline( - this IReadOnlyList source) - where T : IReusable - => source - .ToSortedList(CandlePart.HL2) - .CalcHtTrendline(); - - private static List CalcHtTrendline( this IReadOnlyList source) where T : IReusable { + // prefer HL2 when IQuote + IReadOnlyList values + = source.ToPreferredList(CandlePart.HL2); + // initialize - int length = source.Count; + int length = values.Count; List results = new(length); double[] pr = new double[length]; // price @@ -49,7 +46,7 @@ private static List CalcHtTrendline( // roll through source values for (int i = 0; i < length; i++) { - IReusable s = source[i]; + IReusable s = values[i]; pr[i] = s.Value; if (i > 5) diff --git a/src/e-k/Ichimoku/Ichimoku.StaticSeries.cs b/src/e-k/Ichimoku/Ichimoku.StaticSeries.cs index 3fcf3cabe..f370ff6a2 100644 --- a/src/e-k/Ichimoku/Ichimoku.StaticSeries.cs +++ b/src/e-k/Ichimoku/Ichimoku.StaticSeries.cs @@ -50,7 +50,7 @@ public static IReadOnlyList GetIchimoku( chikouOffset); private static List CalcIchimoku( - this List quotesList, + this IReadOnlyList quotes, int tenkanPeriods, int kijunPeriods, int senkouBPeriods, @@ -67,7 +67,7 @@ private static List CalcIchimoku( chikouOffset); // initialize - int length = quotesList.Count; + int length = quotes.Count; List results = new(length); int senkouStartPeriod = Math.Max( @@ -77,15 +77,15 @@ private static List CalcIchimoku( // roll through source values for (int i = 0; i < length; i++) { - TQuote q = quotesList[i]; + TQuote q = quotes[i]; // tenkan-sen conversion line decimal? tenkanSen = CalcIchimokuTenkanSen( - i, quotesList, tenkanPeriods); + i, quotes, tenkanPeriods); // kijun-sen base line decimal? kijunSen = CalcIchimokuKijunSen( - i, quotesList, kijunPeriods); + i, quotes, kijunPeriods); // senkou span A decimal? senkouSpanA = null; @@ -105,14 +105,14 @@ private static List CalcIchimoku( // senkou span B decimal? senkouSpanB = CalcIchimokuSenkouB( - i, quotesList, senkouOffset, senkouBPeriods); + i, quotes, senkouOffset, senkouBPeriods); // chikou line decimal? chikouSpan = null; - if (i + chikouOffset < quotesList.Count) + if (i + chikouOffset < quotes.Count) { - chikouSpan = quotesList[i + chikouOffset].Close; + chikouSpan = quotes[i + chikouOffset].Close; } results.Add(new( @@ -128,7 +128,7 @@ private static List CalcIchimoku( } private static decimal? CalcIchimokuTenkanSen( - int i, List quotesList, int tenkanPeriods) + int i, IReadOnlyList quotes, int tenkanPeriods) where TQuote : IQuote { if (i < tenkanPeriods - 1) @@ -141,7 +141,7 @@ private static List CalcIchimoku( for (int p = i - tenkanPeriods + 1; p <= i; p++) { - TQuote d = quotesList[p]; + TQuote d = quotes[p]; if (d.High > max) { @@ -160,7 +160,7 @@ private static List CalcIchimoku( private static decimal? CalcIchimokuKijunSen( int i, - List quotesList, + IReadOnlyList quotes, int kijunPeriods) where TQuote : IQuote { @@ -174,7 +174,7 @@ private static List CalcIchimoku( for (int p = i - kijunPeriods + 1; p <= i; p++) { - TQuote d = quotesList[p]; + TQuote d = quotes[p]; if (d.High > max) { @@ -192,7 +192,7 @@ private static List CalcIchimoku( private static decimal? CalcIchimokuSenkouB( int i, - List quotesList, + IReadOnlyList quotes, int senkouOffset, int senkouBPeriods) where TQuote : IQuote @@ -208,7 +208,7 @@ private static List CalcIchimoku( for (int p = i - senkouOffset - senkouBPeriods + 1; p <= i - senkouOffset; p++) { - TQuote d = quotesList[p]; + TQuote d = quotes[p]; if (d.High > max) { diff --git a/src/m-r/Mama/Mama.StaticSeries.cs b/src/m-r/Mama/Mama.StaticSeries.cs index 4bded7fcd..3110c5702 100644 --- a/src/m-r/Mama/Mama.StaticSeries.cs +++ b/src/m-r/Mama/Mama.StaticSeries.cs @@ -5,25 +5,20 @@ namespace Skender.Stock.Indicators; public static partial class Mama { public static IReadOnlyList ToMama( - this IReadOnlyList results, + this IReadOnlyList source, double fastLimit = 0.5, double slowLimit = 0.05) where T : IReusable - => results - .ToSortedList(CandlePart.HL2) - .CalcMama(fastLimit, slowLimit); - - private static List CalcMama( - this List source, - double fastLimit, - double slowLimit) - where T : IReusable { // check parameter arguments Validate(fastLimit, slowLimit); + // prefer HL2 when IQuote + IReadOnlyList values + = source.ToPreferredList(CandlePart.HL2); + // initialize - int length = source.Count; + int length = values.Count; List results = new(length); double prevMama = double.NaN; @@ -48,7 +43,7 @@ private static List CalcMama( // roll through source values for (int i = 0; i < length; i++) { - IReusable s = source[i]; + IReusable s = values[i]; pr[i] = s.Value; // skip incalculable periods diff --git a/tests/indicators/_common/Generics/Sorting.Tests.cs b/tests/indicators/_common/Generics/Sorting.Tests.cs index d89adf62f..4bb16536b 100644 --- a/tests/indicators/_common/Generics/Sorting.Tests.cs +++ b/tests/indicators/_common/Generics/Sorting.Tests.cs @@ -6,7 +6,7 @@ namespace Utilities; public class Sorting : TestBase { [TestMethod] - public void ToSortedCollection() + public void ToSortedList() { // baseline for comparison IReadOnlyList baseline = @@ -22,11 +22,11 @@ public void ToSortedCollection() new(Timestamp: DateTime.Parse("1/8/2000", invariantCulture), Sma: double.NaN) ]; - // PUBLIC VARIANT, generic sorted Collection - Collection sortResults = baseline - .ToSortedCollection(); + // PUBLIC VARIANT, generic sorted list + IReadOnlyList sortResults = baseline + .ToSortedList(); Assert.AreEqual(5, sortResults[4].Sma); - Assert.AreEqual(DateTime.Parse("1/9/2000", invariantCulture), sortResults.LastOrDefault().Timestamp); + Assert.AreEqual(DateTime.Parse("1/9/2000", invariantCulture), sortResults[^1].Timestamp); } } diff --git a/tests/indicators/_common/Observables/StreamHub.Stackoverflow.Tests.cs b/tests/indicators/_common/Observables/StreamHub.Stackoverflow.Tests.cs index 0452f5f96..0e61b8fcc 100644 --- a/tests/indicators/_common/Observables/StreamHub.Stackoverflow.Tests.cs +++ b/tests/indicators/_common/Observables/StreamHub.Stackoverflow.Tests.cs @@ -17,7 +17,7 @@ public void FatLongStack() QuoteHub provider = new(); // setup: define ~10 subscribers (flat) - List<(string label, IEnumerable results, bool irregular)> subscribers = new() + List<(string label, IReadOnlyList results, bool irregular)> subscribers = new() { HubRef(provider.ToAdl()), HubRef(provider.ToEma(14)) @@ -35,7 +35,7 @@ public void FatLongStack() provider.Add(quotesList[i]); } - subscribers.Insert(0, new(provider.ToString(), provider.Quotes.Cast(), false)); + subscribers.Insert(0, new(provider.ToString(), provider.Quotes, false)); // assert: this just has to not fail, really @@ -43,9 +43,9 @@ public void FatLongStack() Console.WriteLine("--------------------"); // assert: all non-irregular subscribers have the same count - foreach ((string label, IEnumerable results, bool irregular) in subscribers) + foreach ((string label, IReadOnlyList results, bool irregular) in subscribers) { - int resultQty = results.Count(); + int resultQty = results.Count; Console.WriteLine($"Hub: {resultQty} - {label}"); if (irregular) { continue; } resultQty.Should().Be(qtyQuotes); @@ -69,9 +69,9 @@ public void FatLongStack() Console.WriteLine("--------------------"); // assert: all have same count - foreach ((string label, IEnumerable results, bool irregular) in subscribers) + foreach ((string label, IReadOnlyList results, bool irregular) in subscribers) { - int resultQty = results.Count(); + int resultQty = results.Count; Console.WriteLine($"Cut: {resultQty} - {label}"); if (irregular) { continue; } resultQty.Should().Be(cutoff); @@ -94,7 +94,7 @@ public void ManyChainDepths() QuoteHub provider = new(); // setup: subscribe a large chain depth - List<(string label, IEnumerable results, bool irregular)> subscribers = new(chainDepth + 2); + List<(string label, IReadOnlyList results, bool irregular)> subscribers = new(chainDepth + 2); SmaHub init = provider.ToSma(1); SmaHub sma = init.ToSma(2); @@ -119,7 +119,7 @@ public void ManyChainDepths() provider.Add(quotesList[i]); } - subscribers.Insert(0, new(provider.ToString(), provider.Quotes.Cast(), false)); + subscribers.Insert(0, new(provider.ToString(), provider.Quotes, false)); Console.WriteLine($"Subscribers: {subscribers.Count}"); Console.WriteLine("--------------------"); @@ -127,9 +127,9 @@ public void ManyChainDepths() // assert: this just has to not fail, really // assert: all non-irregular subscribers have the same count - foreach ((string label, IEnumerable results, bool irregular) in subscribers) + foreach ((string label, IReadOnlyList results, bool irregular) in subscribers) { - int resultQty = results.Count(); + int resultQty = results.Count; Console.WriteLine($"Hub: {resultQty} - {label}"); if (irregular) { continue; } resultQty.Should().Be(qtyQuotes); @@ -151,9 +151,9 @@ public void ManyChainDepths() provider.Quotes.Count.Should().Be(cutoff); // assert: all have same count - foreach ((string label, IEnumerable results, bool irregular) in subscribers) + foreach ((string label, IReadOnlyList results, bool irregular) in subscribers) { - int resultQty = results.Count(); + int resultQty = results.Count; Console.WriteLine($"Cut: {resultQty} - {label}"); if (irregular) { continue; } resultQty.Should().Be(cutoff); @@ -176,7 +176,7 @@ public void ManySubscribers() // setup: define all possible subscribers // TODO: add to this as more Hubs come online - List<(string label, IEnumerable results, bool irregular)> subscribers = new() + List<(string label, IReadOnlyList results, bool irregular)> subscribers = new() { HubRef(provider.ToAdl()), HubRef(provider.ToAlligator()), @@ -203,7 +203,7 @@ public void ManySubscribers() provider.Add(quotesList[i]); } - subscribers.Insert(0, new(provider.ToString(), provider.Quotes.Cast(), false)); + subscribers.Insert(0, new(provider.ToString(), provider.Quotes, false)); // assert: this just has to not fail, really @@ -211,9 +211,9 @@ public void ManySubscribers() Console.WriteLine("--------------------"); // assert: all non-irregular subscribers have the same count - foreach ((string label, IEnumerable results, bool irregular) in subscribers) + foreach ((string label, IReadOnlyList results, bool irregular) in subscribers) { - int resultQty = results.Count(); + int resultQty = results.Count; Console.WriteLine($"Hub: {resultQty} - {label}"); if (irregular) { continue; } resultQty.Should().Be(qtyQuotes); @@ -237,9 +237,9 @@ public void ManySubscribers() Console.WriteLine("--------------------"); // assert: all have same count - foreach ((string label, IEnumerable results, bool irregular) in subscribers) + foreach ((string label, IReadOnlyList results, bool irregular) in subscribers) { - int resultQty = results.Count(); + int resultQty = results.Count; Console.WriteLine($"Cut: {resultQty} - {label}"); if (irregular) { continue; } resultQty.Should().Be(cutoff); @@ -249,12 +249,12 @@ public void ManySubscribers() /// /// Utility to get references to a hub's results. /// - private static (string, IEnumerable, bool) HubRef( + private static (string, IReadOnlyList, bool) HubRef( StreamHub hub, bool irregular = false) where TIn : ISeries where TOut : ISeries { - IEnumerable results = hub.Cache.Cast(); + IReadOnlyList results = hub.Cache; return (hub.ToString(), results, irregular); } } diff --git a/tests/indicators/_common/Quotes/Quote.Aggregates.Tests.cs b/tests/indicators/_common/Quotes/Quote.Aggregates.Tests.cs index 9cb91b204..8fa697629 100644 --- a/tests/indicators/_common/Quotes/Quote.Aggregates.Tests.cs +++ b/tests/indicators/_common/Quotes/Quote.Aggregates.Tests.cs @@ -43,7 +43,7 @@ public void Aggregate() // no history scenario IReadOnlyList noQuotes = []; - IEnumerable noResults = noQuotes.Aggregate(PeriodSize.Day); + IReadOnlyList noResults = noQuotes.Aggregate(PeriodSize.Day); Assert.IsFalse(noResults.Any()); } @@ -86,7 +86,7 @@ public void AggregateTimeSpan() // no history scenario IReadOnlyList noQuotes = []; - IEnumerable noResults = noQuotes.Aggregate(TimeSpan.FromDays(1)); + IReadOnlyList noResults = noQuotes.Aggregate(TimeSpan.FromDays(1)); Assert.IsFalse(noResults.Any()); } diff --git a/tests/indicators/_common/Quotes/Quote.Converters.Tests.cs b/tests/indicators/_common/Quotes/Quote.Converters.Tests.cs index 704f4096b..8d837fe98 100644 --- a/tests/indicators/_common/Quotes/Quote.Converters.Tests.cs +++ b/tests/indicators/_common/Quotes/Quote.Converters.Tests.cs @@ -7,29 +7,6 @@ namespace Utilities; [TestClass] public partial class Quotes : TestBase { - [TestMethod] - public void ToSortedCollection() - { - IReadOnlyList quotes = Data.GetMismatch(); - - Collection h = quotes.ToSortedCollection(); - - // proper quantities - Assert.AreEqual(502, h.Count); - - // check first date - DateTime firstDate = DateTime.ParseExact("01/18/2016", "MM/dd/yyyy", TestBase.invariantCulture); - Assert.AreEqual(firstDate, h[0].Timestamp); - - // check last date - DateTime lastDate = DateTime.ParseExact("12/31/2018", "MM/dd/yyyy", TestBase.invariantCulture); - Assert.AreEqual(lastDate, h.LastOrDefault().Timestamp); - - // spot check an out of sequence date - DateTime spotDate = DateTime.ParseExact("03/16/2017", "MM/dd/yyyy", TestBase.invariantCulture); - Assert.AreEqual(spotDate, h[50].Timestamp); - } - [TestMethod] public void ToSortedList() { diff --git a/tests/indicators/_common/Quotes/Quote.StreamHub.Tests.cs b/tests/indicators/_common/Quotes/Quote.StreamHub.Tests.cs index 36dd4ef05..babf4c1c3 100644 --- a/tests/indicators/_common/Quotes/Quote.StreamHub.Tests.cs +++ b/tests/indicators/_common/Quotes/Quote.StreamHub.Tests.cs @@ -10,8 +10,7 @@ public override void QuoteObserver() { // tests quote redistribution - List quotesList = Quotes - .ToSortedList(); + List quotesList = Quotes.ToList(); int length = Quotes.Count; @@ -43,8 +42,7 @@ public void ChainProvider() { int smaPeriods = 8; - List quotesList = Quotes - .ToSortedList(); + List quotesList = Quotes.ToList(); int length = quotesList.Count; @@ -102,8 +100,7 @@ public void AddQuote() { // covers both single and batch add - List quotesList = Quotes - .ToSortedList(); + List quotesList = Quotes.ToList(); int length = Quotes.Count; diff --git a/tests/indicators/_common/Use (QuotePart)/QuotePart.StreamHub.Tests.cs b/tests/indicators/_common/Use (QuotePart)/QuotePart.StreamHub.Tests.cs index 4aa893bdb..9a5bbb284 100644 --- a/tests/indicators/_common/Use (QuotePart)/QuotePart.StreamHub.Tests.cs +++ b/tests/indicators/_common/Use (QuotePart)/QuotePart.StreamHub.Tests.cs @@ -8,8 +8,7 @@ public override void QuoteObserver() { CandlePart candlePart = CandlePart.HLC3; - List quotesList = Quotes - .ToSortedList(); + List quotesList = Quotes.ToList(); int length = quotesList.Count; @@ -84,8 +83,7 @@ public void ChainProvider() int smaPeriods = 8; CandlePart candlePart = CandlePart.OHLC4; - List quotesList = Quotes - .ToSortedList(); + List quotesList = Quotes.ToList(); int length = quotesList.Count; diff --git a/tests/indicators/a-d/Adl/Adl.StreamHub.Tests.cs b/tests/indicators/a-d/Adl/Adl.StreamHub.Tests.cs index 9b83c46a3..0b2d3e66b 100644 --- a/tests/indicators/a-d/Adl/Adl.StreamHub.Tests.cs +++ b/tests/indicators/a-d/Adl/Adl.StreamHub.Tests.cs @@ -6,8 +6,7 @@ public class AdlHub : StreamHubTestBase, ITestChainProvider [TestMethod] public override void QuoteObserver() { - List quotesList = Quotes - .ToSortedList(); + List quotesList = Quotes.ToList(); int length = quotesList.Count; @@ -71,8 +70,7 @@ public void ChainProvider() { const int smaPeriods = 8; - List quotesList = Quotes - .ToSortedList(); + List quotesList = Quotes.ToList(); int length = quotesList.Count; diff --git a/tests/indicators/a-d/Alligator/Alligator.StreamHub.Tests.cs b/tests/indicators/a-d/Alligator/Alligator.StreamHub.Tests.cs index 22a33b156..f6db7e617 100644 --- a/tests/indicators/a-d/Alligator/Alligator.StreamHub.Tests.cs +++ b/tests/indicators/a-d/Alligator/Alligator.StreamHub.Tests.cs @@ -6,8 +6,7 @@ public class AlligatorHub : StreamHubTestBase, ITestChainObserver [TestMethod] public override void QuoteObserver() { - List quotesList = Quotes - .ToSortedList(); + List quotesList = Quotes.ToList(); int length = quotesList.Count; @@ -70,8 +69,7 @@ IReadOnlyList seriesList [TestMethod] public void ChainObserver() { - List quotesList = Quotes - .ToSortedList(); + List quotesList = Quotes.ToList(); int length = quotesList.Count; diff --git a/tests/indicators/a-d/Atr/Atr.StreamHub.Tests.cs b/tests/indicators/a-d/Atr/Atr.StreamHub.Tests.cs index ced05e39e..0f3e5e419 100644 --- a/tests/indicators/a-d/Atr/Atr.StreamHub.Tests.cs +++ b/tests/indicators/a-d/Atr/Atr.StreamHub.Tests.cs @@ -6,8 +6,7 @@ public class AtrHub : StreamHubTestBase, ITestChainProvider [TestMethod] public override void QuoteObserver() { - List quotesList = Quotes - .ToSortedList(); + List quotesList = Quotes.ToList(); int length = quotesList.Count; @@ -71,8 +70,7 @@ public void ChainProvider() { int smaPeriods = 8; - List quotesList = Quotes - .ToSortedList(); + List quotesList = Quotes.ToList(); int length = quotesList.Count; diff --git a/tests/indicators/a-d/AtrStop/AtrStop.StreamHub.Tests.cs b/tests/indicators/a-d/AtrStop/AtrStop.StreamHub.Tests.cs index b36b6141d..539fc18ec 100644 --- a/tests/indicators/a-d/AtrStop/AtrStop.StreamHub.Tests.cs +++ b/tests/indicators/a-d/AtrStop/AtrStop.StreamHub.Tests.cs @@ -6,8 +6,7 @@ public class AtrStop : StreamHubTestBase [TestMethod] public override void QuoteObserver() { - List quotesList = Quotes - .ToSortedList(); + List quotesList = Quotes.ToList(); int length = quotesList.Count; @@ -55,7 +54,7 @@ IReadOnlyList streamList quotesList.RemoveAt(400); // time-series, for comparison - IEnumerable seriesList + IReadOnlyList seriesList = quotesList .ToAtrStop(); @@ -87,7 +86,7 @@ IReadOnlyList streamList = observer.Results; // time-series, for comparison - IEnumerable seriesList + IReadOnlyList seriesList = Quotes .ToAtrStop(endType: EndType.HighLow); diff --git a/tests/indicators/a-d/Bop/Bop.StaticSeries.Tests.cs b/tests/indicators/a-d/Bop/Bop.StaticSeries.Tests.cs index cb297e871..7169a2238 100644 --- a/tests/indicators/a-d/Bop/Bop.StaticSeries.Tests.cs +++ b/tests/indicators/a-d/Bop/Bop.StaticSeries.Tests.cs @@ -44,7 +44,7 @@ public void Chainor() [TestMethod] public void NaN() { - IEnumerable r = Data.GetBtcUsdNan() + IReadOnlyList r = Data.GetBtcUsdNan() .ToBop(50); Assert.AreEqual(0, r.Count(x => x.Bop is double.NaN)); diff --git a/tests/indicators/e-k/Ema/Ema.StreamHub.Tests.cs b/tests/indicators/e-k/Ema/Ema.StreamHub.Tests.cs index 5e4e1f2c4..60354ebfb 100644 --- a/tests/indicators/e-k/Ema/Ema.StreamHub.Tests.cs +++ b/tests/indicators/e-k/Ema/Ema.StreamHub.Tests.cs @@ -6,8 +6,7 @@ public class EmaHub : StreamHubTestBase, ITestChainObserver, ITestChainProvider [TestMethod] public override void QuoteObserver() { - List quotesList = Quotes - .ToSortedList(); + List quotesList = Quotes.ToList(); int length = quotesList.Count; @@ -71,8 +70,7 @@ public void ChainObserver() int emaPeriods = 12; int smaPeriods = 8; - List quotesList = Quotes - .ToSortedList(); + List quotesList = Quotes.ToList(); int length = quotesList.Count; @@ -114,8 +112,7 @@ public void ChainProvider() int emaPeriods = 20; int smaPeriods = 10; - List quotesList = Quotes - .ToSortedList(); + List quotesList = Quotes.ToList(); int length = quotesList.Count; diff --git a/tests/indicators/m-r/Renko/Renko.StreamHub.Tests.cs b/tests/indicators/m-r/Renko/Renko.StreamHub.Tests.cs index c995d2dc7..9e859a39d 100644 --- a/tests/indicators/m-r/Renko/Renko.StreamHub.Tests.cs +++ b/tests/indicators/m-r/Renko/Renko.StreamHub.Tests.cs @@ -9,8 +9,7 @@ public override void QuoteObserver() decimal brickSize = 2.5m; EndType endType = EndType.HighLow; - List quotesList = Quotes - .ToSortedList(); + List quotesList = Quotes.ToList(); int length = quotesList.Count; @@ -76,8 +75,7 @@ public void ChainProvider() EndType endType = EndType.Close; int smaPeriods = 50; - List quotesList = Quotes - .ToSortedList(); + List quotesList = Quotes.ToList(); int length = quotesList.Count; diff --git a/tests/indicators/m-r/Rsi/Rsi.StaticSeries.Tests.cs b/tests/indicators/m-r/Rsi/Rsi.StaticSeries.Tests.cs index e5c60430b..f70a73693 100644 --- a/tests/indicators/m-r/Rsi/Rsi.StaticSeries.Tests.cs +++ b/tests/indicators/m-r/Rsi/Rsi.StaticSeries.Tests.cs @@ -93,7 +93,7 @@ public void Chainor() [TestMethod] public void NaN() { - IEnumerable r = Data.GetBtcUsdNan() + IReadOnlyList r = Data.GetBtcUsdNan() .ToRsi(); Assert.AreEqual(0, r.Count(x => x.Rsi is double.NaN)); diff --git a/tests/indicators/s-z/Sma/Sma.StreamHub.Tests.cs b/tests/indicators/s-z/Sma/Sma.StreamHub.Tests.cs index ff1efc058..c09661948 100644 --- a/tests/indicators/s-z/Sma/Sma.StreamHub.Tests.cs +++ b/tests/indicators/s-z/Sma/Sma.StreamHub.Tests.cs @@ -6,8 +6,7 @@ public class SmaHub : StreamHubTestBase, ITestChainObserver, ITestChainProvider [TestMethod] public override void QuoteObserver() { - List quotesList = Quotes - .ToSortedList(); + List quotesList = Quotes.ToList(); int length = quotesList.Count; @@ -70,8 +69,7 @@ IReadOnlyList seriesList [TestMethod] public void ChainObserver() { - List quotesList = Quotes - .ToSortedList(); + List quotesList = Quotes.ToList(); int length = quotesList.Count; @@ -118,8 +116,7 @@ public void ChainProvider() int emaPeriods = 12; int smaPeriods = 8; - List quotesList = Quotes - .ToSortedList(); + List quotesList = Quotes.ToList(); int length = quotesList.Count; diff --git a/tests/indicators/s-z/Tr/Tr.StreamHub.Tests.cs b/tests/indicators/s-z/Tr/Tr.StreamHub.Tests.cs index 8225ac7f0..b67bcc866 100644 --- a/tests/indicators/s-z/Tr/Tr.StreamHub.Tests.cs +++ b/tests/indicators/s-z/Tr/Tr.StreamHub.Tests.cs @@ -6,8 +6,7 @@ public class TrHub : StreamHubTestBase, ITestChainProvider [TestMethod] public override void QuoteObserver() { - List quotesList = Quotes - .ToSortedList(); + List quotesList = Quotes.ToList(); int length = quotesList.Count; @@ -71,8 +70,7 @@ public void ChainProvider() { int smaPeriods = 8; - List quotesList = Quotes - .ToSortedList(); + List quotesList = Quotes.ToList(); int length = quotesList.Count; diff --git a/tests/other/Custom.Indicator.Tests.cs b/tests/other/Custom.Indicator.Tests.cs index 261064fe7..133d4d488 100644 --- a/tests/other/Custom.Indicator.Tests.cs +++ b/tests/other/Custom.Indicator.Tests.cs @@ -90,9 +90,9 @@ public void Chainor() [TestMethod] public void QuoteToSortedList() { - IEnumerable mismatch = Data.GetMismatch(); + IReadOnlyList mismatch = Data.GetMismatch(); - Collection h = mismatch.ToSortedCollection(); + IReadOnlyList h = mismatch.ToSortedList(); // proper quantities Assert.AreEqual(502, h.Count); @@ -103,7 +103,7 @@ public void QuoteToSortedList() // check last date DateTime lastDate = DateTime.ParseExact("12/31/2018", "MM/dd/yyyy", EnglishCulture); - Assert.AreEqual(lastDate, h.LastOrDefault().Timestamp); + Assert.AreEqual(lastDate, h[^1].Timestamp); // spot check an out of sequence date DateTime spotDate = DateTime.ParseExact("03/16/2017", "MM/dd/yyyy", EnglishCulture); diff --git a/tests/other/Custom.Results.Tests.cs b/tests/other/Custom.Results.Tests.cs index a45bd6264..d7b4c7f60 100644 --- a/tests/other/Custom.Results.Tests.cs +++ b/tests/other/Custom.Results.Tests.cs @@ -29,7 +29,7 @@ public void CustomSeriesClass() [TestMethod] public void CustomSeriesClassLinq() { - IEnumerable emaResults = quotes.ToEma(14); + IReadOnlyList emaResults = quotes.ToEma(14); // can use a derive Indicator class using Linq diff --git a/tests/other/PublicApi.Interface.Tests.cs b/tests/other/PublicApi.Interface.Tests.cs index 95a3ab60d..9dad62942 100644 --- a/tests/other/PublicApi.Interface.Tests.cs +++ b/tests/other/PublicApi.Interface.Tests.cs @@ -105,13 +105,13 @@ public void StreamMany() // from quote provider provider.EndTransmission(); // get static equivalents for comparison - IEnumerable staticAdl = quotes.ToAdl(); + IReadOnlyList staticAdl = quotes.ToAdl(); IReadOnlyList staticAtr = quotes.ToAtr(); IReadOnlyList staticAtrStop = quotes.ToAtrStop(); - IEnumerable staticAlligator = quotes.ToAlligator(); - IEnumerable staticEma = quotes.ToEma(20); - IEnumerable staticQuotePart = quotes.Use(CandlePart.OHL3); - IEnumerable staticSma = quotes.ToSma(20); + IReadOnlyList staticAlligator = quotes.ToAlligator(); + IReadOnlyList staticEma = quotes.ToEma(20); + IReadOnlyList staticQuotePart = quotes.Use(CandlePart.OHL3); + IReadOnlyList staticSma = quotes.ToSma(20); IReadOnlyList staticTr = quotes.ToTr(); // final results should persist in scope diff --git a/tests/other/Sut.CustomItems.cs b/tests/other/Sut.CustomItems.cs index dcc922fd1..c070ca3ab 100644 --- a/tests/other/Sut.CustomItems.cs +++ b/tests/other/Sut.CustomItems.cs @@ -84,11 +84,11 @@ public static IReadOnlyList GetIndicator( int lookbackPeriods) where T : IReusable => source - .ToSortedCollection() + .ToSortedList() .CalcIndicator(lookbackPeriods); private static List CalcIndicator( - this Collection source, + this IReadOnlyList source, int lookbackPeriods) where T : IReusable { diff --git a/tests/performance/Perf.Utility.cs b/tests/performance/Perf.Utility.cs index 7dfb9cea5..eb1401be1 100644 --- a/tests/performance/Perf.Utility.cs +++ b/tests/performance/Perf.Utility.cs @@ -11,9 +11,6 @@ public class Utility [Benchmark] public object ToSortedList() => q.ToSortedList(); - [Benchmark] - public object ToSortedCollection() => q.ToSortedCollection(); - [Benchmark] public object ToListQuoteD() => q.ToQuoteDList(); From 214ce0595d4bbe9ee8e90a64d6e2652af6df4c4e Mon Sep 17 00:00:00 2001 From: Dave Skender <8432125+DaveSkender@users.noreply.github.com> Date: Sun, 27 Oct 2024 17:57:43 -0400 Subject: [PATCH 37/38] leave note on CMO tests --- tests/indicators/a-d/Cmo/Cmo.StaticSeries.Tests.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/indicators/a-d/Cmo/Cmo.StaticSeries.Tests.cs b/tests/indicators/a-d/Cmo/Cmo.StaticSeries.Tests.cs index 37ca7fa75..866f2b762 100644 --- a/tests/indicators/a-d/Cmo/Cmo.StaticSeries.Tests.cs +++ b/tests/indicators/a-d/Cmo/Cmo.StaticSeries.Tests.cs @@ -3,6 +3,9 @@ namespace StaticSeries; [TestClass] public class Cmo : StaticSeriesTestBase { + // TODO: test for CMO isUp works as expected + // when there’s no price change + [TestMethod] public override void Standard() { From abde78a7e347e936eec5636f92c11336ede10abb Mon Sep 17 00:00:00 2001 From: Dave Skender <8432125+DaveSkender@users.noreply.github.com> Date: Sun, 27 Oct 2024 18:03:21 -0400 Subject: [PATCH 38/38] code cleanup --- src/_common/BinarySettings.cs | 3 +-- src/_common/Generics/Sorting.cs | 2 -- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/_common/BinarySettings.cs b/src/_common/BinarySettings.cs index 5ce4f2eac..6912d3f11 100644 --- a/src/_common/BinarySettings.cs +++ b/src/_common/BinarySettings.cs @@ -33,8 +33,7 @@ namespace Skender.Stock.Indicators; /// public readonly struct BinarySettings( byte settings, - byte mask = 0b11111111) - : IEquatable + byte mask = 0b11111111) : IEquatable { public byte Settings { get; } = settings; public byte Mask { get; } = mask; diff --git a/src/_common/Generics/Sorting.cs b/src/_common/Generics/Sorting.cs index cf90af7f8..56ed632c6 100644 --- a/src/_common/Generics/Sorting.cs +++ b/src/_common/Generics/Sorting.cs @@ -1,5 +1,3 @@ -using System.Collections.ObjectModel; - namespace Skender.Stock.Indicators; // SORTED of SERIES