mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-08-23 21:18:04 +00:00
volume indicators
This commit is contained in:
@@ -162,7 +162,7 @@ public sealed class Alma : AbstractBase
|
||||
Last = new TValue(input.Time, result);
|
||||
if (publish)
|
||||
{
|
||||
PubEvent(Last);
|
||||
PubEvent(Last, isNew);
|
||||
}
|
||||
return Last;
|
||||
}
|
||||
@@ -202,10 +202,56 @@ public sealed class Alma : AbstractBase
|
||||
|
||||
public override void Prime(ReadOnlySpan<double> source, TimeSpan? step = null)
|
||||
{
|
||||
foreach (var value in source)
|
||||
if (source.Length == 0)
|
||||
{
|
||||
Update(new TValue(DateTime.MinValue, value));
|
||||
return;
|
||||
}
|
||||
|
||||
// Reset state
|
||||
_buffer.Clear();
|
||||
_state = default;
|
||||
_p_state = default;
|
||||
|
||||
int warmupLength = Math.Min(source.Length, WarmupPeriod);
|
||||
int startIndex = source.Length - warmupLength;
|
||||
|
||||
// Seed LastValidValue from history before warmup window
|
||||
double lastValid = double.NaN;
|
||||
for (int i = startIndex - 1; i >= 0; i--)
|
||||
{
|
||||
if (double.IsFinite(source[i]))
|
||||
{
|
||||
lastValid = source[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If not found, search in warmup window
|
||||
if (double.IsNaN(lastValid))
|
||||
{
|
||||
for (int i = startIndex; i < source.Length; i++)
|
||||
{
|
||||
if (double.IsFinite(source[i]))
|
||||
{
|
||||
lastValid = source[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize state with seeded LastValidValue
|
||||
if (double.IsFinite(lastValid))
|
||||
{
|
||||
_state = new State(lastValid, IsInitialized: true);
|
||||
}
|
||||
|
||||
// Feed the warmup data
|
||||
for (int i = startIndex; i < source.Length; i++)
|
||||
{
|
||||
Update(new TValue(DateTime.MinValue, source[i]), isNew: true, publish: false);
|
||||
}
|
||||
|
||||
_p_state = _state;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
|
||||
@@ -392,7 +392,7 @@ public sealed class Sgma : AbstractBase
|
||||
}
|
||||
else
|
||||
{
|
||||
val = 0.0;
|
||||
val = double.NaN;
|
||||
}
|
||||
|
||||
ring[ringIdx] = val;
|
||||
|
||||
@@ -31,6 +31,8 @@ public sealed class Sinema : AbstractBase
|
||||
private readonly double _weightSum;
|
||||
private readonly RingBuffer _buffer;
|
||||
private readonly TValuePublishedHandler _handler;
|
||||
private readonly ITValuePublisher? _source;
|
||||
private bool _disposed;
|
||||
|
||||
[StructLayout(LayoutKind.Auto)]
|
||||
private record struct State(double LastValidValue);
|
||||
@@ -67,6 +69,7 @@ public sealed class Sinema : AbstractBase
|
||||
|
||||
public Sinema(ITValuePublisher source, int period) : this(period)
|
||||
{
|
||||
_source = source;
|
||||
source.Pub += _handler;
|
||||
}
|
||||
|
||||
@@ -77,6 +80,7 @@ public sealed class Sinema : AbstractBase
|
||||
{
|
||||
Last = new TValue(source.LastTime, Last.Value);
|
||||
}
|
||||
_source = source;
|
||||
source.Pub += _handler;
|
||||
}
|
||||
|
||||
@@ -443,4 +447,20 @@ public sealed class Sinema : AbstractBase
|
||||
_p_state = default;
|
||||
Last = default;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes the indicator and unsubscribes from the source.
|
||||
/// </summary>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (!_disposed)
|
||||
{
|
||||
if (disposing && _source != null)
|
||||
{
|
||||
_source.Pub -= _handler;
|
||||
}
|
||||
_disposed = true;
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,8 @@ public sealed class Sma : AbstractBase
|
||||
private readonly int _period;
|
||||
private readonly RingBuffer _buffer;
|
||||
private readonly TValuePublishedHandler _handler;
|
||||
private readonly ITValuePublisher? _source;
|
||||
private bool _disposed;
|
||||
|
||||
[StructLayout(LayoutKind.Auto)]
|
||||
private record struct State(double Sum, double LastValidValue, int TickCount);
|
||||
@@ -58,6 +60,7 @@ public sealed class Sma : AbstractBase
|
||||
|
||||
public Sma(ITValuePublisher source, int period) : this(period)
|
||||
{
|
||||
_source = source;
|
||||
source.Pub += _handler;
|
||||
}
|
||||
|
||||
@@ -68,6 +71,7 @@ public sealed class Sma : AbstractBase
|
||||
{
|
||||
Last = new TValue(source.LastTime, Last.Value);
|
||||
}
|
||||
_source = source;
|
||||
source.Pub += _handler;
|
||||
}
|
||||
|
||||
@@ -652,4 +656,20 @@ public sealed class Sma : AbstractBase
|
||||
_p_state = default;
|
||||
Last = default;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes the indicator and unsubscribes from the source.
|
||||
/// </summary>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (!_disposed)
|
||||
{
|
||||
if (disposing && _source != null)
|
||||
{
|
||||
_source.Pub -= _handler;
|
||||
}
|
||||
_disposed = true;
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user