Stochastic Spread Analyzer
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © ekrem6nel

//@version=4
study("Stochastic Spread Analyzer")
lengthSmall = input(20, minval=1)
lengthMid = input(80, minval=1)
lengthHigh = input(320, minval=1)

htf1 = input(4)
htf2 = input(16)
htf3 = input(64)
length = input(10)
lenk = input(3)
lend = input(3)
macd_fast = input(12)
macd_slow = input(26)
macd_smooth = input(9)
portfolio = input("SPY")

stokCandle(c, h, l, length, lenk, lend) =>
    k = sma(stoch(c, h, l, length), lenk)
    d = sma(k, lend)
    [k, d]

stok(src, length, lenk, lend) =>
    stokCandle(src, src, src, length, lenk, lend)

signalColor(k, d, floorColor, ceilingColor, upColor, downColor) =>
    k < 20 ? floorColor : (k > 80 ? ceilingColor : (change(d) > 0 ? upColor : downColor))
    

[fc, fo, fh, fl, fv]=security(portfolio, "", [close, open, high, low, obv])

calculateScore(src_c, src_low, src_high) =>
    lower = lowest(src_low, lengthSmall)
    upper = highest(src_high, lengthSmall)
    
    lowerMid = lowest(src_low, lengthMid)
    upperMid = highest(src_high, lengthMid)
    
    lowerHigh = lowest(src_low, lengthHigh)
    upperHigh = highest(src_high, lengthHigh)
    
    basis = avg(upper, lower)
    up = src_c - lower
    dn = upper - src_c
    r = upper - lower
    p = up/r
    upMid = src_c - lowerMid
    dnMid = upperMid - src_c
    rMid = upperMid - lowerMid
    pMid = upMid/rMid
    upHigh = src_c - lowerHigh
    dnHigh = upperHigh - src_c
    rHigh = upperHigh - lowerHigh
    pHigh = upHigh/rHigh
    
    score = (p*pMid*pHigh)*100
    scoreEma = ema(score, 200)
    [score, scoreEma]

[score, scoreEma] = calculateScore(close/fc, low/fl, high/fh)
[scoreObv, scoreObvEma] = calculateScore(obv/fv, obv/fv, obv/fv)

[k, d] = stok(score, length, lenk, lend)
[krsi, drsi] = stok(rsi(score, length), length, lenk, lend)
[m, s, h] = macd(score, macd_fast, macd_slow, macd_smooth)
[kh, dh] = stok(h, length, lenk, lend)
[km, dm] = stok(m, length, lenk, lend)

[kobv, dobv] = stok(scoreObv, length, lenk, lend)
[krsiobv, drsiobv] = stok(rsi(scoreObv, length), length, lenk, lend)
[mobv, sobv, hobv] = macd(scoreObv, macd_fast, macd_slow, macd_smooth)
[khobv, dhobv] = stok(hobv, length, lenk, lend)
[kmobv, dmobv] = stok(mobv, length, lenk, lend)

floorColor = color.red
ceilingColor = color.lime
upColor = color.lime
downColor = color.red

floorColorObv = color.orange
ceilingColorObv = color.blue
upColorObv = color.blue
downColorObv = color.orange

powerColor = signalColor(kh, dh, floorColor, ceilingColor, upColor, downColor)
trendColor = signalColor(score, scoreEma, floorColor, ceilingColor, upColor, downColor)
segmentColor = signalColor(k, d, floorColor, ceilingColor, upColor, downColor)

powerColorObv = signalColor(khobv, dhobv, floorColorObv, ceilingColorObv, upColorObv, downColorObv)
trendColorObv = signalColor(scoreObv, scoreObvEma, floorColorObv, ceilingColorObv, upColorObv, downColorObv)
segmentColorObv = signalColor(kobv, dobv, floorColorObv, ceilingColorObv, upColorObv, downColorObv)

h80 = hline(20, "Upper Band", color=#606060)
h20 = hline(80, "Lower Band", color=#606060)
fill(h20, h80, color = color.purple, transp=80, title="Background")

sobvp = plot(20 + kobv*0.6, color=powerColorObv, linewidth = 1, style = plot.style_columns, transp = 60, histbase = 20)
//maobvp = plot(dmobv, color = segmentColorObv, linewidth = 1)

sp = plot(k, color=powerColor, linewidth = 2)
map = plot(d, color = color.orange, linewidth = 1)
fill(sp, map, color = trendColor , transp=60, title="Fill")