mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-08-20 11:38:05 +00:00
corrections
This commit is contained in:
+59
-60
@@ -1,73 +1,72 @@
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace QuanTAlib;
|
||||
|
||||
public class Zlema : AbstractBase
|
||||
namespace QuanTAlib
|
||||
{
|
||||
private readonly int _period;
|
||||
private CircularBuffer? _buffer;
|
||||
private readonly double _alpha;
|
||||
private readonly int _lag;
|
||||
private double _lastZLEMA, _p_lastZLEMA;
|
||||
|
||||
public Zlema(int period)
|
||||
public class Zlema : AbstractBase
|
||||
{
|
||||
if (period < 1)
|
||||
private readonly CircularBuffer _buffer;
|
||||
private readonly int _lag;
|
||||
private readonly Ema _ema;
|
||||
private double _lastZLEMA, _p_lastZLEMA;
|
||||
|
||||
public Zlema(int period)
|
||||
{
|
||||
throw new ArgumentException("Period must be greater than or equal to 1.", nameof(period));
|
||||
if (period < 1)
|
||||
{
|
||||
throw new ArgumentException("Period must be greater than or equal to 1.", nameof(period));
|
||||
}
|
||||
WarmupPeriod = period;
|
||||
_lag = (int)(0.5 * (period - 1));
|
||||
_buffer = new CircularBuffer(_lag + 1);
|
||||
_ema = new Ema(period, useSma: false);
|
||||
Name = $"Zlema({period})";
|
||||
Init();
|
||||
}
|
||||
_period = period;
|
||||
WarmupPeriod = period;
|
||||
_alpha = 2.0 / (_period + 1);
|
||||
_lag = (_period - 1) / 2;
|
||||
Name = $"Zlema({_period})";
|
||||
Init();
|
||||
}
|
||||
|
||||
public Zlema(object source, int period) : this(period)
|
||||
{
|
||||
var pubEvent = source.GetType().GetEvent("Pub");
|
||||
pubEvent?.AddEventHandler(source, new ValueSignal(Sub));
|
||||
}
|
||||
|
||||
public override void Init()
|
||||
{
|
||||
base.Init();
|
||||
_buffer = new CircularBuffer(_period);
|
||||
_lastZLEMA = 0;
|
||||
}
|
||||
|
||||
protected override void ManageState(bool isNew)
|
||||
{
|
||||
if (isNew)
|
||||
public Zlema(object source, int period) : this(period)
|
||||
{
|
||||
_lastValidValue = Input.Value;
|
||||
_index++;
|
||||
_p_lastZLEMA = _lastZLEMA;
|
||||
var pubEvent = source.GetType().GetEvent("Pub");
|
||||
pubEvent?.AddEventHandler(source, new ValueSignal(Sub));
|
||||
}
|
||||
else
|
||||
|
||||
public override void Init()
|
||||
{
|
||||
_lastZLEMA = _p_lastZLEMA;
|
||||
base.Init();
|
||||
_buffer.Clear();
|
||||
_ema.Init();
|
||||
_lastZLEMA = 0;
|
||||
_p_lastZLEMA = 0;
|
||||
}
|
||||
|
||||
protected override void ManageState(bool isNew)
|
||||
{
|
||||
if (isNew)
|
||||
{
|
||||
_lastValidValue = Input.Value;
|
||||
_index++;
|
||||
_p_lastZLEMA = _lastZLEMA;
|
||||
}
|
||||
else
|
||||
{
|
||||
_lastZLEMA = _p_lastZLEMA;
|
||||
}
|
||||
}
|
||||
|
||||
protected override double Calculation()
|
||||
{
|
||||
ManageState(Input.IsNew);
|
||||
|
||||
_buffer.Add(Input.Value, Input.IsNew);
|
||||
|
||||
double lagValue = _buffer[Math.Max(0, _buffer.Count - 1 - _lag)];
|
||||
double errorCorrection = 2 * Input.Value - lagValue;
|
||||
double zlema = _ema.Calc(new TValue(errorCorrection, Input.IsNew)).Value;
|
||||
|
||||
_lastZLEMA = zlema;
|
||||
IsHot = _index >= WarmupPeriod;
|
||||
|
||||
return zlema;
|
||||
}
|
||||
}
|
||||
|
||||
protected override double Calculation()
|
||||
{
|
||||
ManageState(Input.IsNew);
|
||||
|
||||
_buffer!.Add(Input.Value, Input.IsNew);
|
||||
|
||||
int lag = Math.Max(Math.Min((int)((_period - 1) * 0.5), _buffer.Count - 1), 0) + 1;
|
||||
double zlValue = 2 * Input.Value - _buffer[_buffer.Count - lag];
|
||||
|
||||
// Dynamic alpha factor for index <= period
|
||||
double k = (_index <= _period) ? (2.0 / (_index + 1)) : _alpha;
|
||||
double zlema = (zlValue - _lastZLEMA) * k + _lastZLEMA;
|
||||
|
||||
_lastZLEMA = zlema;
|
||||
IsHot = _index >= WarmupPeriod;
|
||||
|
||||
return zlema;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user