mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-08-03 11:47:44 +00:00
[CodeFactor] Apply fixes to commit 9697fac
This commit is contained in:
@@ -223,7 +223,7 @@ public sealed class Bbands : AbstractBase
|
||||
|
||||
for (int i = 0; i < source.Length; i++)
|
||||
{
|
||||
Update(new TValue(startTime + i * step.Value, source[i]), isNew: true);
|
||||
Update(new TValue(startTime + (i * step.Value), source[i]), isNew: true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -367,5 +367,4 @@ public sealed class Bbands : AbstractBase
|
||||
TSeries results = indicator.Update(source);
|
||||
return (results, indicator);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ public sealed class JbandsIndicator : Indicator, IWatchlistIndicator
|
||||
|
||||
private Jbands? _indicator;
|
||||
|
||||
public int MinHistoryDepths => (int)Math.Ceiling(20.0 + 80.0 * Math.Pow(Period, 0.36));
|
||||
public int MinHistoryDepths => (int)Math.Ceiling(20.0 + (80.0 * Math.Pow(Period, 0.36)));
|
||||
public override string ShortName => $"Jbands({Period},{Phase})";
|
||||
|
||||
public JbandsIndicator()
|
||||
|
||||
@@ -99,7 +99,7 @@ public sealed class Jbands : ITValuePublisher, IDisposable
|
||||
_logLengthDivider = Math.Log(Math.Max(_lengthDivider, 1e-12));
|
||||
_logSqrtDivider = Math.Log(Math.Max(sqrtDivider, 1e-12));
|
||||
|
||||
WarmupPeriod = (int)Math.Ceiling(20.0 + 80.0 * Math.Pow(period, 0.36));
|
||||
WarmupPeriod = (int)Math.Ceiling(20.0 + (80.0 * Math.Pow(period, 0.36)));
|
||||
|
||||
_handler = Handle;
|
||||
Name = $"Jbands({period},{phase})";
|
||||
|
||||
@@ -197,7 +197,7 @@ public sealed class Kchannel : ITValuePublisher
|
||||
double trueRange = Math.Max(tr1, Math.Max(tr2, tr3));
|
||||
|
||||
// ATR using RMA with warmup compensation
|
||||
double newRawRma = (_state.RawRma * (_period - 1) + trueRange) / _period;
|
||||
double newRawRma = ((_state.RawRma * (_period - 1)) + trueRange) / _period;
|
||||
double newE = (1.0 - _atrAlpha) * _state.E;
|
||||
double atrValue = newE > Epsilon ? newRawRma / (1.0 - newE) : newRawRma;
|
||||
|
||||
@@ -360,7 +360,7 @@ public sealed class Kchannel : ITValuePublisher
|
||||
double tr = Math.Max(tr1, Math.Max(tr2, tr3));
|
||||
|
||||
// ATR (RMA with warmup)
|
||||
rawRma = (rawRma * (period - 1) + tr) / period;
|
||||
rawRma = ((rawRma * (period - 1)) + tr) / period;
|
||||
e = (1.0 - atrAlpha) * e;
|
||||
double atr = e > Epsilon ? rawRma / (1.0 - e) : rawRma;
|
||||
|
||||
|
||||
@@ -192,7 +192,7 @@ public sealed class Starchannel : ITValuePublisher
|
||||
double trueRange = Math.Max(tr1, Math.Max(tr2, tr3));
|
||||
|
||||
// ATR using RMA with warmup compensation (uses _atrPeriod for separate ATR smoothing)
|
||||
double newRawRma = (_state.RawRma * (_atrPeriod - 1) + trueRange) / _atrPeriod;
|
||||
double newRawRma = ((_state.RawRma * (_atrPeriod - 1)) + trueRange) / _atrPeriod;
|
||||
double newE = (1.0 - _atrAlpha) * _state.E;
|
||||
double atrValue = newE > Epsilon ? newRawRma / (1.0 - newE) : newRawRma;
|
||||
|
||||
@@ -406,7 +406,7 @@ public sealed class Starchannel : ITValuePublisher
|
||||
double tr = Math.Max(tr1, Math.Max(tr2, tr3));
|
||||
|
||||
// ATR (RMA with warmup compensation, uses effectiveAtrPeriod)
|
||||
rawRma = (rawRma * (effectiveAtrPeriod - 1) + tr) / effectiveAtrPeriod;
|
||||
rawRma = ((rawRma * (effectiveAtrPeriod - 1)) + tr) / effectiveAtrPeriod;
|
||||
e = (1.0 - atrAlpha) * e;
|
||||
double atr = e > Epsilon ? rawRma / (1.0 - e) : rawRma;
|
||||
|
||||
|
||||
@@ -279,7 +279,7 @@ public sealed class Stbands : AbstractBase
|
||||
for (int i = 0; i < source.Length; i++)
|
||||
{
|
||||
// Treat as close price only
|
||||
Update(new TValue(startTime + i * step.Value, source[i]), isNew: true);
|
||||
Update(new TValue(startTime + (i * step.Value), source[i]), isNew: true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -406,5 +406,4 @@ public sealed class Stbands : AbstractBase
|
||||
TSeries results = indicator.Update(source);
|
||||
return (results, indicator);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -136,9 +136,9 @@ public sealed class TtmLrc : ITValuePublisher
|
||||
// sumX = 0 + 1 + ... + (n-1) = n(n-1)/2
|
||||
_sumX = 0.5 * period * (period - 1);
|
||||
// sumX² = 0² + 1² + ... + (n-1)² = (n-1)n(2n-1)/6
|
||||
double sumX2 = (period - 1.0) * period * (2.0 * period - 1.0) / 6.0;
|
||||
double sumX2 = (period - 1.0) * period * ((2.0 * period) - 1.0) / 6.0;
|
||||
// denominator = n * sumX² - sumX²
|
||||
_denominator = period * sumX2 - _sumX * _sumX;
|
||||
_denominator = (period * sumX2) - (_sumX * _sumX);
|
||||
|
||||
Reset();
|
||||
}
|
||||
@@ -253,8 +253,8 @@ public sealed class TtmLrc : ITValuePublisher
|
||||
if (count < _period)
|
||||
{
|
||||
sx = 0.5 * n * (n - 1);
|
||||
double sx2 = (n - 1.0) * n * (2.0 * n - 1.0) / 6.0;
|
||||
denom = n * sx2 - sx * sx;
|
||||
double sx2 = (n - 1.0) * n * ((2.0 * n) - 1.0) / 6.0;
|
||||
denom = (n * sx2) - (sx * sx);
|
||||
}
|
||||
|
||||
double slope, intercept, regression;
|
||||
@@ -267,8 +267,8 @@ public sealed class TtmLrc : ITValuePublisher
|
||||
}
|
||||
else
|
||||
{
|
||||
slope = (n * sumXY - sx * sumY) / denom;
|
||||
intercept = (sumY - slope * sx) / n;
|
||||
slope = ((n * sumXY) - (sx * sumY)) / denom;
|
||||
intercept = (sumY - (slope * sx)) / n;
|
||||
// Regression value at current point (x = count - 1)
|
||||
regression = Math.FusedMultiplyAdd(slope, count - 1, intercept);
|
||||
}
|
||||
@@ -304,8 +304,8 @@ public sealed class TtmLrc : ITValuePublisher
|
||||
Midline = new TValue(input.Time, regression);
|
||||
Upper1 = new TValue(input.Time, regression + stdDev);
|
||||
Lower1 = new TValue(input.Time, regression - stdDev);
|
||||
Upper2 = new TValue(input.Time, regression + 2.0 * stdDev);
|
||||
Lower2 = new TValue(input.Time, regression - 2.0 * stdDev);
|
||||
Upper2 = new TValue(input.Time, regression + (2.0 * stdDev));
|
||||
Lower2 = new TValue(input.Time, regression - (2.0 * stdDev));
|
||||
|
||||
PubEvent(Midline, isNew);
|
||||
return Midline;
|
||||
@@ -412,8 +412,8 @@ public sealed class TtmLrc : ITValuePublisher
|
||||
|
||||
// Precompute constants for full period
|
||||
double sumXFull = 0.5 * period * (period - 1);
|
||||
double sumX2Full = (period - 1.0) * period * (2.0 * period - 1.0) / 6.0;
|
||||
double denomFull = period * sumX2Full - sumXFull * sumXFull;
|
||||
double sumX2Full = (period - 1.0) * period * ((2.0 * period) - 1.0) / 6.0;
|
||||
double denomFull = (period * sumX2Full) - (sumXFull * sumXFull);
|
||||
|
||||
// Track last valid value for NaN substitution
|
||||
double lastValid = double.NaN;
|
||||
@@ -483,8 +483,8 @@ public sealed class TtmLrc : ITValuePublisher
|
||||
if (count < period)
|
||||
{
|
||||
sx = 0.5 * n * (n - 1);
|
||||
double sx2 = (n - 1.0) * n * (2.0 * n - 1.0) / 6.0;
|
||||
denom = n * sx2 - sx * sx;
|
||||
double sx2 = (n - 1.0) * n * ((2.0 * n) - 1.0) / 6.0;
|
||||
denom = (n * sx2) - (sx * sx);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -502,8 +502,8 @@ public sealed class TtmLrc : ITValuePublisher
|
||||
}
|
||||
else
|
||||
{
|
||||
slope = (n * sumXY - sx * sumY) / denom;
|
||||
intercept = (sumY - slope * sx) / n;
|
||||
slope = ((n * sumXY) - (sx * sumY)) / denom;
|
||||
intercept = (sumY - (slope * sx)) / n;
|
||||
regression = Math.FusedMultiplyAdd(slope, count - 1, intercept);
|
||||
}
|
||||
|
||||
@@ -533,8 +533,8 @@ public sealed class TtmLrc : ITValuePublisher
|
||||
midline[i] = regression;
|
||||
upper1[i] = regression + stdDev;
|
||||
lower1[i] = regression - stdDev;
|
||||
upper2[i] = regression + 2.0 * stdDev;
|
||||
lower2[i] = regression - 2.0 * stdDev;
|
||||
upper2[i] = regression + (2.0 * stdDev);
|
||||
lower2[i] = regression - (2.0 * stdDev);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -100,7 +100,7 @@ public sealed class Ubands : AbstractBase
|
||||
|
||||
// Precompute coefficients for FMA optimization
|
||||
_k0 = 1.0 - c1; // coefficient for val
|
||||
_k1 = 2.0 * c1 - _c2; // coefficient for PrevInput1
|
||||
_k1 = (2.0 * c1) - _c2; // coefficient for PrevInput1
|
||||
_k2 = -(c1 + _c3); // coefficient for PrevInput2
|
||||
|
||||
WarmupPeriod = period;
|
||||
@@ -261,7 +261,7 @@ public sealed class Ubands : AbstractBase
|
||||
|
||||
for (int i = 0; i < source.Length; i++)
|
||||
{
|
||||
Update(new TValue(startTime + i * step.Value, source[i]), isNew: true);
|
||||
Update(new TValue(startTime + (i * step.Value), source[i]), isNew: true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -316,7 +316,7 @@ public sealed class Ubands : AbstractBase
|
||||
double c1 = (1.0 + c2 - c3) / 4.0;
|
||||
|
||||
double k0 = 1.0 - c1;
|
||||
double k1 = 2.0 * c1 - c2;
|
||||
double k1 = (2.0 * c1) - c2;
|
||||
double k2 = -(c1 + c3);
|
||||
|
||||
// Use stackalloc for residual buffer if small enough
|
||||
@@ -404,5 +404,4 @@ public sealed class Ubands : AbstractBase
|
||||
TSeries results = indicator.Update(source);
|
||||
return (results, indicator);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -217,7 +217,7 @@ public sealed class Uchannel : AbstractBase
|
||||
{
|
||||
// USF: (1-c1)*s0 + (2*c1-c2)*s1 - (c1+c3)*s2 + c2*usf1 + c3*usf2
|
||||
strValue = Math.FusedMultiplyAdd(1 - _c1_str, str_s0,
|
||||
Math.FusedMultiplyAdd(2 * _c1_str - _c2_str, str_s1,
|
||||
Math.FusedMultiplyAdd((2 * _c1_str) - _c2_str, str_s1,
|
||||
Math.FusedMultiplyAdd(-(_c1_str + _c3_str), str_s2,
|
||||
Math.FusedMultiplyAdd(_c2_str, usStr1, _c3_str * usStr2))));
|
||||
}
|
||||
@@ -237,7 +237,7 @@ public sealed class Uchannel : AbstractBase
|
||||
else
|
||||
{
|
||||
cenValue = Math.FusedMultiplyAdd(1 - _c1_cen, cen_s0,
|
||||
Math.FusedMultiplyAdd(2 * _c1_cen - _c2_cen, cen_s1,
|
||||
Math.FusedMultiplyAdd((2 * _c1_cen) - _c2_cen, cen_s1,
|
||||
Math.FusedMultiplyAdd(-(_c1_cen + _c3_cen), cen_s2,
|
||||
Math.FusedMultiplyAdd(_c2_cen, usCen1, _c3_cen * usCen2))));
|
||||
}
|
||||
@@ -337,7 +337,7 @@ public sealed class Uchannel : AbstractBase
|
||||
for (int i = 0; i < source.Length; i++)
|
||||
{
|
||||
// Treat as close price only
|
||||
Update(new TValue(startTime + i * step.Value, source[i]), isNew: true);
|
||||
Update(new TValue(startTime + (i * step.Value), source[i]), isNew: true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -471,7 +471,7 @@ public sealed class Uchannel : AbstractBase
|
||||
else
|
||||
{
|
||||
strValue = Math.FusedMultiplyAdd(1 - c1_str, str_s0,
|
||||
Math.FusedMultiplyAdd(2 * c1_str - c2_str, str_s1,
|
||||
Math.FusedMultiplyAdd((2 * c1_str) - c2_str, str_s1,
|
||||
Math.FusedMultiplyAdd(-(c1_str + c3_str), str_s2,
|
||||
Math.FusedMultiplyAdd(c2_str, usStr1, c3_str * usStr2))));
|
||||
}
|
||||
@@ -489,7 +489,7 @@ public sealed class Uchannel : AbstractBase
|
||||
else
|
||||
{
|
||||
cenValue = Math.FusedMultiplyAdd(1 - c1_cen, cen_s0,
|
||||
Math.FusedMultiplyAdd(2 * c1_cen - c2_cen, cen_s1,
|
||||
Math.FusedMultiplyAdd((2 * c1_cen) - c2_cen, cen_s1,
|
||||
Math.FusedMultiplyAdd(-(c1_cen + c3_cen), cen_s2,
|
||||
Math.FusedMultiplyAdd(c2_cen, usCen1, c3_cen * usCen2))));
|
||||
}
|
||||
|
||||
@@ -206,9 +206,9 @@ public sealed class Vwapbands : AbstractBase
|
||||
{
|
||||
_state = _state with
|
||||
{
|
||||
SumPV = _state.SumPV + price * vol,
|
||||
SumPV = _state.SumPV + (price * vol),
|
||||
SumVol = _state.SumVol + vol,
|
||||
SumPV2 = _state.SumPV2 + price * price * vol,
|
||||
SumPV2 = _state.SumPV2 + (price * price * vol),
|
||||
Count = _state.Count + 1
|
||||
};
|
||||
}
|
||||
@@ -228,10 +228,10 @@ public sealed class Vwapbands : AbstractBase
|
||||
double stdev = Math.Sqrt(variance);
|
||||
|
||||
// Calculate bands
|
||||
double upper1 = vwap + _multiplier * stdev;
|
||||
double lower1 = vwap - _multiplier * stdev;
|
||||
double upper2 = vwap + 2.0 * _multiplier * stdev;
|
||||
double lower2 = vwap - 2.0 * _multiplier * stdev;
|
||||
double upper1 = vwap + (_multiplier * stdev);
|
||||
double lower1 = vwap - (_multiplier * stdev);
|
||||
double upper2 = vwap + (2.0 * _multiplier * stdev);
|
||||
double lower2 = vwap - (2.0 * _multiplier * stdev);
|
||||
|
||||
// Update output values
|
||||
Vwap = new TValue(input.Time, vwap);
|
||||
@@ -316,7 +316,7 @@ public sealed class Vwapbands : AbstractBase
|
||||
|
||||
for (int i = 0; i < source.Length; i++)
|
||||
{
|
||||
Update(new TValue(startTime + i * step.Value, source[i]), 1.0, isNew: true, reset: false);
|
||||
Update(new TValue(startTime + (i * step.Value), source[i]), 1.0, isNew: true, reset: false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -423,10 +423,10 @@ public sealed class Vwapbands : AbstractBase
|
||||
|
||||
vwap[i] = vwapVal;
|
||||
stdDev[i] = stdev;
|
||||
upper1[i] = vwapVal + multiplier * stdev;
|
||||
lower1[i] = vwapVal - multiplier * stdev;
|
||||
upper2[i] = vwapVal + 2.0 * multiplier * stdev;
|
||||
lower2[i] = vwapVal - 2.0 * multiplier * stdev;
|
||||
upper1[i] = vwapVal + (multiplier * stdev);
|
||||
lower1[i] = vwapVal - (multiplier * stdev);
|
||||
upper2[i] = vwapVal + (2.0 * multiplier * stdev);
|
||||
lower2[i] = vwapVal - (2.0 * multiplier * stdev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,9 +200,9 @@ public sealed class Vwapsd : AbstractBase
|
||||
{
|
||||
_state = _state with
|
||||
{
|
||||
SumPV = _state.SumPV + price * vol,
|
||||
SumPV = _state.SumPV + (price * vol),
|
||||
SumVol = _state.SumVol + vol,
|
||||
SumPV2 = _state.SumPV2 + price * price * vol,
|
||||
SumPV2 = _state.SumPV2 + (price * price * vol),
|
||||
Count = _state.Count + 1
|
||||
};
|
||||
}
|
||||
@@ -222,8 +222,8 @@ public sealed class Vwapsd : AbstractBase
|
||||
double stdev = Math.Sqrt(variance);
|
||||
|
||||
// Calculate bands
|
||||
double upper = vwap + _numDevs * stdev;
|
||||
double lower = vwap - _numDevs * stdev;
|
||||
double upper = vwap + (_numDevs * stdev);
|
||||
double lower = vwap - (_numDevs * stdev);
|
||||
|
||||
// Update output values
|
||||
Vwap = new TValue(input.Time, vwap);
|
||||
@@ -302,7 +302,7 @@ public sealed class Vwapsd : AbstractBase
|
||||
|
||||
for (int i = 0; i < source.Length; i++)
|
||||
{
|
||||
Update(new TValue(startTime + i * step.Value, source[i]), 1.0, isNew: true, reset: false);
|
||||
Update(new TValue(startTime + (i * step.Value), source[i]), 1.0, isNew: true, reset: false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -405,8 +405,8 @@ public sealed class Vwapsd : AbstractBase
|
||||
|
||||
vwap[i] = vwapVal;
|
||||
stdDev[i] = stdev;
|
||||
upper[i] = vwapVal + numDevs * stdev;
|
||||
lower[i] = vwapVal - numDevs * stdev;
|
||||
upper[i] = vwapVal + (numDevs * stdev);
|
||||
lower[i] = vwapVal - (numDevs * stdev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ using System.Buffers;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
|
||||
namespace QuanTAlib;
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -433,7 +433,7 @@ public static class ErrorHelpers
|
||||
double diff = act - pred;
|
||||
double ratio = diff / delta;
|
||||
// δ² * (√(1 + (error/δ)²) - 1)
|
||||
output[i] = deltaSquared * (Math.Sqrt(1.0 + ratio * ratio) - 1.0);
|
||||
output[i] = deltaSquared * (Math.Sqrt(1.0 + (ratio * ratio)) - 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ public sealed class Ccyc : AbstractBase
|
||||
throw new ArgumentException("Alpha must be between 0 and 1 (exclusive).", nameof(alpha));
|
||||
}
|
||||
|
||||
double halfAlpha = 1.0 - 0.5 * alpha;
|
||||
double halfAlpha = 1.0 - (0.5 * alpha);
|
||||
_chp = halfAlpha * halfAlpha;
|
||||
double oneMinusAlpha = 1.0 - alpha;
|
||||
_cfb1 = 2.0 * oneMinusAlpha;
|
||||
@@ -125,7 +125,7 @@ public sealed class Ccyc : AbstractBase
|
||||
double price0 = price;
|
||||
|
||||
// 4-tap FIR smoother: smooth = (x + 2*x1 + 2*x2 + x3) / 6
|
||||
double smooth = (price0 + 2.0 * price1 + 2.0 * price2 + price3) / 6.0;
|
||||
double smooth = (price0 + (2.0 * price1) + (2.0 * price2) + price3) / 6.0;
|
||||
|
||||
// Shift smooth history
|
||||
double smooth2 = s.Smooth1;
|
||||
@@ -136,13 +136,13 @@ public sealed class Ccyc : AbstractBase
|
||||
if (count < 7)
|
||||
{
|
||||
// Bootstrap: second-difference of raw price
|
||||
cycle = (price0 - 2.0 * price1 + price2) * 0.25;
|
||||
cycle = (price0 - (2.0 * price1) + price2) * 0.25;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Steady-state: 2-pole high-pass IIR on smoothed input
|
||||
// cycle = c_hp * (smooth - 2*smooth1 + smooth2) + c_fb1*cycle1 + c_fb2*cycle2
|
||||
double diff = smooth0 - 2.0 * smooth1 + smooth2;
|
||||
double diff = smooth0 - (2.0 * smooth1) + smooth2;
|
||||
cycle = Math.FusedMultiplyAdd(_chp, diff,
|
||||
Math.FusedMultiplyAdd(_cfb1, s.Cycle1, _cfb2 * s.Cycle2));
|
||||
}
|
||||
@@ -240,7 +240,7 @@ public sealed class Ccyc : AbstractBase
|
||||
return;
|
||||
}
|
||||
|
||||
double halfAlpha = 1.0 - 0.5 * alpha;
|
||||
double halfAlpha = 1.0 - (0.5 * alpha);
|
||||
double chp = halfAlpha * halfAlpha;
|
||||
double oneMinusAlpha = 1.0 - alpha;
|
||||
double cfb1 = 2.0 * oneMinusAlpha;
|
||||
@@ -263,7 +263,7 @@ public sealed class Ccyc : AbstractBase
|
||||
price1 = price0;
|
||||
price0 = val;
|
||||
|
||||
double smooth = (price0 + 2.0 * price1 + 2.0 * price2 + price3) / 6.0;
|
||||
double smooth = (price0 + (2.0 * price1) + (2.0 * price2) + price3) / 6.0;
|
||||
smooth2 = smooth1;
|
||||
smooth1 = smooth0;
|
||||
smooth0 = smooth;
|
||||
@@ -272,11 +272,11 @@ public sealed class Ccyc : AbstractBase
|
||||
int barNum = i + 1;
|
||||
if (barNum < 7)
|
||||
{
|
||||
cycle = (price0 - 2.0 * price1 + price2) * 0.25;
|
||||
cycle = (price0 - (2.0 * price1) + price2) * 0.25;
|
||||
}
|
||||
else
|
||||
{
|
||||
double diff = smooth0 - 2.0 * smooth1 + smooth2;
|
||||
double diff = smooth0 - (2.0 * smooth1) + smooth2;
|
||||
cycle = Math.FusedMultiplyAdd(chp, diff,
|
||||
Math.FusedMultiplyAdd(cfb1, cycle1, cfb2 * cycle2));
|
||||
}
|
||||
|
||||
@@ -43,7 +43,6 @@ public sealed class Cg : AbstractBase
|
||||
private double _p_weightedSum;
|
||||
private double _p_sum;
|
||||
|
||||
|
||||
public override bool IsHot => _buffer.IsFull;
|
||||
|
||||
/// <summary>
|
||||
@@ -112,7 +111,6 @@ public sealed class Cg : AbstractBase
|
||||
// after each update (or track differential updates which is complex)
|
||||
RecalculateSums();
|
||||
|
||||
|
||||
// Calculate CG
|
||||
double cg = CalculateCg();
|
||||
|
||||
|
||||
@@ -185,7 +185,7 @@ public sealed class Ebsw : AbstractBase
|
||||
double wave = (filt0 + filt1 + filt2) / 3.0;
|
||||
|
||||
// Power: 3-bar average of squared filtered values
|
||||
double pwr = (filt0 * filt0 + filt1 * filt1 + filt2 * filt2) / 3.0;
|
||||
double pwr = ((filt0 * filt0) + (filt1 * filt1) + (filt2 * filt2)) / 3.0;
|
||||
|
||||
// Automatic gain control: normalize by RMS, clamp to [-1, +1]
|
||||
double sineWave = pwr > 0 ? wave / Math.Sqrt(pwr) : 0;
|
||||
@@ -326,7 +326,7 @@ public sealed class Ebsw : AbstractBase
|
||||
double wave = (filt0 + filt1 + filt2) / 3.0;
|
||||
|
||||
// Power
|
||||
double pwr = (filt0 * filt0 + filt1 * filt1 + filt2 * filt2) / 3.0;
|
||||
double pwr = ((filt0 * filt0) + (filt1 * filt1) + (filt2 * filt2)) / 3.0;
|
||||
|
||||
// AGC normalization
|
||||
double sineWave = pwr > 0 ? wave / Math.Sqrt(pwr) : 0;
|
||||
|
||||
@@ -162,10 +162,10 @@ public sealed class Homod : AbstractBase
|
||||
double price0 = price;
|
||||
|
||||
// Calculate bandwidth based on smooth period
|
||||
double bandwidth = 0.075 * s.SmoothPeriod + 0.54;
|
||||
double bandwidth = (0.075 * s.SmoothPeriod) + 0.54;
|
||||
|
||||
// 4-bar weighted moving average: (4*p0 + 3*p1 + 2*p2 + p3) / 10
|
||||
double smoothPrice = (4.0 * price0 + 3.0 * price1 + 2.0 * price2 + price3) / 10.0;
|
||||
double smoothPrice = ((4.0 * price0) + (3.0 * price1) + (2.0 * price2) + price3) / 10.0;
|
||||
|
||||
// Shift smooth price history
|
||||
double sp6 = s.Sp5;
|
||||
@@ -177,7 +177,7 @@ public sealed class Homod : AbstractBase
|
||||
double sp0 = smoothPrice;
|
||||
|
||||
// Hilbert Transform detrender: coefficients [0.0962, 0, 0.5769, 0, -0.5769, 0, -0.0962] * bandwidth
|
||||
double detrender = (0.0962 * sp0 + 0.5769 * sp2 - 0.5769 * sp4 - 0.0962 * sp6) * bandwidth;
|
||||
double detrender = ((0.0962 * sp0) + (0.5769 * sp2) - (0.5769 * sp4) - (0.0962 * sp6)) * bandwidth;
|
||||
|
||||
// Shift detrender history
|
||||
double det6 = s.Det5;
|
||||
@@ -189,7 +189,7 @@ public sealed class Homod : AbstractBase
|
||||
double det0 = detrender;
|
||||
|
||||
// Q1 via Hilbert Transform of detrender
|
||||
double q1 = (0.0962 * det0 + 0.5769 * det2 - 0.5769 * det4 - 0.0962 * det6) * bandwidth;
|
||||
double q1 = ((0.0962 * det0) + (0.5769 * det2) - (0.5769 * det4) - (0.0962 * det6)) * bandwidth;
|
||||
|
||||
// I1 is detrender delayed by 3 bars
|
||||
double i1 = det3;
|
||||
@@ -213,10 +213,10 @@ public sealed class Homod : AbstractBase
|
||||
double q1_0 = q1;
|
||||
|
||||
// JI = Hilbert Transform of I1
|
||||
double ji = (0.0962 * i1_0 + 0.5769 * i1_2 - 0.5769 * i1_4 - 0.0962 * i1_6) * bandwidth;
|
||||
double ji = ((0.0962 * i1_0) + (0.5769 * i1_2) - (0.5769 * i1_4) - (0.0962 * i1_6)) * bandwidth;
|
||||
|
||||
// JQ = Hilbert Transform of Q1
|
||||
double jq = (0.0962 * q1_0 + 0.5769 * q1_2 - 0.5769 * q1_4 - 0.0962 * q1_6) * bandwidth;
|
||||
double jq = ((0.0962 * q1_0) + (0.5769 * q1_2) - (0.5769 * q1_4) - (0.0962 * q1_6)) * bandwidth;
|
||||
|
||||
// Calculate I2 and Q2 (phasor rotation)
|
||||
double i2Raw = i1 - jq;
|
||||
|
||||
@@ -139,8 +139,8 @@ public sealed class HtDcperiod : AbstractBase
|
||||
double input1 = buffer[KEY_Q1];
|
||||
DoHilbertTransform(buffer, KEY_JQ, input1, true, hilbertIdx, adjustedPrevPeriod);
|
||||
|
||||
q2 = 0.2 * (buffer[KEY_Q1] + buffer[KEY_JI]) + 0.8 * prevQ2;
|
||||
i2 = 0.2 * (i1ForOddPrev3 - buffer[KEY_JQ]) + 0.8 * prevI2;
|
||||
q2 = (0.2 * (buffer[KEY_Q1] + buffer[KEY_JI])) + (0.8 * prevQ2);
|
||||
i2 = (0.2 * (i1ForOddPrev3 - buffer[KEY_JQ])) + (0.8 * prevI2);
|
||||
|
||||
i1ForEvenPrev3 = i1ForEvenPrev2;
|
||||
i1ForEvenPrev2 = buffer[KEY_DETRENDER];
|
||||
@@ -164,8 +164,8 @@ public sealed class HtDcperiod : AbstractBase
|
||||
hilbertIdx = 0;
|
||||
}
|
||||
|
||||
q2 = 0.2 * (buffer[KEY_Q1] + buffer[KEY_JI]) + 0.8 * prevQ2;
|
||||
i2 = 0.2 * (i1ForEvenPrev3 - buffer[KEY_JQ]) + 0.8 * prevI2;
|
||||
q2 = (0.2 * (buffer[KEY_Q1] + buffer[KEY_JI])) + (0.8 * prevQ2);
|
||||
i2 = (0.2 * (i1ForEvenPrev3 - buffer[KEY_JQ])) + (0.8 * prevI2);
|
||||
|
||||
i1ForOddPrev3 = i1ForOddPrev2;
|
||||
i1ForOddPrev2 = buffer[KEY_DETRENDER];
|
||||
@@ -289,7 +289,7 @@ public sealed class HtDcperiod : AbstractBase
|
||||
}
|
||||
|
||||
// Calculate smoothed price using WMA
|
||||
double adjustedPrevPeriod = 0.075 * s.Period + 0.54;
|
||||
double adjustedPrevPeriod = (0.075 * s.Period) + 0.54;
|
||||
|
||||
s.PeriodWMASub += price;
|
||||
s.PeriodWMASub -= s.TrailingWMAValue;
|
||||
|
||||
@@ -142,8 +142,8 @@ public sealed class HtPhasor : AbstractBase
|
||||
double input1 = buffer[KEY_Q1];
|
||||
DoHilbertTransform(buffer, KEY_JQ, input1, true, hilbertIdx, adjustedPrevPeriod);
|
||||
|
||||
q2 = 0.2 * (buffer[KEY_Q1] + buffer[KEY_JI]) + 0.8 * prevQ2;
|
||||
i2 = 0.2 * (i1ForOddPrev3 - buffer[KEY_JQ]) + 0.8 * prevI2;
|
||||
q2 = (0.2 * (buffer[KEY_Q1] + buffer[KEY_JI])) + (0.8 * prevQ2);
|
||||
i2 = (0.2 * (i1ForOddPrev3 - buffer[KEY_JQ])) + (0.8 * prevI2);
|
||||
|
||||
i1ForEvenPrev3 = i1ForEvenPrev2;
|
||||
i1ForEvenPrev2 = buffer[KEY_DETRENDER];
|
||||
@@ -167,8 +167,8 @@ public sealed class HtPhasor : AbstractBase
|
||||
hilbertIdx = 0;
|
||||
}
|
||||
|
||||
q2 = 0.2 * (buffer[KEY_Q1] + buffer[KEY_JI]) + 0.8 * prevQ2;
|
||||
i2 = 0.2 * (i1ForEvenPrev3 - buffer[KEY_JQ]) + 0.8 * prevI2;
|
||||
q2 = (0.2 * (buffer[KEY_Q1] + buffer[KEY_JI])) + (0.8 * prevQ2);
|
||||
i2 = (0.2 * (i1ForEvenPrev3 - buffer[KEY_JQ])) + (0.8 * prevI2);
|
||||
|
||||
i1ForOddPrev3 = i1ForOddPrev2;
|
||||
i1ForOddPrev2 = buffer[KEY_DETRENDER];
|
||||
@@ -178,8 +178,8 @@ public sealed class HtPhasor : AbstractBase
|
||||
private static void CalcSmoothedPeriod(
|
||||
ref double re, double i2, double q2, ref double prevI2, ref double prevQ2, ref double im, ref double period)
|
||||
{
|
||||
re = Math.FusedMultiplyAdd(0.2, i2 * prevI2 + q2 * prevQ2, 0.8 * re);
|
||||
im = Math.FusedMultiplyAdd(0.2, i2 * prevQ2 - q2 * prevI2, 0.8 * im);
|
||||
re = Math.FusedMultiplyAdd(0.2, (i2 * prevI2) + (q2 * prevQ2), 0.8 * re);
|
||||
im = Math.FusedMultiplyAdd(0.2, (i2 * prevQ2) - (q2 * prevI2), 0.8 * im);
|
||||
|
||||
prevQ2 = q2;
|
||||
prevI2 = i2;
|
||||
@@ -228,7 +228,7 @@ public sealed class HtPhasor : AbstractBase
|
||||
double p2 = Get(priceHistory, historyIdx, 2);
|
||||
double p3 = Get(priceHistory, historyIdx, 3);
|
||||
|
||||
double smoothedValue = (4.0 * p0 + 3.0 * p1 + 2.0 * p2 + p3) * 0.1;
|
||||
double smoothedValue = ((4.0 * p0) + (3.0 * p1) + (2.0 * p2) + p3) * 0.1;
|
||||
|
||||
s.PeriodWMASub = p0 + p1 + p2 + p3;
|
||||
s.PeriodWMASum = smoothedValue * 10.0;
|
||||
@@ -306,7 +306,7 @@ public sealed class HtPhasor : AbstractBase
|
||||
double prevQ2 = s.PrevQ2;
|
||||
double period = s.Period;
|
||||
|
||||
double adjustedPrevPeriod = 0.075 * period + 0.54;
|
||||
double adjustedPrevPeriod = (0.075 * period) + 0.54;
|
||||
_smoothPrice[s.SmoothPriceIdx] = smoothedValue;
|
||||
|
||||
double q2, i2;
|
||||
|
||||
@@ -293,7 +293,6 @@ public sealed class Alligator : ITValuePublisher
|
||||
return new TSeries(tList, vList);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the indicator state using the provided bar series history.
|
||||
/// </summary>
|
||||
@@ -337,7 +336,6 @@ public sealed class Alligator : ITValuePublisher
|
||||
return (results, indicator);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Jaw period value.
|
||||
/// </summary>
|
||||
|
||||
@@ -642,5 +642,4 @@ public sealed class Amat : ITValuePublisher, IDisposable
|
||||
TSeries results = amat.Update(source);
|
||||
return (results, amat);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -240,7 +240,6 @@ public sealed class Chop : ITValuePublisher
|
||||
return Math.Clamp(chop, 0.0, 100.0);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the indicator state using the provided bar series history.
|
||||
/// </summary>
|
||||
@@ -282,5 +281,4 @@ public sealed class Chop : ITValuePublisher
|
||||
TSeries results = indicator.Update(source);
|
||||
return (results, indicator);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -52,7 +52,7 @@ public sealed class HtTrendmodeIndicator : Indicator, IWatchlistIndicator
|
||||
SourceType.HL2 => (GetPrice(PriceType.High) + GetPrice(PriceType.Low)) / 2,
|
||||
SourceType.HLC3 => (GetPrice(PriceType.High) + GetPrice(PriceType.Low) + GetPrice(PriceType.Close)) / 3,
|
||||
SourceType.OHLC4 => (GetPrice(PriceType.Open) + GetPrice(PriceType.High) + GetPrice(PriceType.Low) + GetPrice(PriceType.Close)) / 4,
|
||||
SourceType.HLCC4 => (GetPrice(PriceType.High) + GetPrice(PriceType.Low) + 2 * GetPrice(PriceType.Close)) / 4,
|
||||
SourceType.HLCC4 => (GetPrice(PriceType.High) + GetPrice(PriceType.Low) + (2 * GetPrice(PriceType.Close))) / 4,
|
||||
_ => GetPrice(PriceType.Close)
|
||||
};
|
||||
|
||||
|
||||
@@ -186,8 +186,8 @@ public sealed class HtTrendmode : AbstractBase
|
||||
double input1 = buffer[KEY_Q1];
|
||||
DoHilbertTransform(buffer, KEY_JQ, input1, true, hilbertIdx, adjustedPrevPeriod);
|
||||
|
||||
q2 = 0.2 * (buffer[KEY_Q1] + buffer[KEY_JI]) + 0.8 * prevQ2;
|
||||
i2 = 0.2 * (i1ForOddPrev3 - buffer[KEY_JQ]) + 0.8 * prevI2;
|
||||
q2 = (0.2 * (buffer[KEY_Q1] + buffer[KEY_JI])) + (0.8 * prevQ2);
|
||||
i2 = (0.2 * (i1ForOddPrev3 - buffer[KEY_JQ])) + (0.8 * prevI2);
|
||||
|
||||
i1ForEvenPrev3 = i1ForEvenPrev2;
|
||||
i1ForEvenPrev2 = buffer[KEY_DETRENDER];
|
||||
@@ -211,8 +211,8 @@ public sealed class HtTrendmode : AbstractBase
|
||||
hilbertIdx = 0;
|
||||
}
|
||||
|
||||
q2 = 0.2 * (buffer[KEY_Q1] + buffer[KEY_JI]) + 0.8 * prevQ2;
|
||||
i2 = 0.2 * (i1ForEvenPrev3 - buffer[KEY_JQ]) + 0.8 * prevI2;
|
||||
q2 = (0.2 * (buffer[KEY_Q1] + buffer[KEY_JI])) + (0.8 * prevQ2);
|
||||
i2 = (0.2 * (i1ForEvenPrev3 - buffer[KEY_JQ])) + (0.8 * prevI2);
|
||||
|
||||
i1ForOddPrev3 = i1ForOddPrev2;
|
||||
i1ForOddPrev2 = buffer[KEY_DETRENDER];
|
||||
@@ -304,7 +304,7 @@ public sealed class HtTrendmode : AbstractBase
|
||||
}
|
||||
|
||||
// Calculate smoothed price using WMA
|
||||
double adjustedPrevPeriod = 0.075 * s.Period + 0.54;
|
||||
double adjustedPrevPeriod = (0.075 * s.Period) + 0.54;
|
||||
|
||||
s.PeriodWMASub += price;
|
||||
s.PeriodWMASub -= s.TrailingWMAValue;
|
||||
@@ -488,7 +488,7 @@ public sealed class HtTrendmode : AbstractBase
|
||||
double smaValue = (dcPeriodInt > 0) ? sumPrice / (double)dcPeriodInt : price;
|
||||
|
||||
// WMA smoothing of SMA: (4*current + 3*prev1 + 2*prev2 + prev3) / 10
|
||||
double trendline = (4.0 * smaValue + 3.0 * s.ITrend1 + 2.0 * s.ITrend2 + s.ITrend3) / 10.0;
|
||||
double trendline = ((4.0 * smaValue) + (3.0 * s.ITrend1) + (2.0 * s.ITrend2) + s.ITrend3) / 10.0;
|
||||
s.ITrend3 = s.ITrend2;
|
||||
s.ITrend2 = s.ITrend1;
|
||||
s.ITrend1 = smaValue;
|
||||
|
||||
@@ -234,7 +234,7 @@ public sealed class Pfe : AbstractBase
|
||||
_s = default;
|
||||
_ps = default;
|
||||
|
||||
int warmupLength = Math.Min(source.Length, WarmupPeriod + _smoothPeriod * 3);
|
||||
int warmupLength = Math.Min(source.Length, WarmupPeriod + (_smoothPeriod * 3));
|
||||
int startIndex = source.Length - warmupLength;
|
||||
|
||||
// Seed LastValidValue
|
||||
|
||||
@@ -265,7 +265,6 @@ public sealed class Super : ITValuePublisher
|
||||
return new TSeries(t, v);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the indicator state using the provided bar series history.
|
||||
/// </summary>
|
||||
|
||||
@@ -392,7 +392,6 @@ public sealed class Vhf : AbstractBase
|
||||
prevClose = val;
|
||||
hasPrevClose = true;
|
||||
|
||||
|
||||
// Calculate VHF
|
||||
if (closeFilled >= closeBufSize && diffFilled >= period)
|
||||
{
|
||||
|
||||
@@ -339,5 +339,4 @@ public sealed class Vortex : ITValuePublisher
|
||||
TSeries results = indicator.Update(source);
|
||||
return (results, indicator);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ public sealed class PseudoHuber : BiInputIndicatorBase
|
||||
{
|
||||
double diff = actual - predicted;
|
||||
double ratio = diff / Delta;
|
||||
double sqrtTerm = Math.Sqrt(1.0 + ratio * ratio);
|
||||
double sqrtTerm = Math.Sqrt(1.0 + (ratio * ratio));
|
||||
return Math.FusedMultiplyAdd(_deltaSquared, sqrtTerm, -_deltaSquared);
|
||||
}
|
||||
|
||||
|
||||
@@ -393,7 +393,7 @@ public sealed class CsvFeed : IFeed
|
||||
|
||||
while (left < right)
|
||||
{
|
||||
int mid = left + (right - left) / 2;
|
||||
int mid = left + ((right - left) / 2);
|
||||
|
||||
if (Data[mid].Time < startTime)
|
||||
{
|
||||
|
||||
@@ -400,7 +400,7 @@ public sealed class ALaguerre : AbstractBase
|
||||
s.LastValid = input;
|
||||
|
||||
// Filt = (L0 + 2*L1 + 2*L2 + L3) / 6
|
||||
double result = (s.L0 + 2.0 * s.L1 + 2.0 * s.L2 + s.L3) / 6.0;
|
||||
double result = (s.L0 + (2.0 * s.L1) + (2.0 * s.L2) + s.L3) / 6.0;
|
||||
s.LastResult = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -159,7 +159,7 @@ public sealed class Bpf : AbstractBase
|
||||
|
||||
// Highpass Filter Step
|
||||
// hp = hp_c1 * (val - 2*src1 + src2) + hp_c2 * hp1 + hp_c3 * hp2
|
||||
double term1 = _hpC1 * (val - 2.0 * _state.Src1 + _state.Src2);
|
||||
double term1 = _hpC1 * (val - (2.0 * _state.Src1) + _state.Src2);
|
||||
double hp = Math.FusedMultiplyAdd(_hpC2, _state.Hp1, Math.FusedMultiplyAdd(_hpC3, _state.Hp2, term1));
|
||||
|
||||
// Lowpass Filter Step (Bandpass output)
|
||||
@@ -187,7 +187,6 @@ public sealed class Bpf : AbstractBase
|
||||
return indicator.Update(source);
|
||||
}
|
||||
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void Batch(ReadOnlySpan<double> source, Span<double> output, int lowerPeriod, int upperPeriod)
|
||||
{
|
||||
@@ -240,7 +239,7 @@ public sealed class Bpf : AbstractBase
|
||||
}
|
||||
|
||||
// Highpass
|
||||
double term1 = hpC1 * (val - 2.0 * src1 + src2);
|
||||
double term1 = hpC1 * (val - (2.0 * src1) + src2);
|
||||
double hp = Math.FusedMultiplyAdd(hpC2, hp1, Math.FusedMultiplyAdd(hpC3, hp2, term1));
|
||||
|
||||
// Lowpass
|
||||
|
||||
@@ -93,7 +93,7 @@ public sealed class Butter2 : AbstractBase
|
||||
DateTime baseTime = DateTime.UtcNow;
|
||||
for (int i = 0; i < source.Length; i++)
|
||||
{
|
||||
Update(new TValue(baseTime + interval * i, source[i]));
|
||||
Update(new TValue(baseTime + (interval * i), source[i]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ public sealed class Butter3 : AbstractBase
|
||||
double c1 = a1 * a1;
|
||||
|
||||
coef2 = b1 + c1;
|
||||
coef3 = -(c1 + b1 * c1);
|
||||
coef3 = -(c1 + (b1 * c1));
|
||||
coef4 = c1 * c1;
|
||||
coef1 = (1.0 - b1 + c1) * (1.0 - c1) / 8.0;
|
||||
}
|
||||
@@ -87,7 +87,7 @@ public sealed class Butter3 : AbstractBase
|
||||
DateTime baseTime = DateTime.UtcNow;
|
||||
for (int i = 0; i < source.Length; i++)
|
||||
{
|
||||
Update(new TValue(baseTime + interval * i, source[i]));
|
||||
Update(new TValue(baseTime + (interval * i), source[i]));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ public sealed class Butter3 : AbstractBase
|
||||
: Math.FusedMultiplyAdd(_coef4, _state.Y3,
|
||||
Math.FusedMultiplyAdd(_coef3, _state.Y2,
|
||||
Math.FusedMultiplyAdd(_coef2, _state.Y1,
|
||||
_coef1 * (x + 3.0 * _state.X1 + 3.0 * _state.X2 + _state.X3))));
|
||||
_coef1 * (x + (3.0 * _state.X1) + (3.0 * _state.X2) + _state.X3))));
|
||||
|
||||
// Update state: shift history
|
||||
_state.X3 = _state.X2;
|
||||
@@ -203,7 +203,7 @@ public sealed class Butter3 : AbstractBase
|
||||
: Math.FusedMultiplyAdd(coef4, y3,
|
||||
Math.FusedMultiplyAdd(coef3, y2,
|
||||
Math.FusedMultiplyAdd(coef2, y1,
|
||||
coef1 * (x + 3.0 * x1 + 3.0 * x2 + x3))));
|
||||
coef1 * (x + (3.0 * x1) + (3.0 * x2) + x3))));
|
||||
|
||||
x3 = x2;
|
||||
x2 = x1;
|
||||
|
||||
@@ -226,7 +226,7 @@ public sealed class Cfitz : AbstractBase
|
||||
}
|
||||
|
||||
// Endpoint correction: b̃ = -0.5*B_0 - Σ B_j
|
||||
double btilde = -0.5 * _b0 - sumBj;
|
||||
double btilde = (-0.5 * _b0) - sumBj;
|
||||
weightedSum += btilde * _history[0];
|
||||
|
||||
return weightedSum;
|
||||
@@ -303,7 +303,7 @@ public sealed class Cfitz : AbstractBase
|
||||
ws += bWeights[j] * source[j]; // y_{j+1} in 0-index is source[j]
|
||||
sBj += bWeights[j];
|
||||
}
|
||||
double bt = -0.5 * b0 - sBj;
|
||||
double bt = (-0.5 * b0) - sBj;
|
||||
ws += bt * source[T - 1];
|
||||
output[t] = ws;
|
||||
}
|
||||
@@ -317,7 +317,7 @@ public sealed class Cfitz : AbstractBase
|
||||
ws += bWeights[j] * source[T - 1 - j];
|
||||
sBj += bWeights[j];
|
||||
}
|
||||
double bt = -0.5 * b0 - sBj;
|
||||
double bt = (-0.5 * b0) - sBj;
|
||||
ws += bt * source[0];
|
||||
output[t] = ws;
|
||||
}
|
||||
@@ -339,7 +339,7 @@ public sealed class Cfitz : AbstractBase
|
||||
sumFwd += bWeights[j];
|
||||
}
|
||||
// Far endpoint correction
|
||||
double btFwd = -0.5 * b0 - sumFwd;
|
||||
double btFwd = (-0.5 * b0) - sumFwd;
|
||||
ws += btFwd * source[T - 1];
|
||||
|
||||
// Backward terms: j=1..tp-2 = t-1 in 0-indexed
|
||||
@@ -351,7 +351,7 @@ public sealed class Cfitz : AbstractBase
|
||||
sumBwd += bWeights[j];
|
||||
}
|
||||
// Near endpoint correction
|
||||
double btBwd = -0.5 * b0 - sumBwd;
|
||||
double btBwd = (-0.5 * b0) - sumBwd;
|
||||
ws += btBwd * source[0];
|
||||
|
||||
output[t] = ws;
|
||||
|
||||
@@ -72,9 +72,9 @@ public sealed class Cheby1 : AbstractBase
|
||||
double omegaD = coshMu * Wc;
|
||||
double K = Math.FusedMultiplyAdd(sigma, sigma, omegaD * omegaD);
|
||||
|
||||
double a0z = 1.0 - 2.0 * sigma + K;
|
||||
double a1z = 2.0 * K - 2.0;
|
||||
double a2z = 1.0 + 2.0 * sigma + K;
|
||||
double a0z = 1.0 - (2.0 * sigma) + K;
|
||||
double a1z = (2.0 * K) - 2.0;
|
||||
double a2z = 1.0 + (2.0 * sigma) + K;
|
||||
double b0z = K;
|
||||
double b1z = 2.0 * K;
|
||||
double b2z = K;
|
||||
@@ -202,7 +202,6 @@ public sealed class Cheby1 : AbstractBase
|
||||
return indicator.Update(source);
|
||||
}
|
||||
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void Batch(ReadOnlySpan<double> source, Span<double> output, int period, double ripple = 1.0)
|
||||
{
|
||||
@@ -231,11 +230,11 @@ public sealed class Cheby1 : AbstractBase
|
||||
double coshMu = Math.Cosh(mu);
|
||||
double sigma = -sinhMu * Wc;
|
||||
double omegaD = coshMu * Wc;
|
||||
double K = sigma * sigma + omegaD * omegaD;
|
||||
double K = (sigma * sigma) + (omegaD * omegaD);
|
||||
|
||||
double a0z = 1.0 - 2.0 * sigma + K;
|
||||
double a1z = 2.0 * K - 2.0;
|
||||
double a2z = 1.0 + 2.0 * sigma + K;
|
||||
double a0z = 1.0 - (2.0 * sigma) + K;
|
||||
double a1z = (2.0 * K) - 2.0;
|
||||
double a2z = 1.0 + (2.0 * sigma) + K;
|
||||
double b0z = K;
|
||||
double b1z = 2.0 * K;
|
||||
double b2z = K;
|
||||
|
||||
@@ -77,12 +77,12 @@ public sealed class Cheby2 : AbstractBase
|
||||
double Kz = omegaZ * omegaZ;
|
||||
double dcGain = Kz / Kp;
|
||||
|
||||
double a0z = 1.0 - 2.0 * sigmaP + Kp;
|
||||
double a1z = 2.0 * Kp - 2.0;
|
||||
double a2z = 1.0 + 2.0 * sigmaP + Kp;
|
||||
double a0z = 1.0 - (2.0 * sigmaP) + Kp;
|
||||
double a1z = (2.0 * Kp) - 2.0;
|
||||
double a2z = 1.0 + (2.0 * sigmaP) + Kp;
|
||||
|
||||
double b0z = dcGain * (1.0 + Kz);
|
||||
double b1z = dcGain * (2.0 * Kz - 2.0);
|
||||
double b1z = dcGain * ((2.0 * Kz) - 2.0);
|
||||
double b2z = dcGain * (1.0 + Kz);
|
||||
|
||||
// Normalize
|
||||
@@ -258,12 +258,12 @@ public sealed class Cheby2 : AbstractBase
|
||||
double Kz = omegaZ * omegaZ;
|
||||
double dcGain = Kz / Kp;
|
||||
|
||||
double a0z = 1.0 - 2.0 * sigmaP + Kp;
|
||||
double a1z = 2.0 * Kp - 2.0;
|
||||
double a2z = 1.0 + 2.0 * sigmaP + Kp;
|
||||
double a0z = 1.0 - (2.0 * sigmaP) + Kp;
|
||||
double a1z = (2.0 * Kp) - 2.0;
|
||||
double a2z = 1.0 + (2.0 * sigmaP) + Kp;
|
||||
|
||||
double b0z = dcGain * (1.0 + Kz);
|
||||
double b1z = dcGain * (2.0 * Kz - 2.0);
|
||||
double b1z = dcGain * ((2.0 * Kz) - 2.0);
|
||||
double b2z = dcGain * (1.0 + Kz);
|
||||
|
||||
double b0 = b0z / a0z;
|
||||
|
||||
@@ -49,7 +49,7 @@ public sealed class Edcf : AbstractBase
|
||||
// But the inner loop looks back within the same window, so we only need 'length' samples
|
||||
// However, the EasyLanguage code accesses Price[count + LookBack] where count goes to Length-1
|
||||
// and LookBack goes to Length-1, so max index = 2*(Length-1). We need 2*Length - 1 in the buffer.
|
||||
_buffer = new RingBuffer(2 * length - 1);
|
||||
_buffer = new RingBuffer((2 * length) - 1);
|
||||
WarmupPeriod = length;
|
||||
Name = $"Edcf({_length})";
|
||||
}
|
||||
@@ -215,12 +215,12 @@ public sealed class Edcf : AbstractBase
|
||||
|
||||
public override void Prime(ReadOnlySpan<double> source, TimeSpan? step = null)
|
||||
{
|
||||
long initialTicks = DateTime.UtcNow.Ticks - source.Length * (step?.Ticks ?? TimeSpan.FromSeconds(1).Ticks);
|
||||
long initialTicks = DateTime.UtcNow.Ticks - (source.Length * (step?.Ticks ?? TimeSpan.FromSeconds(1).Ticks));
|
||||
TimeSpan increment = step ?? TimeSpan.FromSeconds(1);
|
||||
|
||||
for (int i = 0; i < source.Length; i++)
|
||||
{
|
||||
Update(new TValue(initialTicks + i * increment.Ticks, source[i]));
|
||||
Update(new TValue(initialTicks + (i * increment.Ticks), source[i]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ public sealed class Elliptic : AbstractBase
|
||||
double sigma_scaled = C_sigma * Wc;
|
||||
double Kp_scaled = C_Kp_norm * Wc * Wc;
|
||||
|
||||
double a0_denom = 1.0 - 2.0 * sigma_scaled + Kp_scaled;
|
||||
double a0_denom = 1.0 - (2.0 * sigma_scaled) + Kp_scaled;
|
||||
if (Math.Abs(a0_denom) < 1e-9)
|
||||
{
|
||||
a0_denom = 1e-9;
|
||||
@@ -73,12 +73,12 @@ public sealed class Elliptic : AbstractBase
|
||||
|
||||
const double norm_factor = C_Kp_norm / (C_k * C_wz * C_wz);
|
||||
|
||||
double b0_val = norm_factor * C_k * (1.0 + omega_z_scaled * omega_z_scaled) / a0_denom;
|
||||
double b1_val = norm_factor * C_k * (2.0 * omega_z_scaled * omega_z_scaled - 2.0) / a0_denom;
|
||||
double b0_val = norm_factor * C_k * (1.0 + (omega_z_scaled * omega_z_scaled)) / a0_denom;
|
||||
double b1_val = norm_factor * C_k * ((2.0 * omega_z_scaled * omega_z_scaled) - 2.0) / a0_denom;
|
||||
double b2_val = b0_val;
|
||||
|
||||
double a1_val = (2.0 * Kp_scaled - 2.0) / a0_denom;
|
||||
double a2_val = (1.0 + 2.0 * sigma_scaled + Kp_scaled) / a0_denom;
|
||||
double a1_val = ((2.0 * Kp_scaled) - 2.0) / a0_denom;
|
||||
double a2_val = (1.0 + (2.0 * sigma_scaled) + Kp_scaled) / a0_denom;
|
||||
|
||||
// Validate and Normalize for Unity Gain at DC
|
||||
// DC Gain = (b0 + b1 + b2) / (1 + a1 + a2)
|
||||
@@ -207,7 +207,6 @@ public sealed class Elliptic : AbstractBase
|
||||
return indicator.Update(source);
|
||||
}
|
||||
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void Batch(ReadOnlySpan<double> source, Span<double> output, int period)
|
||||
{
|
||||
@@ -255,7 +254,7 @@ public sealed class Elliptic : AbstractBase
|
||||
double sigma_scaled = C_sigma * Wc;
|
||||
double Kp_scaled = C_Kp_norm * Wc * Wc;
|
||||
|
||||
double a0_denom = 1.0 - 2.0 * sigma_scaled + Kp_scaled;
|
||||
double a0_denom = 1.0 - (2.0 * sigma_scaled) + Kp_scaled;
|
||||
if (Math.Abs(a0_denom) < 1e-9)
|
||||
{
|
||||
a0_denom = 1e-9;
|
||||
@@ -263,12 +262,12 @@ public sealed class Elliptic : AbstractBase
|
||||
|
||||
const double norm_factor = C_Kp_norm / (C_k * C_wz * C_wz);
|
||||
|
||||
double b0 = norm_factor * C_k * (1.0 + omega_z_scaled * omega_z_scaled) / a0_denom;
|
||||
double b1 = norm_factor * C_k * (2.0 * omega_z_scaled * omega_z_scaled - 2.0) / a0_denom;
|
||||
double b0 = norm_factor * C_k * (1.0 + (omega_z_scaled * omega_z_scaled)) / a0_denom;
|
||||
double b1 = norm_factor * C_k * ((2.0 * omega_z_scaled * omega_z_scaled) - 2.0) / a0_denom;
|
||||
double b2 = b0;
|
||||
|
||||
double a1 = (2.0 * Kp_scaled - 2.0) / a0_denom;
|
||||
double a2 = (1.0 + 2.0 * sigma_scaled + Kp_scaled) / a0_denom;
|
||||
double a1 = ((2.0 * Kp_scaled) - 2.0) / a0_denom;
|
||||
double a2 = (1.0 + (2.0 * sigma_scaled) + Kp_scaled) / a0_denom;
|
||||
|
||||
// Normalize constants for Unity Gain
|
||||
double sum_b = b0 + b1 + b2;
|
||||
|
||||
@@ -50,7 +50,7 @@ public sealed class Gauss : AbstractBase
|
||||
}
|
||||
|
||||
_sigma = sigma;
|
||||
KernelSize = (int)(2 * Math.Ceiling(3.0 * sigma) + 1);
|
||||
KernelSize = (int)((2 * Math.Ceiling(3.0 * sigma)) + 1);
|
||||
WarmupPeriod = KernelSize;
|
||||
Name = $"Gauss({sigma:F2})";
|
||||
_buffer = new RingBuffer(KernelSize);
|
||||
@@ -241,7 +241,7 @@ public sealed class Gauss : AbstractBase
|
||||
throw new ArgumentException("Source and output spans must be of equal length.", nameof(output));
|
||||
}
|
||||
|
||||
int kernelSize = (int)(2 * Math.Ceiling(3.0 * sigma) + 1);
|
||||
int kernelSize = (int)((2 * Math.Ceiling(3.0 * sigma)) + 1);
|
||||
|
||||
// Use stackalloc for small kernels, ArrayPool for large ones to avoid stack overflow
|
||||
double[]? rented = null;
|
||||
|
||||
@@ -53,7 +53,7 @@ public sealed class Hp : AbstractBase
|
||||
Lambda = lambda;
|
||||
|
||||
double s = Math.Sqrt(lambda);
|
||||
_alpha = (s * 0.5 - 1.0) / (s * 0.5 + 1.0);
|
||||
_alpha = ((s * 0.5) - 1.0) / ((s * 0.5) + 1.0);
|
||||
_alpha = Math.Clamp(_alpha, 0.0001, 0.9999);
|
||||
_oneMinusAlpha = 1.0 - _alpha;
|
||||
_halfAlpha = 0.5 * _alpha;
|
||||
@@ -218,7 +218,7 @@ public sealed class Hp : AbstractBase
|
||||
}
|
||||
|
||||
double s = Math.Sqrt(lambda);
|
||||
double alpha = (s * 0.5 - 1.0) / (s * 0.5 + 1.0);
|
||||
double alpha = ((s * 0.5) - 1.0) / ((s * 0.5) + 1.0);
|
||||
alpha = Math.Clamp(alpha, 0.0001, 0.9999);
|
||||
|
||||
double oneMinusAlpha = 1.0 - alpha;
|
||||
|
||||
@@ -251,7 +251,7 @@ public sealed class Hpf : AbstractBase
|
||||
double a = (cosW + sinW - 1.0) / cosW;
|
||||
double oneMinusA = 1.0 - a;
|
||||
|
||||
double t = 1.0 - 0.5 * a;
|
||||
double t = 1.0 - (0.5 * a);
|
||||
double c1 = t * t;
|
||||
double c2 = 2.0 * oneMinusA;
|
||||
double c3 = oneMinusA * oneMinusA;
|
||||
@@ -316,7 +316,6 @@ public sealed class Hpf : AbstractBase
|
||||
return (results, indicator);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Unsubscribes from the source publisher if one was provided during construction.
|
||||
/// </summary>
|
||||
|
||||
@@ -263,7 +263,7 @@ public sealed class Laguerre : AbstractBase
|
||||
s.LastValid = input;
|
||||
|
||||
// Filt = (L0 + 2*L1 + 2*L2 + L3) / 6
|
||||
return (s.L0 + 2.0 * s.L1 + 2.0 * s.L2 + s.L3) / 6.0;
|
||||
return (s.L0 + (2.0 * s.L1) + (2.0 * s.L2) + s.L3) / 6.0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -131,7 +131,7 @@ public sealed class OneEuro : AbstractBase
|
||||
s.DxHat = Math.FusedMultiplyAdd(_alphaD, dx - s.DxHat, s.DxHat);
|
||||
|
||||
// Step 3: Adaptive cutoff
|
||||
double fc = MinCutoff + Beta * Math.Abs(s.DxHat);
|
||||
double fc = MinCutoff + (Beta * Math.Abs(s.DxHat));
|
||||
|
||||
// Step 4: Smoothing factor α = r / (r + 1), r = 2π·fc
|
||||
double r = 2.0 * Math.PI * fc;
|
||||
@@ -223,7 +223,7 @@ public sealed class OneEuro : AbstractBase
|
||||
dxHat = Math.FusedMultiplyAdd(alphaD, dx - dxHat, dxHat);
|
||||
|
||||
// Adaptive cutoff
|
||||
double fc = minCutoff + beta * Math.Abs(dxHat);
|
||||
double fc = minCutoff + (beta * Math.Abs(dxHat));
|
||||
|
||||
// Smoothing factor
|
||||
double r = 2.0 * Math.PI * fc;
|
||||
|
||||
@@ -88,7 +88,7 @@ public sealed class Rls : AbstractBase
|
||||
_p_P = new double[matSize];
|
||||
for (int i = 0; i < order; i++)
|
||||
{
|
||||
_P[i * order + i] = delta;
|
||||
_P[(i * order) + i] = delta;
|
||||
}
|
||||
|
||||
// Ring buffer holds order+1 values: current + order past values
|
||||
@@ -247,7 +247,7 @@ public sealed class Rls : AbstractBase
|
||||
int rowBase = i * _order;
|
||||
for (int j = 0; j < _order; j++)
|
||||
{
|
||||
_P[rowBase + j] = _invLambda * (_P[rowBase + j] - ki * px[j]);
|
||||
_P[rowBase + j] = _invLambda * (_P[rowBase + j] - (ki * px[j]));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -304,7 +304,7 @@ public sealed class Rls : AbstractBase
|
||||
double[] P = new double[matSize];
|
||||
for (int i = 0; i < order; i++)
|
||||
{
|
||||
P[i * order + i] = delta;
|
||||
P[(i * order) + i] = delta;
|
||||
}
|
||||
|
||||
// Temporary buffers for Px and k
|
||||
@@ -391,7 +391,7 @@ public sealed class Rls : AbstractBase
|
||||
int rowBase = i * order;
|
||||
for (int j = 0; j < order; j++)
|
||||
{
|
||||
P[rowBase + j] = invLambda * (P[rowBase + j] - ki * px[j]);
|
||||
P[rowBase + j] = invLambda * (P[rowBase + j] - (ki * px[j]));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -414,7 +414,7 @@ public sealed class Rls : AbstractBase
|
||||
Array.Clear(_p_P);
|
||||
for (int i = 0; i < _order; i++)
|
||||
{
|
||||
_P[i * _order + i] = delta;
|
||||
_P[(i * _order) + i] = delta;
|
||||
}
|
||||
|
||||
Last = default;
|
||||
|
||||
@@ -159,7 +159,7 @@ public sealed class Roofing : AbstractBase
|
||||
|
||||
// Stage 1: Highpass Filter (removes trend)
|
||||
// hp = hpC1 * (val - 2*src1 + src2) + hpC2 * hp1 + hpC3 * hp2
|
||||
double hpInput = _hpC1 * (val - 2.0 * _state.Src1 + _state.Src2);
|
||||
double hpInput = _hpC1 * (val - (2.0 * _state.Src1) + _state.Src2);
|
||||
double hp = Math.FusedMultiplyAdd(_hpC2, _state.Hp1, Math.FusedMultiplyAdd(_hpC3, _state.Hp2, hpInput));
|
||||
|
||||
// Stage 2: Super Smoother (removes noise from HP output)
|
||||
@@ -238,7 +238,7 @@ public sealed class Roofing : AbstractBase
|
||||
}
|
||||
|
||||
// Highpass
|
||||
double hpInput = hpC1 * (val - 2.0 * src1 + src2);
|
||||
double hpInput = hpC1 * (val - (2.0 * src1) + src2);
|
||||
double hp = Math.FusedMultiplyAdd(hpC2, hp1, Math.FusedMultiplyAdd(hpC3, hp2, hpInput));
|
||||
|
||||
// Super Smoother
|
||||
|
||||
@@ -156,7 +156,7 @@ public sealed class Sak : AbstractBase
|
||||
break;
|
||||
|
||||
case "HP":
|
||||
_c0 = 1.0 - alpha / 2.0; _b0 = 1; _b1 = -1; _b2 = 0;
|
||||
_c0 = 1.0 - (alpha / 2.0); _b0 = 1; _b1 = -1; _b2 = 0;
|
||||
_a1 = decay; _a2 = 0;
|
||||
break;
|
||||
|
||||
@@ -245,7 +245,7 @@ public sealed class Sak : AbstractBase
|
||||
double oldest = _smaBuf!.IsFull ? _smaBuf.Oldest : 0.0;
|
||||
_smaBuf.Add(val, isNew);
|
||||
// _state.Y1 holds the running sum
|
||||
y = Math.FusedMultiplyAdd(_oneDivN, val, _state.Y1 - _oneDivN * oldest);
|
||||
y = Math.FusedMultiplyAdd(_oneDivN, val, _state.Y1 - (_oneDivN * oldest));
|
||||
_state.Y1 = y;
|
||||
}
|
||||
else
|
||||
@@ -388,7 +388,7 @@ public sealed class Sak : AbstractBase
|
||||
{
|
||||
double oldest = (smaBuf != null && smaBuf.IsFull) ? smaBuf.Oldest : 0.0;
|
||||
smaBuf?.Add(val);
|
||||
y = Math.FusedMultiplyAdd(oneDivN, val, state.Y1 - oneDivN * oldest);
|
||||
y = Math.FusedMultiplyAdd(oneDivN, val, state.Y1 - (oneDivN * oldest));
|
||||
state.Y1 = y;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -69,17 +69,17 @@ public sealed class Sgf : AbstractBase
|
||||
double weight = 0;
|
||||
if (_polyOrder == 2)
|
||||
{
|
||||
weight = 3.0 * (3.0 * _period * _period - 7.0 - 20.0 * k * k);
|
||||
weight = 3.0 * ((3.0 * _period * _period) - 7.0 - (20.0 * k * k));
|
||||
}
|
||||
else if (_polyOrder == 4)
|
||||
{
|
||||
double k2 = k * k;
|
||||
weight = 15.0 + k2 * (-20.0 + k2 * 6.0);
|
||||
weight = 15.0 + (k2 * (-20.0 + (k2 * 6.0)));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Guard against division by zero when halfWindow == 0 (period == 1)
|
||||
weight = (halfWindow == 0) ? 1.0 : 1.0 - Math.Abs((double)k) / (double)halfWindow;
|
||||
weight = (halfWindow == 0) ? 1.0 : 1.0 - (Math.Abs((double)k) / (double)halfWindow);
|
||||
}
|
||||
|
||||
_weights[i] = weight;
|
||||
@@ -287,17 +287,17 @@ public sealed class Sgf : AbstractBase
|
||||
double weight = 0;
|
||||
if (polyOrder == 2)
|
||||
{
|
||||
weight = 3.0 * (3.0 * period * period - 7.0 - 20.0 * k * k);
|
||||
weight = 3.0 * ((3.0 * period * period) - 7.0 - (20.0 * k * k));
|
||||
}
|
||||
else if (polyOrder == 4)
|
||||
{
|
||||
double k2 = k * k;
|
||||
weight = 15.0 + k2 * (-20.0 + k2 * 6.0);
|
||||
weight = 15.0 + (k2 * (-20.0 + (k2 * 6.0)));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Guard against division by zero when halfWindow == 0 (period == 1)
|
||||
weight = (halfWindow == 0) ? 1.0 : 1.0 - Math.Abs((double)k) / (double)halfWindow;
|
||||
weight = (halfWindow == 0) ? 1.0 : 1.0 - (Math.Abs((double)k) / (double)halfWindow);
|
||||
}
|
||||
|
||||
weights[i] = weight;
|
||||
|
||||
@@ -58,7 +58,7 @@ public sealed class Ssf3 : AbstractBase
|
||||
double c1 = a1 * a1;
|
||||
|
||||
coef2 = b1 + c1;
|
||||
coef3 = -(c1 + b1 * c1);
|
||||
coef3 = -(c1 + (b1 * c1));
|
||||
coef4 = c1 * c1;
|
||||
coef1 = 1.0 - coef2 - coef3 - coef4;
|
||||
}
|
||||
@@ -88,7 +88,7 @@ public sealed class Ssf3 : AbstractBase
|
||||
DateTime baseTime = DateTime.UtcNow;
|
||||
for (int i = 0; i < source.Length; i++)
|
||||
{
|
||||
Update(new TValue(baseTime + interval * i, source[i]));
|
||||
Update(new TValue(baseTime + (interval * i), source[i]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ public sealed class Usf : AbstractBase
|
||||
|
||||
// Precompute coefficients for FMA optimization
|
||||
_k0 = 1.0 - _c1; // coefficient for val
|
||||
_k1 = 2.0 * _c1 - _c2; // coefficient for PrevInput1
|
||||
_k1 = (2.0 * _c1) - _c2; // coefficient for PrevInput1
|
||||
_k2 = -(_c1 + _c3); // coefficient for PrevInput2
|
||||
|
||||
Name = $"Usf({period})";
|
||||
@@ -281,7 +281,7 @@ public sealed class Usf : AbstractBase
|
||||
|
||||
// Precompute coefficients for FMA (outside loop)
|
||||
double k0 = 1.0 - c1;
|
||||
double k1 = 2.0 * c1 - c2;
|
||||
double k1 = (2.0 * c1) - c2;
|
||||
double k2 = -(c1 + c3);
|
||||
|
||||
for (; i < len; i++)
|
||||
|
||||
@@ -102,7 +102,7 @@ public sealed class Voss : AbstractBase
|
||||
double twoPiOverPeriod = 2.0 * Math.PI / period;
|
||||
_f1 = Math.Cos(twoPiOverPeriod);
|
||||
double g1 = Math.Cos(bandwidth * twoPiOverPeriod);
|
||||
_s1 = 1.0 / g1 - Math.Sqrt(1.0 / (g1 * g1) - 1.0);
|
||||
_s1 = (1.0 / g1) - Math.Sqrt((1.0 / (g1 * g1)) - 1.0);
|
||||
|
||||
_vossRing = new double[_order + 1];
|
||||
_s.LastValid = double.NaN;
|
||||
@@ -203,11 +203,11 @@ public sealed class Voss : AbstractBase
|
||||
for (int count = 0; count < _order; count++)
|
||||
{
|
||||
int idx = _order - count; // lookback distance
|
||||
int ringPos = (_vossIdx - idx + ringLen * 2) % ringLen;
|
||||
int ringPos = (_vossIdx - idx + (ringLen * 2)) % ringLen;
|
||||
sumC += (double)(count + 1) / _order * _vossRing[ringPos];
|
||||
}
|
||||
|
||||
double vossVal = (double)(3 + _order) / 2.0 * filt - sumC;
|
||||
double vossVal = ((double)(3 + _order) / 2.0 * filt) - sumC;
|
||||
|
||||
// State shifts for next bar
|
||||
if (isNew)
|
||||
@@ -261,7 +261,7 @@ public sealed class Voss : AbstractBase
|
||||
double twoPiOverPeriod = 2.0 * Math.PI / period;
|
||||
double f1 = Math.Cos(twoPiOverPeriod);
|
||||
double g1 = Math.Cos(bandwidth * twoPiOverPeriod);
|
||||
double s1 = 1.0 / g1 - Math.Sqrt(1.0 / (g1 * g1) - 1.0);
|
||||
double s1 = (1.0 / g1) - Math.Sqrt((1.0 / (g1 * g1)) - 1.0);
|
||||
|
||||
int order = 3 * predict;
|
||||
double[] vossHistory = new double[source.Length];
|
||||
@@ -319,7 +319,7 @@ public sealed class Voss : AbstractBase
|
||||
}
|
||||
}
|
||||
|
||||
double vossVal = (double)(3 + order) / 2.0 * filt - sumC;
|
||||
double vossVal = ((double)(3 + order) / 2.0 * filt) - sumC;
|
||||
vossHistory[i] = vossVal;
|
||||
output[i] = vossVal;
|
||||
|
||||
|
||||
@@ -160,17 +160,17 @@ public sealed class Wiener : AbstractBase
|
||||
|
||||
// result = mean + k * (src - mean)
|
||||
double src0 = _buffer[^1];
|
||||
return mean + kp * (src0 - mean);
|
||||
return mean + (kp * (src0 - mean));
|
||||
}
|
||||
|
||||
public override void Prime(ReadOnlySpan<double> source, TimeSpan? step = null)
|
||||
{
|
||||
long initialTicks = DateTime.UtcNow.Ticks - source.Length * (step?.Ticks ?? TimeSpan.FromSeconds(1).Ticks);
|
||||
long initialTicks = DateTime.UtcNow.Ticks - (source.Length * (step?.Ticks ?? TimeSpan.FromSeconds(1).Ticks));
|
||||
TimeSpan increment = step ?? TimeSpan.FromSeconds(1);
|
||||
|
||||
for (int i = 0; i < source.Length; i++)
|
||||
{
|
||||
Update(new TValue(initialTicks + i * increment.Ticks, source[i]));
|
||||
Update(new TValue(initialTicks + (i * increment.Ticks), source[i]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -178,21 +178,21 @@ public sealed class Asi : ITValuePublisher
|
||||
double R;
|
||||
if (absHC >= absLC && absHC >= absHL)
|
||||
{
|
||||
R = Math.FusedMultiplyAdd(-0.5, absLC, absHC) + 0.25 * absC1O1;
|
||||
R = Math.FusedMultiplyAdd(-0.5, absLC, absHC) + (0.25 * absC1O1);
|
||||
}
|
||||
else if (absLC >= absHC && absLC >= absHL)
|
||||
{
|
||||
R = Math.FusedMultiplyAdd(-0.5, absHC, absLC) + 0.25 * absC1O1;
|
||||
R = Math.FusedMultiplyAdd(-0.5, absHC, absLC) + (0.25 * absC1O1);
|
||||
}
|
||||
else
|
||||
{
|
||||
R = absHL + 0.25 * absC1O1;
|
||||
R = absHL + (0.25 * absC1O1);
|
||||
}
|
||||
|
||||
if (R > 0.0)
|
||||
{
|
||||
// SI = 50 * [(C-C1) + 0.5*(C-O) + 0.25*(C1-O1)] / R * (K/T)
|
||||
double numerator = Math.FusedMultiplyAdd(0.5, close - open, close - prevClose) + 0.25 * (prevClose - prevOpen);
|
||||
double numerator = Math.FusedMultiplyAdd(0.5, close - open, close - prevClose) + (0.25 * (prevClose - prevOpen));
|
||||
si = 50.0 * numerator / R * (K / _limitMove);
|
||||
}
|
||||
}
|
||||
@@ -348,20 +348,20 @@ public sealed class Asi : ITValuePublisher
|
||||
double R;
|
||||
if (absHC >= absLC && absHC >= absHL)
|
||||
{
|
||||
R = Math.FusedMultiplyAdd(-0.5, absLC, absHC) + 0.25 * absC1O1;
|
||||
R = Math.FusedMultiplyAdd(-0.5, absLC, absHC) + (0.25 * absC1O1);
|
||||
}
|
||||
else if (absLC >= absHC && absLC >= absHL)
|
||||
{
|
||||
R = Math.FusedMultiplyAdd(-0.5, absHC, absLC) + 0.25 * absC1O1;
|
||||
R = Math.FusedMultiplyAdd(-0.5, absHC, absLC) + (0.25 * absC1O1);
|
||||
}
|
||||
else
|
||||
{
|
||||
R = absHL + 0.25 * absC1O1;
|
||||
R = absHL + (0.25 * absC1O1);
|
||||
}
|
||||
|
||||
if (R > 0.0)
|
||||
{
|
||||
double numerator = Math.FusedMultiplyAdd(0.5, c - o, c - pc) + 0.25 * (pc - po);
|
||||
double numerator = Math.FusedMultiplyAdd(0.5, c - o, c - pc) + (0.25 * (pc - po));
|
||||
si = 50.0 * numerator / R * (K / limitMove);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,11 +48,11 @@ public sealed class CfbIndicator : Indicator, IWatchlistIndicator
|
||||
protected override void OnInit()
|
||||
{
|
||||
// Generate lengths array
|
||||
int count = (MaxLength - MinLength) / Step + 1;
|
||||
int count = ((MaxLength - MinLength) / Step) + 1;
|
||||
int[] lengths = new int[count];
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
lengths[i] = MinLength + i * Step;
|
||||
lengths[i] = MinLength + (i * Step);
|
||||
}
|
||||
|
||||
_cfb = new Cfb(lengths);
|
||||
|
||||
@@ -299,7 +299,6 @@ public sealed class Cfb : ITValuePublisher, IDisposable
|
||||
return new TSeries(t, v);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the indicator state using the provided value series history.
|
||||
/// </summary>
|
||||
|
||||
@@ -170,7 +170,7 @@ public sealed class Rsx : ITValuePublisher
|
||||
double rsx;
|
||||
if (smoothedAbsMomentum > 1e-10)
|
||||
{
|
||||
double v4 = (smoothedMomentum / smoothedAbsMomentum + 1.0) * 50.0;
|
||||
double v4 = ((smoothedMomentum / smoothedAbsMomentum) + 1.0) * 50.0;
|
||||
rsx = Math.Clamp(v4, 0.0, 100.0);
|
||||
}
|
||||
else
|
||||
@@ -214,7 +214,6 @@ public sealed class Rsx : ITValuePublisher
|
||||
return new TSeries(t, v);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the indicator state using the provided series history.
|
||||
/// </summary>
|
||||
@@ -328,7 +327,7 @@ public sealed class Rsx : ITValuePublisher
|
||||
double rsx;
|
||||
if (smoothedAbsMomentum > 1e-10)
|
||||
{
|
||||
double v4 = (smoothedMomentum / smoothedAbsMomentum + 1.0) * 50.0;
|
||||
double v4 = ((smoothedMomentum / smoothedAbsMomentum) + 1.0) * 50.0;
|
||||
rsx = Math.Clamp(v4, 0.0, 100.0);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -176,11 +176,11 @@ public sealed class Sam : AbstractBase
|
||||
double price1 = s.Price0;
|
||||
double price0 = price;
|
||||
|
||||
double smoothPrice = (price0 + 2.0 * price1 + 2.0 * price2 + price3) / 6.0;
|
||||
double smoothPrice = (price0 + (2.0 * price1) + (2.0 * price2) + price3) / 6.0;
|
||||
|
||||
// ── Stage 2: Hilbert Transform ──
|
||||
// Adaptive bandwidth based on previous smooth period
|
||||
double bandwidth = 0.075 * s.DcPeriod + 0.54;
|
||||
double bandwidth = (0.075 * s.DcPeriod) + 0.54;
|
||||
|
||||
// Shift smooth price history
|
||||
double sp6 = s.Sp5;
|
||||
@@ -192,7 +192,7 @@ public sealed class Sam : AbstractBase
|
||||
double sp0 = smoothPrice;
|
||||
|
||||
// Detrender: Hilbert Transform of smooth price
|
||||
double detrender = (0.0962 * sp0 + 0.5769 * sp2 - 0.5769 * sp4 - 0.0962 * sp6) * bandwidth;
|
||||
double detrender = ((0.0962 * sp0) + (0.5769 * sp2) - (0.5769 * sp4) - (0.0962 * sp6)) * bandwidth;
|
||||
|
||||
// Shift detrender history
|
||||
double det6 = s.Det5;
|
||||
@@ -204,7 +204,7 @@ public sealed class Sam : AbstractBase
|
||||
double det0 = detrender;
|
||||
|
||||
// Q1 via Hilbert Transform of detrender
|
||||
double q1 = (0.0962 * det0 + 0.5769 * det2 - 0.5769 * det4 - 0.0962 * det6) * bandwidth;
|
||||
double q1 = ((0.0962 * det0) + (0.5769 * det2) - (0.5769 * det4) - (0.0962 * det6)) * bandwidth;
|
||||
|
||||
// I1 is detrender delayed by 3 bars
|
||||
double i1 = det3;
|
||||
@@ -229,10 +229,10 @@ public sealed class Sam : AbstractBase
|
||||
|
||||
// ── Stage 3: Phase advance ──
|
||||
// JI = Hilbert Transform of I1
|
||||
double ji = (0.0962 * i1_0 + 0.5769 * i1_2 - 0.5769 * i1_4 - 0.0962 * i1_6) * bandwidth;
|
||||
double ji = ((0.0962 * i1_0) + (0.5769 * i1_2) - (0.5769 * i1_4) - (0.0962 * i1_6)) * bandwidth;
|
||||
|
||||
// JQ = Hilbert Transform of Q1
|
||||
double jq = (0.0962 * q1_0 + 0.5769 * q1_2 - 0.5769 * q1_4 - 0.0962 * q1_6) * bandwidth;
|
||||
double jq = ((0.0962 * q1_0) + (0.5769 * q1_2) - (0.5769 * q1_4) - (0.0962 * q1_6)) * bandwidth;
|
||||
|
||||
// Phasor addition: I2 = I1 - JQ, Q2 = Q1 + JI
|
||||
double i2Raw = i1 - jq;
|
||||
|
||||
@@ -119,7 +119,6 @@ public sealed class Vel : ITValuePublisher, IDisposable
|
||||
return new TSeries(t, v);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the indicator state using the provided series history.
|
||||
/// </summary>
|
||||
|
||||
@@ -116,8 +116,8 @@ public sealed class Betadist : AbstractBase
|
||||
ser += LanczosCoeff[k] / (x + k);
|
||||
}
|
||||
|
||||
return 0.5 * Math.Log(2.0 * Math.PI)
|
||||
+ (x + 0.5) * Math.Log(t)
|
||||
return (0.5 * Math.Log(2.0 * Math.PI))
|
||||
+ ((x + 0.5) * Math.Log(t))
|
||||
- t
|
||||
+ Math.Log(ser);
|
||||
}
|
||||
@@ -161,7 +161,7 @@ public sealed class Betadist : AbstractBase
|
||||
|
||||
// ln-prefactor: cfX^cfA * (1-cfX)^cfB / (cfA * B(cfA,cfB))
|
||||
// B(a,b) = B(b,a) so the log-beta term is symmetric.
|
||||
double lnPrefactor = cfA * Math.Log(cfX) + cfB * Math.Log(1.0 - cfX)
|
||||
double lnPrefactor = (cfA * Math.Log(cfX)) + (cfB * Math.Log(1.0 - cfX))
|
||||
- Math.Log(cfA)
|
||||
- (LnGamma(cfA) + LnGamma(cfB) - LnGamma(cfA + cfB));
|
||||
|
||||
@@ -186,7 +186,7 @@ public sealed class Betadist : AbstractBase
|
||||
double qam = p - 1.0;
|
||||
|
||||
double c = 1.0;
|
||||
double d = 1.0 - qab * x / qap;
|
||||
double d = 1.0 - (qab * x / qap);
|
||||
if (Math.Abs(d) < FpMin)
|
||||
{
|
||||
d = FpMin;
|
||||
@@ -201,13 +201,13 @@ public sealed class Betadist : AbstractBase
|
||||
|
||||
// Even step: d_{2m}
|
||||
double aa = m * (q - m) * x / ((qam + m2) * (p + m2));
|
||||
d = 1.0 + aa * d;
|
||||
d = 1.0 + (aa * d);
|
||||
if (Math.Abs(d) < FpMin)
|
||||
{
|
||||
d = FpMin;
|
||||
}
|
||||
|
||||
c = 1.0 + aa / c;
|
||||
c = 1.0 + (aa / c);
|
||||
if (Math.Abs(c) < FpMin)
|
||||
{
|
||||
c = FpMin;
|
||||
@@ -218,13 +218,13 @@ public sealed class Betadist : AbstractBase
|
||||
|
||||
// Odd step: d_{2m+1}
|
||||
aa = -(p + m) * (qab + m) * x / ((p + m2) * (qap + m2));
|
||||
d = 1.0 + aa * d;
|
||||
d = 1.0 + (aa * d);
|
||||
if (Math.Abs(d) < FpMin)
|
||||
{
|
||||
d = FpMin;
|
||||
}
|
||||
|
||||
c = 1.0 + aa / c;
|
||||
c = 1.0 + (aa / c);
|
||||
if (Math.Abs(c) < FpMin)
|
||||
{
|
||||
c = FpMin;
|
||||
|
||||
@@ -108,8 +108,8 @@ public sealed class Binomdist : AbstractBase
|
||||
ser += LanczosCoeff[k] / (x + k);
|
||||
}
|
||||
|
||||
return 0.5 * Math.Log(2.0 * Math.PI)
|
||||
+ (x + 0.5) * Math.Log(t)
|
||||
return (0.5 * Math.Log(2.0 * Math.PI))
|
||||
+ ((x + 0.5) * Math.Log(t))
|
||||
- t
|
||||
+ Math.Log(ser);
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ public sealed class Cwt : AbstractBase
|
||||
}
|
||||
|
||||
int halfWindow = (int)Math.Round(3.0 * scale);
|
||||
_windowSize = 2 * halfWindow + 1;
|
||||
_windowSize = (2 * halfWindow) + 1;
|
||||
_normFactor = 1.0 / Math.Sqrt(scale);
|
||||
|
||||
// Precompute kernel: ψ(k/s) = exp(-k²/(2s²)) * (cos(ω₀k/s) - i·sin(ω₀k/s))
|
||||
@@ -104,7 +104,7 @@ public sealed class Cwt : AbstractBase
|
||||
double[] kernelReal, double[] kernelImag,
|
||||
int halfWindow, double scale, double omega0)
|
||||
{
|
||||
int windowSize = 2 * halfWindow + 1;
|
||||
int windowSize = (2 * halfWindow) + 1;
|
||||
double invScale = 1.0 / scale;
|
||||
for (int j = 0; j < windowSize; j++)
|
||||
{
|
||||
@@ -245,7 +245,7 @@ public sealed class Cwt : AbstractBase
|
||||
}
|
||||
|
||||
int halfWindow = (int)Math.Round(3.0 * scale);
|
||||
int windowSize = 2 * halfWindow + 1;
|
||||
int windowSize = (2 * halfWindow) + 1;
|
||||
double normFactor = 1.0 / Math.Sqrt(scale);
|
||||
double lastValid = 0.0;
|
||||
|
||||
|
||||
@@ -123,7 +123,7 @@ public sealed class Gammadist : AbstractBase
|
||||
}
|
||||
|
||||
double t = z + 7.5;
|
||||
return Math.FusedMultiplyAdd(z + 0.5, Math.Log(t), 0.5 * Math.Log(2.0 * Math.PI) - t + Math.Log(x));
|
||||
return Math.FusedMultiplyAdd(z + 0.5, Math.Log(t), (0.5 * Math.Log(2.0 * Math.PI)) - t + Math.Log(x));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -151,7 +151,7 @@ public sealed class Gammadist : AbstractBase
|
||||
}
|
||||
}
|
||||
|
||||
return sum * Math.Exp(-x + a * Math.Log(x) - lnGammaA);
|
||||
return sum * Math.Exp(-x + (a * Math.Log(x)) - lnGammaA);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -180,7 +180,7 @@ public sealed class Gammadist : AbstractBase
|
||||
d = FpMin;
|
||||
}
|
||||
|
||||
c = b + an / c;
|
||||
c = b + (an / c);
|
||||
if (Math.Abs(c) < FpMin)
|
||||
{
|
||||
c = FpMin;
|
||||
@@ -195,7 +195,7 @@ public sealed class Gammadist : AbstractBase
|
||||
}
|
||||
}
|
||||
|
||||
return Math.Exp(-x + a * Math.Log(x) - lnGammaA) * h;
|
||||
return Math.Exp(-x + (a * Math.Log(x)) - lnGammaA) * h;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -98,8 +98,8 @@ public sealed class Lognormdist : AbstractBase
|
||||
double az = Math.Abs(z);
|
||||
double t = 1.0 / Math.FusedMultiplyAdd(P, az, 1.0);
|
||||
double phi = Math.Exp(-0.5 * az * az) * (1.0 / Math.Sqrt(2.0 * Math.PI));
|
||||
double poly = ((((Math.FusedMultiplyAdd(B5, t, B4) * t) + B3) * t + B2) * t + B1) * t;
|
||||
double cdf = 1.0 - phi * poly;
|
||||
double poly = ((((((Math.FusedMultiplyAdd(B5, t, B4) * t) + B3) * t) + B2) * t) + B1) * t;
|
||||
double cdf = 1.0 - (phi * poly);
|
||||
return z >= 0.0 ? cdf : 1.0 - cdf;
|
||||
}
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@ public sealed class Normdist : AbstractBase
|
||||
double poly = Math.FusedMultiplyAdd(a3, t, a2);
|
||||
poly = Math.FusedMultiplyAdd(poly, t, a1);
|
||||
poly *= t;
|
||||
double val = 1.0 - poly * Math.Exp(-(ax * ax));
|
||||
double val = 1.0 - (poly * Math.Exp(-(ax * ax)));
|
||||
return x >= 0.0 ? val : -val;
|
||||
}
|
||||
|
||||
@@ -153,7 +153,7 @@ public sealed class Normdist : AbstractBase
|
||||
}
|
||||
|
||||
double mean = sum / count;
|
||||
double variance = sumSq / count - mean * mean;
|
||||
double variance = (sumSq / count) - (mean * mean);
|
||||
double stddev = variance > 0.0 ? Math.Sqrt(variance) : 0.0;
|
||||
return (mean, stddev, count);
|
||||
}
|
||||
@@ -305,7 +305,7 @@ public sealed class Normdist : AbstractBase
|
||||
else
|
||||
{
|
||||
double mean = sum / count;
|
||||
double variance = sumSq / count - mean * mean;
|
||||
double variance = (sumSq / count) - (mean * mean);
|
||||
double stddev = variance > 0.0 ? Math.Sqrt(variance) : 0.0;
|
||||
double z = stddev > 0.0 ? (val - mean) / stddev : 0.0;
|
||||
double zFinal = (z - mu) * invSigmaSqrt2;
|
||||
|
||||
@@ -121,7 +121,7 @@ public sealed class Poissondist : AbstractBase
|
||||
}
|
||||
|
||||
double t = z + 7.5;
|
||||
return Math.FusedMultiplyAdd(z + 0.5, Math.Log(t), 0.5 * Math.Log(2.0 * Math.PI) - t + Math.Log(x));
|
||||
return Math.FusedMultiplyAdd(z + 0.5, Math.Log(t), (0.5 * Math.Log(2.0 * Math.PI)) - t + Math.Log(x));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -149,7 +149,7 @@ public sealed class Poissondist : AbstractBase
|
||||
}
|
||||
}
|
||||
|
||||
return sum * Math.Exp(-x + a * Math.Log(x) - lnGammaA);
|
||||
return sum * Math.Exp(-x + (a * Math.Log(x)) - lnGammaA);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -178,7 +178,7 @@ public sealed class Poissondist : AbstractBase
|
||||
d = FpMin;
|
||||
}
|
||||
|
||||
c = b + an / c;
|
||||
c = b + (an / c);
|
||||
if (Math.Abs(c) < FpMin)
|
||||
{
|
||||
c = FpMin;
|
||||
@@ -193,7 +193,7 @@ public sealed class Poissondist : AbstractBase
|
||||
}
|
||||
}
|
||||
|
||||
return Math.Exp(-x + a * Math.Log(x) - lnGammaA) * h;
|
||||
return Math.Exp(-x + (a * Math.Log(x)) - lnGammaA) * h;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -89,7 +89,7 @@ public sealed class Tdist : AbstractBase
|
||||
double t2 = t * t;
|
||||
double bx = nuD / Math.FusedMultiplyAdd(1.0, t2, nuD); // ν / (ν + t²)
|
||||
double ibeta = Betadist.IncompleteBeta(bx, nuD * 0.5, 0.5);
|
||||
return t >= 0.0 ? 1.0 - 0.5 * ibeta : 0.5 * ibeta;
|
||||
return t >= 0.0 ? 1.0 - (0.5 * ibeta) : 0.5 * ibeta;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
|
||||
@@ -161,7 +161,6 @@ public sealed class Apo : ITValuePublisher, IDisposable
|
||||
Update(args.Value, args.IsNew);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the indicator state using the provided series history.
|
||||
/// </summary>
|
||||
|
||||
@@ -339,8 +339,8 @@ public sealed class Bbi : AbstractBase
|
||||
double old4 = b4[h4]; sum4 = c4 < p4 ? sum4 + val - old4 : sum4 - old4 + val; if (c4 < p4) { c4++; }
|
||||
b4[h4] = val; h4 = (h4 + 1) % p4;
|
||||
|
||||
output[i] = (sum1 / Math.Max(1, c1) + sum2 / Math.Max(1, c2)
|
||||
+ sum3 / Math.Max(1, c3) + sum4 / Math.Max(1, c4)) * 0.25;
|
||||
output[i] = ((sum1 / Math.Max(1, c1)) + (sum2 / Math.Max(1, c2))
|
||||
+ (sum3 / Math.Max(1, c3)) + (sum4 / Math.Max(1, c4))) * 0.25;
|
||||
}
|
||||
}
|
||||
finally
|
||||
|
||||
@@ -360,7 +360,6 @@ public sealed class Bbs : ITValuePublisher
|
||||
// === Bandwidth ===
|
||||
double bandwidth = bbMean != 0.0 ? ((bbUpper - bbLower) / bbMean) * 100.0 : 0.0; // skipcq: CS-R1077 - Exact-zero div guard: price avg
|
||||
|
||||
|
||||
// === IsHot ===
|
||||
if (!_state.IsHot && _state.Bars >= WarmupPeriod)
|
||||
{
|
||||
|
||||
@@ -56,8 +56,8 @@ public sealed class Cfo : AbstractBase
|
||||
WarmupPeriod = period;
|
||||
|
||||
_sumX = period * (period - 1) / 2.0;
|
||||
double sumX2 = period * (period - 1.0) * (2.0 * period - 1.0) / 6.0;
|
||||
_denomX = period * sumX2 - _sumX * _sumX;
|
||||
double sumX2 = period * (period - 1.0) * ((2.0 * period) - 1.0) / 6.0;
|
||||
_denomX = (period * sumX2) - (_sumX * _sumX);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -160,8 +160,8 @@ public sealed class Cfo : AbstractBase
|
||||
}
|
||||
|
||||
// Linear regression: slope, intercept, TSF
|
||||
double slope = (_period * _state.SumXY - _sumX * _state.SumY) / _denomX;
|
||||
double intercept = (_state.SumY - slope * _sumX) / _period;
|
||||
double slope = ((_period * _state.SumXY) - (_sumX * _state.SumY)) / _denomX;
|
||||
double intercept = (_state.SumY - (slope * _sumX)) / _period;
|
||||
double tsf = Math.FusedMultiplyAdd(slope, _period - 1, intercept);
|
||||
|
||||
// CFO = 100 * (source - tsf) / source
|
||||
@@ -265,8 +265,8 @@ public sealed class Cfo : AbstractBase
|
||||
}
|
||||
|
||||
double sumX = period * (period - 1) / 2.0;
|
||||
double sumX2 = period * (period - 1.0) * (2.0 * period - 1.0) / 6.0;
|
||||
double denomX = period * sumX2 - sumX * sumX;
|
||||
double sumX2 = period * (period - 1.0) * ((2.0 * period) - 1.0) / 6.0;
|
||||
double denomX = (period * sumX2) - (sumX * sumX);
|
||||
|
||||
double sumY = 0.0;
|
||||
double sumXY = 0.0;
|
||||
@@ -311,8 +311,8 @@ public sealed class Cfo : AbstractBase
|
||||
continue;
|
||||
}
|
||||
|
||||
double slope = (period * sumXY - sumX * sumY) / denomX;
|
||||
double intercept = (sumY - slope * sumX) / period;
|
||||
double slope = ((period * sumXY) - (sumX * sumY)) / denomX;
|
||||
double intercept = (sumY - (slope * sumX)) / period;
|
||||
double tsf = Math.FusedMultiplyAdd(slope, period - 1, intercept);
|
||||
|
||||
output[i] = val == 0.0 ? double.NaN : 100.0 * (val - tsf) / val; // skipcq: CS-R1077 - Exact-zero guard: val is a price; zero means no data, division by zero produces Infinity
|
||||
|
||||
@@ -203,7 +203,7 @@ public sealed class Coppock : ITValuePublisher
|
||||
{
|
||||
double oldPlain = plainSum;
|
||||
plainSum = plainSum - prevWma + combined;
|
||||
weightedSum = weightedSum - oldPlain + _wmaPeriod * combined;
|
||||
weightedSum = weightedSum - oldPlain + (_wmaPeriod * combined);
|
||||
coppockVal = weightedSum / _wmaNorm;
|
||||
}
|
||||
|
||||
@@ -357,7 +357,7 @@ public sealed class Coppock : ITValuePublisher
|
||||
{
|
||||
double oldPlain = plainSum;
|
||||
plainSum = plainSum - oldest + combined;
|
||||
weightedSum = weightedSum - oldPlain + wmaPeriod * combined;
|
||||
weightedSum = weightedSum - oldPlain + (wmaPeriod * combined);
|
||||
coppockVal = weightedSum / wmaNorm;
|
||||
}
|
||||
wmaBuf[wmaH] = combined;
|
||||
|
||||
@@ -63,7 +63,7 @@ public sealed class Cti : AbstractBase
|
||||
WarmupPeriod = period;
|
||||
|
||||
_sx = period * (period - 1) / 2.0;
|
||||
_sxx = period * (period - 1.0) * (2 * period - 1) / 6.0;
|
||||
_sxx = period * (period - 1.0) * ((2 * period) - 1) / 6.0;
|
||||
_denomX = Math.FusedMultiplyAdd(period, _sxx, -_sx * _sx);
|
||||
}
|
||||
|
||||
@@ -287,7 +287,7 @@ public sealed class Cti : AbstractBase
|
||||
}
|
||||
|
||||
double sx = period * (period - 1) / 2.0;
|
||||
double sxx = period * (period - 1.0) * (2 * period - 1) / 6.0;
|
||||
double sxx = period * (period - 1.0) * ((2 * period) - 1) / 6.0;
|
||||
double denomX = Math.FusedMultiplyAdd(period, sxx, -sx * sx);
|
||||
|
||||
double sumY = 0.0;
|
||||
|
||||
@@ -87,7 +87,7 @@ public sealed class Deco : AbstractBase
|
||||
|
||||
double argShort = rad / shortPeriod;
|
||||
double alphaShort = (Math.Cos(argShort) + Math.Sin(argShort) - 1.0) / Math.Cos(argShort);
|
||||
double oneMinusAlphaHalfShort = 1.0 - alphaShort * 0.5;
|
||||
double oneMinusAlphaHalfShort = 1.0 - (alphaShort * 0.5);
|
||||
double oneMinusAlphaShort = 1.0 - alphaShort;
|
||||
_a1Short = oneMinusAlphaHalfShort * oneMinusAlphaHalfShort;
|
||||
_b1Short = 2.0 * oneMinusAlphaShort;
|
||||
@@ -95,7 +95,7 @@ public sealed class Deco : AbstractBase
|
||||
|
||||
double argLong = rad / longPeriod;
|
||||
double alphaLong = (Math.Cos(argLong) + Math.Sin(argLong) - 1.0) / Math.Cos(argLong);
|
||||
double oneMinusAlphaHalfLong = 1.0 - alphaLong * 0.5;
|
||||
double oneMinusAlphaHalfLong = 1.0 - (alphaLong * 0.5);
|
||||
double oneMinusAlphaLong = 1.0 - alphaLong;
|
||||
_a1Long = oneMinusAlphaHalfLong * oneMinusAlphaHalfLong;
|
||||
_b1Long = 2.0 * oneMinusAlphaLong;
|
||||
@@ -153,7 +153,7 @@ public sealed class Deco : AbstractBase
|
||||
else
|
||||
{
|
||||
// HP[n] = a1*(x[n] - 2*x[n-1] + x[n-2]) + b1*HP[n-1] + c1*HP[n-2]
|
||||
double diff = value - 2.0 * s.Price1 + s.Price2;
|
||||
double diff = value - (2.0 * s.Price1) + s.Price2;
|
||||
hpShort = Math.FusedMultiplyAdd(_a1Short, diff, Math.FusedMultiplyAdd(_b1Short, s.HpShort1, _c1Short * s.HpShort2));
|
||||
hpLong = Math.FusedMultiplyAdd(_a1Long, diff, Math.FusedMultiplyAdd(_b1Long, s.HpLong1, _c1Long * s.HpLong2));
|
||||
|
||||
@@ -262,7 +262,7 @@ public sealed class Deco : AbstractBase
|
||||
|
||||
double argShort = rad / shortPeriod;
|
||||
double alphaShort = (Math.Cos(argShort) + Math.Sin(argShort) - 1.0) / Math.Cos(argShort);
|
||||
double omahShort = 1.0 - alphaShort * 0.5;
|
||||
double omahShort = 1.0 - (alphaShort * 0.5);
|
||||
double omaShort = 1.0 - alphaShort;
|
||||
double a1S = omahShort * omahShort;
|
||||
double b1S = 2.0 * omaShort;
|
||||
@@ -270,7 +270,7 @@ public sealed class Deco : AbstractBase
|
||||
|
||||
double argLong = rad / longPeriod;
|
||||
double alphaLong = (Math.Cos(argLong) + Math.Sin(argLong) - 1.0) / Math.Cos(argLong);
|
||||
double omahLong = 1.0 - alphaLong * 0.5;
|
||||
double omahLong = 1.0 - (alphaLong * 0.5);
|
||||
double omaLong = 1.0 - alphaLong;
|
||||
double a1L = omahLong * omahLong;
|
||||
double b1L = 2.0 * omaLong;
|
||||
@@ -291,7 +291,7 @@ public sealed class Deco : AbstractBase
|
||||
}
|
||||
else
|
||||
{
|
||||
double diff = val - 2.0 * price1 + price2;
|
||||
double diff = val - (2.0 * price1) + price2;
|
||||
double hpS = Math.FusedMultiplyAdd(a1S, diff, Math.FusedMultiplyAdd(b1S, hpS1, c1S * hpS2));
|
||||
double hpL = Math.FusedMultiplyAdd(a1L, diff, Math.FusedMultiplyAdd(b1L, hpL1, c1L * hpL2));
|
||||
output[i] = hpL - hpS;
|
||||
@@ -314,5 +314,4 @@ public sealed class Deco : AbstractBase
|
||||
var results = ind.Update(source);
|
||||
return (results, ind);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -277,7 +277,7 @@ public sealed class Dosc : AbstractBase
|
||||
s.AvgLoss = Math.FusedMultiplyAdd(rsiAlpha, changeDn, rsiDecay * s.AvgLoss);
|
||||
}
|
||||
|
||||
double rsiVal = s.AvgLoss == 0.0 ? 100.0 : 100.0 - 100.0 / (1.0 + s.AvgGain / s.AvgLoss);
|
||||
double rsiVal = s.AvgLoss == 0.0 ? 100.0 : 100.0 - (100.0 / (1.0 + (s.AvgGain / s.AvgLoss)));
|
||||
|
||||
// --- Stage 2: EMA1 of RSI ---
|
||||
double ema1;
|
||||
|
||||
@@ -194,7 +194,7 @@ public sealed class Dymoi : AbstractBase
|
||||
|
||||
int nShort = s.CountShort;
|
||||
double meanShort = s.SumShort / nShort;
|
||||
double varShort = s.SumSqShort / nShort - meanShort * meanShort;
|
||||
double varShort = (s.SumSqShort / nShort) - (meanShort * meanShort);
|
||||
double sdShort = varShort > 0.0 ? Math.Sqrt(varShort) : 0.0;
|
||||
|
||||
// ── Stage 1: StdDev long window (O(1) update) ──
|
||||
@@ -216,7 +216,7 @@ public sealed class Dymoi : AbstractBase
|
||||
|
||||
int nLong = s.CountLong;
|
||||
double meanLong = s.SumLong / nLong;
|
||||
double varLong = s.SumSqLong / nLong - meanLong * meanLong;
|
||||
double varLong = (s.SumSqLong / nLong) - (meanLong * meanLong);
|
||||
double sdLong = varLong > 0.0 ? Math.Sqrt(varLong) : 0.0;
|
||||
|
||||
// ── Stage 2: dynamic period ──
|
||||
@@ -442,7 +442,7 @@ public sealed class Dymoi : AbstractBase
|
||||
}
|
||||
|
||||
double meanS = sumShort / countShort;
|
||||
double varS = sumSqShort / countShort - meanS * meanS;
|
||||
double varS = (sumSqShort / countShort) - (meanS * meanS);
|
||||
double sdShort = varS > 0.0 ? Math.Sqrt(varS) : 0.0;
|
||||
|
||||
// Long StdDev update
|
||||
@@ -463,7 +463,7 @@ public sealed class Dymoi : AbstractBase
|
||||
}
|
||||
|
||||
double meanL = sumLong / countLong;
|
||||
double varL = sumSqLong / countLong - meanL * meanL;
|
||||
double varL = (sumSqLong / countLong) - (meanL * meanL);
|
||||
double sdLong = varL > 0.0 ? Math.Sqrt(varL) : 0.0;
|
||||
|
||||
// Dynamic period
|
||||
|
||||
@@ -58,8 +58,8 @@ public sealed class Inertia : AbstractBase
|
||||
WarmupPeriod = period;
|
||||
|
||||
_sumX = period * (period - 1) / 2.0;
|
||||
double sumX2 = period * (period - 1.0) * (2.0 * period - 1.0) / 6.0;
|
||||
_denomX = period * sumX2 - _sumX * _sumX;
|
||||
double sumX2 = period * (period - 1.0) * ((2.0 * period) - 1.0) / 6.0;
|
||||
_denomX = (period * sumX2) - (_sumX * _sumX);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -160,8 +160,8 @@ public sealed class Inertia : AbstractBase
|
||||
}
|
||||
|
||||
// Linear regression: slope, intercept, TSF
|
||||
double slope = (_period * _state.SumXY - _sumX * _state.SumY) / _denomX;
|
||||
double intercept = (_state.SumY - slope * _sumX) / _period;
|
||||
double slope = ((_period * _state.SumXY) - (_sumX * _state.SumY)) / _denomX;
|
||||
double intercept = (_state.SumY - (slope * _sumX)) / _period;
|
||||
double tsf = Math.FusedMultiplyAdd(slope, _period - 1, intercept);
|
||||
|
||||
// Inertia = source - TSF (raw residual, no normalization)
|
||||
@@ -265,8 +265,8 @@ public sealed class Inertia : AbstractBase
|
||||
}
|
||||
|
||||
double sumX = period * (period - 1) / 2.0;
|
||||
double sumX2 = period * (period - 1.0) * (2.0 * period - 1.0) / 6.0;
|
||||
double denomX = period * sumX2 - sumX * sumX;
|
||||
double sumX2 = period * (period - 1.0) * ((2.0 * period) - 1.0) / 6.0;
|
||||
double denomX = (period * sumX2) - (sumX * sumX);
|
||||
|
||||
double sumY = 0.0;
|
||||
double sumXY = 0.0;
|
||||
@@ -311,8 +311,8 @@ public sealed class Inertia : AbstractBase
|
||||
continue;
|
||||
}
|
||||
|
||||
double slope = (period * sumXY - sumX * sumY) / denomX;
|
||||
double intercept = (sumY - slope * sumX) / period;
|
||||
double slope = ((period * sumXY) - (sumX * sumY)) / denomX;
|
||||
double intercept = (sumY - (slope * sumX)) / period;
|
||||
double tsf = Math.FusedMultiplyAdd(slope, period - 1, intercept);
|
||||
|
||||
output[i] = val - tsf;
|
||||
|
||||
@@ -255,7 +255,7 @@ public sealed class Kst : ITValuePublisher
|
||||
|
||||
// ── KST composite (weighted sum, FMA for w1..w3) ─────────────────────
|
||||
double kstVal = Math.FusedMultiplyAdd(3.0, sm3, Math.FusedMultiplyAdd(2.0, sm2, sm1))
|
||||
+ 4.0 * sm4;
|
||||
+ (4.0 * sm4);
|
||||
|
||||
// ── Signal line (SMA of KST) ──────────────────────────────────────────
|
||||
double sigVal = StepSma(_sigBuf, ref sigSum, ref sigH, ref sigC, kstVal, _sigPeriod, isNew, out double prevSig);
|
||||
@@ -458,7 +458,7 @@ public sealed class Kst : ITValuePublisher
|
||||
double sm4 = BatchStepSma(sm4b, s4, ref sum4, ref sh4, ref sc4, roc4);
|
||||
|
||||
double kstVal = Math.FusedMultiplyAdd(3.0, sm3, Math.FusedMultiplyAdd(2.0, sm2, sm1))
|
||||
+ 4.0 * sm4;
|
||||
+ (4.0 * sm4);
|
||||
|
||||
sigOut[i] = BatchStepSma(sigb, sigPeriod, ref sumSig, ref shSig, ref scSig, kstVal);
|
||||
kstOut[i] = kstVal;
|
||||
|
||||
@@ -135,7 +135,7 @@ public sealed class Mstoch : ITValuePublisher
|
||||
// === Stage 1: Highpass (2-pole Butterworth, removes trend) ===
|
||||
// HP = c1*(src - 2*src1 + src2) + c2*hp1 + c3*hp2
|
||||
double hp = Math.FusedMultiplyAdd(
|
||||
_hpC1, src - 2.0 * s.Src1 + s.Src2,
|
||||
_hpC1, src - (2.0 * s.Src1) + s.Src2,
|
||||
Math.FusedMultiplyAdd(_hpC2, s.Hp1, _hpC3 * s.Hp2));
|
||||
|
||||
// === Stage 1: Super Smoother of HP => Filt ===
|
||||
@@ -332,7 +332,7 @@ public sealed class Mstoch : ITValuePublisher
|
||||
}
|
||||
|
||||
double hp = Math.FusedMultiplyAdd(
|
||||
hpC1, s - 2.0 * prevSrc1 + prevSrc2,
|
||||
hpC1, s - (2.0 * prevSrc1) + prevSrc2,
|
||||
Math.FusedMultiplyAdd(hpC2, prevHp1, hpC3 * prevHp2));
|
||||
|
||||
double filtIn = (hp + prevHp1) * 0.5;
|
||||
|
||||
@@ -222,7 +222,7 @@ public sealed class Trendflex : AbstractBase
|
||||
// Always use Add (not UpdateNewest) because Snapshot/Restore already handles rollback
|
||||
buf.Add(filt);
|
||||
int n = Math.Min(s.Count, period);
|
||||
double slopeSum = n > 0 ? (n * filt - buf.Sum) / period : 0.0;
|
||||
double slopeSum = n > 0 ? ((n * filt) - buf.Sum) / period : 0.0;
|
||||
|
||||
// --- RMS normalization ---
|
||||
s.Ms = Math.FusedMultiplyAdd(RMS_ALPHA, slopeSum * slopeSum, RMS_DECAY * s.Ms);
|
||||
@@ -272,7 +272,7 @@ public sealed class Trendflex : AbstractBase
|
||||
// Slope
|
||||
buf.Add(filt);
|
||||
int n = Math.Min(s.Count, period);
|
||||
double slopeSum = n > 0 ? (n * filt - buf.Sum) / period : 0.0;
|
||||
double slopeSum = n > 0 ? ((n * filt) - buf.Sum) / period : 0.0;
|
||||
|
||||
// RMS
|
||||
s.Ms = Math.FusedMultiplyAdd(RMS_ALPHA, slopeSum * slopeSum, RMS_DECAY * s.Ms);
|
||||
|
||||
@@ -424,7 +424,6 @@ public sealed class Ultosc : AbstractBase
|
||||
return (results, indicator);
|
||||
}
|
||||
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_bp1.Clear();
|
||||
|
||||
@@ -240,8 +240,8 @@ public sealed class Chandelier : ITValuePublisher
|
||||
double lowestLow = _minDequeLow.GetExtremum(_lBuf);
|
||||
|
||||
// Step 3: Chandelier exits — no second-stage smoothing
|
||||
ExitLong = highestHigh - _multiplier * atr;
|
||||
ExitShort = lowestLow + _multiplier * atr;
|
||||
ExitLong = highestHigh - (_multiplier * atr);
|
||||
ExitShort = lowestLow + (_multiplier * atr);
|
||||
|
||||
_s = s;
|
||||
|
||||
|
||||
@@ -241,8 +241,8 @@ public sealed class Ckstop : ITValuePublisher
|
||||
double lowestLow = _minDequeLow.GetExtremum(_lBuf);
|
||||
|
||||
// Step 2b: First (initial) stops
|
||||
double initStopShort = highestHigh - _multiplier * atr;
|
||||
double initStopLong = lowestLow + _multiplier * atr;
|
||||
double initStopShort = highestHigh - (_multiplier * atr);
|
||||
double initStopLong = lowestLow + (_multiplier * atr);
|
||||
|
||||
// Step 3: Track highest/lowest of initial stops over stopPeriod
|
||||
int sBufIdx = (int)(_index % _stopPeriod);
|
||||
|
||||
@@ -179,15 +179,15 @@ public sealed class Pivotdem : ITValuePublisher
|
||||
double x;
|
||||
if (pC < pO)
|
||||
{
|
||||
x = pH + 2.0 * pL + pC; // Bearish: weight Low
|
||||
x = pH + (2.0 * pL) + pC; // Bearish: weight Low
|
||||
}
|
||||
else if (pC > pO)
|
||||
{
|
||||
x = 2.0 * pH + pL + pC; // Bullish: weight High
|
||||
x = (2.0 * pH) + pL + pC; // Bullish: weight High
|
||||
}
|
||||
else
|
||||
{
|
||||
x = pH + pL + 2.0 * pC; // Doji: weight Close
|
||||
x = pH + pL + (2.0 * pC); // Doji: weight Close
|
||||
}
|
||||
|
||||
double halfX = x * 0.5;
|
||||
@@ -331,9 +331,9 @@ public sealed class Pivotdem : ITValuePublisher
|
||||
double pC = close[i - 1];
|
||||
|
||||
double x;
|
||||
if (pC < pO) { x = pH + 2.0 * pL + pC; }
|
||||
else if (pC > pO) { x = 2.0 * pH + pL + pC; }
|
||||
else { x = pH + pL + 2.0 * pC; }
|
||||
if (pC < pO) { x = pH + (2.0 * pL) + pC; }
|
||||
else if (pC > pO) { x = (2.0 * pH) + pL + pC; }
|
||||
else { x = pH + pL + (2.0 * pC); }
|
||||
|
||||
ppOutput[i] = x * 0.25;
|
||||
}
|
||||
@@ -403,9 +403,9 @@ public sealed class Pivotdem : ITValuePublisher
|
||||
double pC = close[i - 1];
|
||||
|
||||
double x;
|
||||
if (pC < pO) { x = pH + 2.0 * pL + pC; }
|
||||
else if (pC > pO) { x = 2.0 * pH + pL + pC; }
|
||||
else { x = pH + pL + 2.0 * pC; }
|
||||
if (pC < pO) { x = pH + (2.0 * pL) + pC; }
|
||||
else if (pC > pO) { x = (2.0 * pH) + pL + pC; }
|
||||
else { x = pH + pL + (2.0 * pC); }
|
||||
|
||||
double halfX = x * 0.5;
|
||||
ppOut[i] = x * 0.25;
|
||||
|
||||
@@ -101,7 +101,7 @@ public sealed class Swings : ITValuePublisher
|
||||
}
|
||||
|
||||
_lookback = lookback;
|
||||
_windowSize = 2 * lookback + 1;
|
||||
_windowSize = (2 * lookback) + 1;
|
||||
|
||||
_hBuf = new double[_windowSize];
|
||||
_lBuf = new double[_windowSize];
|
||||
@@ -361,7 +361,7 @@ public sealed class Swings : ITValuePublisher
|
||||
return;
|
||||
}
|
||||
|
||||
int windowSize = 2 * lookback + 1;
|
||||
int windowSize = (2 * lookback) + 1;
|
||||
|
||||
// Fill warmup bars with NaN
|
||||
int warmup = Math.Min(windowSize - 1, len);
|
||||
|
||||
@@ -189,7 +189,6 @@ public sealed class Granger : AbstractBase
|
||||
double oldY = _windowY.Oldest;
|
||||
double oldYLag = _windowYLag.Oldest;
|
||||
double oldXLag = _windowXLag.Oldest;
|
||||
|
||||
{ double yk = -oldY - _sumYComp; double t = _sumY + yk; _sumYComp = (t - _sumY) - yk; _sumY = t; }
|
||||
{ double yk = -oldYLag - _sumYLagComp; double t = _sumYLag + yk; _sumYLagComp = (t - _sumYLag) - yk; _sumYLag = t; }
|
||||
{ double yk = -oldXLag - _sumXLagComp; double t = _sumXLag + yk; _sumXLagComp = (t - _sumXLag) - yk; _sumXLag = t; }
|
||||
@@ -205,7 +204,6 @@ public sealed class Granger : AbstractBase
|
||||
_windowY.Add(y);
|
||||
_windowYLag.Add(yLag);
|
||||
_windowXLag.Add(xLag);
|
||||
|
||||
{ double yk = y - _sumYComp; double t = _sumY + yk; _sumYComp = (t - _sumY) - yk; _sumY = t; }
|
||||
{ double yk = yLag - _sumYLagComp; double t = _sumYLag + yk; _sumYLagComp = (t - _sumYLag) - yk; _sumYLag = t; }
|
||||
{ double yk = xLag - _sumXLagComp; double t = _sumXLag + yk; _sumXLagComp = (t - _sumXLag) - yk; _sumXLag = t; }
|
||||
|
||||
@@ -357,7 +357,7 @@ public sealed class Jb : AbstractBase
|
||||
double meanSq = mean * mean;
|
||||
|
||||
// m₂ = (Σx² - Σx²/n) / n
|
||||
double m2Numerator = sumSq - (sum * sum) / n;
|
||||
double m2Numerator = sumSq - ((sum * sum) / n);
|
||||
if (m2Numerator < Epsilon)
|
||||
{
|
||||
return 0;
|
||||
@@ -479,8 +479,8 @@ public sealed class Jb : AbstractBase
|
||||
// Kahan subtract old, add new
|
||||
{ double y = (val - oldVal) - sumComp; double t = sum + y; sumComp = (t - sum) - y; sum = t; }
|
||||
{ double y = (vSq - oSq) - sumSqComp; double t = sumSq + y; sumSqComp = (t - sumSq) - y; sumSq = t; }
|
||||
{ double y = (vSq * val - oSq * oldVal) - sumCuComp; double t = sumCu + y; sumCuComp = (t - sumCu) - y; sumCu = t; }
|
||||
{ double y = (vSq * vSq - oSq * oSq) - sumQuComp; double t = sumQu + y; sumQuComp = (t - sumQu) - y; sumQu = t; }
|
||||
{ double y = ((vSq * val) - (oSq * oldVal)) - sumCuComp; double t = sumCu + y; sumCuComp = (t - sumCu) - y; sumCu = t; }
|
||||
{ double y = ((vSq * vSq) - (oSq * oSq)) - sumQuComp; double t = sumQu + y; sumQuComp = (t - sumQu) - y; sumQu = t; }
|
||||
|
||||
output[i] = CalculateJbFromSums(sum, sumSq, sumCu, sumQu, period);
|
||||
}
|
||||
@@ -540,7 +540,7 @@ public sealed class Jb : AbstractBase
|
||||
var vEpsilon = Vector256.Create(Epsilon);
|
||||
var vZero = Vector256<double>.Zero;
|
||||
|
||||
int simdEnd = period + ((len - period) / VectorWidth) * VectorWidth;
|
||||
int simdEnd = period + (((len - period) / VectorWidth) * VectorWidth);
|
||||
|
||||
for (int i = period; i < simdEnd; i += VectorWidth)
|
||||
{
|
||||
|
||||
@@ -94,10 +94,10 @@ public sealed class LinReg : AbstractBase
|
||||
_sum_x = 0.5 * period * (period - 1);
|
||||
|
||||
// sum_x2 = 0^2 + ... + (n-1)^2 = (n-1)n(2n-1)/6
|
||||
double sum_x2 = (period - 1.0) * period * (2.0 * period - 1.0) / 6.0;
|
||||
double sum_x2 = (period - 1.0) * period * ((2.0 * period) - 1.0) / 6.0;
|
||||
|
||||
// denominator = n * sum_x2 - sum_x^2
|
||||
_denominator = period * sum_x2 - _sum_x * _sum_x;
|
||||
_denominator = (period * sum_x2) - (_sum_x * _sum_x);
|
||||
}
|
||||
|
||||
public LinReg(ITValuePublisher source, int period, int offset = 0) : this(period, offset)
|
||||
@@ -130,7 +130,7 @@ public sealed class LinReg : AbstractBase
|
||||
// O(1) update for sum_xy with Kahan compensation
|
||||
// sum_xy_new = sum_xy_old + sum_y_prev - n * oldest
|
||||
{
|
||||
double delta = prev_sum_y - _period * oldest;
|
||||
double delta = prev_sum_y - (_period * oldest);
|
||||
double y = delta - _state.SumXYComp;
|
||||
double t = _state.SumXY + y;
|
||||
_state.SumXYComp = (t - _state.SumXY) - y;
|
||||
@@ -148,7 +148,7 @@ public sealed class LinReg : AbstractBase
|
||||
|
||||
// O(1) update for sum_y2 with Kahan: subtract oldest², add val²
|
||||
{
|
||||
double delta = val * val - oldest * oldest;
|
||||
double delta = (val * val) - (oldest * oldest);
|
||||
double y = delta - _state.SumY2Comp;
|
||||
double t = _state.SumY2 + y;
|
||||
_state.SumY2Comp = (t - _state.SumY2) - y;
|
||||
@@ -235,8 +235,8 @@ public sealed class LinReg : AbstractBase
|
||||
if (!_buffer.IsFull)
|
||||
{
|
||||
sx = 0.5 * n * (n - 1);
|
||||
double sx2 = (n - 1.0) * n * (2.0 * n - 1.0) / 6.0;
|
||||
denom = n * sx2 - sx * sx;
|
||||
double sx2 = (n - 1.0) * n * ((2.0 * n) - 1.0) / 6.0;
|
||||
denom = (n * sx2) - (sx * sx);
|
||||
}
|
||||
|
||||
if (Math.Abs(denom) < MinDenominator)
|
||||
@@ -379,7 +379,6 @@ public sealed class LinReg : AbstractBase
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
double sum_y = 0;
|
||||
double sum_xy = 0;
|
||||
double sumYComp = 0; // Kahan compensation for sum_y
|
||||
@@ -389,8 +388,8 @@ public sealed class LinReg : AbstractBase
|
||||
int count = 0;
|
||||
|
||||
double full_sum_x = 0.5 * period * (period - 1);
|
||||
double full_sum_x2 = (period - 1.0) * period * (2.0 * period - 1.0) / 6.0;
|
||||
double full_denom = period * full_sum_x2 - full_sum_x * full_sum_x;
|
||||
double full_sum_x2 = (period - 1.0) * period * ((2.0 * period) - 1.0) / 6.0;
|
||||
double full_denom = (period * full_sum_x2) - (full_sum_x * full_sum_x);
|
||||
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
@@ -424,8 +423,8 @@ public sealed class LinReg : AbstractBase
|
||||
{
|
||||
double n = count;
|
||||
double sx = 0.5 * n * (n - 1);
|
||||
double sx2 = (n - 1.0) * n * (2.0 * n - 1.0) / 6.0;
|
||||
double denom = n * sx2 - sx * sx;
|
||||
double sx2 = (n - 1.0) * n * ((2.0 * n) - 1.0) / 6.0;
|
||||
double denom = (n * sx2) - (sx * sx);
|
||||
|
||||
if (Math.Abs(denom) < MinDenominator)
|
||||
{
|
||||
@@ -454,7 +453,7 @@ public sealed class LinReg : AbstractBase
|
||||
|
||||
// Kahan compensated update for sum_xy
|
||||
{
|
||||
double delta = prev_sum_y - period * oldest;
|
||||
double delta = prev_sum_y - (period * oldest);
|
||||
double y = delta - sumXYComp;
|
||||
double t = sum_xy + y;
|
||||
sumXYComp = (t - sum_xy) - y;
|
||||
|
||||
@@ -263,7 +263,7 @@ public sealed class Pacf : AbstractBase
|
||||
// Update coefficients: φ_kj = φ_{k-1,j} - φ_kk * φ_{k-1,k-j}
|
||||
for (int j = 1; j < k; j++)
|
||||
{
|
||||
phi[j] = phiPrev[j] - phi[k] * phiPrev[k - j];
|
||||
phi[j] = phiPrev[j] - (phi[k] * phiPrev[k - j]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -100,7 +100,7 @@ public sealed class Polyfit : AbstractBase
|
||||
|
||||
// Power sums and cross products accumulate with normalized t ∈ [0, 1].
|
||||
// Max degree=6 → sz=7, matrix=7*8=56 doubles + powSums=13 + crossSums=7 — all stackalloc safe.
|
||||
Span<double> powSums = stackalloc double[2 * m + 1];
|
||||
Span<double> powSums = stackalloc double[(2 * m) + 1];
|
||||
Span<double> crossSums = stackalloc double[sz];
|
||||
Span<double> aug = stackalloc double[sz * (sz + 1)]; // augmented matrix row-major
|
||||
|
||||
@@ -133,19 +133,19 @@ public sealed class Polyfit : AbstractBase
|
||||
{
|
||||
for (int col = 0; col < sz; col++)
|
||||
{
|
||||
aug[row * stride + col] = powSums[row + col];
|
||||
aug[(row * stride) + col] = powSums[row + col];
|
||||
}
|
||||
aug[row * stride + sz] = crossSums[row];
|
||||
aug[(row * stride) + sz] = crossSums[row];
|
||||
}
|
||||
|
||||
// Gaussian elimination with partial pivoting
|
||||
for (int col = 0; col < sz; col++)
|
||||
{
|
||||
int pivotRow = col;
|
||||
double pivotMax = Math.Abs(aug[col * stride + col]);
|
||||
double pivotMax = Math.Abs(aug[(col * stride) + col]);
|
||||
for (int row = col + 1; row < sz; row++)
|
||||
{
|
||||
double absVal = Math.Abs(aug[row * stride + col]);
|
||||
double absVal = Math.Abs(aug[(row * stride) + col]);
|
||||
if (absVal > pivotMax)
|
||||
{
|
||||
pivotMax = absVal;
|
||||
@@ -168,13 +168,13 @@ public sealed class Polyfit : AbstractBase
|
||||
}
|
||||
}
|
||||
|
||||
double diag = aug[col * stride + col];
|
||||
double diag = aug[(col * stride) + col];
|
||||
for (int row = col + 1; row < sz; row++)
|
||||
{
|
||||
double factor = aug[row * stride + col] / diag;
|
||||
double factor = aug[(row * stride) + col] / diag;
|
||||
for (int k = col; k <= sz; k++)
|
||||
{
|
||||
aug[row * stride + k] = Math.FusedMultiplyAdd(-factor, aug[col * stride + k], aug[row * stride + k]);
|
||||
aug[(row * stride) + k] = Math.FusedMultiplyAdd(-factor, aug[(col * stride) + k], aug[(row * stride) + k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -183,12 +183,12 @@ public sealed class Polyfit : AbstractBase
|
||||
Span<double> a = stackalloc double[sz];
|
||||
for (int row = sz - 1; row >= 0; row--)
|
||||
{
|
||||
double val = aug[row * stride + sz];
|
||||
double val = aug[(row * stride) + sz];
|
||||
for (int k = row + 1; k < sz; k++)
|
||||
{
|
||||
val = Math.FusedMultiplyAdd(-aug[row * stride + k], a[k], val);
|
||||
val = Math.FusedMultiplyAdd(-aug[(row * stride) + k], a[k], val);
|
||||
}
|
||||
a[row] = val / aug[row * stride + row];
|
||||
a[row] = val / aug[(row * stride) + row];
|
||||
}
|
||||
|
||||
// Evaluate polynomial at t=1: P(1) = a0 + a1 + a2 + ... + am
|
||||
|
||||
@@ -81,8 +81,8 @@ public sealed class Stderr : AbstractBase
|
||||
|
||||
// Precompute fixed regression constants
|
||||
_sumX = 0.5 * period * (period - 1);
|
||||
_sumX2 = (period - 1.0) * period * (2.0 * period - 1.0) / 6.0;
|
||||
_denom = period * _sumX2 - _sumX * _sumX;
|
||||
_sumX2 = (period - 1.0) * period * ((2.0 * period) - 1.0) / 6.0;
|
||||
_denom = (period * _sumX2) - (_sumX * _sumX);
|
||||
}
|
||||
|
||||
/// <summary>Creates a chaining constructor that subscribes to an upstream publisher.</summary>
|
||||
@@ -133,7 +133,7 @@ public sealed class Stderr : AbstractBase
|
||||
|
||||
// Correct running sums for newest bar change
|
||||
_sumY = _p_sumY - _p_lastVal + val;
|
||||
_sumXY = _p_sumXY - (_period - 1) * (_p_lastVal - val);
|
||||
_sumXY = _p_sumXY - ((_period - 1) * (_p_lastVal - val));
|
||||
// Re-derive sumXY correctly via recalculation to avoid drift on bar corrections
|
||||
if (_buffer.Count > 0)
|
||||
{
|
||||
@@ -211,7 +211,7 @@ public sealed class Stderr : AbstractBase
|
||||
// O(1) update for sumXY with Kahan compensation
|
||||
// ΣXY_new = ΣXY_old - ΣY_old + oldest + (N-1)*val
|
||||
{
|
||||
double delta = -prevSumY + oldest + (_period - 1) * val;
|
||||
double delta = -prevSumY + oldest + ((_period - 1) * val);
|
||||
double y = delta - _sumXYComp;
|
||||
double t = _sumXY + y;
|
||||
_sumXYComp = (t - _sumXY) - y;
|
||||
@@ -266,16 +266,16 @@ public sealed class Stderr : AbstractBase
|
||||
double sumY = _sumY;
|
||||
double sumXY = _sumXY;
|
||||
double sumX = (n == _period) ? _sumX : 0.5 * n * (n - 1);
|
||||
double sumX2 = (n == _period) ? _sumX2 : (n - 1.0) * n * (2.0 * n - 1.0) / 6.0;
|
||||
double denom = (n == _period) ? _denom : n * sumX2 - sumX * sumX;
|
||||
double sumX2 = (n == _period) ? _sumX2 : (n - 1.0) * n * ((2.0 * n) - 1.0) / 6.0;
|
||||
double denom = (n == _period) ? _denom : (n * sumX2) - (sumX * sumX);
|
||||
|
||||
if (denom == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
double slope = (n * sumXY - sumX * sumY) / denom;
|
||||
double intercept = (sumY - slope * sumX) / n;
|
||||
double slope = ((n * sumXY) - (sumX * sumY)) / denom;
|
||||
double intercept = (sumY - (slope * sumX)) / n;
|
||||
|
||||
// O(N): accumulate residual sum of squares
|
||||
double ssr = 0;
|
||||
@@ -437,8 +437,8 @@ public sealed class Stderr : AbstractBase
|
||||
|
||||
// Precompute constants for full period window
|
||||
double sumXFull = 0.5 * period * (period - 1);
|
||||
double sumX2Full = (period - 1.0) * period * (2.0 * period - 1.0) / 6.0;
|
||||
double denomFull = period * sumX2Full - sumXFull * sumXFull;
|
||||
double sumX2Full = (period - 1.0) * period * ((2.0 * period) - 1.0) / 6.0;
|
||||
double denomFull = (period * sumX2Full) - (sumXFull * sumXFull);
|
||||
|
||||
double sumY = 0;
|
||||
double sumXY = 0;
|
||||
@@ -480,7 +480,7 @@ public sealed class Stderr : AbstractBase
|
||||
|
||||
// O(1) Kahan compensated update for sumXY
|
||||
{
|
||||
double delta = -sumY + oldest + (period - 1) * newest;
|
||||
double delta = -sumY + oldest + ((period - 1) * newest);
|
||||
double y = delta - sumXYComp;
|
||||
double t = sumXY + y;
|
||||
sumXYComp = (t - sumXY) - y;
|
||||
@@ -496,8 +496,8 @@ public sealed class Stderr : AbstractBase
|
||||
sumY = t;
|
||||
}
|
||||
|
||||
double slope = (period * sumXY - sumXFull * sumY) / denomFull;
|
||||
double intercept = (sumY - slope * sumXFull) / period;
|
||||
double slope = ((period * sumXY) - (sumXFull * sumY)) / denomFull;
|
||||
double intercept = (sumY - (slope * sumXFull)) / period;
|
||||
|
||||
double ssr = 0;
|
||||
int start = i - period + 1;
|
||||
@@ -529,16 +529,16 @@ public sealed class Stderr : AbstractBase
|
||||
}
|
||||
|
||||
double sumX = 0.5 * n * (n - 1);
|
||||
double sumX2 = (n - 1.0) * n * (2.0 * n - 1.0) / 6.0;
|
||||
double denom = n * sumX2 - sumX * sumX;
|
||||
double sumX2 = (n - 1.0) * n * ((2.0 * n) - 1.0) / 6.0;
|
||||
double denom = (n * sumX2) - (sumX * sumX);
|
||||
|
||||
if (denom == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
double slope = (n * sumXY - sumX * sumY) / denom;
|
||||
double intercept = (sumY - slope * sumX) / n;
|
||||
double slope = ((n * sumXY) - (sumX * sumY)) / denom;
|
||||
double intercept = (sumY - (slope * sumX)) / n;
|
||||
|
||||
double ssr = 0;
|
||||
for (int k = 0; k < n; k++)
|
||||
|
||||
@@ -314,7 +314,7 @@ public sealed class Trim : AbstractBase
|
||||
}
|
||||
|
||||
int trimCount = (int)(count * trimPct / 100.0);
|
||||
int keepCount = count - 2 * trimCount;
|
||||
int keepCount = count - (2 * trimCount);
|
||||
|
||||
if (keepCount < 1)
|
||||
{
|
||||
@@ -341,7 +341,7 @@ public sealed class Trim : AbstractBase
|
||||
}
|
||||
|
||||
int trimCount = (int)(count * trimPct / 100.0);
|
||||
int keepCount = count - 2 * trimCount;
|
||||
int keepCount = count - (2 * trimCount);
|
||||
|
||||
if (keepCount < 1)
|
||||
{
|
||||
|
||||
@@ -306,7 +306,7 @@ public sealed class Variance : AbstractBase
|
||||
}
|
||||
// Kahan sliding window for sumSq: sumSq += (val² - oldVal²)
|
||||
{
|
||||
double delta = (val * val - oldVal * oldVal) - sumSqComp;
|
||||
double delta = ((val * val) - (oldVal * oldVal)) - sumSqComp;
|
||||
double t = sumSq + delta;
|
||||
sumSqComp = (t - sumSq) - delta;
|
||||
sumSq = t;
|
||||
|
||||
@@ -127,7 +127,7 @@ public sealed class Zscore : AbstractBase
|
||||
double sum = _buffer.Sum;
|
||||
double mean = sum / n;
|
||||
|
||||
double numerator = _sumSq - (sum * sum) / n;
|
||||
double numerator = _sumSq - ((sum * sum) / n);
|
||||
if (numerator < 0)
|
||||
{
|
||||
numerator = 0;
|
||||
@@ -317,7 +317,7 @@ public sealed class Zscore : AbstractBase
|
||||
int n = count;
|
||||
double mean = sum / n;
|
||||
|
||||
double numerator = sumSq - (sum * sum) / n;
|
||||
double numerator = sumSq - ((sum * sum) / n);
|
||||
if (numerator < 0)
|
||||
{
|
||||
numerator = 0;
|
||||
|
||||
@@ -132,7 +132,7 @@ public sealed class Ztest : AbstractBase
|
||||
double sum = _buffer.Sum;
|
||||
double mean = sum / n;
|
||||
|
||||
double numerator = _sumSq - (sum * sum) / n;
|
||||
double numerator = _sumSq - ((sum * sum) / n);
|
||||
if (numerator < 0)
|
||||
{
|
||||
numerator = 0;
|
||||
@@ -325,7 +325,7 @@ public sealed class Ztest : AbstractBase
|
||||
int n = count;
|
||||
double mean = sum / n;
|
||||
|
||||
double numerator = sumSq - (sum * sum) / n;
|
||||
double numerator = sumSq - ((sum * sum) / n);
|
||||
if (numerator < 0)
|
||||
{
|
||||
numerator = 0;
|
||||
|
||||
@@ -59,7 +59,7 @@ public sealed class Bwma : AbstractBase
|
||||
|
||||
_period = period;
|
||||
_order = order;
|
||||
_power = order * 0.5 + 0.5;
|
||||
_power = (order * 0.5) + 0.5;
|
||||
_buffer = new RingBuffer(period);
|
||||
_weights = new double[period];
|
||||
Name = $"Bwma({period}, {order})";
|
||||
@@ -101,12 +101,12 @@ public sealed class Bwma : AbstractBase
|
||||
{
|
||||
double sum = 0;
|
||||
double scale = period > 1 ? 2.0 / (period - 1) : 0.0;
|
||||
double power = order * 0.5 + 0.5;
|
||||
double power = (order * 0.5) + 0.5;
|
||||
|
||||
for (int i = 0; i < period; i++)
|
||||
{
|
||||
double x = period > 1 ? i * scale - 1.0 : 0.0;
|
||||
double arg = 1.0 - x * x;
|
||||
double x = period > 1 ? (i * scale) - 1.0 : 0.0;
|
||||
double arg = 1.0 - (x * x);
|
||||
|
||||
double w;
|
||||
if (arg > 0.0)
|
||||
@@ -366,7 +366,7 @@ public sealed class Bwma : AbstractBase
|
||||
return;
|
||||
}
|
||||
|
||||
double power = order * 0.5 + 0.5;
|
||||
double power = (order * 0.5) + 0.5;
|
||||
|
||||
if (period > len)
|
||||
{
|
||||
|
||||
@@ -120,10 +120,10 @@ public sealed class Crma : AbstractBase
|
||||
{
|
||||
// Find pivot row
|
||||
int pivotRow = col;
|
||||
double pivotMax = Math.Abs(m[col * 5 + col]);
|
||||
double pivotMax = Math.Abs(m[(col * 5) + col]);
|
||||
for (int row = col + 1; row < 4; row++)
|
||||
{
|
||||
double absVal = Math.Abs(m[row * 5 + col]);
|
||||
double absVal = Math.Abs(m[(row * 5) + col]);
|
||||
if (absVal > pivotMax)
|
||||
{
|
||||
pivotMax = absVal;
|
||||
@@ -148,13 +148,13 @@ public sealed class Crma : AbstractBase
|
||||
}
|
||||
|
||||
// Eliminate below
|
||||
double diag = m[col * 5 + col];
|
||||
double diag = m[(col * 5) + col];
|
||||
for (int row = col + 1; row < 4; row++)
|
||||
{
|
||||
double factor = m[row * 5 + col] / diag;
|
||||
double factor = m[(row * 5) + col] / diag;
|
||||
for (int k = col; k < 5; k++)
|
||||
{
|
||||
m[row * 5 + k] = Math.FusedMultiplyAdd(-factor, m[col * 5 + k], m[row * 5 + k]);
|
||||
m[(row * 5) + k] = Math.FusedMultiplyAdd(-factor, m[(col * 5) + k], m[(row * 5) + k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -163,12 +163,12 @@ public sealed class Crma : AbstractBase
|
||||
Span<double> a = stackalloc double[4];
|
||||
for (int row = 3; row >= 0; row--)
|
||||
{
|
||||
double val = m[row * 5 + 4];
|
||||
double val = m[(row * 5) + 4];
|
||||
for (int k = row + 1; k < 4; k++)
|
||||
{
|
||||
val = Math.FusedMultiplyAdd(-m[row * 5 + k], a[k], val);
|
||||
val = Math.FusedMultiplyAdd(-m[(row * 5) + k], a[k], val);
|
||||
}
|
||||
a[row] = val / m[row * 5 + row];
|
||||
a[row] = val / m[(row * 5) + row];
|
||||
}
|
||||
|
||||
return a[0]; // Fitted value at x=0 (newest bar)
|
||||
|
||||
@@ -109,7 +109,7 @@ public sealed class Hamma : AbstractBase
|
||||
double twoPiOverPm1 = 2.0 * Math.PI / (period - 1);
|
||||
for (int i = 0; i < period; i++)
|
||||
{
|
||||
double w = 0.54 - 0.46 * Math.Cos(twoPiOverPm1 * i);
|
||||
double w = 0.54 - (0.46 * Math.Cos(twoPiOverPm1 * i));
|
||||
weights[i] = w;
|
||||
sum += w;
|
||||
}
|
||||
|
||||
@@ -80,14 +80,14 @@ public sealed class Hend : AbstractBase
|
||||
double n2 = n * n;
|
||||
double nm1_2 = (n - 1) * (n - 1);
|
||||
double np1_2 = (n + 1) * (n + 1);
|
||||
double denom = 8.0 * n * (n2 - 1) * (4 * n2 - 1) * (4 * n2 - 9) * (4 * n2 - 25);
|
||||
double denom = 8.0 * n * (n2 - 1) * ((4 * n2) - 1) * ((4 * n2) - 9) * ((4 * n2) - 25);
|
||||
|
||||
double wsum = 0.0;
|
||||
for (int i = 0; i < period; i++)
|
||||
{
|
||||
int k = i - half;
|
||||
double k2 = (double)(k * k);
|
||||
double w = 315.0 * (nm1_2 - k2) * (n2 - k2) * (np1_2 - k2) * (3 * n2 - 16 - 11 * k2) / denom;
|
||||
double w = 315.0 * (nm1_2 - k2) * (n2 - k2) * (np1_2 - k2) * ((3 * n2) - 16 - (11 * k2)) / denom;
|
||||
weights[i] = w;
|
||||
wsum += w;
|
||||
}
|
||||
|
||||
@@ -63,8 +63,8 @@ public sealed class Ilrs : AbstractBase
|
||||
|
||||
// Precompute constants (reversed-x convention: x=0=newest, x=n-1=oldest)
|
||||
_sumX = 0.5 * period * (period - 1);
|
||||
double sumX2 = (period - 1.0) * period * (2.0 * period - 1.0) / 6.0;
|
||||
_denominator = period * sumX2 - _sumX * _sumX;
|
||||
double sumX2 = (period - 1.0) * period * ((2.0 * period) - 1.0) / 6.0;
|
||||
_denominator = (period * sumX2) - (_sumX * _sumX);
|
||||
_s.LastValidValue = double.NaN;
|
||||
}
|
||||
|
||||
@@ -239,8 +239,8 @@ public sealed class Ilrs : AbstractBase
|
||||
{
|
||||
double nd = n;
|
||||
sx = 0.5 * nd * (nd - 1);
|
||||
double sx2 = (nd - 1.0) * nd * (2.0 * nd - 1.0) / 6.0;
|
||||
denom = nd * sx2 - sx * sx;
|
||||
double sx2 = (nd - 1.0) * nd * ((2.0 * nd) - 1.0) / 6.0;
|
||||
denom = (nd * sx2) - (sx * sx);
|
||||
}
|
||||
|
||||
if (Math.Abs(denom) < 1e-10)
|
||||
@@ -305,8 +305,8 @@ public sealed class Ilrs : AbstractBase
|
||||
|
||||
// Precalculate constants for full period
|
||||
double fullSumX = 0.5 * period * (period - 1);
|
||||
double fullSumX2 = (period - 1.0) * period * (2.0 * period - 1.0) / 6.0;
|
||||
double fullDenom = period * fullSumX2 - fullSumX * fullSumX;
|
||||
double fullSumX2 = (period - 1.0) * period * ((2.0 * period) - 1.0) / 6.0;
|
||||
double fullDenom = (period * fullSumX2) - (fullSumX * fullSumX);
|
||||
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
@@ -345,8 +345,8 @@ public sealed class Ilrs : AbstractBase
|
||||
{
|
||||
double n = count;
|
||||
double sx = 0.5 * n * (n - 1);
|
||||
double sx2 = (n - 1.0) * n * (2.0 * n - 1.0) / 6.0;
|
||||
double denom = n * sx2 - sx * sx;
|
||||
double sx2 = (n - 1.0) * n * ((2.0 * n) - 1.0) / 6.0;
|
||||
double denom = (n * sx2) - (sx * sx);
|
||||
|
||||
if (Math.Abs(denom) < 1e-10)
|
||||
{
|
||||
|
||||
@@ -105,7 +105,7 @@ public sealed class Kaiser : AbstractBase
|
||||
for (int k = 0; k < period; k++)
|
||||
{
|
||||
double t = nm1 > 0 ? (2.0 * k / nm1) - 1.0 : 0.0;
|
||||
double argSq = 1.0 - t * t;
|
||||
double argSq = 1.0 - (t * t);
|
||||
double arg = argSq > 0 ? Math.Sqrt(argSq) : 0.0;
|
||||
double w = i0Beta > 0 ? BesselI0(beta * arg) / i0Beta : 1.0;
|
||||
weights[k] = w;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user