This commit is contained in:
Miha Kralj
2026-03-17 09:26:27 -07:00
7 changed files with 31 additions and 31 deletions
+6 -6
View File
@@ -111,7 +111,7 @@ public sealed class Hwc : AbstractBase
_decayGamma = 1.0 - gamma;
_multiplier = multiplier;
int effectivePeriod = Math.Max((int)(2.0 / alpha - 1.0), 1);
int effectivePeriod = Math.Max((int)((2.0 / alpha) - 1.0), 1);
WarmupPeriod = effectivePeriod;
Name = $"Hwc({alpha:F3},{beta:F3},{gamma:F3},{multiplier:F1})";
_state = new State(double.NaN, 0, 0, 0, double.NaN, false);
@@ -179,7 +179,7 @@ public sealed class Hwc : AbstractBase
double prevA = _state.A;
// HWMA: F = α×src + (1−α)×(prevF + prevV + 0.5×prevA)
double forecast = prevF + prevV + 0.5 * prevA;
double forecast = prevF + prevV + (0.5 * prevA);
double newF = Math.FusedMultiplyAdd(forecast, _decayAlpha, _alpha * val);
// V = β×(F prevF) + (1−β)×(prevV + prevA)
@@ -188,7 +188,7 @@ public sealed class Hwc : AbstractBase
// A = γ×(V prevV) + (1−γ)×prevA
double newA = Math.FusedMultiplyAdd(prevA, _decayGamma, _gamma * (newV - prevV));
result = newF + newV + 0.5 * newA;
result = newF + newV + (0.5 * newA);
// Adaptive volatility filter: filt = α×(src forecast)² + (1−α)×prevFilt
double err = val - forecast;
@@ -240,7 +240,7 @@ public sealed class Hwc : AbstractBase
for (int i = 0; i < source.Length; i++)
{
Update(new TValue(startTime + i * step.Value, source[i]), isNew: true);
Update(new TValue(startTime + (i * step.Value), source[i]), isNew: true);
}
}
@@ -299,11 +299,11 @@ public sealed class Hwc : AbstractBase
}
else
{
double forecast = f + v + 0.5 * a;
double forecast = f + v + (0.5 * a);
double newF = Math.FusedMultiplyAdd(forecast, dA, alpha * val);
double newV = Math.FusedMultiplyAdd(v + a, dB, beta * (newF - f));
double newA = Math.FusedMultiplyAdd(a, dG, gamma * (newV - v));
result = newF + newV + 0.5 * newA;
result = newF + newV + (0.5 * newA);
double err = val - forecast;
filt = Math.FusedMultiplyAdd(err * err, alpha, filt * dA);
+1 -1
View File
@@ -174,7 +174,7 @@ public sealed class HwcTests
// Low volatility: small oscillation
indCalm.Update(new TValue(DateTime.UtcNow.AddMinutes(i), 100.0 + Math.Sin(i * 0.1)));
// High volatility: large oscillation
indVolatile.Update(new TValue(DateTime.UtcNow.AddMinutes(i), 100.0 + Math.Sin(i * 0.1) * 20));
indVolatile.Update(new TValue(DateTime.UtcNow.AddMinutes(i), 100.0 + (Math.Sin(i * 0.1) * 20)));
}
double widthCalm = indCalm.Upper.Value - indCalm.Lower.Value;
+4 -4
View File
@@ -74,7 +74,7 @@ public sealed class VwmacdTests
var ind = new Vwmacd(fastPeriod: 3, slowPeriod: 5, signalPeriod: 3);
for (int i = 0; i < 20; i++)
{
var bar = new TBar(DateTime.UtcNow.AddMinutes(i), 100 + i, 105 + i, 95 + i, 101 + i, 1000 + i * 10);
var bar = new TBar(DateTime.UtcNow.AddMinutes(i), 100 + i, 105 + i, 95 + i, 101 + i, 1000 + (i * 10));
ind.Update(bar);
}
Assert.True(double.IsFinite(ind.Last.Value));
@@ -116,7 +116,7 @@ public sealed class VwmacdTests
var ind = new Vwmacd(fastPeriod: 5, slowPeriod: 10, signalPeriod: 3);
for (int i = 0; i < 30; i++)
{
double price = 100.0 + i * 2;
double price = 100.0 + (i * 2);
var bar = new TBar(DateTime.UtcNow.AddMinutes(i), price, price + 1, price - 1, price, 10000);
ind.Update(bar);
}
@@ -130,7 +130,7 @@ public sealed class VwmacdTests
var ind = new Vwmacd(fastPeriod: 5, slowPeriod: 10, signalPeriod: 3);
for (int i = 0; i < 30; i++)
{
double price = 200.0 - i * 2;
double price = 200.0 - (i * 2);
var bar = new TBar(DateTime.UtcNow.AddMinutes(i), price, price + 1, price - 1, price, 10000);
ind.Update(bar);
}
@@ -326,7 +326,7 @@ public sealed class VwmacdTests
// ind1: uniform volume
ind1.Update(new TBar(DateTime.UtcNow.AddMinutes(i), price, price + 1, price - 1, price, 1000));
// ind2: high volume on latter bars (accelerating weight)
ind2.Update(new TBar(DateTime.UtcNow.AddMinutes(i), price, price + 1, price - 1, price, 1000 + i * 500));
ind2.Update(new TBar(DateTime.UtcNow.AddMinutes(i), price, price + 1, price - 1, price, 1000 + (i * 500)));
}
// Both should be finite; values may differ due to volume weighting
@@ -46,8 +46,8 @@ public sealed class BwMfiValidationTests
double range1 = mfi1 * vol1;
double range2 = mfi2 * vol2;
m.Update(new TBar(t, 100, 100 + range1 / 2, 100 - range1 / 2, 100, vol1));
m.Update(new TBar(t.AddMinutes(1), 100, 100 + range2 / 2, 100 - range2 / 2, 100, vol2));
m.Update(new TBar(t, 100, 100 + (range1 / 2), 100 - (range1 / 2), 100, vol1));
m.Update(new TBar(t.AddMinutes(1), 100, 100 + (range2 / 2), 100 - (range2 / 2), 100, vol2));
Assert.Equal(expectedZone, m.Zone);
}
+4 -4
View File
@@ -173,13 +173,13 @@ public sealed class Atrstop : ITValuePublisher
double upperEval, lowerEval;
if (_useHighLow)
{
upperEval = high + _multiplier * atrValue;
lowerEval = low - _multiplier * atrValue;
upperEval = high + (_multiplier * atrValue);
lowerEval = low - (_multiplier * atrValue);
}
else
{
upperEval = close + _multiplier * atrValue;
lowerEval = close - _multiplier * atrValue;
upperEval = close + (_multiplier * atrValue);
lowerEval = close - (_multiplier * atrValue);
}
// Initialize bands on first hot bar
@@ -57,7 +57,7 @@ public sealed class ConvexityIndicatorTests
{
ind.HistoricalData.AddBar(
DateTime.UtcNow.AddMinutes(i),
100 + i * 0.5, 101 + i * 0.5, 99 + i * 0.5, 100.5 + i * 0.5, 1000);
100 + (i * 0.5), 101 + (i * 0.5), 99 + (i * 0.5), 100.5 + (i * 0.5), 1000);
}
ind.ProcessUpdate(new UpdateArgs(UpdateReason.HistoricalBar));
@@ -93,10 +93,10 @@ public sealed class ConvexityTests
for (int i = 1; i <= period; i++)
{
double sign = (i % 2 == 0) ? 1 : -1;
double magnitude = 0.01 + rng.NextDouble() * 0.03;
double magnitude = 0.01 + (rng.NextDouble() * 0.03);
double mktReturn = sign * magnitude;
mkt *= (1 + mktReturn);
ast *= (1 + 2 * mktReturn); // exactly 2x market return
ast *= (1 + (2 * mktReturn)); // exactly 2x market return
c.Update(ast, mkt);
}
@@ -123,7 +123,7 @@ public sealed class ConvexityTests
for (int i = 1; i <= period; i++)
{
double sign = (i % 2 == 0) ? 1 : -1;
double magnitude = 0.01 + rng.NextDouble() * 0.03; // 1%-4% varying
double magnitude = 0.01 + (rng.NextDouble() * 0.03); // 1%-4% varying
double mktReturn = sign * magnitude;
double astReturn;
if (mktReturn > 0)
@@ -157,8 +157,8 @@ public sealed class ConvexityTests
c.Update(100.0, 100.0);
for (int i = 0; i < 50; i++)
{
double ast = 100.0 + rng.NextDouble() * 20 - 10;
double mkt = 100.0 + rng.NextDouble() * 20 - 10;
double ast = 100.0 + (rng.NextDouble() * 20) - 10;
double mkt = 100.0 + (rng.NextDouble() * 20) - 10;
c.Update(ast, mkt);
Assert.True(c.ConvexityValue >= 0, $"Convexity must be ≥ 0, got {c.ConvexityValue} at i={i}");
}
@@ -179,8 +179,8 @@ public sealed class ConvexityTests
for (int i = 1; i <= period + 5; i++)
{
double sign = (i % 2 == 0) ? 1 : -1;
double magnitude = 0.005 + rng.NextDouble() * 0.02;
price *= (1 + sign * magnitude);
double magnitude = 0.005 + (rng.NextDouble() * 0.02);
price *= (1 + (sign * magnitude));
c.Update(price, price);
}
@@ -296,9 +296,9 @@ public sealed class ConvexityTests
for (int i = 0; i < 10; i++)
{
double sign = (i % 2 == 0) ? 1 : -1;
double magnitude = 0.005 + rng.NextDouble() * 0.02;
ast *= (1 + sign * magnitude * 1.5);
mkt *= (1 + sign * magnitude);
double magnitude = 0.005 + (rng.NextDouble() * 0.02);
ast *= (1 + (sign * magnitude * 1.5));
mkt *= (1 + (sign * magnitude));
assetSeries.Add(new TValue(i, ast));
marketSeries.Add(new TValue(i, mkt));
}
@@ -394,7 +394,7 @@ public sealed class ConvexityTests
for (int i = 1; i <= period; i++)
{
double sign = (i % 2 == 0) ? 1 : -1;
double magnitude = 0.01 + rng.NextDouble() * 0.03;
double magnitude = 0.01 + (rng.NextDouble() * 0.03);
double mktRet = sign * magnitude;
mkt *= (1 + mktRet);
ast *= (1 - mktRet); // inverse
@@ -440,8 +440,8 @@ public sealed class ConvexityTests
for (int i = 0; i < 1000; i++)
{
ast *= (1 + (rng.NextDouble() - 0.5) * 0.04);
mkt *= (1 + (rng.NextDouble() - 0.5) * 0.02);
ast *= (1 + ((rng.NextDouble() - 0.5) * 0.04));
mkt *= (1 + ((rng.NextDouble() - 0.5) * 0.02));
c.Update(ast, mkt);
Assert.True(double.IsFinite(c.ConvexityValue), $"ConvexityValue not finite at i={i}");