mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-08-21 20:18:05 +00:00
style patterns
This commit is contained in:
@@ -184,8 +184,8 @@ public class JerkIndicatorTests
|
||||
|
||||
var now = DateTime.UtcNow;
|
||||
|
||||
// Cubic trend: f(x) = x³ has third derivative = 6
|
||||
// Using f(i) = i³, the discrete third differences converge to 6
|
||||
// Cubic trend: f(x) = x³ has third derivative = 6
|
||||
// Using f(i) = i³, the discrete third differences converge to 6
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
double price = 100 + i * i * i; // cubic growth
|
||||
@@ -194,7 +194,7 @@ public class JerkIndicatorTests
|
||||
}
|
||||
|
||||
double lastJerk = indicator.LinesSeries[0].GetValue(0);
|
||||
// For f(x) = x³, discrete third difference = 6
|
||||
// For f(x) = x³, discrete third difference = 6
|
||||
Assert.Equal(6.0, lastJerk, 6);
|
||||
}
|
||||
|
||||
@@ -217,4 +217,4 @@ public class JerkIndicatorTests
|
||||
double lastJerk = indicator.LinesSeries[0].GetValue(0);
|
||||
Assert.Equal(0, lastJerk, 6);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,10 @@ public class JerkIndicator : Indicator, IWatchlistIndicator
|
||||
|
||||
protected override void OnUpdate(UpdateArgs args)
|
||||
{
|
||||
if (_jerk == null || _selector == null) return;
|
||||
if (_jerk == null || _selector == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var item = HistoricalData[0, SeekOriginHistory.End];
|
||||
double value = _selector(item);
|
||||
@@ -60,11 +63,18 @@ public class JerkIndicator : Indicator, IWatchlistIndicator
|
||||
double jerk = _jerk.Last.Value;
|
||||
Color color;
|
||||
if (jerk > 0)
|
||||
{
|
||||
color = Color.Green;
|
||||
}
|
||||
else if (jerk < 0)
|
||||
{
|
||||
color = Color.Red;
|
||||
}
|
||||
else
|
||||
{
|
||||
color = Color.Gray;
|
||||
}
|
||||
|
||||
LinesSeries[0].SetMarker(0, new IndicatorLineMarker(color));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,12 +258,12 @@ public class JerkTests
|
||||
{
|
||||
var source = new TSeries();
|
||||
var jerk = new Jerk(source);
|
||||
|
||||
|
||||
source.Add(new TValue(DateTime.UtcNow, 10));
|
||||
source.Add(new TValue(DateTime.UtcNow, 20));
|
||||
source.Add(new TValue(DateTime.UtcNow, 35));
|
||||
source.Add(new TValue(DateTime.UtcNow, 40));
|
||||
|
||||
|
||||
Assert.True(jerk.IsHot);
|
||||
// jerk = 40 - 3*35 + 3*20 - 10 = 40 - 105 + 60 - 10 = -15
|
||||
Assert.Equal(-15, jerk.Last.Value);
|
||||
@@ -304,4 +304,4 @@ public class JerkTests
|
||||
Assert.Equal(jerkResults[i], chainResults[i], precision: 9);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+66
-16
@@ -78,8 +78,8 @@ public sealed class Jerk : AbstractBase
|
||||
|
||||
if (_state.Count >= 3)
|
||||
{
|
||||
// jerk = val - 3*prev1 + 3*prev2 - prev3
|
||||
// Using FMA: val - 3*prev1 + 3*prev2 - prev3
|
||||
// jerk = val - 3*prev1 + 3*prev2 - prev3
|
||||
// Using FMA: val - 3*prev1 + 3*prev2 - prev3
|
||||
// = FMA(-3, prev1, val) + FMA(3, prev2, -prev3)
|
||||
double term1 = Math.FusedMultiplyAdd(-3.0, _state.Prev1, val);
|
||||
double term2 = Math.FusedMultiplyAdd(3.0, _state.Prev2, -_state.Prev3);
|
||||
@@ -127,7 +127,10 @@ public sealed class Jerk : AbstractBase
|
||||
|
||||
public override TSeries Update(TSeries source)
|
||||
{
|
||||
if (source.Count == 0) return [];
|
||||
if (source.Count == 0)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
int len = source.Count;
|
||||
|
||||
@@ -211,18 +214,34 @@ public sealed class Jerk : AbstractBase
|
||||
public static void Calculate(ReadOnlySpan<double> source, Span<double> output)
|
||||
{
|
||||
if (source.Length != output.Length)
|
||||
{
|
||||
throw new ArgumentException("Source and output must have the same length", nameof(output));
|
||||
}
|
||||
|
||||
int len = source.Length;
|
||||
if (len == 0) return;
|
||||
if (len == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// First three elements have insufficient history
|
||||
output[0] = 0.0;
|
||||
if (len == 1) return;
|
||||
if (len == 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
output[1] = 0.0;
|
||||
if (len == 2) return;
|
||||
if (len == 2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
output[2] = 0.0;
|
||||
if (len == 3) return;
|
||||
if (len == 3)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int i = 3;
|
||||
|
||||
@@ -339,10 +358,25 @@ public sealed class Jerk : AbstractBase
|
||||
|
||||
// Handle NaN/Infinity by substitution (find first finite value)
|
||||
double fallback = FindFinite(curr, p1, p2, p3);
|
||||
if (!double.IsFinite(curr)) curr = fallback;
|
||||
if (!double.IsFinite(p1)) p1 = fallback;
|
||||
if (!double.IsFinite(p2)) p2 = fallback;
|
||||
if (!double.IsFinite(p3)) p3 = fallback;
|
||||
if (!double.IsFinite(curr))
|
||||
{
|
||||
curr = fallback;
|
||||
}
|
||||
|
||||
if (!double.IsFinite(p1))
|
||||
{
|
||||
p1 = fallback;
|
||||
}
|
||||
|
||||
if (!double.IsFinite(p2))
|
||||
{
|
||||
p2 = fallback;
|
||||
}
|
||||
|
||||
if (!double.IsFinite(p3))
|
||||
{
|
||||
p3 = fallback;
|
||||
}
|
||||
|
||||
// jerk = curr - 3*prev1 + 3*prev2 - prev3
|
||||
double term1 = Math.FusedMultiplyAdd(-3.0, p1, curr);
|
||||
@@ -354,10 +388,26 @@ public sealed class Jerk : AbstractBase
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static double FindFinite(double a, double b, double c, double d)
|
||||
{
|
||||
if (double.IsFinite(a)) return a;
|
||||
if (double.IsFinite(b)) return b;
|
||||
if (double.IsFinite(c)) return c;
|
||||
if (double.IsFinite(d)) return d;
|
||||
if (double.IsFinite(a))
|
||||
{
|
||||
return a;
|
||||
}
|
||||
|
||||
if (double.IsFinite(b))
|
||||
{
|
||||
return b;
|
||||
}
|
||||
|
||||
if (double.IsFinite(c))
|
||||
{
|
||||
return c;
|
||||
}
|
||||
|
||||
if (double.IsFinite(d))
|
||||
{
|
||||
return d;
|
||||
}
|
||||
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user