Add Ehlers Hilbert Transform Instantaneous Trend (HTIT) implementation and tests

- Implemented the HTIT indicator in Htit.cs, utilizing the Hilbert Transform for trend analysis.
- Added unit tests for HTIT validation against TA-Lib, Skender, and Ooples implementations in Htit.Validation.Tests.cs.
- Created documentation for HTIT in Htit.md, detailing its core concepts, formula, parameters, usage, and interpretation.
This commit is contained in:
Miha Kralj
2025-12-14 16:52:02 -08:00
parent f7b8fe1654
commit 822aaa0d40
18 changed files with 951 additions and 267 deletions
+4 -4
View File
@@ -437,19 +437,19 @@ public class RingBufferTests
}
[Fact]
public void Newest_EmptyBuffer_ReturnsZero()
public void Newest_EmptyBuffer_ReturnsNaN()
{
var buffer = new RingBuffer(5);
Assert.Equal(0, buffer.Newest);
Assert.True(double.IsNaN(buffer.Newest));
}
[Fact]
public void Oldest_EmptyBuffer_ReturnsZero()
public void Oldest_EmptyBuffer_ReturnsNaN()
{
var buffer = new RingBuffer(5);
Assert.Equal(0, buffer.Oldest);
Assert.True(double.IsNaN(buffer.Oldest));
}
[Fact]
+4 -2
View File
@@ -110,13 +110,14 @@ public sealed class RingBuffer : IEnumerable<double>
/// <summary>
/// Gets the newest (most recently added) value.
/// Returns double.NaN if buffer is empty.
/// </summary>
public double Newest
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
if (_count == 0) return 0;
if (_count == 0) return double.NaN;
int idx = (_head - 1 + _capacity) % _capacity;
return _buffer[idx];
}
@@ -124,13 +125,14 @@ public sealed class RingBuffer : IEnumerable<double>
/// <summary>
/// Gets the oldest value in the buffer.
/// Returns double.NaN if buffer is empty.
/// </summary>
public double Oldest
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
if (_count == 0) return 0;
if (_count == 0) return double.NaN;
int start = _count == _capacity ? _head : 0;
return _buffer[start];
}
+1 -1
View File
@@ -21,12 +21,12 @@ public class TBarSeries : IReadOnlyList<TBar>
public string Name { get; set; } = "Bar";
public event Action<TBar>? Pub;
// Note: These views share underlying storage. Do not modify directly; use TBarSeries.Add() instead.
public TSeries Open { get; }
public TSeries High { get; }
public TSeries Low { get; }
public TSeries Close { get; }
public TSeries Volume { get; }
// Aliases for convenience
public TSeries O => Open;
public TSeries H => High;