fix: add validation for empty span in MinScalar and MaxScalar methods; ensure valid OHLC values in GBM calculations

This commit is contained in:
Miha Kralj
2025-12-13 22:51:26 -08:00
parent 7168866098
commit fd3065e7b9
3 changed files with 33 additions and 16 deletions
+6
View File
@@ -37,6 +37,9 @@ public static class SimdExtensions
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static double MinScalar(ReadOnlySpan<double> span)
{
if (span.Length == 0)
throw new ArgumentException("Span must not be empty", nameof(span));
double min = span[0];
for (int i = 1; i < span.Length; i++)
{
@@ -49,6 +52,9 @@ public static class SimdExtensions
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static double MaxScalar(ReadOnlySpan<double> span)
{
if (span.Length == 0)
throw new ArgumentException("Span must not be empty", nameof(span));
double max = span[0];
for (int i = 1; i < span.Length; i++)
{
+9 -12
View File
@@ -124,8 +124,7 @@ public static class ValidationHelper
{
int count = qSeries.Count;
int start = Math.Max(0, count - skip);
var (_, length) = outRange.GetOffsetAndLength(tOutput.Length);
int validCount = length;
var (offset, length) = outRange.GetOffsetAndLength(tOutput.Length);
for (int i = start; i < count; i++)
{
@@ -133,8 +132,8 @@ public static class ValidationHelper
if (i < lookback) continue;
int tIndex = i - lookback;
if (tIndex >= validCount) continue;
int tIndex = i - offset;
if (tIndex < 0 || tIndex >= length) continue;
double tValue = tOutput[tIndex];
@@ -146,8 +145,7 @@ public static class ValidationHelper
{
int count = qResults.Count;
int start = Math.Max(0, count - skip);
var (_, length) = outRange.GetOffsetAndLength(tOutput.Length);
int validCount = length;
var (offset, length) = outRange.GetOffsetAndLength(tOutput.Length);
for (int i = start; i < count; i++)
{
@@ -155,8 +153,8 @@ public static class ValidationHelper
if (i < lookback) continue;
int tIndex = i - lookback;
if (tIndex >= validCount) continue;
int tIndex = i - offset;
if (tIndex < 0 || tIndex >= length) continue;
double tValue = tOutput[tIndex];
@@ -168,8 +166,7 @@ public static class ValidationHelper
{
int count = qOutput.Length;
int start = Math.Max(0, count - skip);
var (_, length) = outRange.GetOffsetAndLength(tOutput.Length);
int validCount = length;
var (offset, length) = outRange.GetOffsetAndLength(tOutput.Length);
for (int i = start; i < count; i++)
{
@@ -177,8 +174,8 @@ public static class ValidationHelper
if (i < lookback) continue;
int tIndex = i - lookback;
if (tIndex >= validCount) continue;
int tIndex = i - offset;
if (tIndex < 0 || tIndex >= length) continue;
double tValue = tOutput[tIndex];
+18 -4
View File
@@ -132,8 +132,13 @@ public class GBM : IFeed
double open = _lastPrice;
double close = price;
double high = Math.Max(open, close) * (1.0 + NextDouble() * 0.01);
double low = Math.Min(open, close) * (1.0 - NextDouble() * 0.01);
double high = Math.Max(open, close) * (1.0 + Math.Abs(NextDouble()) * 0.01);
double low = Math.Min(open, close) * (1.0 - Math.Abs(NextDouble()) * 0.01);
// Ensure valid OHLC
high = Math.Max(high, Math.Max(open, close));
low = Math.Min(low, Math.Min(open, close));
low = Math.Max(0.0, low);
_currentBar = new TBar(currentTime, open, high, low, close, volume);
_hasCurrentBar = true;
@@ -215,8 +220,17 @@ public class GBM : IFeed
t[i] = currentTime;
o[i] = open;
c[i] = close;
h[i] = Math.Max(open, close) * (1.0 + rnd1 * 0.01);
l[i] = Math.Min(open, close) * (1.0 - rnd2 * 0.01);
double high = Math.Max(open, close) * (1.0 + Math.Abs(rnd1) * 0.01);
double low = Math.Min(open, close) * (1.0 - Math.Abs(rnd2) * 0.01);
// Ensure valid OHLC
high = Math.Max(high, Math.Max(open, close));
low = Math.Min(low, Math.Min(open, close));
low = Math.Max(0.0, low);
h[i] = high;
l[i] = low;
v[i] = 1000 + rnd3 * 1000;
currentPrice = price;