style patterns

This commit is contained in:
Miha Kralj
2026-01-25 16:01:45 -08:00
parent 2836f253c4
commit e59665c8f0
399 changed files with 6892 additions and 1323 deletions
+1 -1
View File
@@ -204,4 +204,4 @@ public class RemaIndicatorTests
Assert.NotEqual(result1, result2);
}
}
}
+1 -1
View File
@@ -55,4 +55,4 @@ public class RemaIndicator : Indicator, IWatchlistIndicator
TValue result = ma.Update(new TValue(item.TimeLeft.Ticks, _priceSelector(item)), isNew: args.IsNewBar());
Series.SetValue(result.Value, ma.IsHot, ShowColdValues);
}
}
}
+20 -3
View File
@@ -447,7 +447,9 @@ public class RemaTests
var gbm = new GBM(startPrice: 100, mu: 0.05, sigma: 0.2, seed: 42);
for (int i = 0; i < source.Length; i++)
{
source[i] = gbm.Next().Close;
}
// Warm up
Rema.Batch(source.AsSpan(), output.AsSpan(), 100);
@@ -491,7 +493,10 @@ public class RemaTests
// Verify against a fresh REMA fed with same data
var verifyRema = new Rema(5);
foreach (var val in history) verifyRema.Update(new TValue(DateTime.UtcNow, val));
foreach (var val in history)
{
verifyRema.Update(new TValue(DateTime.UtcNow, val));
}
Assert.Equal(verifyRema.Last.Value, rema.Last.Value, 1e-10);
Assert.Equal(verifyRema.IsHot, rema.IsHot);
@@ -511,7 +516,10 @@ public class RemaTests
rema.Prime(history);
var verifyRema = new Rema(5);
foreach (var val in history) verifyRema.Update(new TValue(DateTime.UtcNow, val));
foreach (var val in history)
{
verifyRema.Update(new TValue(DateTime.UtcNow, val));
}
Assert.Equal(verifyRema.Last.Value, rema.Last.Value, 1e-10);
}
@@ -531,7 +539,10 @@ public class RemaTests
public void Calculate_ReturnsCorrectResultsAndHotIndicator()
{
var series = new TSeries();
for (int i = 1; i <= 20; i++) series.Add(DateTime.UtcNow, i * 10);
for (int i = 1; i <= 20; i++)
{
series.Add(DateTime.UtcNow, i * 10);
}
var (results, indicator) = Rema.Calculate(series, 5);
@@ -640,14 +651,20 @@ public class RemaTests
// 3. Streaming Mode
var streamingInd = new Rema(period, lambda);
for (int i = 0; i < series.Count; i++)
{
streamingInd.Update(series[i]);
}
double streamingResult = streamingInd.Last.Value;
// 4. Eventing Mode
var pubSource = new TSeries();
var eventingInd = new Rema(pubSource, period, lambda);
for (int i = 0; i < series.Count; i++)
{
pubSource.Add(series[i]);
}
double eventingResult = eventingInd.Last.Value;
Assert.Equal(expected, spanResult, precision: 9);
+9 -3
View File
@@ -304,7 +304,10 @@ public sealed class RemaValidationTests : IDisposable
private static double CalculateDiffVariance(double[] values, int startIdx, int count)
{
if (count < 2) return 0;
if (count < 2)
{
return 0;
}
// Calculate differences
double sumDiff = 0;
@@ -319,10 +322,13 @@ public sealed class RemaValidationTests : IDisposable
n++;
}
if (n < 2) return 0;
if (n < 2)
{
return 0;
}
double mean = sumDiff / n;
double variance = (sumDiffSq / n) - (mean * mean);
return Math.Max(0, variance); // Ensure non-negative due to floating point
}
}
}
+40 -7
View File
@@ -69,7 +69,9 @@ public sealed class Rema : AbstractBase
{
ArgumentOutOfRangeException.ThrowIfNegativeOrZero(period);
if (lambda < 0.0 || lambda > 1.0)
{
throw new ArgumentOutOfRangeException(nameof(lambda), "Lambda must be between 0 and 1");
}
_alpha = 2.0 / (period + 1);
_decay = 1.0 - _alpha;
@@ -108,7 +110,10 @@ public sealed class Rema : AbstractBase
/// <inheritdoc/>
public override void Prime(ReadOnlySpan<double> source, TimeSpan? step = null)
{
if (source.Length == 0) return;
if (source.Length == 0)
{
return;
}
_state = State.New();
_p_state = State.New();
@@ -152,7 +157,9 @@ public sealed class Rema : AbstractBase
finally
{
if (rented != null)
{
ArrayPool<double>.Shared.Return(rented);
}
}
}
@@ -196,7 +203,10 @@ public sealed class Rema : AbstractBase
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
public override TSeries Update(TSeries source)
{
if (source.Count == 0) return [];
if (source.Count == 0)
{
return [];
}
int len = source.Count;
var t = new List<long>(len);
@@ -245,7 +255,9 @@ public sealed class Rema : AbstractBase
state.E *= decay;
if (state.E <= COVERAGE_THRESHOLD)
{
state.IsHot = true;
}
result = input;
}
@@ -273,7 +285,9 @@ public sealed class Rema : AbstractBase
state.E *= decay;
if (!state.IsHot && state.E <= COVERAGE_THRESHOLD)
{
state.IsHot = true;
}
if (state.E <= COMPENSATOR_THRESHOLD)
{
@@ -311,9 +325,13 @@ public sealed class Rema : AbstractBase
{
double val = Unsafe.Add(ref srcRef, i);
if (!double.IsFinite(val))
{
val = lastValidValue;
}
else
{
lastValidValue = val;
}
double result;
@@ -326,7 +344,9 @@ public sealed class Rema : AbstractBase
state.E *= decay;
if (state.E <= COVERAGE_THRESHOLD)
{
state.IsHot = true;
}
result = val;
}
@@ -345,7 +365,9 @@ public sealed class Rema : AbstractBase
state.E *= decay;
if (!state.IsHot && state.E <= COVERAGE_THRESHOLD)
{
state.IsHot = true;
}
if (state.E <= COMPENSATOR_THRESHOLD)
{
@@ -399,13 +421,24 @@ public sealed class Rema : AbstractBase
public static void Batch(ReadOnlySpan<double> source, Span<double> output, int period, double lambda = 0.5)
{
if (period <= 0)
{
throw new ArgumentException("Period must be greater than 0", nameof(period));
if (lambda < 0.0 || lambda > 1.0)
throw new ArgumentOutOfRangeException(nameof(lambda), "Lambda must be between 0 and 1");
if (source.Length != output.Length)
throw new ArgumentException("Source and output must have the same length", nameof(output));
}
if (source.Length == 0) return;
if (lambda < 0.0 || lambda > 1.0)
{
throw new ArgumentOutOfRangeException(nameof(lambda), "Lambda must be between 0 and 1");
}
if (source.Length != output.Length)
{
throw new ArgumentException("Source and output must have the same length", nameof(output));
}
if (source.Length == 0)
{
return;
}
double alpha = 2.0 / (period + 1);