Swing Boxes
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © tarasenko_

//@version=5
indicator("Swing Boxes", overlay = 1)




// Inputs
// Main Settings
p = input.int(200, "Black Box Period", 0, group = "Main Settings")
atr_p = input.int(14, "ATR Period", 1, group = "Main Settings")
atr_f = input.float(1.0, "ATR Factor", 0.1, step = 0.1, group = "Main Settings")

// Extra
show_box = input.bool(false, "Show Boxes?", group = "Extra")
show_midline = input.bool(false, "Show Baseline?", group = "Extra")




// Calculations
h = high 
l = low 
highest_low = p != 0 ? ta.highest(p) : open
lowest_high = p != 0 ? ta.lowest(p) : open
atr = ta.atr(atr_p)

// e means epsilon from calculus, so it is used
// for making top and bottom for "boxes", which are
// based on ATR
e = atr * atr_f                 
src = close[1]

// If previous close is higher than variable, which contains previous HIGHEST value, 
// then update the this variable by taking up-to-date highest value and add
// epsilon(e) to it
//
// Analogically for price being lower than variable, which contains previous LOWEST value
if src > nz(h[1], h) 
    h := highest_low + e
else if src < nz(l[1], l) 
    l := lowest_high - e
else 
    h := nz(h[1], h) 
    l := nz(l[1], l) 

// Baseline. Formed as a midline between box's top and bottom
bl = (h + l) / 2

// Colours
col = bl > bl[1] ? #00ff00 : #ff0000
col := bl == bl[1] ? col[1] : col

// Signal logic
buy = bl > bl[1] and col != col[1]
sell = bl < bl[1] and col != col[1]




// Visuals
plot(show_midline ? bl : na, "bl", col, 2)
plot(show_box ? h : na, "Box Top"   , color.gray, 1, plot.style_stepline)
plot(show_box ? l : na, "Box Bottom", color.gray, 1, plot.style_stepline)

plotshape(buy , "Buy" , shape.triangleup  , location.belowbar, col, 0, "" , col, size = size.tiny)
plotshape(sell, "sell", shape.triangledown, location.abovebar, col, 0, "", col, size = size.tiny)

barcolor(col)
