TradingView filter calculations

Adaptive Laguerre Filters: Gamma, Initialization and Lag

An adaptive Laguerre filter changes the damping coefficient of a four-stage recursive price filter. The Ehlers nonlinear version measures the gap between current price and the previous filtered value, normalizes that error over a lookback window, and takes a five-bar median to obtain alpha. Gamma equals 1 minus alpha. Its output stays in price units; Laguerre RSI is a separate oscillator. Adaptation changes the smoothing and delay, but does not remove either.

See the decision guide

Separate the filter recurrence from its adaptation rule

John Ehlers publishes the fixed filter in Time Warp: Without Space Travel, Figure 7. His presentation Building Trading Systems On NonLinear Filters, slides 19 and 20, supplies the error-based adaptive rule. The accessible paper and presentation are distinct sources; the public TradingView publication by everget helps identify the indicator family, but this example is an independent implementation of the equations.

  • Brackets mean one bar ago. L1 uses the newly computed L0 and the previous L0 and L1. Replacing every term with a previous-bar value changes the filter.
  • The median uses five successive normalized errors, each calculated against its own rolling range. Taking a median of five raw errors and normalizing once is a different algorithm.
  • The source uses a 20-bar error range and the high-low midpoint as price. These are reference settings, not a measured optimum for every instrument.
StageEquation on bar t
First stageL0 = (1 − gamma) × P + gamma × L0[1]
Second stageL1 = −gamma × L0 + L0[1] + gamma × L1[1]
Third stageL2 = −gamma × L1 + L1[1] + gamma × L2[1]
Fourth stageL3 = −gamma × L2 + L2[1] + gamma × L3[1]
Price-level outputF = (L0 + 2 × L1 + 2 × L2 + L3) / 6
Tracking errorD = abs(P − F[1]); H = highest(D, N); B = lowest(D, N)
Adaptive coefficient when H > BR = (D − B) / (H − B); alpha = median(R, 5); gamma = 1 − alpha

Bound gamma and make startup behavior explicit

The sample below is a bounded port with stated conventions, not a claim of identical startup output on every platform. It caps gamma at 0.95 by default. The original normalized-error rule can reach gamma = 1; preventing that endpoint changes the result and must stay visible in comparisons.

  • At gamma = 0, the recurrence reduces to (P + 2P[1] + 2P[2] + P[3]) / 6 after startup. It is a four-tap weighted average, not an exact copy of the current price.
  • At gamma = 1, L0 receives zero current-input weight. With equal initial states, every stage can remain frozen despite a new price. The ceiling avoids that endpoint; it does not prove that every adaptive sequence has desirable behavior.
  • The source presentation updates alpha only when the error range is nonzero. Carrying a normalized ratio through a zero-range bar, seeding alpha at 0.5, using the N + 4 gate and imposing the ceiling are explicit choices in this port.
  • Recursive state depends on loaded history. Increase the earlier data and compare the same later timestamps within a stated tolerance; the first computed value is not proof of convergence.
ConditionPolicy in this exampleConsequence
Gamma range0 ≤ gamma ≤ ceiling < 1; default ceiling 0.95The first stage always receives some current input. A higher ceiling permits a longer slow tail.
Startupalpha = 0.5; ratio = 0.5; set all four states to P while index < N + 4At N = 20, adaptive recursion begins at zero-based index 24. Startup output follows input.
H = BCarry the previous ratio; retain alpha without a median updateNo division by zero. On a fully flat input seeded at that price, output remains at the same price.
Missing sourceStop with a runtime errorThis audit does not invent zero prices or silently bridge missing observations.
Fixed comparisonsSeed all stages with the first input, then use gamma 0.2 or 0.8The flat pre-step history gives all three filters the same state before the step.

Reproduce a ten-unit step

This synthetic input is 100 at indices 0 through 39, then 110 from index 40 onward. Use N = 20, a five-bar median and ceiling 0.95. Step bar 1 is index 40. The table is independently calculated from the stated equations, not a market backtest. All outputs retain the arbitrary price units of the input.

  • On the first step bar, the adaptive states are L0 = 105, L1 = 97.5, L2 = 101.25 and L3 = 99.375. Their weighted sum divided by 6 is 100.3125. Intermediate stages can be below the starting price even when the final output rises.
  • The first three post-step ratios are 1, 0.96875 and 0.90625. The five-value median is still 0.5 for the first two bars, then becomes 0.90625. Gamma therefore falls to 0.09375 on step bar 3.
  • The adaptive line first reaches 105 on step bar 4 and 109 on bar 6. Fixed gamma 0.2 reaches them on bars 3 and 5; fixed gamma 0.8 on bars 17 and 31. These are threshold timings for this fixture, not universal lag values.
  • Adaptation is slower than fixed 0.2 in this example. After the initial catch-up, falling normalized error raises gamma and leaves a slower tail. Calling a filter adaptive does not establish that it always leads a fixed filter.
Step barAdaptive gammaAdaptive outputFixed 0.2Fixed 0.8
10.500000100.312500100.896000100.056000
20.500000100.937500102.764800100.187200
30.093750103.287259105.196800100.344000
40.093750106.441522107.618560100.512640
50.093750108.762930109.030656100.695936
60.328726109.432528109.653944100.902292
100.950000109.663358109.997238102.077128

Measure smoothing separately from step delay

A second fixture uses P[n] = 100 + sin(2πn/4) for indices 0 through 999. Measure RMS of output minus 100 over indices 400 through 999, after the declared startup. Input RMS is 0.707107. Lower output RMS here means stronger suppression of this particular four-bar oscillation; it does not measure performance on other frequencies or price series.

  • Fixed gamma 0.8 suppresses this oscillation more strongly and takes longer to reach the step thresholds. The adaptive rule neither smooths most nor reacts fastest in these two fixtures.
  • Because gamma responds to the input, one fixed frequency-response curve cannot describe the adaptive filter for all amplitudes and histories. Test several periods, impulses, ramps and gaps with the actual seed and parameter limits.
  • A smoother line can still produce repeated slope reversals in sideways prices. A gap can trigger adaptation without beginning a sustained trend. Entries, exits, position size and trading costs require separate rules.
FilterOutput RMSStep bars to 50% / 90%
Adaptive, ceiling 0.950.0284364 / 6
Fixed gamma 0.20.0236693 / 5
Fixed gamma 0.80.00386717 / 31

Run the complete Pine Script v6 audit

Paste this indicator into Pine Editor and select Step, Flat or 4-bar sine to reproduce the fixtures. Keep the default length and ceiling for the tables. Inspect Sample index, Adaptive gamma, Normalized error and the three outputs in the Data Window on completed bars. Market mode uses hl2 by default.

  • The code performs each recurrence on every bar. Market prices and the derived gamma can change while the current bar is open; compare completed bars when checking agreement. The example contains no future references or higher-timeframe requests.
  • The first N + 4 adaptive outputs are seed values, so exclude them from signal analysis. With a longer error window, the fixed step at index 40 may fall inside startup; use N = 20 for the published comparison.
  • The script is an indicator and places no orders. Syntax validation checks language acceptance; it does not certify chart parity, profitable rules or a particular third-party implementation.
Independent implementation of the public equations, with bounded gamma and explicit startup. The final source passed the Pineify syntax checker; numerical checks are separate.pine
//@version=6
indicator("Adaptive Laguerre: public formula audit", overlay = true, precision = 6)
source = input.source(hl2, "Market source")
mode = input.string("Market", "Input", options = ["Market", "Step", "Flat", "4-bar sine"])
length = input.int(20, "Error range length", minval = 2, maxval = 500)
gammaCap = input.float(0.95, "Adaptive gamma ceiling", minval = 0.0, maxval = 0.999, step = 0.01)
p = switch mode
    "Step" => bar_index < 40 ? 100.0 : 110.0
    "Flat" => 100.0
    "4-bar sine" => 100.0 + math.sin(2.0 * math.pi * bar_index / 4.0)
    => source
if na(p)
    runtime.error("This audit requires a continuous source without missing values.")

laguerre(float x, float gamma) =>
    var float s0 = na
    var float s1 = na
    var float s2 = na
    var float s3 = na
    if na(s0[1])
        s0 := x
        s1 := x
        s2 := x
        s3 := x
    else
        s0 := (1.0 - gamma) * x + gamma * s0[1]
        s1 := -gamma * s0 + s0[1] + gamma * s1[1]
        s2 := -gamma * s1 + s1[1] + gamma * s2[1]
        s3 := -gamma * s2 + s2[1] + gamma * s3[1]
    (s0 + 2.0 * s1 + 2.0 * s2 + s3) / 6.0

var float output = na
var float l0 = na
var float l1 = na
var float l2 = na
var float l3 = na
var float alpha = 0.5
var float ratio = 0.5
error = math.abs(p - nz(output[1], p))
lowError = ta.lowest(error, length)
highError = ta.highest(error, length)
span = highError - lowError
ratio := span > 0.0 ? (error - lowError) / span : nz(ratio[1], 0.5)
medianRatio = ta.median(ratio, 5)
ready = bar_index >= length + 4
if ready and span > 0.0
    alpha := medianRatio
gamma = math.min(gammaCap, math.max(0.0, 1.0 - alpha))
if not ready
    l0 := p
    l1 := p
    l2 := p
    l3 := p
else
    l0 := (1.0 - gamma) * p + gamma * l0[1]
    l1 := -gamma * l0 + l0[1] + gamma * l1[1]
    l2 := -gamma * l1 + l1[1] + gamma * l2[1]
    l3 := -gamma * l2 + l2[1] + gamma * l3[1]
output := (l0 + 2.0 * l1 + 2.0 * l2 + l3) / 6.0
fast = laguerre(p, 0.2)
slow = laguerre(p, 0.8)
plot(output, "Adaptive output", color = color.blue, linewidth = 2)
plot(fast, "Fixed gamma 0.2", color = color.orange)
plot(slow, "Fixed gamma 0.8", color = color.purple)
plot(p, "Input", color = color.new(color.gray, 65))
plot(gamma, "Adaptive gamma", display = display.data_window)
plot(error, "Absolute tracking error", display = display.data_window)
plot(ratio, "Normalized error", display = display.data_window)
plot(bar_index, "Sample index", display = display.data_window)

Keep the output distinct from Laguerre RSI

This filter combines the four stages into a price-level series. Laguerre RSI instead compares adjacent stages, sums upward and downward differences, and normalizes them into an oscillator. A price filter near 100 and an RSI near 0.8 are different quantities even if their internal stages use the same gamma.

  • Do not apply RSI thresholds such as 0.2 and 0.8 to this price-level output. A price crossing the filtered line, a slope reversal and a Laguerre RSI threshold crossing are separate events.
  • Before comparing two scripts, match the adaptation formula, alpha versus gamma convention, source, window, median, bounds and initialization. ATR-based or fractal-energy variants need their own specifications.

Give Pineify a numerical acceptance target

Ask the Pine Script AI Coding Agent to draft or revise this public recurrence with the same seed, error normalization, five-bar median and gamma ceiling. Supply the step table and request diagnostic plots for the first bar where results diverge. Review the generated code and request a syntax check where the feature is available, then compare completed-bar values on TradingView.

  • Provide public formulas or source you have permission to use. The task does not require reconstructing a protected indicator.
  • If adding alerts, specify the event and confirmation rule separately. If converting to a strategy, also specify fills, costs and exits before interpreting a backtest.
Where Pineify fits

Pine Script AI Coding Agent

Draft or revise a public filter algorithm with explicit initialization and diagnostic outputs, then check its syntax and numerical behavior.

Draft a filter implementation

Frequently asked questions

Educational information, not investment advice. Examples use synthetic inputs and are not historical or live trading results. Filter smoothness, syntax acceptance and response times do not guarantee returns.

Sources and verification

Published by Pineify. Pineify is an independent product and is not affiliated with TradingView. Sources support the technical explanations; examples do not establish trading performance.