Dynamic Zones of On Chart Stochastic [Loxx]
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © loxx

//@version=5
indicator("Dynamic Zones of On Chart Stochastic [Loxx]",
     shorttitle= "DZOCS [Loxx]", 
     overlay = true, 
     timeframe="", 
     timeframe_gaps = true)
     
import loxx/loxxdynamiczone/3

greencolor = #2DD204
redcolor = #D2042D

SM02 = 'Signal D'
SM03 = 'Middle Crossover'
SM04 = 'Levels Crossover'

variant(type, src, len) =>
    sig = 0.0
    if type == "SMA"
        sig := ta.sma(src, len) 
    else if type == "EMA"
        sig := ta.ema(src, len) 
    else if type == "WMA"
        sig := ta.wma(src, len)   
    else if type == "RMA"
        sig := ta.rma(src, len)  
    sig
    
_iStoch(priceR, priceH, priceL, int period, int slowing)=>
    _hi = priceH, _lo = priceL, _re = priceR, _ma = priceH, _mi= priceL
    for k = 1 to period - 1 
        _mi := math.min(_mi, nz(_lo[k]))
        _ma := math.max(_ma, nz(_hi[k]))
    sumlow  = 0.
    sumhigh = 0.
    for k = 1 to slowing - 1 
        sumlow  += nz(_re[k]) - nz(_mi[k])
        sumhigh += nz(_ma[k]) - nz(_mi[k]) 
    out = 100.0 * sumlow/sumhigh
    out

stper = input.int(13, "Stoch Period", group = "Basic Settings")
dper  =  input.int(13, "D Period", group = "Basic Settings")
sloper = input.int(8, "Slow Period", group = "Basic Settings")
type = input.string("SMA", "D Smoothing Type", options = ["EMA", "WMA", "RMA", "SMA"], group = "Basic Settings")

dzper = input.int(70, "Dynamic Zone Period", group = "Levels Settings")
buyprob  = input.float(0.1, "Dynamic Zone Buy Probability Level", group = "Levels Settings")
sellprob = input.float(0.1, "Dynamic Zone Sell Probability Level", group = "Levels Settings")

sigtype = input.string(SM03, "Signal type", options = [SM02, SM03, SM04], group = "Signal Settings")

colorbars = input.bool(false, "Color bars?", group = "UI Options")
showsignals = input.bool(false, "Show signals?", group = "UI Options")

stoValue = _iStoch(close, high, low, stper, sloper)

sigValue  = variant(type, stoValue,dper)
max = ta.highest(high, dzper)
min = ta.lowest(low, dzper)
rng = max-min
k = min + rng * stoValue /100
d = min + rng * sigValue /100

bli = loxxdynamiczone.dZone("buy", k, buyprob,  dzper)
sli = loxxdynamiczone.dZone("sell", k, sellprob,  dzper)
zli = loxxdynamiczone.dZone("sell", k, 0.5,  dzper)

state = 0.
if sigtype == SM02
    if (k<d) 
        state :=-1
    if (k>d) 
        state := 1
else if sigtype == SM03
    if (k<zli) 
        state :=-1
    if (k>zli)
        state := 1
else if sigtype == SM04
    if (k<bli) 
        state :=-1
    if (k>sli)
        state := 1

colorout = state == -1 ? redcolor : state == 1 ? greencolor : color.gray

plot(k, "K", color= colorout, linewidth = 3)

plot(d, "D", color= color.white, linewidth = 1)

plot(sli, "High Level", color = color.gray)
plot(bli, "Low Level" ,color = color.gray)

plot(zli, "Middle", color = color.gray)

barcolor(colorbars ? colorout : na)

goLong = sigtype == SM02 ? ta.crossover(k, d) : sigtype == SM03 ? ta.crossover(k, zli) : ta.crossover(k, sli)
goShort = sigtype == SM02 ? ta.crossunder(k, d) : sigtype == SM03 ? ta.crossunder(k, zli) :  ta.crossunder(k, bli)

plotshape(goLong and showsignals, title = "Long", color = color.yellow, textcolor = color.yellow, text = "L", style = shape.triangleup, location = location.belowbar, size = size.tiny)
plotshape(goShort and showsignals, title = "Short", color = color.fuchsia, textcolor = color.fuchsia, text = "S", style = shape.triangledown, location = location.abovebar, size = size.tiny)

alertcondition(goLong, title="Long", message="Dynamic Zones of On Chart Stochastic [Loxx]: Long\nSymbol: {{ticker}}\nPrice: {{close}}")
alertcondition(goShort, title="Short", message="Dynamic Zones of On Chart Stochastic [Loxx]: Short\nSymbol: {{ticker}}\nPrice: {{close}}")



