The following script calculates the 90th and 10th percentile of price over a 100-bar lookback window using linear interpolation, generating statistical channels that adapt to shifting market volatility.
Pine Script v6: Adaptive percentile channel indicatorpinescript
//@version=6
indicator("Adaptive Percentile Bands [v6]", overlay = true)
// Input configuration
int lookback = input.int(100, "Lookback Period", minval = 10)
float upperPercentile = input.float(90.0, "Upper Percentile (%)", minval = 50.0, maxval = 100.0)
float lowerPercentile = input.float(10.0, "Lower Percentile (%)", minval = 0.0, maxval = 50.0)
// Calculate interpolated percentiles
float upperBand = ta.percentile_linear_interpolation(high, lookback, upperPercentile)
float lowerBand = ta.percentile_linear_interpolation(low, lookback, lowerPercentile)
float medianBand = ta.percentile_linear_interpolation(close, lookback, 50.0)
// Breakout signals
bool upperBreakout = ta.crossover(close, upperBand)
bool lowerBreakout = ta.crossunder(close, lowerBand)
// Visual plots
plot(upperBand, "90th Percentile Band", color = color.red, linewidth = 2)
plot(medianBand, "50th Percentile (Median)", color = color.gray, linewidth = 1, style = plot.style_linebr)
plot(lowerBand, "10th Percentile Band", color = color.green, linewidth = 2)
// Shape markers
plotshape(upperBreakout, "High Percentile Break", shape.triangleup, location.abovebar, color.red, size = size.tiny)
plotshape(lowerBreakout, "Low Percentile Break", shape.triangledown, location.belowbar, color.green, size = size.tiny)
// Dynamic channel fill
fill(plot(upperBand), plot(lowerBand), color = color.new(color.blue, 94), title = "Percentile Distribution Zone")