Dynamic Zone of Bollinger Band Stops Line [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 Zone of Bollinger Band Stops Line [Loxx]",
     shorttitle= "DZBBSL [Loxx]", 
     overlay = true, 
     timeframe="", 
     timeframe_gaps = true)

import loxx/loxxdynamiczone/3

greencolor = #2DD204
redcolor = #D2042D

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
    
_bbline(per, type, src, dev)=>
    StdDev = ta.stdev(src, per) 
    ma = variant(type, src, per)
    result = 0., _trend = 0.
    smax = ma + (StdDev * dev)
    smin = ma - (StdDev * dev)
    _trend := nz(_trend[1])
    if (close > nz(smax[1])) 
        _trend := 1 
    if (close < nz(smin[1])) 
        _trend := -1 
    if (_trend == 1)  
        if (smin < nz(smin[1])) 
            smin := nz(smin[1]) 
        result := smin
    if (_trend == -1)  
        if (smax > nz(smax[1])) 
            smax := nz(smax[1]) 
        result := smax
    result
    
SM02 = 'Slope'
SM03 = 'Middle Crossover'
SM04 = 'Levels Crossover'

per = input.int(20, "Period", group = "Basic Settings")
src = input.source(close, "Source", group = "Basic Settings")
dev = input.float(0.5, "Deviations Multiple", group = "Basic Settings")
type = input.string("SMA", "Source Filter Type", options = ["EMA", "WMA", "RMA", "SMA"], group = "Basic Settings")

dzper = input.int(35, "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")

out = _bbline(per, type, src, dev)
sig = out[1]

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

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

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

plot(out, "BBLine", color= colorout, linewidth = 3)

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

barcolor(colorbars ? colorout : na)

goLong = sigtype == SM02 ? ta.crossover(out, sig) : sigtype == SM03 ? ta.crossover(out, zli) : ta.crossover(out, sli)
goShort = sigtype == SM02 ? ta.crossunder(out, sig) : sigtype == SM03 ? ta.crossunder(out, zli) :  ta.crossunder(out, 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 Zone of Bollinger Band Stops Line [Loxx]: Long\nSymbol: {{ticker}}\nPrice: {{close}}")
alertcondition(goShort, title="Short", message="Dynamic Zone of Bollinger Band Stops Line [Loxx]]: Short\nSymbol: {{ticker}}\nPrice: {{close}}")



