Equity Sessions [vnhilton]
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © vnhilton

//@version=5
indicator("Equity Sessions [vnhilton]", "Equity Sessions", true, max_boxes_count = 500)
//________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
//Inputs
errorMsg = input.bool(true,   "Show Error Message On Non-Intraday Timeframes?")

lookback     = input.int(2,  "Number of Day Lookbacks", 1, 250,                             group = "Main Settings")
advPeriod    = input.int(20, "ADV/DATR Period",         1,      inline = "Period Settings", group = "Main Settings")
datrPeriod   = input.int(20, "",                        1,      inline = "Period Settings", group = "Main Settings")

textSize     = input.string("Small",      "Text Size/Placement",  ["Auto", "Tiny", "Small", "Normal", "Large", "Huge"], inline = "Text Settings",   group = "Text Settings")
dvFormat     = input.string("%",          "DV/ADV/ATR Format",    ["%", "Multiplier"],                                  inline = "Format Settings", group = "Text Settings")
advFormat    = input.string("Multiplier", "",                     ["%", "Multiplier"],                                  inline = "Format Settings", group = "Text Settings")
datrFormat   = input.string("Multiplier", "",                     ["%", "Multiplier"],                                  inline = "Format Settings", group = "Text Settings")

sessionOn1   = input.bool(true, "", inline = "Toggles #1", group = "Session #1 (Pre-Market)")
sessionOn2   = input.bool(true, "", inline = "Toggles #2", group = "Session #2")
sessionOn3   = input.bool(true, "", inline = "Toggles #3", group = "Session #3")
sessionOn4   = input.bool(true, "", inline = "Toggles #4", group = "Session #4")
sessionOn5   = input.bool(true, "", inline = "Toggles #5", group = "Session #5")
sessionOn6   = input.bool(true, "", inline = "Toggles #6", group = "Session #6")
sessionOn7   = input.bool(true, "", inline = "Toggles #7", group = "Session #7 (After-Hours)")

showVolume1  = input.bool(true, "", inline = "Toggles #1", group = "Session #1 (Pre-Market)")
showVolume2  = input.bool(true, "", inline = "Toggles #2", group = "Session #2")
showVolume3  = input.bool(true, "", inline = "Toggles #3", group = "Session #3")
showVolume4  = input.bool(true, "", inline = "Toggles #4", group = "Session #4")
showVolume5  = input.bool(true, "", inline = "Toggles #5", group = "Session #5")
showVolume6  = input.bool(true, "", inline = "Toggles #6", group = "Session #6")
showVolume7  = input.bool(true, "", inline = "Toggles #7", group = "Session #7 (After-Hours)")

showDV1      = input.bool(true, "", inline = "Toggles #1", group = "Session #1 (Pre-Market)")
showDV2      = input.bool(true, "", inline = "Toggles #2", group = "Session #2")
showDV3      = input.bool(true, "", inline = "Toggles #3", group = "Session #3")
showDV4      = input.bool(true, "", inline = "Toggles #4", group = "Session #4")
showDV5      = input.bool(true, "", inline = "Toggles #5", group = "Session #5")
showDV6      = input.bool(true, "", inline = "Toggles #6", group = "Session #6")
showDV7      = input.bool(true, "", inline = "Toggles #7", group = "Session #7 (After-Hours)")

showADV1     = input.bool(true, "", inline = "Toggles #1", group = "Session #1 (Pre-Market)")
showADV2     = input.bool(true, "", inline = "Toggles #2", group = "Session #2")
showADV3     = input.bool(true, "", inline = "Toggles #3", group = "Session #3")
showADV4     = input.bool(true, "", inline = "Toggles #4", group = "Session #4")
showADV5     = input.bool(true, "", inline = "Toggles #5", group = "Session #5")
showADV6     = input.bool(true, "", inline = "Toggles #6", group = "Session #6")
showADV7     = input.bool(true, "", inline = "Toggles #7", group = "Session #7 (After-Hours)")

showSATR1    = input.bool(true, "", inline = "Toggles #1", group = "Session #1 (Pre-Market)")
showSATR2    = input.bool(true, "", inline = "Toggles #2", group = "Session #2")
showSATR3    = input.bool(true, "", inline = "Toggles #3", group = "Session #3")
showSATR4    = input.bool(true, "", inline = "Toggles #4", group = "Session #4")
showSATR5    = input.bool(true, "", inline = "Toggles #5", group = "Session #5")
showSATR6    = input.bool(true, "", inline = "Toggles #6", group = "Session #6")
showSATR7    = input.bool(true, "", inline = "Toggles #7", group = "Session #7 (After-Hours)")

showATR1    = input.bool(true, "Show Session/Volume/DV/ADV/SATR/ATR?", inline = "Toggles #1", group = "Session #1 (Pre-Market)")
showATR2    = input.bool(true, "Show Session/Volume/DV/ADV/SATR/ATR?", inline = "Toggles #2", group = "Session #2")
showATR3    = input.bool(true, "Show Session/Volume/DV/ADV/SATR/ATR?", inline = "Toggles #3", group = "Session #3")
showATR4    = input.bool(true, "Show Session/Volume/DV/ADV/SATR/ATR?", inline = "Toggles #4", group = "Session #4")
showATR5    = input.bool(true, "Show Session/Volume/DV/ADV/SATR/ATR?", inline = "Toggles #5", group = "Session #5")
showATR6    = input.bool(true, "Show Session/Volume/DV/ADV/SATR/ATR?", inline = "Toggles #6", group = "Session #6")
showATR7    = input.bool(true, "Show Session/Volume/DV/ADV/SATR/ATR?", inline = "Toggles #7", group = "Session #7 (After-Hours)")

name1        = input.string("Pre-Market",      "Name/Placement",         inline = "Name & Constraints #1", group = "Session #1 (Pre-Market)")
name2        = input.string("Late Prints",     "Name/Session/Placement", inline = "Name & Constraints #2", group = "Session #2")
name3        = input.string("Morning",         "Name/Session/Placement", inline = "Name & Constraints #3", group = "Session #3")
name4        = input.string("Initial Balance", "Name/Session/Placement", inline = "Name & Constraints #4", group = "Session #4")
name5        = input.string("Lunch",           "Name/Session/Placement", inline = "Name & Constraints #5", group = "Session #5")
name6        = input.string("Afternoon",       "Name/Session/Placement", inline = "Name & Constraints #6", group = "Session #6")
name7        = input.string("After-Hours",     "Name/Placement",         inline = "Name & Constraints #7", group = "Session #7 (After-Hours)")

session2     = input.string("All",     "", ["All", "Regular"], inline = "Name & Constraints #2", group = "Session #2")
session3     = input.string("Regular", "", ["All", "Regular"], inline = "Name & Constraints #3", group = "Session #3")
session4     = input.string("Regular", "", ["All", "Regular"], inline = "Name & Constraints #4", group = "Session #4")
session5     = input.string("Regular", "", ["All", "Regular"], inline = "Name & Constraints #5", group = "Session #5")
session6     = input.string("Regular", "", ["All", "Regular"], inline = "Name & Constraints #6", group = "Session #6")

textPlace1    = input.string("Bottom", "", ["Top", "Bottom"], inline = "Name & Constraints #1", group = "Session #1 (Pre-Market)")
textPlace2    = input.string("Top",    "", ["Top", "Bottom"], inline = "Name & Constraints #1", group = "Session #2")
textPlace3    = input.string("Bottom", "", ["Top", "Bottom"], inline = "Name & Constraints #1", group = "Session #3")
textPlace4    = input.string("Top",    "", ["Top", "Bottom"], inline = "Name & Constraints #1", group = "Session #4")
textPlace5    = input.string("Bottom", "", ["Top", "Bottom"], inline = "Name & Constraints #1", group = "Session #5")
textPlace6    = input.string("Bottom", "", ["Top", "Bottom"], inline = "Name & Constraints #1", group = "Session #6")
textPlace7    = input.string("Bottom", "", ["Top", "Bottom"], inline = "Name & Constraints #1", group = "Session #7 (After-Hours)")

time1        = input.session("0400-0930", "Time", tooltip = "Don't make the end time within after-hours",                                                                              group = "Session #1 (Pre-Market)")
time2        = input.session("0800-0815", "Time",                                                                                                                                      group = "Session #2")
time3        = input.session("0930-1130", "Time",                                                                                                                                      group = "Session #3")
time4        = input.session("0930-1030", "Time",                                                                                                                                      group = "Session #4")
time5        = input.session("1130-1400", "Time",                                                                                                                                      group = "Session #5")
time6        = input.session("1400-1600", "Time",                                                                                                                                      group = "Session #6")
time7        = input.session("0930-2000", "Time", tooltip = "Make the start time earlier than official after-hours start time in case of short days, but not when pre-market starts",  group = "Session #7 (After-Hours)")

borderColor1 = input.color(color.new(color.orange, 100), "Border/Background/Text/Color", inline = "Colors #1", group = "Session #1 (Pre-Market)")
borderColor2 = input.color(color.new(color.yellow, 100), "Border/Background/Text Color", inline = "Colors #2", group = "Session #2")
borderColor3 = input.color(color.new(color.green,  100), "Border/Background/Text Color", inline = "Colors #3", group = "Session #3")
borderColor4 = input.color(color.new(color.silver, 100), "Border/Background/Text Color", inline = "Colors #4", group = "Session #4")
borderColor5 = input.color(color.new(color.red,    100), "Border/Background/Text Color", inline = "Colors #5", group = "Session #5")
borderColor6 = input.color(color.new(color.teal,   100), "Border/Background/Text Color", inline = "Colors #6", group = "Session #6")
borderColor7 = input.color(color.new(color.blue,   100), "Border/Background/Text/Color", inline = "Colors #7", group = "Session #7 (After-Hours)")

bgColor1     = input.color(color.new(color.orange, 90), "", inline = "Colors #1", group = "Session #1 (Pre-Market)")
bgColor2     = input.color(color.new(color.yellow, 90), "", inline = "Colors #2", group = "Session #2")
bgColor3     = input.color(color.new(color.green,  90), "", inline = "Colors #3", group = "Session #3")
bgColor4     = input.color(color.new(color.silver, 90), "", inline = "Colors #4", group = "Session #4")
bgColor5     = input.color(color.new(color.red,    90), "", inline = "Colors #5", group = "Session #5")
bgColor6     = input.color(color.new(color.teal,   90), "", inline = "Colors #6", group = "Session #6")
bgColor7     = input.color(color.new(color.blue,   90), "", inline = "Colors #7", group = "Session #7 (After-Hours)")

textColor1   = input.color(color.orange,                "", inline = "Colors #1", group = "Session #1 (Pre-Market)")
textColor2   = input.color(color.yellow,                "", inline = "Colors #2", group = "Session #2")
textColor3   = input.color(color.green,                 "", inline = "Colors #3", group = "Session #3")
textColor4   = input.color(color.silver,                "", inline = "Colors #4", group = "Session #4")
textColor5   = input.color(color.red,                   "", inline = "Colors #5", group = "Session #5")
textColor6   = input.color(color.teal,                  "", inline = "Colors #6", group = "Session #6")
textColor7   = input.color(color.blue,                  "", inline = "Colors #7", group = "Session #7 (After-Hours)")

borderWidth1 = input.int(1, "Border Width/Style", 0, inline = "Border Type #1", group = "Session #1 (Pre-Market)")
borderWidth2 = input.int(1, "Border Width/Style", 0, inline = "Border Type #2", group = "Session #2")
borderWidth3 = input.int(1, "Border Width/Style", 0, inline = "Border Type #3", group = "Session #3")
borderWidth4 = input.int(1, "Border Width/Style", 0, inline = "Border Type #4", group = "Session #4")
borderWidth5 = input.int(1, "Border Width/Style", 0, inline = "Border Type #5", group = "Session #5")
borderWidth6 = input.int(1, "Border Width/Style", 0, inline = "Border Type #6", group = "Session #6")
borderWidth7 = input.int(1, "Border Width/Style", 0, inline = "Border Type #7", group = "Session #7 (After-Hours)")

borderStyle1 = input.string("Solid", "", ["Dashed", "Dotted", "Solid"], inline = "Border Type #1", group = "Session #1 (Pre-Market)")
borderStyle2 = input.string("Solid", "", ["Dashed", "Dotted", "Solid"], inline = "Border Type #2", group = "Session #2")
borderStyle3 = input.string("Solid", "", ["Dashed", "Dotted", "Solid"], inline = "Border Type #3", group = "Session #3")
borderStyle4 = input.string("Solid", "", ["Dashed", "Dotted", "Solid"], inline = "Border Type #4", group = "Session #4")
borderStyle5 = input.string("Solid", "", ["Dashed", "Dotted", "Solid"], inline = "Border Type #5", group = "Session #5")
borderStyle6 = input.string("Solid", "", ["Dashed", "Dotted", "Solid"], inline = "Border Type #6", group = "Session #6")
borderStyle7 = input.string("Solid", "", ["Dashed", "Dotted", "Solid"], inline = "Border Type #7", group = "Session #7 (After-Hours)")
//________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
//Boxes
var box   [] boxes1        = array.new<box>()
var box   [] boxes2        = array.new<box>()
var box   [] boxes3        = array.new<box>()
var box   [] boxes4        = array.new<box>()
var box   [] boxes5        = array.new<box>()
var box   [] boxes6        = array.new<box>()
var box   [] boxes7        = array.new<box>()

var box   [] boxesText1    = array.new<box>()
var box   [] boxesText2    = array.new<box>()
var box   [] boxesText3    = array.new<box>()
var box   [] boxesText4    = array.new<box>()
var box   [] boxesText5    = array.new<box>()
var box   [] boxesText6    = array.new<box>()
var box   [] boxesText7    = array.new<box>()

//Variables
var bool  [] createdChecks = array.new<bool>(7,  false)
var float [] sessionHighs  = array.new<float>(7, na)
var float [] sessionLows   = array.new<float>(7, na)
var int   [] sessionVols   = array.new<int>(7,   0)

//Table
var table error = table.new(position.top_right, 1, 1, bgcolor=color.red)

//Daily Values
adv = ta.sma(volume, advPeriod)
atr = ta.atr(datrPeriod)

[dVol, dADV, dATR] = request.security(syminfo.tickerid, "D", [volume, adv[1], atr[1]], lookahead = barmerge.lookahead_on)

//Text Size
chosenTextSize  = switch textSize
    "Auto"    => size.auto
    "Tiny"    => size.tiny
    "Small"   => size.small
    "Normal"  => size.normal
    "Large"   => size.large
    => size.huge
//________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
//Text Placement Function
TextPlacement(choice) =>
    choice == "Top" ? text.align_bottom : text.align_top

//Format Text Function
FormatText(number, reference, format) =>
    if format == "%"
        str.tostring(number * 100 / reference, '#0.00') + "%"
    else
        str.tostring(number       / reference, '#0.00') + "x"

//Constraints Function
Constraints(choice) =>
    switch
        choice == "All"     => time(timeframe.period, session.extended)
        choice == "Regular" => time(timeframe.period, session.regular)
        => not(time(timeframe.period, session.regular))

//Border Style Function
BorderStyle(choice) =>
    switch
        choice == "Dashed" => line.style_dashed
        choice == "Dotted" => line.style_dotted
        => line.style_solid

//Plot Function
Plot(number, created, session, sessionOn, constrained, boxes, borderColor, borderWidth, borderStyle, bgColor, boxesText, name, textColor, textAlign, showVol, showDV, showADV, showSATR, showATR) =>
    if session and sessionOn and constrained
        if array.size(boxes) == lookback + 1
            box.delete(array.shift(boxes))
            box.delete(array.shift(boxesText))
        
        if not created
            array.set(sessionHighs, number, high)
            array.set(sessionLows,  number, low)

            array.push(boxes,     box.new(bar_index, array.get(sessionHighs, number), bar_index, array.get(sessionLows, number), borderColor, borderWidth, borderStyle, bgcolor = bgColor))
            array.push(boxesText, box.new(bar_index, array.get(sessionLows, number),  bar_index, array.get(sessionLows, number), color.new(#000000, 100), bgcolor = color.new(#000000, 100), text_size = chosenTextSize, text_color = textColor, text_halign = text.align_left, text_valign = textAlign))
            
            array.set(sessionVols,   number, array.get(sessionVols, number) + int(volume))
            array.set(createdChecks, number, true)
        else
            array.set(sessionHighs, number, math.max(array.get(sessionHighs, number), high))
            array.set(sessionLows,  number, math.min(array.get(sessionLows,  number), low))
            array.set(sessionVols,  number, array.get(sessionVols, number) + int(volume))

            box.set_top(array.last(boxes),    array.get(sessionHighs, number))
            box.set_right(array.last(boxes),  bar_index)
            box.set_bottom(array.last(boxes), array.get(sessionLows,  number))

            box.set_top(array.last(boxesText),    textAlign == text.align_top ? array.get(sessionLows,  number) : array.get(sessionHighs,  number))
            box.set_bottom(array.last(boxesText), textAlign == text.align_top ? array.get(sessionLows,  number) : array.get(sessionHighs,  number))

            dv         = showDV   ? " • " + FormatText(array.get(sessionVols, number), dVol, dvFormat)  : na
            adVol      = showADV  ? " • " + FormatText(array.get(sessionVols, number), dADV, advFormat) : na
            sessionATR = array.get(sessionHighs, number) - array.get(sessionLows, number)      
            dayATR     = showATR  ? " • " + FormatText(sessionATR, dATR, datrFormat)                    : na
            
            finalText = name + "\n" + (showVol ? "Volume: " + str.tostring(array.get(sessionVols, number), format.volume) : na) + dv + adVol + "\n" + (showSATR ? "ATR: " + str.tostring(sessionATR) : na) + dayATR
            box.set_text(array.last(boxesText), finalText)

    if created and (na(session) or not constrained) 
        array.set(sessionHighs, number, na)
        array.set(sessionLows,  number, na)
        array.set(sessionVols,  number, 0)

        array.set(createdChecks, number, false)
//________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
//MAIN
if timeframe.isdwm
    if errorMsg
        table.cell(error, 0, 0, "ERROR: Sessions indicator only works on intraday timeframes.", text_color=color.white)
else
    Plot(0, array.get(createdChecks, 0), time(timeframe.period, time1), sessionOn1, Constraints("Extended"), boxes1, borderColor1, borderWidth1, BorderStyle(borderStyle1), bgColor1, boxesText1, name1, textColor1, TextPlacement(textPlace1), showVolume1, showDV1, showADV1, showSATR1, showATR1)
    Plot(1, array.get(createdChecks, 1), time(timeframe.period, time2), sessionOn2, Constraints(session2),   boxes2, borderColor2, borderWidth2, BorderStyle(borderStyle2), bgColor2, boxesText2, name2, textColor2, TextPlacement(textPlace2), showVolume2, showDV2, showADV2, showSATR2, showATR2)
    Plot(2, array.get(createdChecks, 2), time(timeframe.period, time3), sessionOn3, Constraints(session3),   boxes3, borderColor3, borderWidth3, BorderStyle(borderStyle3), bgColor3, boxesText3, name3, textColor3, TextPlacement(textPlace3), showVolume3, showDV3, showADV3, showSATR3, showATR3)
    Plot(3, array.get(createdChecks, 3), time(timeframe.period, time4), sessionOn4, Constraints(session4),   boxes4, borderColor4, borderWidth4, BorderStyle(borderStyle4), bgColor4, boxesText4, name4, textColor4, TextPlacement(textPlace4), showVolume4, showDV4, showADV4, showSATR4, showATR4)
    Plot(4, array.get(createdChecks, 4), time(timeframe.period, time5), sessionOn5, Constraints(session5),   boxes5, borderColor5, borderWidth5, BorderStyle(borderStyle5), bgColor5, boxesText5, name5, textColor5, TextPlacement(textPlace5), showVolume5, showDV5, showADV5, showSATR5, showATR5)
    Plot(5, array.get(createdChecks, 5), time(timeframe.period, time6), sessionOn6, Constraints(session6),   boxes6, borderColor6, borderWidth6, BorderStyle(borderStyle6), bgColor6, boxesText6, name6, textColor6, TextPlacement(textPlace6), showVolume6, showDV6, showADV6, showSATR6, showATR6)
    Plot(6, array.get(createdChecks, 6), time(timeframe.period, time7), sessionOn7, Constraints("Extended"), boxes7, borderColor7, borderWidth7, BorderStyle(borderStyle7), bgColor7, boxesText7, name7, textColor7, TextPlacement(textPlace7), showVolume7, showDV7, showADV7, showSATR7, showATR7)

