Skip to content

Commit ae70593

Browse files
authored
code analysis fixes (#970)
* remove List from public API * code cleanup (general)
1 parent 585b961 commit ae70593

123 files changed

Lines changed: 3266 additions & 2015 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.editorconfig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ dotnet_diagnostic.IDE0071.severity=suggestion
9090
dotnet_diagnostic.IDE0047.severity=suggestion
9191
csharp_indent_labels = no_change
9292
csharp_prefer_simple_using_statement = true:suggestion
93-
csharp_prefer_braces = true:silent
93+
csharp_prefer_braces = true:suggestion
9494
csharp_style_prefer_method_group_conversion = true:silent
9595
csharp_style_expression_bodied_methods = true:suggestion
9696
csharp_style_expression_bodied_constructors = false:suggestion
@@ -143,7 +143,7 @@ dotnet_style_allow_statement_immediately_after_block_experimental= false:silent
143143

144144
# Naming rules
145145

146-
dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion
146+
dotnet_naming_rule.interface_should_be_begins_with_i.severity = warning
147147
dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
148148
dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
149149

.github/build.main.yml

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ pool:
99
vmImage: "ubuntu-latest"
1010

1111
workspace:
12-
clean: all
12+
clean: all
1313

1414
variables:
1515
BuildConfiguration: "Release"
@@ -18,34 +18,43 @@ steps:
1818
- task: gitversion/setup@0
1919
displayName: use GitVersion 5.x
2020
inputs:
21-
versionSpec: '5.x'
21+
versionSpec: "5.x"
2222

2323
- task: gitversion/execute@0
2424
displayName: get GitVersion
2525
inputs:
2626
useConfigFile: true
27-
configFilePath: 'gitversion.yml'
27+
configFilePath: "gitversion.yml"
2828
updateAssemblyInfo: true
2929

3030
- task: UseDotNet@2
3131
displayName: "use .NET SDK 7.0.x"
3232
inputs:
3333
version: 7.0.x
34-
includePreviewVersions: true
34+
includePreviewVersions: false
3535

3636
- task: DotNetCoreCLI@2
3737
displayName: build
3838
inputs:
39+
command: "build"
3940
projects: "**/*.csproj"
40-
arguments: "--configuration $(BuildConfiguration) /p:Version=$(GitVersion.NuGetVersion) /p:ContinuousIntegrationBuild=true"
41+
arguments: >
42+
--configuration $(BuildConfiguration)
43+
/p:Version=$(GitVersion.NuGetVersion)
44+
/p:ContinuousIntegrationBuild=true
45+
/warnaserror
4146
4247
- task: DotNetCoreCLI@2
4348
displayName: "test indicators"
4449
inputs:
4550
command: test
4651
testRunTitle: "Indicator Tests"
4752
projects: "tests/indicators/Tests.Indicators.csproj"
48-
arguments: '--configuration $(BuildConfiguration) --no-restore --no-build --collect:"XPlat Code Coverage" -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Format=cobertura'
53+
arguments: >
54+
--configuration $(BuildConfiguration)
55+
--no-restore
56+
--no-build
57+
--collect:"XPlat Code Coverage" -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Format=cobertura
4958
publishTestResults: true
5059

5160
- task: DotNetCoreCLI@2
@@ -54,7 +63,11 @@ steps:
5463
command: test
5564
testRunTitle: "External Tests"
5665
projects: "tests/external/Tests.Other.csproj"
57-
arguments: "--configuration $(BuildConfiguration) --no-restore --no-build /p:CollectCoverage=false"
66+
arguments: >
67+
--configuration $(BuildConfiguration)
68+
--no-restore
69+
--no-build
70+
/p:CollectCoverage=false
5871
publishTestResults: true
5972

6073
- task: PublishCodeCoverageResults@1
@@ -87,6 +100,6 @@ steps:
87100
- task: PublishPipelineArtifact@1
88101
displayName: "save artifacts"
89102
inputs:
90-
targetPath: '$(Pipeline.Workspace)/a'
91-
artifact: 'packages'
92-
publishLocation: 'pipeline'
103+
targetPath: "$(Pipeline.Workspace)/a"
104+
artifact: "packages"
105+
publishLocation: "pipeline"

.vscode/settings.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
"chandeliertype",
4848
"chartable",
4949
"chikou",
50+
"Cobertura",
5051
"daveskender",
5152
"Dema",
5253
"Detrended",
@@ -93,6 +94,8 @@
9394
"Mrkt",
9495
"Mulloy",
9596
"Munehisa",
97+
"nobuild",
98+
"nupkg",
9699
"Quong",
97100
"Renko",
98101
"Schaff",
@@ -101,6 +104,7 @@
101104
"Siepman",
102105
"Skender",
103106
"Smma",
107+
"snupkg",
104108
"Soudack",
105109
"Starc",
106110
"Stoch",
@@ -116,6 +120,7 @@
116120
"Vitali",
117121
"Vwap",
118122
"Vwma",
123+
"warnaserror",
119124
"Woodie"
120125
],
121126
"cSpell.ignorePaths": [

docs/guide.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@ using Skender.Stock.Indicators;
6161
IEnumerable<Quote> quotes = GetHistoryFromFeed("MSFT");
6262

6363
// calculate 20-period SMA
64-
IEnumerable<SmaResult> results = quotes.GetSma(20);
64+
IEnumerable<SmaResult> results = quotes
65+
.GetSma(20);
6566

6667
// use results as needed for your use case (example only)
6768
foreach (SmaResult r in results)

docs/performance.md

Lines changed: 100 additions & 100 deletions
Large diffs are not rendered by default.

docs/utilities.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,11 @@ var results = quotes
3030

3131
### Using tuple quotes
3232

33-
`quotes.ToTuple()` is a method for converting any `TQuote` collection to a simple [tuple](https://docs.microsoft.com/dotnet/csharp/language-reference/builtin-types/value-tuples) `(DateTime, double)` formatted `List`. Most indicators in our library will accept this tuple format. With that said, there are many indicators that also require the full OHLCV quote format, so it cannot be used universally.
33+
`quotes.ToTupleCollection()` is a method for converting any `TQuote` collection to a simple [tuple](https://docs.microsoft.com/dotnet/csharp/language-reference/builtin-types/value-tuples) `(DateTime, double)` formatted `Collection`. Most indicators in our library will accept this tuple format. With that said, there are many indicators that also require the full OHLCV quote format, so it cannot be used universally.
3434

3535
### Sort quotes
3636

37-
`quotes.ToSortedList()` sorts any collection of `TQuote` or tuple `(DateTime, double)` and returns it as a `List` sorted by ascending `Date`. 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.
37+
`quotes.ToSortedCollection()` sorts any collection of `TQuote` or tuple `(DateTime, double)` and returns it as a `Collection` sorted by ascending `Date`. 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.
3838

3939
### Resize quote history
4040

@@ -156,7 +156,7 @@ See [individual indicator pages]({{site.baseurl}}/indicators/#content) for infor
156156
157157
### Using tuple results
158158

159-
`results.ToTuple(nullTo)` is a method for converting results collections to a simpler `(DateTime Date, double? Value)` formatted [tuple](https://docs.microsoft.com/dotnet/csharp/language-reference/builtin-types/value-tuples) `List`.
159+
`results.ToTupleCollection(nullTo)` is a method for converting results collections to a simpler `(DateTime Date, double? Value)` formatted [tuple](https://docs.microsoft.com/dotnet/csharp/language-reference/builtin-types/value-tuples) `Collection`.
160160

161161
This is not required in normal use; however, the last option may be useful for users who create [custom indicators]({{site.baseurl}}/custom-indicators/#content).
162162

@@ -173,7 +173,7 @@ A few options to consider:
173173
174174
### Sort results
175175

176-
`results.ToSortedList()` sorts any collection of indicator results and returns it as a `List` sorted by ascending `Date`. 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).
176+
`results.ToSortedCollection()` sorts any collection of indicator results and returns it as a `Collection` sorted by ascending `Date`. 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).
177177

178178
## Utilities for numerical analysis
179179

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
namespace Skender.Stock.Indicators;
22

3-
public static class Numerics
3+
public static class Numerix
44
{
55
// STANDARD DEVIATION
66
public static double StdDev(this double[] values)
77
{
88
// ref: https://stackoverflow.com/questions/2253874/standard-deviation-in-linq
99
// and then modified to an iterative model without LINQ, for performance improvement
1010

11+
if (values is null)
12+
{
13+
throw new ArgumentNullException(nameof(values), "StdDev values cannot be null.");
14+
}
15+
1116
double sd = 0;
1217
int n = values.Length;
1318
if (n > 1)
@@ -36,9 +41,23 @@ public static double StdDev(this double[] values)
3641
// SLOPE of BEST FIT LINE
3742
public static double Slope(double[] x, double[] y)
3843
{
39-
// TODO: add better error handling for mismatch size arrays
44+
// validate parameters
45+
if (x is null)
46+
{
47+
throw new ArgumentNullException(nameof(x), "Slope X values cannot be null.");
48+
}
49+
50+
if (y is null)
51+
{
52+
throw new ArgumentNullException(nameof(y), "Slope Y values cannot be null.");
53+
}
54+
55+
if (x.Length != y.Length)
56+
{
57+
throw new ArgumentException("Slope X and Y arrays must be the same size.");
58+
}
4059

41-
int length = Math.Min(x.Length, y.Length);
60+
int length = x.Length;
4261

4362
// get averages for period
4463
double sumX = 0;

src/_common/ObsoleteV2.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ namespace Skender.Stock.Indicators;
55
// OBSOLETE IN v2.0.0
66
public static partial class Indicator
77
{
8+
#pragma warning disable CA1002 // Do not expose generic lists
9+
810
// 2.4.1
911
[ExcludeFromCodeCoverage]
1012
[Obsolete("Rename 'ToBasicTuple(..)' to 'ToTuple(..)' to fix.", false)]
@@ -19,4 +21,6 @@ public static partial class Indicator
1921
public static List<(DateTime Date, double Value)> ToResultTuple(
2022
this IEnumerable<IReusableResult> basicData)
2123
=> basicData.ToTuple();
24+
25+
#pragma warning restore CA1002 // Do not expose generic lists
2226
}

src/_common/Quotes/Quote.Converters.cs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Collections.ObjectModel;
12
using System.Globalization;
23

34
namespace Skender.Stock.Indicators;
@@ -20,7 +21,7 @@ public static partial class QuoteUtility
2021
.Select(x => x.ToTuple(candlePart));
2122

2223
// sort quotes
23-
public static List<TQuote> ToSortedList<TQuote>(
24+
internal static List<TQuote> ToSortedList<TQuote>(
2425
this IEnumerable<TQuote> quotes)
2526
where TQuote : IQuote => quotes
2627
.OrderBy(x => x.Date)
@@ -29,7 +30,15 @@ public static List<TQuote> ToSortedList<TQuote>(
2930
// TUPLE QUOTES
3031

3132
// convert quotes to tuple list
32-
public static List<(DateTime, double)> ToTuple<TQuote>(
33+
public static Collection<(DateTime, double)> ToTupleCollection<TQuote>(
34+
this IEnumerable<TQuote> quotes,
35+
CandlePart candlePart)
36+
where TQuote : IQuote
37+
=> quotes
38+
.ToTuple(candlePart)
39+
.ToCollection();
40+
41+
internal static List<(DateTime, double)> ToTuple<TQuote>(
3342
this IEnumerable<TQuote> quotes,
3443
CandlePart candlePart)
3544
where TQuote : IQuote => quotes
@@ -38,8 +47,15 @@ public static List<TQuote> ToSortedList<TQuote>(
3847
.ToList();
3948

4049
// convert tuples to list, with sorting
41-
public static List<(DateTime, double)> ToSortedList(
42-
this IEnumerable<(DateTime date, double value)> tuples) => tuples
50+
public static Collection<(DateTime, double)> ToSortedCollection(
51+
this IEnumerable<(DateTime date, double value)> tuples)
52+
=> tuples
53+
.ToSortedList()
54+
.ToCollection();
55+
56+
internal static List<(DateTime, double)> ToSortedList(
57+
this IEnumerable<(DateTime date, double value)> tuples)
58+
=> tuples
4359
.OrderBy(x => x.date)
4460
.ToList();
4561

src/_common/Results/Result.Utilities.cs

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
using System.Collections.ObjectModel;
2+
13
namespace Skender.Stock.Indicators;
24

35
// HELPER FUNCTIONS
@@ -34,7 +36,7 @@ public static IEnumerable<TResult> Condense<TResult>(
3436
List<TResult> resultsList = results
3537
.ToList();
3638

37-
_ = resultsList
39+
resultsList
3840
.RemoveAll(match:
3941
x => x.Value is null or (double and double.NaN));
4042

@@ -126,14 +128,20 @@ public static IEnumerable<TResultR> SyncIndex<TResultR, TResultM>(
126128
}
127129
}
128130

129-
_ = resultsList.RemoveAll(x => toRemove.Contains(x));
131+
resultsList.RemoveAll(x => toRemove.Contains(x));
130132
}
131133

132134
return resultsList.ToSortedList();
133135
}
134136

135137
// CONVERT TO TUPLE (default with pruning)
136-
public static List<(DateTime Date, double Value)> ToTuple(
138+
public static Collection<(DateTime Date, double Value)> ToTupleCollection(
139+
this IEnumerable<IReusableResult> reusable)
140+
=> reusable
141+
.ToTuple()
142+
.ToCollection();
143+
144+
internal static List<(DateTime Date, double Value)> ToTuple(
137145
this IEnumerable<IReusableResult> reusable)
138146
{
139147
List<(DateTime date, double value)> prices = new();
@@ -152,7 +160,7 @@ public static IEnumerable<TResultR> SyncIndex<TResultR, TResultM>(
152160
}
153161

154162
// CONVERT TO TUPLE with nullable value option and no pruning
155-
public static List<(DateTime Date, double? Value)> ToTuple(
163+
internal static List<(DateTime Date, double? Value)> ToTuple(
156164
this IEnumerable<IReusableResult> reusable,
157165
NullTo nullTo)
158166
{
@@ -170,9 +178,17 @@ public static IEnumerable<TResultR> SyncIndex<TResultR, TResultM>(
170178
}
171179

172180
// RETURN SORTED LIST of RESULTS
173-
public static List<TResult> ToSortedList<TResult>(
181+
public static Collection<TResult> ToSortedCollection<TResult>(
174182
this IEnumerable<TResult> results)
175-
where TResult : IResult => results
183+
where TResult : IResult
184+
=> results
185+
.ToSortedList()
186+
.ToCollection();
187+
188+
internal static List<TResult> ToSortedList<TResult>(
189+
this IEnumerable<TResult> results)
190+
where TResult : IResult
191+
=> results
176192
.OrderBy(x => x.Date)
177193
.ToList();
178194

0 commit comments

Comments
 (0)