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.
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.")