mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-08-06 13:07:44 +00:00
91 lines
2.5 KiB
C#
91 lines
2.5 KiB
C#
using System;
|
|
using System.Linq;
|
|
using System.Runtime.CompilerServices;
|
|
|
|
namespace QuanTAlib;
|
|
|
|
public class Vidya : AbstractBase
|
|
{
|
|
|
|
private readonly int _longPeriod;
|
|
private readonly double _alpha;
|
|
private double _lastVIDYA, _p_lastVIDYA;
|
|
private readonly CircularBuffer? _shortBuffer;
|
|
private readonly CircularBuffer? _longBuffer;
|
|
|
|
public Vidya(int shortPeriod, int longPeriod = 0, double alpha = 0.2)
|
|
{
|
|
if (shortPeriod < 1)
|
|
{
|
|
throw new ArgumentException("Short period must be greater than or equal to 1.", nameof(shortPeriod));
|
|
}
|
|
_longPeriod = (longPeriod == 0) ? shortPeriod * 4 : longPeriod;
|
|
_alpha = alpha;
|
|
WarmupPeriod = _longPeriod;
|
|
Name = $"Vidya({shortPeriod},{_longPeriod})";
|
|
_shortBuffer = new CircularBuffer(shortPeriod);
|
|
_longBuffer = new CircularBuffer(_longPeriod);
|
|
Init();
|
|
}
|
|
|
|
public Vidya(object source, int shortPeriod, int longPeriod = 0, double alpha = 0.2)
|
|
: this(shortPeriod, longPeriod, alpha)
|
|
{
|
|
var pubEvent = source.GetType().GetEvent("Pub");
|
|
pubEvent?.AddEventHandler(source, new ValueSignal(Sub));
|
|
}
|
|
|
|
public override void Init()
|
|
{
|
|
base.Init();
|
|
_lastVIDYA = 0;
|
|
}
|
|
|
|
protected override void ManageState(bool isNew)
|
|
{
|
|
if (isNew)
|
|
{
|
|
_lastValidValue = Input.Value;
|
|
_index++;
|
|
_p_lastVIDYA = _lastVIDYA;
|
|
}
|
|
else
|
|
{
|
|
_lastVIDYA = _p_lastVIDYA;
|
|
}
|
|
}
|
|
|
|
protected override double Calculation()
|
|
{
|
|
ManageState(Input.IsNew);
|
|
|
|
_shortBuffer!.Add(Input.Value, Input.IsNew);
|
|
_longBuffer!.Add(Input.Value, Input.IsNew);
|
|
|
|
double vidya;
|
|
if (_index <= _longPeriod)
|
|
{
|
|
vidya = _shortBuffer.Average();
|
|
}
|
|
else
|
|
{
|
|
double shortStdDev = CalculateStdDev(_shortBuffer);
|
|
double longStdDev = CalculateStdDev(_longBuffer);
|
|
double s = _alpha * (shortStdDev / longStdDev);
|
|
vidya = (s * Input.Value) + ((1 - s) * _lastVIDYA);
|
|
}
|
|
|
|
_lastVIDYA = vidya;
|
|
IsHot = _index >= WarmupPeriod;
|
|
|
|
return vidya;
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
private static double CalculateStdDev(CircularBuffer buffer)
|
|
{
|
|
double mean = buffer.Average();
|
|
double sumSquaredDiff = buffer.Sum(x => Math.Pow(x - mean, 2));
|
|
return Math.Sqrt(sumSquaredDiff / buffer.Count);
|
|
}
|
|
} |