Polynomial Regression Slope [QTL]
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © henryph24

//@version=5
indicator(title='Polynomial Regression Slope', shorttitle='PRS', overlay=false)

//CUSTOM
RS(y, t, o, degree) =>
    if degree == 1
        var x = 1
        x += 1
        b0 = math.sum(x, t)
        b1 = math.sum(math.pow(x, 2), t)
        c0 = math.sum(y, t)
        c1 = math.sum(x * y, t)
        a0 = (c0 * b1 - c1 * b0) / (t * b1 - math.pow(b0, 2))
        a1 = (t * c1 - b0 * c0) / (t * b1 - math.pow(b0, 2))
        lr = a0 + a1 * (x + o)
        LRS = lr - (na(lr[1]) ? lr : nz(lr[1]))
        LRS
    else if degree ==2
        var x = 1
        x += 1
        b0 = math.sum(x, t)
        b1 = math.sum(math.pow(x, 2), t)
        b2 = math.sum(math.pow(x, 3), t)
        b3 = math.sum(math.pow(x, 4), t)
        c0 = math.sum(y, t)
        c1 = math.sum(x * y, t)
        c2 = math.sum(math.pow(x, 2) * y, t)
        a0 = ((b1 * b3 - math.pow(b2, 2)) * (c0 * b2 - c1 * b1) - (b0 * b2 - math.pow(b1, 2)) * (c1 * b3 - c2 * b2)) / ((b1 * b3 - math.pow(b2, 2)) * (t * b2 - b0 * b1) - (b0 * b2 - math.pow(b1, 2)) * (b0 * b3 - b1 * b2))
        a1 = (c0 * b2 - c1 * b1 - (t * b2 - b0 * b1) * a0) / (b0 * b2 - math.pow(b1, 2))
        a2 = (c0 - t * a0 - b0 * a1) / b1
        qr = a0 + a1 * (x + o) + a2 * math.pow(x + o, 2)
        QRS = qr - (na(qr[1]) ? qr : nz(qr[1]))
        QRS
    else if degree == 3
        x = 1
        x += 1
        b0 = math.sum(x, t)
        b1 = math.sum(math.pow(x, 2), t)
        b2 = math.sum(math.pow(x, 3), t)
        b3 = math.sum(math.pow(x, 4), t)
        b4 = math.sum(math.pow(x, 5), t)
        b5 = math.sum(math.pow(x, 6), t)
        c0 = math.sum(y, t)
        c1 = math.sum(x * y, t)
        c2 = math.sum(math.pow(x, 2) * y, t)
        c3 = math.sum(math.pow(x, 3) * y, t)

        det = b0 * (b2 * b4 * b5 - b3 * b4 * b4) + b1 * (b3 * b3 * b5 - b2 * b4 * b5) + b2 * (b1 * b4 * b4 - b2 * b3 * b4) - b0 * b0 * b5 * b5 - b1 * b1 * b4 * b4 - b2 * b2 * b3 * b3

        a0 = (c0 * (b2 * b4 * b5 - b3 * b4 * b4) + c1 * (b3 * b3 * b5 - b2 * b4 * b5) + c2 * (b1 * b4 * b4 - b2 * b3 * b4) - c3 * (b0 * b4 * b4 - b1 * b3 * b4)) / det
        a1 = (c1 * (b0 * b4 * b5 - b2 * b3 * b5) + c2 * (b0 * b3 * b4 - b1 * b4 * b5) + c3 * (b0 * b2 * b4 - b1 * b3 * b4) - c0 * (b1 * b4 * b5 - b2 * b3 * b5)) / det
        a2 = (c2 * (b0 * b3 * b5 - b1 * b4 * b5) + c3 * (b0 * b1 * b4 - b0 * b2 * b3) + c0 * (b1 * b3 * b3 - b2 * b2 * b5) - c1 * (b0 * b2 * b4 - b1 * b3 * b4)) / det
        a3 = (c3 * (b0 * b1 * b5 - b0 * b2 * b4) + c0 * (b1 * b2 * b3 - b1 * b1 * b5) + c1 * (b0 * b2 * b2 - b1 * b1 * b4) - c2 * (b0 * b1 * b3 - b0 * b0 * b5)) / det

        cr = a0 + a1 * (x + o) + a2 * math.pow(x + o, 2) + a3 * math.pow(x + o, 3)
        CRS = cr - (na(cr[1]) ? cr : nz(cr[1]))
        CRS


//TOGGLE
isLinearSlope = input.bool(defval=true, title="Show Linear Regression")
isQuadraticSlope = input.bool(defval=true, title="Show Quadratic Regression")
isCubicSlope = input.bool(defval=true, title="Show Cubic Regression")
//UI
src = input(defval=close, title='Source')
per = input.int(defval=60, minval=1, title='Sample Size')
//INV

lrs = RS(src,per,0,1)
qrs = RS(src, per, 0,2)
crs = RS(src,per,0,3)
//PLOT
l_col = lrs > 0 ? color.rgb(25, 0, 255) : color.red
q_col = qrs > 0 ? color.rgb(0, 250, 8) : color.rgb(255, 0, 0)
c_col = crs > 0 ? color.rgb(0, 220, 254) : color.rgb(241, 0, 253)
plot(isLinearSlope ? lrs : na, color = l_col, linewidth=2, style = plot.style_columns)
plot(isQuadraticSlope ? qrs : na, color = q_col, linewidth=2, style = plot.style_columns)
plot(isCubicSlope ? crs : na, color = c_col, linewidth=2, style = plot.style_columns)

