David Varadi Intermediate Oscillator
// This work is licensed under a Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0) https://creativecommons.org/licenses/by-nc-sa/4.0/
// © EliCobra

//@version=5
indicator("David Varadi Intermediate Oscillator", "{Ʌ} - DVI", false, timeframe = "", timeframe_gaps = true)

mmult = input.float(0.8, "Magnitude Weight", group = "Composite Weight Ratio")
smult = input.float(0.2, "Stretch Weight", group = "Composite Weight Ratio")
nlen1 = input.int(5, "Magnitude Length 1", group = "Magnitude Lengths")
nlen2 = input.int(100, "Magnitude Length 2", group = "Magnitude Lengths")
nlen3 = input.int(5, "Magnitude Length 3", group = "Magnitude Lengths")
mlen1 = input.int(10, "Stretch Length 1", group = "Stretch Lengths")
mlen2 = input.int(100, "Stretch Length 1", group = "Stretch Lengths")
mlen3 = input.int(2, "Stretch Length 1", group = "Stretch Lengths")
colbar = input.string("None", "Bar Coloring", ["None", "Trend", "Extremeties", "Reversions"], group = "UI Options")
revshow = input.bool(true, "Show Reversal Signals", group = "UI Options")

k = 3
b = close > close[1] ? 1 : -1
r = close / ta.sma(close, 3) - 1

magnitude = ta.percentrank(ta.sma((nlen1 * ta.sma(r, nlen1) + nlen2 * ta.sma(r, nlen2) / 10) / 2, nlen3), 252)
stretch = ta.percentrank(ta.sma((mlen1 * ta.sma(r, mlen1) + mlen2 * ta.sma(r, mlen2) / 10) / 2, mlen3), 252)

dvi = mmult * magnitude + smult * stretch

d = plot(dvi, "DVI", dvi > 50 ? color.from_gradient(dvi, 50, 70, #a5a5a5, #00b350) : color.from_gradient(dvi, 30, 50, #bb0010, #9e9e9e))
hline(50, "Mid Line", #ffffff80, hline.style_dotted)
u = plot(80, "Upper Line", #ffffff80, display = display.pane)
l = plot(20, "Lower Line", #ffffff80, display = display.pane)

fill(d, u, 100, 80, #bb0010c0, #bb001000)
fill(d, l, 20, 0, #00b35100, #00b351b2)

plotshape(revshow ? dvi > 80 and dvi < dvi[1] and not (dvi[1] < dvi[2]) ? 110 : na : na, "OB", shape.triangledown, location.absolute, #bb0010, size = size.tiny)
plotshape(revshow ? dvi < 20 and dvi > dvi[1] and not (dvi[1] > dvi[2]) ? -10 : na : na, "OS", shape.triangleup, location.absolute, #00b350, size = size.tiny)

color col = switch colbar
    "None" => na
    "Trend" => dvi > 50 ? #00b350 : #bb0010
    "Extremeties" => dvi > 80 ? #00b350 : dvi < 20 ? #bb0010 : #b3b3b3c2
    "Reversions" => dvi > 80 and dvi < dvi[1] and not (dvi[1] < dvi[2]) ? #bb0010 : dvi < 20 and dvi > dvi[1] and not (dvi[1] > dvi[2]) ? #00b350 : #b3b3b3c2

barcolor(col)