Normalized Smoothed MACD: Range Mapping and Pine Script | Pineify
Normalized Smoothed MACD maps an EMA difference into its recent min-max range, smooths that mapped series, and smooths it again for a signal line. A positive NSM value is not proof that the fast EMA exceeds the slow EMA. Normalization changes the meaning of zero, and the smoothing and initialization must be checked separately.
Inspect the Pine ScriptSeparate the five stages
The helper first computes a fast and a slow exponential recurrence from price. Their difference is M. Let L and H be the lowest and highest M values in the normalization window, including the current bar. When H differs from L, raw normalized value R = 2 × (M − L)/(H − L) − 1. When they are equal, the code sets R to zero.
The plotted value V then updates as previous V + alphaSmooth × (R − previous V). Signal S updates as previous S + alphaSignal × (V − previous S). Each alpha is 2/(max(period, 1)+1); the default smoothing and signal periods are 5 and 9, giving alpha 1/3 and 1/5.
The default call fixes close, fast 12, slow 26, signal 9, smooth 5, and normalization 20. It exposes no settings inputs. The main line is green only when it strictly rises; otherwise, including a tie, it is red. The signal line is orange and zero is a plotted horizontal reference.
Zero and 0.8 do not mean what raw MACD means
Before smoothing, R = 0 means M is at the midpoint (L + H)/2 of its current range. It does not mean M = 0. For a hypothetical range L = −10 and H = −2, M = −3.6 produces R = +0.6 even though the fast-minus-slow difference remains negative.
Now assume previous V = −0.6 and R = +0.6 with smoothing 5. The next V is −0.2. If R stays +0.6 one more bar, V becomes approximately +0.066667. The smoothed zero crossing is delayed relative to the raw range-midpoint crossing; it still does not imply a positive raw MACD.
An unsmoothed R of +0.8 means M lies 90% of the way from L to H. With L = −10 and H = −2, that value is −2.8. It is not 90% of the maximum, a percentile, a standard-deviation score, or a probability. The plotted V is additionally smoothed, so its +0.8 cannot generally be inverted to the current M using that formula.
A rolling range can change the output without a new MACD value
Hold M at −4. With L = −10 and H = −2, the raw normalized value is +0.5. If the old minimum leaves the window and the new minimum is −5 while H stays −2, R becomes −1/3. That change arises from the reference range, not a change in current M.
A tiny nonzero range does not force the indicator toward zero. For example, L = 1, H = 1.000002, and M = 1.000001 give R near zero, while either endpoint maps to −1 or +1. Tiny changes can therefore occupy the full normalized scale. Only exact equality selects the explicit zero branch.
If R becomes zero after a previously nonzero V, smoothing makes V decay toward zero rather than resetting it immediately. With normalization length 1, each current range collapses to a single value, so R remains zero and the zero-seeded V and S remain zero.
For finite valid values, current M lies inside its own min-max window. R is in [−1, 1], and the zero-seeded smoothing recurrences are convex combinations, so V and S stay in that interval in exact arithmetic. The implementation uses exact equality, not a small-range tolerance.
Initialization is not the standard price-seeded EMA
The two price recurrences use different fallbacks in the same expression: their previous-value term defaults to zero, while the subtraction’s previous value defaults to current price. On the first valid bar, both outputs are therefore zero, regardless of price. They then begin converging from zero on following bars.
For a constant price of 100 and defaults, the first three values are:
| Bar | Fast | Slow | M | R | V | S |
|---|---|---|---|---|---|---|
| 1 | 0 | 0 | 0 | 0 | 0 | 0 |
| 2 | 15.384615 | 7.407407 | 7.977208 | 1 | 0.333333 | 0.066667 |
| 3 | 28.402367 | 14.266118 | 14.136249 | 1 | 0.555556 | 0.164444 |
The apparent early momentum is an initialization artifact on a price that never changes. This page retains that helper behavior for an explicit comparison with the local implementation; it does not present it as equivalent to a standard price-seeded MACD.
There is no full 20-bar warmup gate. The extrema functions can use available observations while history is still short. Compare initialization, available history, and the entire pipeline before comparing values between implementations. Any seed correction is a deliberate algorithm change requiring its own numerical checks.
Shared scale does not calibrate different markets
For the same observation sequence and initialization, multiplying all prices by a positive constant scales both price recurrences and their difference. The factor cancels in min-max normalization. This removes that multiplicative unit scaling; it does not make unrelated market histories equivalent.
Two symbols at +0.8 can have different price trends, range widths, costs, and future outcomes. A shared numeric bound does not make a threshold equally reliable across symbols or timeframes. A normalization window is also not a fixed signal delay, and smoothing does not establish a universal reduction in false crossovers.
Ordinary MACD uses the fast-minus-slow zero directly. Keep that meaning separate from NSM’s rolling range and smoothed output. No specific NSM origin or unsupported development history is asserted here.
Turn a line comparison into an explicit event
The code plots values only. It does not detect divergence, create alerts, manage positions, or identify institutional activity. Its open-bar values can change with current close. A signal-line crossing, zero crossing, and change of line color are different conditions.
For an adaptation, define which series is crossing which, how equality is treated, whether the bar must be closed, and when a trade could first execute. Pivot-based divergence needs the future confirmation bars required by that pivot rule; it cannot be counted as known on the earlier pivot bar.
Reference: Pine live-bar and repainting behavior. Any strategy study also needs exits, sizing, costs, and independent evaluation data. No performance estimate is established here.
Pine Script v6: implementation and limits
The complete source retains the local helper’s initialization and fixed parameters so its behavior can be inspected directly. Syntax validation does not remove the documented flat-price startup artifact. No alerts, divergence detector, or orders are implemented.
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Pineify
//@version=6
indicator(title="Normalized Smoothed MACD", overlay=false, max_labels_count=500)
// NSM Calculation — normalized and smoothed MACD variant
p_ta_nsm(series float price, simple int fastPeriod, simple int slowPeriod, simple int macdSignal, simple int smoothPeriod, simple int normPeriod) =>
emaf = 0.0
emas = 0.0
val = 0.0
nval = 0.0
sig = 0.0
alphaf = 2.0 / (1.0 + math.max(fastPeriod, 1))
alphas = 2.0 / (1.0 + math.max(slowPeriod, 1))
alphasig = 2.0 / (1.0 + math.max(macdSignal, 1))
alphasm = 2.0 / (1.0 + math.max(smoothPeriod, 1))
emaf := nz(emaf[1]) + alphaf * (price - nz(emaf[1], price))
emas := nz(emas[1]) + alphas * (price - nz(emas[1], price))
imacd = emaf - emas
mmax = ta.highest(imacd, normPeriod)
mmin = ta.lowest(imacd, normPeriod)
nval := mmin != mmax ? 2.0 * (imacd - mmin) / (mmax - mmin) - 1.0 : 0.0
val := nz(val[1]) + alphasm * (nval - nz(val[1]))
sig := nz(sig[1]) + alphasig * (val - nz(sig[1]))
[val, sig]
// Apply NSM with default parameters
[p_ind_1_value, p_ind_1_signal] = p_ta_nsm(close, 12, 26, 9, 5, 20)
// Zero line
hline(0, "NSM - Zero", color=color.new(#787B86, 50))
// NSM value line — green when rising, red when falling
plot(p_ind_1_value, "NSM", p_ind_1_value > p_ind_1_value[1] ? color.rgb(76, 175, 80, 0) : color.rgb(242, 54, 69, 0), linewidth=2)
// NSM signal line — orange, 1px width
plot(p_ind_1_signal, "NSM - Signal", color.rgb(255, 109, 0, 0), linewidth=1)
Specify a checkable adaptation in Pineify
Specify whether to preserve or change the price-recurrence seeds, how long to warm up, how to handle tiny normalization ranges, and which event should be confirmed. Ask the Pine Script AI Coding Agent for these choices explicitly. Compare flat-price startup, the negative-MACD positive-normalization example, and range-expiry behavior before evaluating a strategy.
Open Pine Script AI Coding AgentEducational indicator analysis. No measured trading performance is established here. Syntax validation does not prove formula equivalence, execution assumptions or profitability.