Faytterro Bands
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © faytterro

//@version=5
indicator("Faytterro Bands", overlay=true, max_lines_count=500, max_bars_back = 500)
src=input(hlc3,title="source")
len=input.int(50,title="lenght", maxval=500)

cr(x, y) =>
    z = 0.0
    weight = 0.0
    for i = 0 to y-1
        z:=z + x[i]*((y-1)/2+1-math.abs(i-(y-1)/2))
    z/(((y+1)/2)*(y+1)/2)
cr= cr(src,2*len-1) 

width=2

//plot(cr, color= #cf0202, linewidth=width,offset=-len+1)

dizii = array.new_float(500)
for k=0 to len-1
    sum=0.0
    for i=0 to 2*len-2-k
        sum +=(len-math.abs(len-1-k-i))*src[i]/(len*len-k*(k+1)/2)
    array.set(dizii,k, sum )

mult = input.float(2.0, minval=0.001, maxval=50, title="StdDev")
dev = mult * ta.stdev(src, len)
upper = cr + cr(dev, 2*len-1)
lower = cr - cr(dev, 2*len-1)
cu = input.color(color.rgb(255, 137, 137), "upper band color")
cl = input.color(color.rgb(137, 255, 97), "lower band color")
plot(lower, color=  cl, offset=1-len, linewidth=2, display = display.pane)
plot(upper, color=  cu, offset=1-len, linewidth=2, display = display.pane)
dashed=input.bool(false)
transp=input.bool(true)
d = dashed? 2 : 1
tra=transp? 1 : 0
// extrapolation
diz = array.new_float(500)
var lin=array.new_line()
diz2 = array.new_float(500)
var lin2=array.new_line(0)
if barstate.islast
    for k=0 to len-1
        sum=0.0
        dv=0.0
        for i=0 to 2*len-2-k
            sum +=(len-math.abs(len-1-k-i))*src[i]/(len*len-k*(k+1)/2) 
            dv +=(len-math.abs(len-1-k-i))*dev[i]/(len*len-k*(k+1)/2)
        array.set(diz,k, sum + dv)
        array.set(diz2,k, sum - dv)
    for i=0 to (len/d-1)
        array.push(lin, line.new(na, na, na, na))
        line.set_xy1(array.get(lin,i), bar_index[len]+i*d+1, array.get(diz,i*d))
        line.set_xy2(array.get(lin,i), bar_index[len]+i*d+2, array.get(diz,i*d+1))
        line.set_color(array.get(lin,i),color.new(cu, tra*i*95/(len/d-1)))//array.get(diz,i*2+1)>=array.get(diz,i*2)?  #35cf02 : #cf0202)
        line.set_width(array.get(lin,i),width)
        array.push(lin2, line.new(na, na, na, na))
        line.set_xy1(array.get(lin2,i), bar_index[len]+i*d+1, array.get(diz2,i*d))
        line.set_xy2(array.get(lin2,i), bar_index[len]+i*d+2, array.get(diz2,i*d+1))
        line.set_color(array.get(lin2,i),color.new(cl, tra*i*95/(len/d-1)) )//array.get(diz2,i*2+1)>=array.get(diz2,i*2)?  #35cf02 : #cf0202)
        line.set_width(array.get(lin2,i),width)
plot(array.get(diz,len-1), color = color.new(cu,100))
plot(array.get(diz2,len-1), color = color.new(cl,100))
alertcondition(ta.crossover(close,array.get(diz,len-1)) or ta.crossunder(close,array.get(diz2,len-1)), title = "faytterro bands alert", 
 message = "warning! this is an early warning alert, not a buy or sell signal. Remember that the indicator repaints to a limited extent on the last bars.")