Class optimization

This commit is contained in:
Miha
2024-10-27 16:11:08 -07:00
parent b2fcdda785
commit 6c67a0cf31
77 changed files with 2634 additions and 1455 deletions
+47 -38
View File
@@ -1,4 +1,4 @@
using System;
using System.Runtime.CompilerServices;
namespace QuanTAlib;
/// <summary>
@@ -42,28 +42,30 @@ public class Htit : AbstractBase
private readonly CircularBuffer _sdBuffer = new(2);
private readonly CircularBuffer _itBuffer = new(4);
private const double ALPHA = 0.2;
private const double BETA = 0.8;
private const double TWO_PI = 2.0 * System.Math.PI;
private const double MIN_PERIOD = 6.0;
private const double MAX_PERIOD = 50.0;
private const double PERIOD_UPPER_LIMIT = 1.5;
private const double PERIOD_LOWER_LIMIT = 0.67;
private double _lastPd = 0;
private double _p_lastPd = 0;
/// <summary>
/// Initializes a new instance of the Htit class.
/// </summary>
public Htit()
{
Name = "Htit";
WarmupPeriod = 12;
}
/// <summary>
/// Initializes a new instance of the Htit class with a specified source.
/// </summary>
/// <param name="source">The data source object that publishes updates.</param>
public Htit(object source) : this()
{
var pubEvent = source.GetType().GetEvent("Pub");
pubEvent?.AddEventHandler(source, new ValueSignal(Sub));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected override void ManageState(bool isNew)
{
if (isNew)
@@ -77,6 +79,26 @@ public class Htit : AbstractBase
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static double CalculateSmoothedPrice(double p0, double p1, double p2, double p3)
{
return (4.0 * p0 + 3.0 * p1 + 2.0 * p2 + p3) * 0.1;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static double CalculateHilbertTransform(double b0, double b2, double b4, double b6, double adj)
{
return (0.0962 * (b0 - b6) + 0.5769 * (b2 - b4)) * adj;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static double ClampPeriod(double pd, double lastPd)
{
pd = pd > PERIOD_UPPER_LIMIT * lastPd ? PERIOD_UPPER_LIMIT * lastPd : pd;
pd = pd < PERIOD_LOWER_LIMIT * lastPd ? PERIOD_LOWER_LIMIT * lastPd : pd;
return System.Math.Clamp(pd, MIN_PERIOD, MAX_PERIOD);
}
protected override double Calculation()
{
ManageState(Input.IsNew);
@@ -100,65 +122,52 @@ public class Htit : AbstractBase
return pr;
}
double adj = (0.075 * _lastPd) + 0.54;
double adj = 0.075 * _lastPd + 0.54;
// Smooth and detrender
double sp = ((4 * _priceBuffer[0]) + (3 * _priceBuffer[1]) + (2 * _priceBuffer[2]) + _priceBuffer[3]) / 10;
double sp = CalculateSmoothedPrice(_priceBuffer[0], _priceBuffer[1], _priceBuffer[2], _priceBuffer[3]);
_spBuffer.Add(sp, Input.IsNew);
double dt = ((0.0962 * _spBuffer[0]) + (0.5769 * _spBuffer[2]) - (0.5769 * _spBuffer[4]) - (0.0962 * _spBuffer[6])) * adj;
double dt = CalculateHilbertTransform(_spBuffer[0], _spBuffer[2], _spBuffer[4], _spBuffer[6], adj);
_dtBuffer.Add(dt, Input.IsNew);
// In-phase and quadrature
double q1 = ((0.0962 * _dtBuffer[0]) + (0.5769 * _dtBuffer[2]) - (0.5769 * _dtBuffer[4]) - (0.0962 * _dtBuffer[6])) * adj;
double q1 = CalculateHilbertTransform(_dtBuffer[0], _dtBuffer[2], _dtBuffer[4], _dtBuffer[6], adj);
_q1Buffer.Add(q1, Input.IsNew);
double i1 = _dtBuffer[3];
_i1Buffer.Add(i1, Input.IsNew);
// Advance the phases by 90 degrees
double jI = ((0.0962 * _i1Buffer[0]) + (0.5769 * _i1Buffer[2]) - (0.5769 * _i1Buffer[4]) - (0.0962 * _i1Buffer[6])) * adj;
double jQ = ((0.0962 * _q1Buffer[0]) + (0.5769 * _q1Buffer[2]) - (0.5769 * _q1Buffer[4]) - (0.0962 * _q1Buffer[6])) * adj;
double jI = CalculateHilbertTransform(_i1Buffer[0], _i1Buffer[2], _i1Buffer[4], _i1Buffer[6], adj);
double jQ = CalculateHilbertTransform(_q1Buffer[0], _q1Buffer[2], _q1Buffer[4], _q1Buffer[6], adj);
// Phasor addition for 3-bar averaging
double i2 = i1 - jQ;
double q2 = q1 + jI;
i2 = (0.2 * i2) + (0.8 * _i2Buffer[0]);
q2 = (0.2 * q2) + (0.8 * _q2Buffer[0]);
double i2 = ALPHA * (i1 - jQ) + BETA * _i2Buffer[0];
double q2 = ALPHA * (q1 + jI) + BETA * _q2Buffer[0];
_i2Buffer.Add(i2, Input.IsNew);
_q2Buffer.Add(q2, Input.IsNew);
// Homodyne discriminator
double re = (i2 * _i2Buffer[1]) + (q2 * _q2Buffer[1]);
double im = (i2 * _q2Buffer[1]) - (q2 * _i2Buffer[1]);
re = (0.2 * re) + (0.8 * _reBuffer[0]);
im = (0.2 * im) + (0.8 * _imBuffer[0]);
double re = ALPHA * (i2 * _i2Buffer[1] + q2 * _q2Buffer[1]) + BETA * _reBuffer[0];
double im = ALPHA * (i2 * _q2Buffer[1] - q2 * _i2Buffer[1]) + BETA * _imBuffer[0];
_reBuffer.Add(re, Input.IsNew);
_imBuffer.Add(im, Input.IsNew);
// Calculate period
double pd = (im != 0 && re != 0) ? 2 * Math.PI / Math.Atan(im / re) : 0;
// Adjust period to thresholds
pd = (pd > 1.5 * _lastPd) ? 1.5 * _lastPd : pd;
pd = (pd < 0.67 * _lastPd) ? 0.67 * _lastPd : pd;
pd = (pd < 6) ? 6 : pd;
pd = (pd > 50) ? 50 : pd;
// Smooth the period
pd = (0.2 * pd) + (0.8 * _lastPd);
double pd = (im != 0 && re != 0) ? TWO_PI / System.Math.Atan(im / re) : 0;
pd = ClampPeriod(pd, _lastPd);
pd = ALPHA * pd + BETA * _lastPd;
_pdBuffer.Add(pd, Input.IsNew);
double sd = (0.33 * pd) + (0.67 * _sdBuffer[0]);
double sd = 0.33 * pd + 0.67 * _sdBuffer[0];
_sdBuffer.Add(sd, Input.IsNew);
// Smooth dominant cycle period
int dcPeriods = (int)(sd + 0.5);
double sumPr = _priceBuffer.GetSpan().Slice(0, Math.Min(dcPeriods, _priceBuffer.Count)).ToArray().Sum();
double sumPr = _priceBuffer.GetSpan().Slice(0, System.Math.Min(dcPeriods, _priceBuffer.Count)).ToArray().Sum();
double it = dcPeriods > 0 ? sumPr / dcPeriods : pr;
_itBuffer.Add(it, Input.IsNew);
@@ -166,9 +175,9 @@ public class Htit : AbstractBase
_lastPd = pd;
// Final indicator
if (_index >= 11) // 12th bar
if (_index >= 11)
{
return ((4 * _itBuffer[0]) + (3 * _itBuffer[1]) + (2 * _itBuffer[2]) + _itBuffer[3]) / 10;
return CalculateSmoothedPrice(_itBuffer[0], _itBuffer[1], _itBuffer[2], _itBuffer[3]);
}
return pr;