fix(nlma): restore original Igorad cycle zone numerator (i-phase+1)

The cycle zone t parameter must use (i-phase+1) per original MQL4 NonLagMA v7.1.

Using (i-phase) eliminated the intentional discontinuity at the phase/cycle boundary, producing incorrect kernel weights visible in the signature SVG.
This commit is contained in:
Miha Kralj
2026-03-02 15:03:38 -08:00
parent f0f9382817
commit fbdc9172cc
3 changed files with 4 additions and 4 deletions
+2 -2
View File
@@ -228,7 +228,7 @@ public sealed class Nlma : AbstractBase
/// <summary>
/// Computes original Igorad two-phase kernel weights.
/// Phase zone (i=0..period-2): t = i/(period-2), g = t≤0.5 ? 1 : 1/(3πt+1), w = g*cos(πt)
/// Cycle zone (i=period-1..flen-2): t = 1 + (i-phase)*(2*Cycle-1)/(Cycle*period-1), same g/w
/// Cycle zone (i=period-1..flen-2): t = 1 + (i-phase+1)*(2*Cycle-1)/(Cycle*period-1), same g/w
/// Last tap (i=flen-1): weight = 0.
/// weights[0] = newest bar, weights[flen-1] = oldest bar.
/// Returns the signed weight sum for normalization.
@@ -263,7 +263,7 @@ public sealed class Nlma : AbstractBase
else
{
// Cycle zone: t continues from 1 upward
double numer = (double)(i - phase) * (2 * Cycle - 1);
double numer = (double)(i - phase + 1) * (2 * Cycle - 1);
double denom = (double)(Cycle * period - 1);
t = 1.0 + (denom > 0 ? numer / denom : 0.0);
}
+1 -1
View File
@@ -150,7 +150,7 @@ for i = 0 to flen-1:
if i <= Phase - 1:
t = i / (Phase - 1)
else:
t = 1 + (i - Phase + 1) * (2*Cycle - 1) / (Cycle * period - 1)
t = 1.0 + (i - Phase + 1) * (2*Cycle - 1) / (Cycle * period - 1)
if t <= 0.5:
g = 1.0
+1 -1
View File
@@ -43,7 +43,7 @@ nlma(series float source, simple int period) =>
t := phase > 1 ? float(i) / float(phase - 1) : 0.0
else
// Cycle zone: t continues from 1 upward
float numer = float(i - phase) * float(2 * cycle - 1)
float numer = float(i - phase + 1) * float(2 * cycle - 1)
float denom = float(cycle * period - 1)
t := 1.0 + (denom > 0 ? numer / denom : 0.0)