TradingView indicator guide

Gaussian Channel indicator: formula, poles and limits

A Gaussian Channel indicator places bands around a smoothed price series. In the recursive construction used here, identical exponential filters run in sequence: their final output is the center line, and the same cascade applied to True Range determines band width. The result describes past and current prices; it does not predict the next move. Check the specific script before comparing channels because source, coefficients, poles, initialization and optional lag adjustments can differ.

Draft a Gaussian Channel

Choose a defined algorithm, not just a script name

DonovanWall describes Gaussian Channel [DW] as an experiment combining the Ehlers filtering approach with True Range. That community implementation supports up to nine poles, an optional Reduced Lag Mode and a Fast Response Mode that blends one-pole and N-pole outputs. These are author-defined choices, not a universal TradingView specification. This page uses an independently written, causal cascade with one to four poles, first-input seeding and no lag adjustment.

  • Here, Gaussian refers to the recursive approximation used in this trading-filter family. It does not mean market returns follow a normal distribution.
  • A centered Gaussian-weighted window is a different construction. If it uses observations after the plotted timestamp, that historical point was not available at that time.
  • Record author, version, source, timeframe and settings when comparing charts. Matching only a displayed period does not establish numerical parity.

Calculate the center and width with separate cascades

Let X[t] be the price source and a be the smoothing coefficient. Set F0[t] = X[t]. For each stage k from 1 to N, compute Fk[t] = a × F(k−1)[t] + (1−a) × Fk[t−1]. The center is FN[t]. Each stage uses the current output of the preceding stage and its own previous output. Seed all stages with the first available input, then retain their states.

  • The coefficient formula sets the cascade magnitude to 1/√2 at angular frequency 2π/P: substituting it into [a² / (1 + (1−a)² − 2(1−a)cos(2π/P))]^N gives 1/2. This is a filter cutoff definition, not a market-cycle forecast.
  • This range smoother is not the default TradingView ATR, which uses an RMA. Replacing it with ta.atr changes the channel.
  • With nonnegative True Range, first-input seeding, 0 < a < 1 and m ≥ 0, the recursive range stays nonnegative. The upper band therefore cannot fall below the lower band in this version.
  • At a fixed a, increasing N adds delay. At a fixed P, a is recalculated for N, so a comparison must hold the intended parameter constant. Raising m changes width without changing the center.
QuantityDefinition in this exampleInterpretation
Coefficientb = (1 − cos(2π/P)) / (2^(1/N) − 1); a = √(b² + 2b) − bP is a cutoff period in bars; N is the number of poles.
True Rangemax(high − low, |high − previous close|, |low − previous close|)Use high − low on the first bar when previous close is unavailable.
Filtered range RRun the same N stages and coefficient on True RangeIts initialization is separate from the price filter.
BandsU = FN + mR; L = FN − mRmR is the half-width; the full width is 2mR.

Reproduce a three-bar calculation and a failed continuation

This hypothetical fixture isolates the recurrence: use close as the price source, two poles, a = 0.5 and m = 1.5. Before A, both price stages are 100, both range stages are 2, and the previous close is 100. The fixed coefficient is chosen for hand calculation; it is not the coefficient produced by the default script setting P = 20.

  • At A: F1 = 0.5 × 104 + 0.5 × 100 = 102; F2 = 0.5 × 102 + 0.5 × 100 = 101. True Range is 4, so R1 = 3 and R2 = 2.5.
  • At B: close 108 exceeds upper 107.5, while A closed below its upper band. A confirmed-close crossover rule would identify B.
  • At C: close falls to 100 and returns inside the channel. Its larger True Range expands the full width to 13.125. Neither the earlier breakout nor the widening band prevented the reversal.
  • This is an arithmetic counterexample to guaranteed continuation. It is not a historical backtest or an estimate of how often breakouts fail.
BarHigh / low / closePrice F1 / F2Range R1 / R2Lower / upper
A104 / 100 / 104102 / 1013 / 2.597.25 / 104.75
B108 / 104 / 108105 / 1033.5 / 398.5 / 107.5
C108 / 100 / 100102.5 / 102.755.75 / 4.37596.1875 / 109.3125

Inspect an explicit Pine Script v6 implementation

The example exposes one to four poles and a cutoff period. It uses chart-timeframe data, has no future offset, and applies no Reduced Lag or Fast Response transformation. After a stated warm-up, alerts detect a close crossing its current band on a confirmed bar. The plotted channel itself continues to develop during the open bar.

  • Default P = 20, N = 2 and m = 1.5 are demonstration settings. With these values, a is approximately 0.3821217336.
  • Price and range calls maintain independent states. All four stages calculate every bar; the pole input selects which stage becomes the output.
  • The first 5 × P bars are excluded from alerts as an explicit warm-up policy. This is not a proof that initialization error has become zero.
  • The source input changes the center calculation. Alerts still compare close with the bands, which is a separate, intentional decision rule.
  • Select Once Per Bar Close when creating an alert. The indicator contains no entries, exits, position sizing or transaction-cost model.
Pine v6 syntax check passed on 2026-10-17. Syntax validation does not prove parity with another script or profitable trading behavior.pine
//@version=6
indicator("Gaussian channel: explicit cascade", overlay = true)

source = input.source(close, "Price source")
period = input.int(20, "Cutoff period in bars", minval = 5, maxval = 500)
poles = input.int(2, "Poles", minval = 1, maxval = 4)
multiplier = input.float(1.5, "Filtered TR multiplier", minval = 0, step = 0.1)

// The total cascade has half power at frequency 2*pi/period.
beta = (1 - math.cos(2 * math.pi / period)) / (math.pow(2.0, 1.0 / poles) - 1)
alpha = math.sqrt(beta * beta + 2 * beta) - beta

onePole(float x, float a) =>
    var float y = na
    y := na(y[1]) ? x : a * x + (1 - a) * y[1]
    y

// Each written call has independent state, seeded from its first input.
p1 = onePole(source, alpha)
p2 = onePole(p1, alpha)
p3 = onePole(p2, alpha)
p4 = onePole(p3, alpha)
trueRange = ta.tr(true)
r1 = onePole(trueRange, alpha)
r2 = onePole(r1, alpha)
r3 = onePole(r2, alpha)
r4 = onePole(r3, alpha)
basis = poles == 1 ? p1 : poles == 2 ? p2 : poles == 3 ? p3 : p4
filteredTR = poles == 1 ? r1 : poles == 2 ? r2 : poles == 3 ? r3 : r4
halfWidth = multiplier * filteredTR
upper = basis + halfWidth
lower = basis - halfWidth

plot(basis, "Basis", color = color.blue, linewidth = 2)
upperPlot = plot(upper, "Upper", color = color.gray)
lowerPlot = plot(lower, "Lower", color = color.gray)
fill(upperPlot, lowerPlot, color = color.new(color.blue, 92))
plot(alpha, "Alpha", display = display.data_window)
plot(p1, "Price pole 1", display = display.data_window)
plot(r1, "TR pole 1", display = display.data_window)
plot(filteredTR, "Filtered TR", display = display.data_window)
plot(halfWidth, "Half width", display = display.data_window)

// Warm-up is an alert eligibility rule, not a claim that seed error becomes zero.
ready = bar_index >= 5 * period
crossAbove = ta.crossover(close, upper)
crossBelow = ta.crossunder(close, lower)
alertcondition(ready and barstate.isconfirmed and crossAbove, "Close crosses above upper", "Confirmed close crossed above the Gaussian upper band.")
alertcondition(ready and barstate.isconfirmed and crossBelow, "Close crosses below lower", "Confirmed close crossed below the Gaussian lower band.")

Separate lag, edge behavior and trading failures

A smooth line can hide the timing cost of smoothing. Inspect abrupt changes, the beginning of the dataset and the current open bar separately; they create different problems.

  • For the unadjusted cascade, each stage is a convex combination of its current input and previous state. Starting within the input range, it cannot overshoot that range on its own. Do not attribute compensation-related overshoot to this baseline formula.
  • For a simple two-times-current-minus-prior compensation, a jump from 100 to 110 creates a transformed input of 120. That constructed value explains why a faster-looking line can exceed observed prices; it does not reveal future prices.
  • Band width measures filtered range in price units. It is not a confidence interval, a probability of reversal or a guaranteed support/resistance boundary.
CaseWhat can happenCheck before using the signal
Abrupt reversalThe center retains earlier prices while the new price moves away. A breakout can fail on the next bar.Compare close and each stage around a reversal, including the fixture above.
Short or changed historyFirst-input seeding affects early values. Loading a different starting dataset can change the recursive path.Repeat the calculation with more preceding bars and compare the same timestamps.
Current right edgeHigh, low, close, center and width can move before the candle closes.Keep developing plots separate from confirmed alert decisions.
Centered-window variantThe right edge lacks future observations available to interior historical points. Padding, truncation or later revisions can distort comparisons.Read the kernel, window alignment and historical revision policy.
Fast or lag-adjusted variantExtra transformations change the response. Aggressive compensation can amplify changes or overshoot.Treat every enabled mode as a different calculation and test discontinuities.
Sideways marketRepeated crossings can alternate without a sustained trend. Costs can accumulate if every crossing becomes an order.Define a complete trading rule and evaluate untouched observations with costs.

How to use the Gaussian Channel indicator on TradingView

Start with a numerical comparison on standard candles. Keep symbol, session, timeframe, source and available history fixed. Choose completed timestamps, read the Data Window, then recompute the first stage, final stage and width before interpreting any color or crossover.

  • Check one quiet section, one large gap, one reversal and the first available bars. Verify True Range includes the previous close when a gap exceeds high minus low.
  • State whether a signal means a wick touch, a close outside, a crossover, or a rising center. These conditions can disagree on the same bar.
  • If two scripts disagree, compare coefficients, stage count, initialization and optional modes before changing the multiplier. The multiplier cannot fix a center-line mismatch.
  • Give the Pine Script AI Coding Agent the recurrence, chosen seed, confirmation rule and hypothetical table when requesting a modification. Ask for intermediate Data Window values so the result remains inspectable.
  • Only after values match, define exits, sizing, costs and out-of-sample tests. An indicator alert is not a complete strategy.
Where Pineify fits

Pine Script AI Coding Agent

Draft or revise a Gaussian Channel with explicit filter stages, range smoothing and confirmation rules. Verify intermediate bar values before adding strategy rules.

Draft a Gaussian Channel

Frequently asked questions

Educational information, not investment advice. The calculation table is hypothetical. Filter smoothness, band crossings and syntax validation do not establish future price direction or profitable strategy performance.

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.