refactor: remove unused JMA power parameter from entire stack

This commit is contained in:
Miha Kralj
2026-03-01 22:14:30 -08:00
parent ce04e2792b
commit fa77882be7
6 changed files with 24 additions and 35 deletions
+1 -1
View File
@@ -635,7 +635,7 @@ public class JbandsTests
{
// Verify that middle band matches standalone JMA
var jbands = new Jbands(14, 0);
var jma = new Jma(14, 0, 0.45);
var jma = new Jma(14, 0);
var gbm = new GBM(startPrice: 100, mu: 0.01, sigma: 0.1, seed: 999);
for (int i = 0; i < 200; i++)
+8 -12
View File
@@ -32,11 +32,11 @@ public class JmaTests
double[] wrongSizeOutput = new double[3];
// Period must be > 0
Assert.Throws<ArgumentOutOfRangeException>(() => Jma.Batch(source.AsSpan(), output.AsSpan(), 0, 0, 1.0));
Assert.Throws<ArgumentOutOfRangeException>(() => Jma.Batch(source.AsSpan(), output.AsSpan(), -1, 0, 1.0));
Assert.Throws<ArgumentOutOfRangeException>(() => Jma.Batch(source.AsSpan(), output.AsSpan(), 0, 0));
Assert.Throws<ArgumentOutOfRangeException>(() => Jma.Batch(source.AsSpan(), output.AsSpan(), -1, 0));
// Output must be same length as source
Assert.Throws<ArgumentException>(() => Jma.Batch(source.AsSpan(), wrongSizeOutput.AsSpan(), 3, 0, 1.0));
Assert.Throws<ArgumentException>(() => Jma.Batch(source.AsSpan(), wrongSizeOutput.AsSpan(), 3, 0));
}
[Fact]
@@ -235,8 +235,10 @@ public class JmaTests
}
[Fact]
public void Jma_Power_AffectsResult()
public void Jma_Power_RemovedFromApi()
{
// Power parameter was removed — it was never used in calculation.
// Verify the 2-parameter Batch still works correctly.
var series = new TSeries();
var gbm = new GBM(startPrice: 100.0, mu: 0.02, sigma: 0.1, seed: 42);
for (int i = 0; i < 100; i++)
@@ -245,14 +247,8 @@ public class JmaTests
series.Add(bar.Time, bar.Close);
}
var jmaPowerDefault = Jma.Batch(series, 10, power: 0.45);
var jmaPower1 = Jma.Batch(series, 10, power: 1.0);
var jmaPower2 = Jma.Batch(series, 10, power: 2.0);
// Power parameter is kept for API compatibility with Pine reference
// but does not affect output in this implementation
Assert.Equal(jmaPowerDefault.Last.Value, jmaPower1.Last.Value, 1e-10);
Assert.Equal(jmaPowerDefault.Last.Value, jmaPower2.Last.Value, 1e-10);
var result = Jma.Batch(series, 10);
Assert.True(double.IsFinite(result.Last.Value));
}
[Fact]
+10 -16
View File
@@ -64,18 +64,13 @@ public sealed class Jma : AbstractBase
public override bool IsHot => _state.Bars >= WarmupPeriod;
public Jma(int period, int phase = 0, double power = 0.45)
public Jma(int period, int phase = 0)
{
if (period < 1)
{
throw new ArgumentOutOfRangeException(nameof(period), "Period must be >= 1.");
}
if (!double.IsFinite(power))
{
throw new ArgumentException("Power must be finite.", nameof(power));
}
// --- Phase parameter: maps -100..100 -> 0.5..2.5 (Jurik convention) ---
if (phase < -100)
{
@@ -115,7 +110,7 @@ public sealed class Jma : AbstractBase
WarmupPeriod = (int)Math.Ceiling(20.0 + 80.0 * Math.Pow(period, 0.36));
_handler = Handle;
Name = $"Jma({period},{phase},{power})"; // power kept for signature compatibility (ignored in calculation)
Name = $"Jma({period},{phase})";
_devBuffer = new RingBuffer(DevWindowSize);
_volBuffer = new RingBuffer(VolWindowSize);
@@ -123,8 +118,8 @@ public sealed class Jma : AbstractBase
Reset();
}
public Jma(ITValuePublisher source, int period, int phase = 0, double power = 0.45)
: this(period, phase, power)
public Jma(ITValuePublisher source, int period, int phase = 0)
: this(period, phase)
{
_source = source;
source.Pub += _handler;
@@ -358,9 +353,9 @@ public sealed class Jma : AbstractBase
}
}
public static TSeries Batch(TSeries source, int period, int phase = 0, double power = 0.45)
public static TSeries Batch(TSeries source, int period, int phase = 0)
{
var jma = new Jma(period, phase, power);
var jma = new Jma(period, phase);
return jma.Update(source);
}
@@ -370,8 +365,7 @@ public sealed class Jma : AbstractBase
public static void Batch(ReadOnlySpan<double> source,
Span<double> output,
int period,
int phase = 0,
double power = 0.45)
int phase = 0)
{
if (output.Length != source.Length)
{
@@ -383,16 +377,16 @@ public sealed class Jma : AbstractBase
return;
}
var jma = new Jma(period, phase, power);
var jma = new Jma(period, phase);
for (int i = 0; i < source.Length; i++)
{
output[i] = jma.Step(source[i], isNew: true);
}
}
public static (TSeries Results, Jma Indicator) Calculate(TSeries source, int period, int phase = 0, double power = 0.45)
public static (TSeries Results, Jma Indicator) Calculate(TSeries source, int period, int phase = 0)
{
var indicator = new Jma(period, phase, power);
var indicator = new Jma(period, phase);
TSeries results = indicator.Update(source);
return (results, indicator);
}
+1 -1
View File
@@ -170,7 +170,7 @@ HAS_FRAMA = _bind("qtl_frama", [_dp, _dp, _ci, _ci])
HAS_HOLT = _bind("qtl_holt", [_dp, _dp, _ci, _ci, _cd])
HAS_HTIT = _bind("qtl_htit", [_dp, _dp, _ci])
HAS_HWMA = _bind("qtl_hwma", [_dp, _dp, _ci, _ci])
HAS_JMA = _bind("qtl_jma", [_dp, _dp, _ci, _ci, _ci, _cd])
HAS_JMA = _bind("qtl_jma", [_dp, _dp, _ci, _ci, _ci])
HAS_KAMA = _bind("qtl_kama", [_dp, _dp, _ci, _ci, _ci, _ci])
HAS_LTMA = _bind("qtl_ltma", [_dp, _dp, _ci, _ci])
HAS_MAMA = _bind("qtl_mama", [_dp, _dp, _cd, _ci, _cd, _dp])
+2 -3
View File
@@ -107,16 +107,15 @@ def hwma(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
return _wrap(output, idx, f"HWMA_{period}", "trends_iir", offset)
def jma(close: object, period: int = 14, phase: int = 0, power: float = 0.45, offset: int = 0, **kwargs) -> object:
def jma(close: object, period: int = 14, phase: int = 0, offset: int = 0, **kwargs) -> object:
"""Jurik Moving Average."""
period = int(period)
phase = int(phase)
power = float(power)
offset = int(offset)
src, idx = _arr(close)
n = len(src)
output = _out(n)
_check(_lib.qtl_jma(_ptr(src), _ptr(output), n, period, phase, power))
_check(_lib.qtl_jma(_ptr(src), _ptr(output), n, period, phase))
return _wrap(output, idx, f"JMA_{period}", "trends_iir", offset)
+2 -2
View File
@@ -1146,13 +1146,13 @@ public static unsafe partial class Exports
}
[UnmanagedCallersOnly(EntryPoint = "qtl_jma")]
public static int QtlJma(double* source, double* output, int n, int period, int phase, double power)
public static int QtlJma(double* source, double* output, int n, int period, int phase)
{
if (source == null || output == null) return StatusCodes.QTL_ERR_NULL_PTR;
if (n <= 0) return StatusCodes.QTL_ERR_INVALID_LENGTH;
try
{
Jma.Batch(Src(source, n), Dst(output, n), period, phase, power);
Jma.Batch(Src(source, n), Dst(output, n), period, phase);
return StatusCodes.QTL_OK;
}
catch { return StatusCodes.QTL_ERR_INTERNAL; }