mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-08-02 19:37:43 +00:00
78 lines
2.0 KiB
C#
78 lines
2.0 KiB
C#
namespace QuanTAlib;
|
|
|
|
//https://user42.tuxfamily.org/chart/manual/Regularized-Exponential-Moving-Average.html
|
|
|
|
public class Rema : AbstractBase
|
|
{
|
|
private readonly int _period;
|
|
private readonly double _lambda;
|
|
private double _lastRema, _prevRema;
|
|
private double _savedLastRema, _savedPrevRema;
|
|
|
|
public int Period => _period;
|
|
public double Lambda => _lambda;
|
|
|
|
public Rema(int period, double lambda = 0.5) : base()
|
|
{
|
|
if (period < 1)
|
|
throw new ArgumentOutOfRangeException(nameof(period), "Period must be greater than or equal to 1.");
|
|
if (lambda < 0)
|
|
throw new ArgumentOutOfRangeException(nameof(lambda), "Lambda must be non-negative.");
|
|
|
|
_period = period;
|
|
_lambda = lambda;
|
|
Name = $"REMA({period},{lambda:F2})";
|
|
WarmupPeriod = period;
|
|
Init();
|
|
}
|
|
|
|
public override void Init()
|
|
{
|
|
base.Init();
|
|
_lastRema = 0;
|
|
_prevRema = 0;
|
|
_savedLastRema = 0;
|
|
_savedPrevRema = 0;
|
|
}
|
|
|
|
protected override void ManageState(bool isNew)
|
|
{
|
|
if (isNew)
|
|
{
|
|
_savedLastRema = _lastRema;
|
|
_savedPrevRema = _prevRema;
|
|
_index++;
|
|
}
|
|
else
|
|
{
|
|
_lastRema = _savedLastRema;
|
|
_prevRema = _savedPrevRema;
|
|
}
|
|
}
|
|
|
|
protected override double Calculation()
|
|
{
|
|
ManageState(Input.IsNew);
|
|
|
|
double alpha = 2.0 / (Math.Min(_period, _index) + 1);
|
|
|
|
if (_index > 2)
|
|
{
|
|
double rema = (_lastRema + alpha * (Input.Value - _lastRema) + _lambda * (_lastRema + (_lastRema - _prevRema))) / (1 + _lambda);
|
|
_prevRema = _lastRema;
|
|
_lastRema = rema;
|
|
}
|
|
else if (_index == 2)
|
|
{
|
|
_prevRema = _lastRema;
|
|
_lastRema = Input.Value;
|
|
}
|
|
else
|
|
{ // _index == 1
|
|
_lastRema = Input.Value;
|
|
}
|
|
|
|
IsHot = _index >= WarmupPeriod;
|
|
return _lastRema;
|
|
}
|
|
} |