TradingView indicator guides

Ehlers EMA Smoother: inspect the two-stage calculation

This implementation sends a standard-coefficient EMA into a two-pole Super Smoother and plots the result on the price chart. The extra filter changes the response; it does not establish a fixed lead over another moving average or a profitable trading signal.

Use the formulas and hypothetical step calculation below to check the source. The supplied script fixes both periods at three chart bars, draws one blue line, and defines no alerts, entries or exits.

Inspect the Pine Script

The EMA stage uses the ordinary coefficient

For period K, alpha = 2 / (K + 1). The first stage is x[t] = alpha × source[t] + (1 − alpha) × x[t−1]. With K = 3, alpha is 0.5. This is not a special modified smoothing factor. The helper name is local to this source; it is not a built-in Pine function.

The source fallback in nz(res[1], source) initializes the first stage to the current source when no previous value exists. On uninterrupted data, this follows the ordinary recursive EMA form. Different startup and missing-value policies can still produce different early values.

The second stage is a recursive low-pass filter

a = exp(−π√2 / P)

c2 = 2a × cos(π√2 / P)

c3 = −a²; c1 = (1 − c2 − c3) / 2

y[t] = c1 × (x[t] + x[t−1]) + c2 × y[t−1] + c3 × y[t−2]

The recurrence corresponds to the two-pole SuperSmoother form in John Ehlers' Predictive Indicators paper. Here it receives an EMA rather than the raw price, and uses radians. That correspondence does not date this particular combined implementation or validate any claimed trading performance.

A recursive filter retains earlier state. Its coefficient signs can permit overshoot, so its output need not be a convex average of recent prices. Neither an IIR label nor an extra smoothing stage proves universally lower phase delay than every FIR or EMA configuration.

Worked step: a settled input rises from 100 to 110

Assume both stages have settled at 100, with K = P = 3. These are hypothetical calculation inputs, not market data or a backtest. The first EMA becomes 0.5 × 110 + 0.5 × 100 = 105.

QuantityApproximate value
a0.227419
c10.505457
c20.040806
c3−0.051719
Current / previous EMA105 / 100
Previous two filter outputs100 / 100
New filter output102.527285

The second stage gives approximately 0.505457 × 205 + 0.040806 × 100 − 0.051719 × 100 = 102.527285. It moves less than the first EMA on this particular first step. That calculation is a useful counterexample to treating the second stage as automatically faster on every move.

Repeat with a constant input, a step, a ramp and alternating values. Keep the seed and full history fixed. A comparison of K = 3 followed by P = 3 against EMA 14 is a comparison of different filters and settings, not evidence of equal smoothness or a universal two-bar advantage.

Complete Pine Script v6 example

Paste this indicator into the Pine Editor, save it and add it to a standard chart. The calculation uses the chart close and timeframe. K and P are fixed at 3 in the call; there are no configurable length inputs in the settings panel.

Pine Script v6
// 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="Ehlers EMA Smoother", overlay=true, max_labels_count=500)

//—————————————————————————————————— xEMA — standard EMA coefficient with explicit source seed
p_ta_xema(series float source, simple int length) =>
    mult = 2.0 / (length + 1.0)
    res = float(na)
    res := mult * source + (1.0 - mult) * nz(res[1], source)

//—————————————————————————————————— Super Smoother by John Ehlers
p_ta_ehlers_super_smoother(series float source, simple int lower) =>
    PI=3.14159265359
    a1 = math.exp(-PI * math.sqrt(2) / lower)
    coeff2 = 2 * a1 * math.cos(math.sqrt(2) * PI / lower)
    coeff3 = -math.pow(a1, 2)
    coeff1 = (1 - coeff2 - coeff3) / 2
    filt = 0.0
    filt := nz(coeff1 * (source + nz(source[1], source)) + coeff2 * filt[1] + coeff3 * nz(filt[2], filt[1]), source)

//—————————————————————————————————— Ehlers EMA Smoother
p_ta_ehlers_ema_smoother(series float source, simple int smoothK = 3, simple int smoothP = 3) =>
    p_ta_ehlers_super_smoother(p_ta_xema(source, smoothK), smoothP)

// Indicator calculation
p_ind_1 = p_ta_ehlers_ema_smoother(close, 3, 3) // EEMAS

// Plot the smoothed line
plot(p_ind_1, "EEMAS", color.rgb(41, 98, 255, 0), 1)

The second-stage nz expression falls back to its current input when the recurrence is unavailable. In this implementation the first loaded value uses this fallback. On the second bar, the missing two-bar filter value is replaced by the previous filter value inside the recurrence. Later values use both prior states. A chart with different loaded history can have different early output.

Existing Ehlers EMA Smoother chart preview
The existing preview illustrates the overlay. It is not proof of a particular symbol, timeframe, parameter advantage or return.

Keep calculation states separate from trading hypotheses

Price above the line, a rising line and a price crossover are different observations. None proves institutional participation, future trend direction or support at that price. A rising MACD histogram also means its value increased from the prior bar; it does not necessarily mean MACD is above its signal line.

  • A crossover rule must define whether it acts during the bar or after the close. This indicator itself has no confirmation gate; the current plot updates with the current close.
  • A slope rule must specify its lookback and units. Comparing an absolute slope with a signed average can create unintended conditions. No two-to-five-bar prediction follows from a slope change.
  • A pullback rule needs a measurable distance, a known-at-the-time reference and explicit exit logic. Calling a touch a bounce is not a causal explanation.
  • Any strategy needs sizing, commission, slippage and an out-of-sample evaluation. A stop described in prose is not implemented by this plotting code.

Adding two-bar confirmation, an ADX threshold or another indicator is a testable modification. This page supplies no result establishing that those changes cut false signals by a stated percentage. See TradingView's repainting documentation for the difference between current-bar updates and confirmed values.

Specify the adaptation in Pineify

Ask the Pine Script AI Coding Agent for explicit source and period inputs, the same seed behavior, Data Window plots for both stages and a stated alert confirmation rule. Review the resulting code and request syntax checking before comparing the outputs in TradingView. Syntax success is not evidence of a trading edge.

Open Pine Script AI Coding Agent

Educational calculation guide. No measured win rate, benchmark ranking or account access entitlement is established here.

Implementation questions

In this example it is 2 / (length + 1), the ordinary EMA coefficient. The custom helper explicitly seeds its previous value with the source when history is missing. The name xEMA does not establish a new low-lag formula.

The supplied script calls the helper with literal values 3 and 3. It has no length inputs, so those values cannot be changed in the Inputs tab. Edit the constants or explicitly request input.int controls, with positive bounds, in a separate adaptation.

No universal lead in bars is established. Compare the same source, history and settings, and define the event or frequency being measured. Cascading a filter changes both amplitude and phase response; a short two-stage chain and a longer EMA are not matched simply by their names.

It uses current and previous chart values, so the developing bar can change. It contains no higher-timeframe requests, alertcondition calls or orders. A user can separately create a TradingView alert on a plot condition; its timing must be chosen explicitly.

No tested optimum is supplied. Both lengths count chart bars. The same three-bar setting on a minute chart and a daily chart spans very different elapsed time. A crossover or slope rule requires its own test, exits, costs and risk constraints.

State the source, EMA and Super Smoother periods, seed behavior, plots and desired confirmation rule. Ask the Coding Agent to check syntax, then compare the generated values against known inputs. Account access and generation quotas follow the current plan; this page does not promise unlimited free generation.

For configurable controls, see Pine inputs. Compare the separate EMA and deviation-scaled moving average guides; DSMA adds an adaptive coefficient and is a different calculation.