From fbdc9172cce749fb195df6b2d5e592e49908c1bd Mon Sep 17 00:00:00 2001 From: Miha Kralj Date: Mon, 2 Mar 2026 15:03:38 -0800 Subject: [PATCH] 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. --- lib/trends_FIR/nlma/Nlma.cs | 4 ++-- lib/trends_FIR/nlma/Nlma.md | 2 +- lib/trends_FIR/nlma/nlma.pine | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/trends_FIR/nlma/Nlma.cs b/lib/trends_FIR/nlma/Nlma.cs index 081b8d9a..bd31992d 100644 --- a/lib/trends_FIR/nlma/Nlma.cs +++ b/lib/trends_FIR/nlma/Nlma.cs @@ -228,7 +228,7 @@ public sealed class Nlma : AbstractBase /// /// 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); } diff --git a/lib/trends_FIR/nlma/Nlma.md b/lib/trends_FIR/nlma/Nlma.md index aa67b5e1..3a4aa5e1 100644 --- a/lib/trends_FIR/nlma/Nlma.md +++ b/lib/trends_FIR/nlma/Nlma.md @@ -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 diff --git a/lib/trends_FIR/nlma/nlma.pine b/lib/trends_FIR/nlma/nlma.pine index d303cea6..447956a7 100644 --- a/lib/trends_FIR/nlma/nlma.pine +++ b/lib/trends_FIR/nlma/nlma.pine @@ -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)