feat(validation): add input validation for Bilateral and Blma constructors; enhance Butter and Mgdi calculations with NaN handling

This commit is contained in:
Miha Kralj
2025-12-25 20:53:56 -08:00
parent ac8b2dbb3f
commit 0d077c24d8
15 changed files with 195 additions and 66 deletions
+19
View File
@@ -170,4 +170,23 @@ public class WmaTests
Assert.Throws<ArgumentException>(() => new Wma(0));
Assert.Throws<ArgumentException>(() => new Wma(-1));
}
[Fact]
public void Dispose_UnsubscribesFromSource()
{
var source = new TSeries();
var wma = new Wma(source, 10);
// Verify subscription works
source.Add(new TValue(DateTime.UtcNow, 100));
Assert.Equal(100, wma.Last.Value);
// Dispose
wma.Dispose();
// Verify unsubscription
source.Add(new TValue(DateTime.UtcNow, 200));
// Last value should remain unchanged if unsubscribed
Assert.Equal(100, wma.Last.Value);
}
}
+14 -2
View File
@@ -27,11 +27,13 @@ namespace QuanTAlib;
/// Becomes true when the buffer is full (period samples processed).
/// </remarks>
[SkipLocalsInit]
public sealed class Wma : AbstractBase
public sealed class Wma : AbstractBase, IDisposable
{
private readonly int _period;
private readonly double _divisor;
private readonly RingBuffer _buffer;
private readonly ITValuePublisher? _source;
private readonly Action<TValue>? _handler;
private record struct State(double Sum, double WSum, double LastInput, double LastValidValue, int TickCount);
private State _state;
@@ -59,7 +61,17 @@ public sealed class Wma : AbstractBase
public Wma(ITValuePublisher source, int period) : this(period)
{
source.Pub += (item) => Update(item);
_source = source;
_handler = (item) => Update(item);
_source.Pub += _handler;
}
public void Dispose()
{
if (_source != null && _handler != null)
{
_source.Pub -= _handler;
}
}
public override bool IsHot => _buffer.IsFull;