feat: Add new CodeQL extension for C# and SonarLint configuration

- Introduced a new CodeQL extension for C# in `.github/codeql/extensions/quantalib-csharp/codeql-pack.yml`.
- Added SonarLint configuration in `.sonarlint/CSharp/SonarLint.xml` and `.sonarlint/csharp.ruleset` to suppress specific rules for high-performance indicators.
- Removed outdated `.vscode/launch.json` configurations.
- Updated `.vscode/tasks.json` to streamline build and test tasks, including renaming and consolidating tasks.
- Modified `Directory.Build.props` to enhance SARIF output directory handling and integrate SonarLint rules.
- Refactored various indicator classes to improve code clarity and maintainability, including updates to method parameters for consistency.
- Added XML documentation comments to several classes and methods for better code understanding.
- Improved numerical stability in calculations by replacing direct comparisons with `double.Epsilon` checks in multiple classes.
This commit is contained in:
Miha Kralj
2026-01-21 23:05:38 -06:00
parent 32f3366952
commit da4e56bf40
32 changed files with 187 additions and 187 deletions
+4 -1
View File
@@ -75,6 +75,9 @@ public sealed class Hamma : AbstractBase
_state.LastValidValue = double.NaN;
}
/// <summary>
/// Creates HAMMA with source for event-based chaining.
/// </summary>
/// <param name="source">Data source for event-based updates</param>
/// <param name="period">Lookback period for the Hamming window (default: 10)</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -391,4 +394,4 @@ public sealed class Hamma : AbstractBase
_p_state = _state;
Last = default;
}
}
}
+3
View File
@@ -70,6 +70,9 @@ public sealed class Hanma : AbstractBase
_state = new State(double.NaN, IsInitialized: false);
}
/// <summary>
///
/// </summary>
/// <param name="source">Data source for event-based updates</param>
/// <param name="period">Lookback period for the Hanning window (default: 10)</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+4 -1
View File
@@ -109,6 +109,9 @@ public sealed class Hwma : AbstractBase
_state = new State(double.NaN, 0, 0, double.NaN, IsInitialized: false);
}
/// <summary>
/// Creates HWMA with source for event-based chaining.
/// </summary>
/// <param name="source">Data source for event-based updates</param>
/// <param name="period">Period for smoothing factor calculation (default: 10)</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -339,4 +342,4 @@ public sealed class Hwma : AbstractBase
_p_state = _state;
Last = default;
}
}
}
+9 -9
View File
@@ -101,7 +101,7 @@ public sealed class Sgma : AbstractBase
weights[3] = 0.3429;
weights[4] = -0.0857;
double sum5 = weights[0] + weights[1] + weights[2] + weights[3] + weights[4];
invWeightSum = sum5 != 0.0 ? 1.0 / sum5 : 0.0;
invWeightSum = Math.Abs(sum5) > double.Epsilon ? 1.0 / sum5 : 0.0;
return;
}
@@ -116,7 +116,7 @@ public sealed class Sgma : AbstractBase
weights[6] = -0.0476;
double sum7 = 0.0;
for (int i = 0; i < 7; i++) sum7 += weights[i];
invWeightSum = sum7 != 0.0 ? 1.0 / sum7 : 0.0;
invWeightSum = Math.Abs(sum7) > double.Epsilon ? 1.0 / sum7 : 0.0;
return;
}
@@ -133,7 +133,7 @@ public sealed class Sgma : AbstractBase
weights[8] = -0.0281;
double sum9 = 0.0;
for (int i = 0; i < 9; i++) sum9 += weights[i];
invWeightSum = sum9 != 0.0 ? 1.0 / sum9 : 0.0;
invWeightSum = Math.Abs(sum9) > double.Epsilon ? 1.0 / sum9 : 0.0;
return;
}
}
@@ -376,7 +376,7 @@ public sealed class Sgma : AbstractBase
continue;
}
if (invWeightSum == 0.0)
if (Math.Abs(invWeightSum) < double.Epsilon)
{
output[i] = val;
continue;
@@ -399,7 +399,7 @@ public sealed class Sgma : AbstractBase
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static double CalculateWeightedSumFull(RingBuffer buffer, double[] weights, double invWeightSum, double fallbackValue)
{
if (invWeightSum == 0.0)
if (Math.Abs(invWeightSum) < double.Epsilon)
return fallbackValue;
ReadOnlySpan<double> internalBuf = buffer.InternalBuffer;
@@ -435,7 +435,7 @@ public sealed class Sgma : AbstractBase
Math.FusedMultiplyAdd(window[3], w3, window[4] * w4))));
double weightSum = w0 + w1 + w2 + w3 + w4;
return weightSum != 0.0 ? sum / weightSum : fallbackValue;
return Math.Abs(weightSum) > double.Epsilon ? sum / weightSum : fallbackValue;
}
if (p == 7)
@@ -458,7 +458,7 @@ public sealed class Sgma : AbstractBase
sum = Math.FusedMultiplyAdd(window[6], w6, sum);
double weightSum = w0 + w1 + w2 + w3 + w4 + w5 + w6;
return weightSum != 0.0 ? sum / weightSum : fallbackValue;
return Math.Abs(weightSum) > double.Epsilon ? sum / weightSum : fallbackValue;
}
if (p == 9)
@@ -485,7 +485,7 @@ public sealed class Sgma : AbstractBase
sum = Math.FusedMultiplyAdd(window[8], w8, sum);
double weightSum = w0 + w1 + w2 + w3 + w4 + w5 + w6 + w7 + w8;
return weightSum != 0.0 ? sum / weightSum : fallbackValue;
return Math.Abs(weightSum) > double.Epsilon ? sum / weightSum : fallbackValue;
}
}
@@ -522,4 +522,4 @@ public sealed class Sgma : AbstractBase
_p_lastValidValue = double.NaN;
Last = default;
}
}
}
-1
View File
@@ -189,7 +189,6 @@ public sealed class Sma : AbstractBase
double val = GetValidValue(input.Value);
UpdateState(val);
}
else
{