[CodeFactor] Apply fixes to commit 9697fac

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

Some files were not shown because too many files have changed in this diff Show More