Futures/Spot Ratio
// 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("Futures/Spot Ratio", max_lines_count = 500)
len=input.int(10, step = 1, minval = 1, maxval = 200, title = "Colorful Regression Length")
perp = input.symbol("BTCUSDTPERP", title = "futures")
spt = input.symbol("BTCUSDT", title = "spot")
float futures = request.security(perp, timeframe = "", expression = close)
float spot = request.security(spt, timeframe = "", expression = close)
r = futures/spot-1
a = ta.cum(math.abs(r))/bar_index
while a<1
    a:= a*10
    r:= r*10
src = r
fd(x,y) =>
    100-100/(math.pow(1+1/y,x)+1)
src := fd(src,a)
//plot(a)//, display = display.none)
plot(src, color = color.white, style = plot.style_circles)
line1=hline(50)
hline(100)
hline(0)
p2= plot(50, color=color.rgb(1,1,1,100), display = display.none)
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=input.int(1, title="linewidth", minval=1)
crm=ta.change(cr)
///////////
dx(x) =>
    x-x[1]
pm = dx(cr)
/////////////////////////
y = math.abs(pm)
n = bar_index
m = math.min(math.max(n-2*len+2,1),500)
t = ta.wma(y,m)//ta.cum(y)/n 
f = fd(pm,t/2)
f:= f*2.5
p1=plot(cr, color= color.rgb(math.min(510-2*f,255),math.min(2*f,255),0), linewidth=width,offset=-len+1, display = display.pane)
fill(p1,p2, color= cr>50? color.rgb(0, 255, 8, 80) : color.rgb(255, 82, 82, 80))
/////////////////////////
// extrapolation
diz = array.new_float(501)
var lin=array.new_line()
var lin2=array.new_line()
if barstate.islast
    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(diz,k, sum )
    for i=0 to (len-1)
        array.push(lin, line.new(na, na, na, na))
        fp= 2.5*fd(array.get(diz,i+1)-array.get(diz,i),t/2)
        line.set_color(array.get(lin,i),color.blue)//array.get(diz,i+1)>=array.get(diz,i)?  #35cf02 : #cf0202)
        line.set_xy1(array.get(lin,i), bar_index[len]+i+1, array.get(diz,i))
        line.set_xy2(array.get(lin,i),  bar_index[len]+i+2,array.get(diz,i+1))
        line.set_color(array.get(lin,i), color.rgb(math.min(510-2*fp,255),math.min(2*fp,255),0))
        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+1, 50)
        line.set_xy2(array.get(lin2,i),  bar_index[len]+i+2,50)
        line.set_color(array.get(lin2,i), color.rgb(0,0,0,100))
        linefill.new(array.get(lin2,i),array.get(lin,i), array.get(diz,i)>50? color.rgb(0, 255, 8,80) : color.rgb(255, 82, 82, 80))

fp= 2.5*fd(array.get(diz,1)-array.get(diz,0),t/2)
plot(ta.wma(src,len), color = color.rgb(math.min(510-2*fp,255),math.min(2*fp,255),0,100))