code reviews

This commit is contained in:
Miha Kralj
2026-01-18 22:23:50 -08:00
parent 86fe32a682
commit 4673f48a70
40 changed files with 1155 additions and 309 deletions
+15 -4
View File
@@ -395,7 +395,7 @@ public class TBarTests
}
[Fact]
public void TBar_WithInfinity_HandlesGracefully()
public void TBar_WithPositiveInfinity_HandlesGracefully()
{
var bar = new TBar(12345, 100, double.PositiveInfinity, 90, 105, 1000);
@@ -404,6 +404,17 @@ public class TBarTests
Assert.True(double.IsPositiveInfinity(bar.HL2)); // Uses High
}
[Fact]
public void TBar_WithNegativeInfinity_HandlesGracefully()
{
var bar = new TBar(12345, 100, 110, double.NegativeInfinity, 105, 1000);
Assert.True(double.IsNegativeInfinity(bar.Low));
Assert.True(double.IsNegativeInfinity(bar.L.Value));
Assert.True(double.IsNegativeInfinity(bar.HL2)); // Uses Low
Assert.True(double.IsNegativeInfinity(bar.HLC3)); // Uses Low
}
[Fact]
public void TBar_WithMaxValue_HandlesGracefully()
{
@@ -412,8 +423,8 @@ public class TBarTests
Assert.Equal(double.MaxValue, bar.Open);
Assert.Equal(double.MaxValue, bar.High);
Assert.Equal(double.MinValue, bar.Low);
// HL2 calculation with extreme values
Assert.True(double.IsFinite(bar.HL2) || double.IsInfinity(bar.HL2));
// HL2 = (MaxValue + MinValue) * 0.5 = 0 (symmetric around zero)
Assert.Equal(0.0, bar.HL2);
}
[Fact]
@@ -497,4 +508,4 @@ public class TBarTests
// (90 + 120 + 60) / 3 = 270 / 3 = 90
Assert.Equal(90.0, bar.OHL3);
}
}
}
+10 -2
View File
@@ -23,11 +23,19 @@ public readonly record struct TBar(long Time, double Open, double High, double L
// Computed properties (calculated on demand, no storage overhead)
public double HL2 { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => (High + Low) * 0.5; }
public double OC2 { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => (Open + Close) * 0.5; }
public double OHL3 { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => (Open + High + Low) / 3.0; }
public double HLC3 { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => (High + Low + Close) / 3.0; }
public double OHL3 { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => (Open + High + Low) * (1.0 / 3.0); }
public double HLC3 { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => (High + Low + Close) * (1.0 / 3.0); }
public double OHLC4 { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => (Open + High + Low + Close) * 0.25; }
public double HLCC4 { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => (High + Low + Close + Close) * 0.25; }
/// <summary>
/// Creates a TBar from DateTime and OHLCV values.
/// </summary>
/// <remarks>
/// <b>Performance warning:</b> If <paramref name="time"/>.Kind is not <see cref="DateTimeKind.Utc"/>,
/// <see cref="DateTime.ToUniversalTime"/> is called, which allocates. For hot paths, prefer the
/// primary constructor with pre-computed UTC ticks.
/// </remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public TBar(DateTime time, double open, double high, double low, double close, double volume)
: this(time.Kind == DateTimeKind.Utc ? time.Ticks : time.ToUniversalTime().Ticks, open, high, low, close, volume)