This script plots Nadaraya-Watson excursions outside a channel (envelope). Nadaraya-Watson is a type of Kernel regression method that makes use of the Gaussian kernel as a weighting function. Unlike a regular moving average whose degree of smoothness is commonly determined by the length of its calculation window, the degree of smoothness of the NW envelope is determined by the bandwidth setting, with a higher value bandwidth returning smoother results. The indicator as scripted plots when a bar extends above or below the upper and lower boundaries of the envelope. It is not unlike a Bollinger or Keltner envelope, but with a different calculation basis. The script does work as is. If you put it on any price chart you will see the "excursion" points indicated by "S" and "B". The reason I posted on StackOverflow is because I don't know how to delete older plots of the "excursions". In other words, the chart can get quite cluttered with lower bandwidth settings and difficult to see the price bars. Ideally, I would like the plot to only show the most recent 3 or 4 "excursions". Can you help?
//@version=5
indicator("NW-OB/OS-hl2-BW(3)-multi(1)", overlay = true, max_lines_count = 500, max_labels_count = 500, max_bars_back=500)
//------------------------------------------------------------------------------
//Settings
//-----------------------------------------------------------------------------{
h = input.float(3.,'Bandwidth', minval = 0)
mult = input.float(1, minval = 0)
src = input(hl2, 'Source')
repaint = input(true, 'Repainting Smoothing', tooltip = 'Repainting is an effect where the indicators historical output is subject to change over time. Disabling repainting will cause the indicator to output the endpoints of the calculations')
//Style
upCss = input.color(color.new(color.blue, 100), 'Colors', inline = 'inline1', group = 'Style')
dnCss = input.color(color.new(color.blue, 100), '', inline = 'inline1', group = 'Style')
//-----------------------------------------------------------------------------}
//Functions
//-----------------------------------------------------------------------------{
//Gaussian window
gauss(x, h) => math.exp(-(math.pow(x, 2)/(h * h * 2)))
//-----------------------------------------------------------------------------}
//Append lines
//-----------------------------------------------------------------------------{
n = bar_index
var ln = array.new_line(0)
if barstate.isfirst and repaint
for i = 0 to 499
array.push(ln,line.new(na,na,na,na))
//-----------------------------------------------------------------------------}
//End point method
//-----------------------------------------------------------------------------{
var coefs = array.new_float(0)
var den = 0.
if barstate.isfirst and not repaint
for i = 0 to 499
w = gauss(i, h)
coefs.push(w)
den := coefs.sum()
out = 0.
if not repaint
for i = 0 to 499
out += src[i] * coefs.get(i)
out /= den
mae = ta.sma(math.abs(src - out), 499) * mult
upper = out + mae
lower = out - mae
//-----------------------------------------------------------------------------}
//Compute and display NWE
//-----------------------------------------------------------------------------{
float y2 = na
float y1 = na
nwe = array.new<float>(0)
if barstate.islast and repaint
sae = 0.
//Compute and set NWE point
for i = 0 to math.min(499,n - 1)
sum = 0.
sumw = 0.
//Compute weighted mean
for j = 0 to math.min(499,n - 1)
w = gauss(i - j, h)
sum += src[j] * w
sumw += w
y2 := sum / sumw
sae += math.abs(src[i] - y2)
nwe.push(y2)
sae := sae / math.min(499,n - 1) * mult
for i = 0 to math.min(499,n - 1)
if i%2
line.new(n-i+1, y1 + sae, n-i, nwe.get(i) + sae, color = upCss, style=line.style_solid, width = 1)
line.new(n-i+1, y1 - sae, n-i, nwe.get(i) - sae, color = dnCss, style=line.style_solid, width = 1)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////// width
if src[i] > nwe.get(i) + sae and src[i+1] < nwe.get(i) + sae
label_red = label.new(n-i, src[i], 'S', color = color(na), style = label.style_label_down, size=size.huge, textcolor=color.new(color.red, 0), textalign=text.align_center)
label.delete(label_red[2])
if src[i] < nwe.get(i) - sae and src[i+1] > nwe.get(i) - sae
label_green = label.new(n-i, src[i], 'B', color = color(na), style = label.style_label_up, size=size.huge, textcolor = color.new(color.green, 0), textalign = text.align_center)
label.delete(label_green[2])
y1 := nwe.get(i)
////////////////////////////////////////////////////////////////
Push your
labels into an array. Then check its size. Whenever it is greater than 5, you can use thearray.shiftto remove the first element and get its value which will point to the oldestlabel. Then delete it.