Daily Levels Suite + Market Breadth
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © mcthatsme
//@version=5

indicator("Daily Levels Suite + Premarket High/Low", shorttitle="Daily Levels",overlay=true, max_lines_count=500, max_labels_count=500)

//////////////////////////////////////////////////
/////////           Inputs             ///////////
//////////////////////////////////////////////////
//Groups
var dailyGroup   = "Daily Levels"
var weeklyGroup  = "Weekly Levels"
var monthlyGroup = "Monthly Levels"

//Input for level colors
showDailyLevels = input.bool  (defval=true, title="Show Daily Levels" , group=dailyGroup)

//Previous Day High/Low
currHighName    = input.string(defval="Current Day High"      , title="", group=dailyGroup, inline="1")
currHighColor   = input.color (defval=color.gray            , title="", group=dailyGroup, inline="1")
showCurrHigh    = input.bool  (defval=false                   , title="", group=dailyGroup, inline="1")
currLowName     = input.string(defval="Current Day Low"       , title="", group=dailyGroup, inline="1")
currLowColor    = input.color (defval=color.gray            , title="", group=dailyGroup, inline="1")
showCurrLow     = input.bool  (defval=false                   , title="", group=dailyGroup, inline="1")

//Globex Open (9:30 AM open on stocks, globex on futures), RTH Open (when using futures)
globexOpenName  = input.string(defval="Globex Open"            , title="", group=dailyGroup, inline="2")
globexOpenColor = input.color (defval=color.white            , title="", group=dailyGroup, inline="2")
showGlobexOpen  = input.bool  (defval=false                    , title="", group=dailyGroup, inline="2")
rthOpenName     = input.string(defval="RTH Open"               , title="", group=dailyGroup, inline="2")
rthOpenColor    = input.color (defval=color.orange           , title="", group=dailyGroup, inline="2")
showRthOpen     = input.bool  (defval=true                     , title="", group=dailyGroup, inline="2")

//London Open (3:00 AM EST) and Midnight Open (12:00 AM EST)
londonOpenName  = input.string(defval="London Open"            , title="", group=dailyGroup, inline="3")
londonOpenColor = input.color (defval=color.blue             , title="", group=dailyGroup, inline="3")
showLondonOpen  = input.bool  (defval=false                    , title="", group=dailyGroup, inline="3")
midNOpenName    = input.string(defval="Midnight Open"          , title="", group=dailyGroup, inline="3")
midNOpenColor   = input.color (defval=color.rgb(200, 0, 255) , title="", group=dailyGroup, inline="3")
showMidNOpen    = input.bool  (defval=false                    , title="", group=dailyGroup, inline="3")

//Previous Day High/Low
prevHighName    = input.string(defval="Previous Day High"      , title="", group=dailyGroup, inline="4")
prevHighColor   = input.color (defval=color.green            , title="", group=dailyGroup, inline="4")
showPrevHigh    = input.bool  (defval=true                     , title="", group=dailyGroup, inline="4")
prevLowName     = input.string(defval="Previous Day Low"       , title="", group=dailyGroup, inline="4")
prevLowColor    = input.color (defval=color.green            , title="", group=dailyGroup, inline="4")
showPrevLow     = input.bool  (defval=true                     , title="", group=dailyGroup, inline="4")

//Previous Day H/L 50% and Previous Day O/C 50% Close
midHLName       = input.string(defval="Prev Day 50% (HL2)"     , title="", group=dailyGroup, inline="5")
midHLColor      = input.color (defval=color.yellow           , title="", group=dailyGroup, inline="5")
showPrevMidHL   = input.bool  (defval=true                     , title="", group=dailyGroup, inline="5")
midOCName       = input.string(defval="Prev Day 50% (OC2)"     , title="", group=dailyGroup, inline="5")
midOCColor      = input.color (defval=color.fuchsia          , title="", group=dailyGroup, inline="5")
showPrevMidOC   = input.bool  (defval=false                    , title="", group=dailyGroup, inline="5")

//T2 Open/Close
t2OpenName      = input.string(defval="T+2 Open"               , title="", group=dailyGroup, inline="6")
t2OpenColor     = input.color (defval=color.rgb(248, 217, 44), title="", group=dailyGroup, inline="6")
showT2Open      = input.bool  (defval=false                    , title="", group=dailyGroup, inline="6")
t2CloseName     = input.string(defval="T+2 Close"              , title="", group=dailyGroup, inline="6")
t2CloseColor    = input.color (defval=color.rgb(55, 248, 248), title="", group=dailyGroup, inline="6")
showT2Close     = input.bool  (defval=false                    , title="", group=dailyGroup, inline="6")

//T2 High/Low
t2HighName      = input.string(defval="T+2 High"               , title="", group=dailyGroup, inline="7")
t2HighColor     = input.color (defval=color.red              , title="", group=dailyGroup, inline="7")
showT2High      = input.bool  (defval=true                     , title="", group=dailyGroup, inline="7")
t2LowName       = input.string(defval="T+2 Low"                , title="", group=dailyGroup, inline="7")
t2LowColor      = input.color (defval=color.red              , title="", group=dailyGroup, inline="7")
showT2Low       = input.bool  (defval=true                     , title="", group=dailyGroup, inline="7")

//Overnight High/Low
onHighName      = input.string(defval="Overnight High"         , title="", group=dailyGroup, inline="8")
onHighColor     = input.color (defval=color.purple           , title="", group=dailyGroup, inline="8")
showOnHigh      = input.bool  (defval=true                     , title="", group=dailyGroup, inline="8")
onLowName       = input.string(defval="Overnight Low"          , title="", group=dailyGroup, inline="8")
onLowColor      = input.color (defval=color.purple           , title="", group=dailyGroup, inline="8")
showOnLow       = input.bool  (defval=true                     , title="", group=dailyGroup, inline="8")

//Previous Close
prevCloseName  = input.string(defval="Previous Close"          , title="", group=dailyGroup, inline="9")
prevCloseColor = input.color (defval=color.aqua              , title="", group=dailyGroup, inline="9")
showPrevClose  = input.bool  (defval=true                      , title="", group=dailyGroup, inline="9")
//Daily Settings
numDailyPeriods       = input.int(title="Number of Previous Days", defval=1, group = dailyGroup, minval = 1, maxval = 40)
showUntestedHLCLevels = input.bool(title="Keep Untested High/Low/Close Levels", defval=false, group = dailyGroup)
showInactiveHLCLevels = input.bool(title="Show Already Tested High/Low/Close Levels", defval=false, group = dailyGroup)
extendOptionDaily     = input.string(title="Extend Daily Lines", options=["Right","Both", "None"], defval="Right", group = dailyGroup)
extendLineDaily       = (extendOptionDaily == "Right") ? extend.right :
                         (extendOptionDaily == "Both") ? extend.both :
                         extend.none
linewidthDaily        = input.int(1, "Daily Line Thickness", group = dailyGroup)
styleOptionDaily      = input.string(title="Daily Line Style", options=["solid (─)", "dashed (╌)", "dotted (┈)"],
                         defval="solid (─)", group = dailyGroup)
lineStyleDaily        = (styleOptionDaily == "dotted (┈)") ? line.style_dotted : 
                         (styleOptionDaily == "dashed (╌)") ? line.style_dashed :
                         line.style_solid
labelColorDaily       = input.color(title="", defval=color.white, group = dailyGroup, inline="labelDaily")
showDailyLabels       = input.bool(title="Show Daily Level Labels", defval=true, group = dailyGroup, inline="labelDaily")
labelColorMatchLineD  = input.bool(title="Match Label Color With Line Color", defval=false, group=dailyGroup)
labelDailyTextOption  = input.string(title="Daily Label Text Size", options=[ "Tiny", "Small", "Normal",  "Large", "Huge"], defval="Normal", group=dailyGroup)
labelDailyTextSize    = switch labelDailyTextOption
    "Tiny" => size.tiny
    "Small" => size.small
    "Normal" => size.normal
    "Large" => size.large
    "Huge" => size.huge
labeloffsetDaily      = input.int(title="Daily Label Offset", defval=20, group = dailyGroup)

///////////////////////////
//  Weekly Levels Inputs //
///////////////////////////
showWeeklyLevels   = input.bool(defval=true, title="Show Weekly Levels",  group=weeklyGroup)
prevWeekHighName   = input.string(defval="Prev Week High"      , title="", group=weeklyGroup, inline="6")
wkHighColor        = input.color (defval=color.lime          , title="", group=weeklyGroup, inline="6")
showPrevWeekHigh   = input.bool  (defval=true                  , title="", group=weeklyGroup, inline="6")
prevWeekLowName    = input.string(defval="Prev Week Low"       , title="", group=weeklyGroup, inline="6")
wkLowColor         = input.color (defval=color.lime          , title="", group=weeklyGroup, inline="6")
showPrevWeekLow    = input.bool  (defval=true                  , title="", group=weeklyGroup, inline="6")

prevWeekHalfHLName = input.string(defval="Prev Week Half (HL2)", title="", group=weeklyGroup, inline="7")
wkHalfHLColor      = input.color (defval=color.yellow        , title="", group=weeklyGroup, inline="7")
showPrevWeekHalfHL = input.bool  (defval=true                  , title="", group=weeklyGroup, inline="7")
prevWeekHalfOCName = input.string(defval="Prev Week Half (OC2)", title="", group=weeklyGroup, inline="7")
wkHalfOCColor      = input.color (defval=color.fuchsia       , title="", group=weeklyGroup, inline="7")
showPrevWeekHalfOC = input.bool  (defval=false                 , title="", group=weeklyGroup, inline="7")

wkOpenName         = input.string(defval="Current Week Open"   , title="", group=weeklyGroup, inline="8")
wkOpenColor        = input.color (defval=color.orange        , title="", group=weeklyGroup, inline="8")
showRthWeekOpen    = input.bool  (defval=true                  , title="", group=weeklyGroup, inline="8")
wkCloseName        = input.string(defval="Prev Week Close"     , title="", group=weeklyGroup, inline="8")
wkCloseColor       = input.color (defval=color.aqua          , title="", group=weeklyGroup, inline="8")
showPrevWeekClose  = input.bool  (defval=true                  , title="", group=weeklyGroup, inline="8")

wkVWAPName         = input.string(defval="Prev Week VWAP"      , title="", group=weeklyGroup, inline="9")
wkVWAPColor        = input.color (defval=color.white         , title="", group=weeklyGroup, inline="9")
showPrevWeekVWAP   = input.bool  (defval=false                 , title="", group=weeklyGroup, inline="9")
wkVSD1Name         = input.string(defval="Prev Week VWAP SD1"  , title="", group=weeklyGroup, inline="9")
wkVSD1Color        = input.color (defval=color.green         , title="", group=weeklyGroup, inline="9")
showPrevWeekSD1    = input.bool  (defval=false                 , title="", group=weeklyGroup, inline="9")

wkVSD2Name         = input.string(defval="Prev Week VWAP SD2"  , title="", group=weeklyGroup, inline="10")
wkVSD2Color        = input.color(defval=color.olive          , title="", group=weeklyGroup, inline="10")
showPrevWeekSD2    = input.bool (defval=false                  , title="", group=weeklyGroup, inline="10")
wkVSD3Name         = input.string(defval="Prev Week VWAP SD3"  , title="", group=weeklyGroup, inline="10")
wkVSD3Color        = input.color(defval=color.teal           , title="", group=weeklyGroup, inline="10")
showPrevWeekSD3    = input.bool (defval=false                  , title="", group=weeklyGroup, inline="10")

//Weekly Settings
numWklyPeriods     = input.int(title="Number of Previous Weeks", defval=1, group = weeklyGroup, minval = 1, maxval = 20)
extendOptionWeekly = input.string(title="Extend Weekly Lines", options=["Right","Both", "None"], defval="Right", group = weeklyGroup)
extendLineWeekly   = (extendOptionWeekly == "Right") ? extend.right :
                     (extendOptionWeekly == "Both") ? extend.both :
                     extend.none
linewidthWeekly    = input.int(1, "Weekly Line Thickness", group = weeklyGroup)
styleOptionWeekly  = input.string(title="Weekly Line Style", options=["solid (─)", "dashed (╌)", "dotted (┈)"], defval="dotted (┈)", group = weeklyGroup)
lineStyleWeekly    = (styleOptionWeekly == "dotted (┈)") ? line.style_dotted : 
                     (styleOptionWeekly == "dashed (╌)") ? line.style_dashed :
                     line.style_solid
labelColorWeekly     = input.color(title="", defval=color.white, group = weeklyGroup, inline="labelWeekly")
showWeeklyLabels     = input.bool(title="Show Weekly Level Labels", defval=true, group = weeklyGroup, inline="labelWeekly")
labelColorMatchLineW = input.bool(title="Match Label Color With Line Color", defval=false, group=weeklyGroup)
labelWklyTextOption  = input.string(title="Weekly Label Text Size", options=[ "Tiny", "Small", "Normal",  "Large", "Huge"], defval="Normal", group=weeklyGroup)
labelWklyTextSize    = switch labelWklyTextOption
    "Tiny" => size.tiny
    "Small" => size.small
    "Normal" => size.normal
    "Large" => size.large
    "Huge" => size.huge
labeloffsetWeekly  = input.int(title="Weekly Label Offset", defval=10, group = weeklyGroup)

////////////////////////////
//  Monthly Levels Inputs //
////////////////////////////
showMonthlyLevels   = input.bool(title="Show Monthly Levels", defval=true, group = monthlyGroup)
monHighName         = input.string(defval="Prev Month High"       , title="", group=monthlyGroup, inline="9")
monHighColor        = input.color (defval=color.rgb(1, 219, 147), title="", group=monthlyGroup, inline="9")
showPrevMonthHigh   = input.bool  (defval=true                    , title="", group=monthlyGroup, inline="9")
monLowName          = input.string(defval="Prev Month Low"        , title="", group=monthlyGroup, inline="9")
monLowColor         = input.color (defval=color.rgb(1, 219, 147), title="", group=monthlyGroup, inline="9")
showPrevMonthLow    = input.bool  (defval=true                    , title="", group=monthlyGroup, inline="9")

monHalfHLName       = input.string(defval="Prev Month 50% (HL2)"  , title="", group=monthlyGroup, inline="10")
monHalfColorHL      = input.color (defval=color.rgb(255, 230, 1), title="", group=monthlyGroup, inline="10")
showPrevMonthHalfHL = input.bool  (defval=true                    , title="", group=monthlyGroup, inline="10")
monHalfOCName       = input.string(defval="Prev Month 50% (OC2)"  , title="", group=monthlyGroup, inline="10")
monHalfOCColor      = input.color (defval=color.fuchsia         , title="", group=monthlyGroup, inline="10")
showPrevMonthHalfOC = input.bool  (defval=false                   , title="", group=monthlyGroup, inline="10")

monOpenName         = input.string(defval="Month Open"           , title="", group=monthlyGroup, inline="11")
monOpenColor        = input.color(defval=color.orange          , title="", group=monthlyGroup, inline="11")
showRthMonthOpen    = input.bool (defval=true                    , title="", group=monthlyGroup, inline="11")
monCloseName        = input.string(defval="Prev Month Close"     , title="", group=monthlyGroup, inline="11")
monCloseColor       = input.color(defval=color.aqua            , title="", group=monthlyGroup, inline="11")
showPrevMonthClose  = input.bool (defval=true                    , title="", group=monthlyGroup, inline="11")

//Monthly Settings
numMonPeriods       = input.int(title="Number of Previous Months", defval=1, group = monthlyGroup, minval = 1, maxval = 12)
extendOptionMonthly = input.string(title="Extend Monthly Lines", options=["Right","Both", "None"], defval="Right", group = monthlyGroup)
extendLineMonthly   = (extendOptionMonthly == "Right") ? extend.right :
                     (extendOptionMonthly == "Both") ? extend.both :
                     extend.none
linewidthMonthly    = input.int(1, "Line Thickness", group = monthlyGroup)
styleOptionMonthly  = input.string(title="Line Style", options=["solid (─)", "dashed (╌)", "dotted (┈)"], defval="dashed (╌)", group = monthlyGroup)
lineStyleMonthly    = (styleOptionMonthly == "dotted (┈)") ? line.style_dotted : 
                      (styleOptionMonthly == "dashed (╌)") ? line.style_dashed :
                      line.style_solid
labelColorMonthly    = input.color(title="", defval=color.white, group = monthlyGroup, inline="labelMonthly")
labelColorMatchLineM = input.bool(title="Match Label Color With Line Color", defval=false, group=monthlyGroup)
showMonthlyLabels    = input.bool(title="Show Monthly Level Labels", defval=true, group = monthlyGroup, inline="labelMonthly")
labelMonTextOption   = input.string(title="Monthly Label Text Size", options=[ "Tiny", "Small", "Normal",  "Large", "Huge"], defval="Normal", group=monthlyGroup)
labelMonTextSize     = switch labelMonTextOption
    "Tiny" => size.tiny
    "Small" => size.small
    "Normal" => size.normal
    "Large" => size.large
    "Huge" => size.huge
labeloffsetMonthly  = input.int(title="Monthly Label Offset", defval=10, group = monthlyGroup)

//When lines are first created, the below values are used for the offset
initialLabelOffset  = bar_index + labeloffsetDaily
initialLineOffset   = time + timeframe.multiplier * (timeframe.in_seconds()*1000)

//Creating a UDT to capture all relevant information for a given level
type ValueLine
    float price          = 0
    int   barIndex       = bar_index
    int   barTime        = time
    label llabel         = na
    line  level          = na
    bool  testedInFuture = false

//Type for Weekly VWAP Calc
type VWAP
    float sum
    float volume
    float value

//method to copy values from other valueLine except for label and line objects
method copyValueLine(ValueLine this) =>
    ValueLine.new(this.price, this.barIndex, this.barTime)

// SessionHigh() returns the highest price during the specified 
// session, optionally corrected for the given time zone.
// Returns "na" when the session hasn"t started or isn"t on the chart.
SessionHigh(sessionTime, sessionTimeZone=syminfo.timezone) =>
    insideSession = not na(time(timeframe.period, sessionTime, sessionTimeZone))
    newDayofWeek  = (syminfo.session == session.regular and 
                     (syminfo.type == "stock" or syminfo.type == "fund" or syminfo.type == "dr")) and 
                     dayofweek(time, sessionTimeZone) != dayofweek(time, sessionTimeZone)[1]
    var float sessionHighPrice = na
    var int   sessionHighBarIndex = na
    var int   sessionHighTime     = na

    if insideSession and (not insideSession[1] or newDayofWeek)
        sessionHighPrice := high
        sessionHighBarIndex := bar_index
        sessionHighTime     := time
    else if insideSession
        sessionHighPrice := math.max(sessionHighPrice, high)
        if sessionHighPrice != sessionHighPrice[1]
            sessionHighBarIndex := bar_index
            sessionHighTime     := time
    
    [sessionHighPrice, sessionHighBarIndex, sessionHighTime]

// SessionLow() returns the lowest price during the given session,
// optionally corrected for the specified time zone.
// Returns "na" when the session hasn"t started or isn"t on the chart.
SessionLow(sessionTime, sessionTimeZone=syminfo.timezone) =>
    insideSession = not na(time(timeframe.period, sessionTime, sessionTimeZone))
    newDayofWeek  =(syminfo.session == session.regular and 
                     (syminfo.type == "stock" or syminfo.type == "fund" or syminfo.type == "dr")) and 
                     dayofweek(time, sessionTimeZone) != dayofweek(time, sessionTimeZone)[1]
    var float sessionLowPrice    = na
    var int   sessionLowBarIndex = na
    var int   sessionLowTime     = na

    if insideSession and (not insideSession[1] or newDayofWeek)
        sessionLowPrice := low
        sessionLowBarIndex := bar_index
        sessionLowTime     := time
    else if insideSession
        sessionLowPrice := math.min(sessionLowPrice, low)
        if sessionLowPrice != sessionLowPrice[1]
            sessionLowBarIndex := bar_index
            sessionLowTime     := time

    [sessionLowPrice, sessionLowBarIndex, sessionLowTime]

// SessionOpen() returns the lowest price during the given session,
// optionally corrected for the specified time zone.
// Returns "na" when the session hasn"t started or isn"t on the chart.
SessionOpen(sessionTime, sessionTimeZone=syminfo.timezone) =>
    insideSession = not na(time(timeframe.period, sessionTime, sessionTimeZone))
    newDayofWeek  =(syminfo.session == session.regular and 
                     (syminfo.type == "stock" or syminfo.type == "fund" or syminfo.type == "dr")) and 
                     dayofweek(time, sessionTimeZone) != dayofweek(time, sessionTimeZone)[1]
    var float sessionOpenPrice    = na

    if insideSession and (not insideSession[1] or newDayofWeek)
        sessionOpenPrice := open

    sessionOpenPrice

// MonthName() returns the lowest price during the given session,
// optionally corrected for the specified time zone.
MonthName(monthInput, sessionTimeZone=syminfo.timezone) =>
    string monthName = switch monthInput
        1 => "Jan"
        2 => "Feb"
        3 => "Mar"
        4 => "Apr"
        5 => "May"
        6 => "Jun"
        7 => "Jul"
        8 => "Aug"
        9 => "Sep"
        10 => "Oct"
        11 => "Nov"
        12 => "Dec"

    monthName

// NewMonth() returns a boolean if the next trading session is the start of a new month when using extended hours charts
// optionally corrected for the specified time zone.
NewMonth(int timeInput, sessionTimeZone=syminfo.timezone) =>
    bool newMonth = na
    dayOfWeek  = dayofweek(timeInput, sessionTimeZone)
    dayOfMonth = dayofmonth(timeInput, sessionTimeZone)
    monthNum   = month(timeInput, sessionTimeZone)
    numDaysInMonth = switch monthNum
        1 => 31
        2 => year(timeInput, sessionTimeZone) % 4 == 0 ? 29 : 28
        3 => 31
        4 => 30
        5 => 31
        6 => 30
        7 => 31
        8 => 31
        9 => 30
        10 => 31
        11 => 30
        12 => 31
    
    //Condiitonal statment to deal with friday session being the end of the month
    if dayOfWeek == dayofweek.friday
        //if day of week is friday and days in month is 31 and current day of month is 29
        //then a new month at the start of next week"s session
        if numDaysInMonth == 31 and (dayOfMonth >= 29 or (monthNum == 5 and dayOfMonth == 28))
            newMonth := true
        else if numDaysInMonth == 30 and dayOfMonth >= 28
            newMonth := true
        else if numDaysInMonth == 29 and dayOfMonth >= 27
            newMonth := true
        else if numDaysInMonth == 28 and dayOfMonth >= 26
            newMonth := true
    //On any other day (i.e. Monday - Thursday) and the days of the month is equal to the number of days in the month 
    //then the next session will be a new month
    else if dayOfMonth == numDaysInMonth
        newMonth := true
    else 
        newMonth := false
   
    newMonth

updateIntraDayLines(ValueLine ValueLine, string name, int labelOffset, color lineColor) =>
    if na(ValueLine.llabel)
        ValueLine.llabel := showDailyLabels ? label.new(
                             x = initialLabelOffset, 
                             y = ValueLine.price, 
                             text = name + ": " + str.tostring(ValueLine.price), 
                             xloc = xloc.bar_index, 
                             textcolor = labelColorMatchLineD ? lineColor : labelColorDaily,  
                             textalign = text.align_right, 
                             style = label.style_none, 
                             size = labelDailyTextSize) : na
    ValueLine.llabel.set_x(bar_index + labeloffsetDaily)
    ValueLine.llabel.set_y(ValueLine.price)
    ValueLine.llabel.set_text(name + ": " + str.tostring(ValueLine.price))
    if na(ValueLine.level)
        ValueLine.level  := line.new(
                             x1 = ValueLine.barTime, 
                             y1 = ValueLine.price, 
                             x2 = initialLineOffset, 
                             y2 = ValueLine.price, 
                             xloc = xloc.bar_time, 
                             extend = extendLineDaily, 
                             color = lineColor,
                             style = lineStyleDaily, 
                             width = linewidthDaily)
    ValueLine.level.set_x1(ValueLine.barTime)
    ValueLine.level.set_x2(ValueLine.barTime == time ? initialLineOffset : time)
    ValueLine.level.set_y1(ValueLine.price)
    ValueLine.level.set_y2(ValueLine.price)

updateLines(array<ValueLine> ValueLines, int numLines, bool showOlderLabels, int labelOffset, bool saveUntestedLines = false, bool showInactivePositions = false) =>
    
    lineAdd        = 0   
    sizeArr        = ValueLines.size()

    if sizeArr > 0
        //Updates the number of lines allowed to be plotted for instances where a Value Line object has a value 
        //but no line created yet. This keeps the prior line plotted. Mostly necessary for futures due to new values
        // added to a new ValueLinew object at 4PM EST but new lines using that new value not created until 6PM EST.
        if na(ValueLines.last().level)
            lineAdd := 1
        //Remove any line that is still stored beyond the numLines value
        //also update label locations and lines locations of all but current line
        for i = sizeArr - 1 to 0  
            valueLine = ValueLines.get(i)

            if saveUntestedLines == true
                if valueLine.testedInFuture == true
                    if showInactivePositions
                        valueLine.level.set_extend(extend.none)
                        valueLine.llabel.delete()
                    else
                        valueLine.level.delete()
                        valueLine.llabel.delete()     

                else if valueLine.testedInFuture == false
                    if i < sizeArr - (1 + lineAdd)
                        valueLine.level.set_x2(time)
                        valueLine.llabel.set_x(bar_index + labelOffset)
                        if not showOlderLabels
                            label.delete(valueLine.llabel)
                    else if i == sizeArr - (1 + lineAdd)
                        valueLine.level.set_x2(time)
                        valueLine.llabel.set_x(bar_index + labelOffset)
            else if saveUntestedLines == false  
                //if lines in array go above what user wants on screen, delete lines and labels for that valueline
                if i < sizeArr - (numLines + lineAdd)
                    label.delete(valueLine.llabel)
                    line.delete(valueLine.level)
                //Update prior line to stop at the previous bar
                else if i < sizeArr - (1 + lineAdd)
                    valueLine.llabel.set_x(bar_index + labelOffset)
                    if not showOlderLabels
                        valueLine.level.set_extend(extend.none)
                        label.delete(valueLine.llabel)
                else if i == sizeArr - (1 + lineAdd)
                    valueLine.level.set_x2(valueLine.barTime == time ? initialLineOffset : time)
                    valueLine.llabel.set_x(bar_index + labelOffset)

deleteLines(array<ValueLine> ValueLines, int maxValueLines) =>
    sizeArr = ValueLines.size()
    if sizeArr > 0
        //Check if number of values in ValueLine array is greater than the max allowed
        if sizeArr > maxValueLines
            //If level is not na, shift out value and then delete line
            firstEntry = ValueLines.shift()

            if not na(firstEntry.level)
                line.delete(firstEntry.level)
            if not na(firstEntry.llabel)
                label.delete(firstEntry.llabel)

///////////////////////////////////////////////////////
//////////   End Functions Section    /////////////////
///////////////////////////////////////////////////////

///////////////////////////////////////////////////
////        Variable Declaration        ///////////
///////////////////////////////////////////////////
//Timeframe variables
newDay               = dayofweek(time, "America/New_York") != dayofweek(time, "America/New_York")[1]
ONSessionRange       = syminfo.type == "stock" or syminfo.type == "fund" or syminfo.type == "dr"
                         ? "1600-0930"
                         : "1800-0930"
insideONSession      = not na(time(timeframe.period, ONSessionRange, "America/New_York"))
insideUSSession      = not na(time(timeframe.period, "0930-1600", "America/New_York"))
lonOpenSession       = not na(time(timeframe.period, "0300-0301", "America/New_York"))
midnightOpenSess     = not na(time(timeframe.period, "0000-0001", "America/New_York"))
newUSSession         = insideUSSession     and not insideUSSession[1]
endOfUSSession       = insideUSSession[1]  and not insideUSSession
newLonSession        = lonOpenSession      and not lonOpenSession[1]
newMidnightSession   = midnightOpenSess    and not midnightOpenSess[1]
newONsession         = insideONSession     and not insideONSession[1]
rthOnlyChart         = syminfo.session == session.regular and (syminfo.type == "stock" or syminfo.type == "fund" or syminfo.type == "dr")
                         or (syminfo.type == "futures" and syminfo.session == "us_regular")
rthOpenSess          = rthOnlyChart ? newDay : newUSSession
//Weekly Time Variables
newWeekRTH           = dayofweek(time, "America/New_York")[1] > dayofweek(time, "America/New_York")
newWeekETH           = dayofweek(time, "America/New_York") == dayofweek.friday and endOfUSSession
newWeek              = rthOnlyChart ? newWeekRTH : newWeekETH
//Monthly Time Variables
newMonthRTH          = dayofmonth(time, "America/New_York")[1] > dayofmonth(time, "America/New_York")
newMonthETH          = NewMonth(time) and endOfUSSession
newMonth             = rthOnlyChart ? newMonthRTH : newMonthETH

//Determines RTH vs. ETH for futures charts since pinscript shows session.regular 
//regardless of having RTH or ETH selected
var bool futuresRTH    = syminfo.type == "futures" and syminfo.session == "us_regular"
futuresNewSession = futuresRTH == true ? rthOpenSess : newONsession

var ValueLine currDayHigh        = ValueLine.new()
var ValueLine currDayLow         = ValueLine.new()
var ValueLine prevDayHigh        = ValueLine.new()
var ValueLine prevDayLow         = ValueLine.new()
var ValueLine prevDayClose       = ValueLine.new()
var ValueLine prevDayMid         = ValueLine.new()
var ValueLine prevDayOCMid       = ValueLine.new()
var ValueLine rthOpen            = ValueLine.new()
var ValueLine globexOpen         = ValueLine.new()
var ValueLine londonOpen         = ValueLine.new()
var ValueLine midnightOpen       = ValueLine.new()
var ValueLine t2Open             = ValueLine.new()
var ValueLine t2Close            = ValueLine.new()
var ValueLine t2High             = ValueLine.new()
var ValueLine t2Low              = ValueLine.new()
var ValueLine onHigh             = ValueLine.new()
var ValueLine onLow              = ValueLine.new()
var ValueLine prevWeekHigh       = ValueLine.new()
var ValueLine prevWeekLow        = ValueLine.new()
var ValueLine prevWeek50HL       = ValueLine.new()
var ValueLine prevWeek50OC       = ValueLine.new()
var ValueLine rthWeekOpen        = ValueLine.new()
var ValueLine prevWeekClose      = ValueLine.new()
var ValueLine prevMonthHigh      = ValueLine.new()
var ValueLine prevMonthLow       = ValueLine.new()
var ValueLine prevMonth50HL      = ValueLine.new()
var ValueLine prevMonth50OC      = ValueLine.new()
var ValueLine rthMonthOpen       = ValueLine.new()
var ValueLine prevMonthClose     = ValueLine.new()

//Array Initialization
var prevHigh_Arr     = array.new<ValueLine>(0)
var prevLow_Arr      = array.new<ValueLine>(0)
var prev50HL_Arr     = array.new<ValueLine>(0)
var prev50OC_Arr     = array.new<ValueLine>(0)
var t2Open_Arr       = array.new<ValueLine>(0)
var t2Close_Arr      = array.new<ValueLine>(0)
var t2High_Arr       = array.new<ValueLine>(0)
var t2Low_Arr        = array.new<ValueLine>(0)
var prevClose_Arr    = array.new<ValueLine>(0)
var rthOpen_Arr      = array.new<ValueLine>(0)
var globexOpen_Arr   = array.new<ValueLine>(0)
var londonOpen_Arr   = array.new<ValueLine>(0)
var midnightOpen_Arr = array.new<ValueLine>(0)
var onHigh_Arr       = array.new<ValueLine>(0)
var onLow_Arr        = array.new<ValueLine>(0)

var newWeekVar = false
var prevWeekHigh_Arr        = array.new<ValueLine>(0)
var prevWeekLow_Arr         = array.new<ValueLine>(0)
var prevWeek50HL_Arr        = array.new<ValueLine>(0)
var prevWeek50OC_Arr        = array.new<ValueLine>(0)
var rthWeekOpen_Arr         = array.new<ValueLine>(0)
var prevWeekClose_Arr       = array.new<ValueLine>(0)
var prevWeekVWAP_Arr        = array.new<ValueLine>(0)
var prevWeekVWAP_LBand1_Arr = array.new<ValueLine>(0)
var prevWeekVWAP_UBand1_Arr = array.new<ValueLine>(0)
var prevWeekVWAP_LBand2_Arr = array.new<ValueLine>(0)
var prevWeekVWAP_UBand2_Arr = array.new<ValueLine>(0)
var prevWeekVWAP_LBand3_Arr = array.new<ValueLine>(0)
var prevWeekVWAP_UBand3_Arr = array.new<ValueLine>(0)

var prevMonthHigh_Arr  = array.new<ValueLine>(0)
var prevMonthLow_Arr   = array.new<ValueLine>(0)
var prevMonth50HL_Arr  = array.new<ValueLine>(0)
var prevMonth50OC_Arr  = array.new<ValueLine>(0)
var rthMonthOpen_Arr   = array.new<ValueLine>(0)
var prevMonthClose_Arr = array.new<ValueLine>(0)

[sessionHighPrice, sessionHighBarIndex, sessionHighTime] = SessionHigh("0930-1600", "America/New_York")
[sessionLowPrice , sessionLowBarIndex, sessionLowTime]   = SessionLow("0930-1600", "America/New_York")

//Overnight Calculations
[ONsessionHighPrice, ONsessionHighBarIndex, ONsessionHighTime] = SessionHigh(ONSessionRange, "America/New_York")
[ONsessionLowPrice, ONsessionLowBarIndex , ONsessionLowTime]   = SessionLow(ONSessionRange, "America/New_York")

//Overnight Levels when an RTH Chart is being shown need to be gathered via request secutiry function with extended hours checked
[ONsessionHighPrice_RS, ONsessionHighBarIndex_RS, ONsessionHighTime_RS] = request.security(ticker.modify(syminfo.tickerid, session.extended), "30", SessionHigh(ONSessionRange, "America/New_York"), lookahead=barmerge.lookahead_on)
[ONsessionLowPrice_RS, ONsessionLowBarIndex_RS, ONsessionLowTime_RS]    = request.security(ticker.modify(syminfo.tickerid, session.extended), "30", SessionLow(ONSessionRange, "America/New_York"), lookahead=barmerge.lookahead_on)
globexOpenPrice_RS         = request.security(syminfo.tickerid, "D", open, lookahead=barmerge.lookahead_on)
londonOpenPrice_RS         = request.security(ticker.modify(syminfo.tickerid, session.extended), "30", SessionOpen("0300-0301", "America/New_York"), lookahead=barmerge.lookahead_on)
midnightOpenPrice_RS       = request.security(ticker.modify(syminfo.tickerid, session.extended), "30", SessionOpen("0000-0001", "America/New_York"), lookahead=barmerge.lookahead_on)

if newONsession and syminfo.type == "futures"
    globexOpen.price      := open
    globexOpen.barIndex   := bar_index
    globexOpen.barTime    := time
    globexOpen_Arr.push(globexOpen.copy())

if newLonSession
    londonOpen.price := open
    londonOpen.barIndex   := bar_index
    londonOpen.barTime    := time
    londonOpen_Arr.push(londonOpen.copy())

if newMidnightSession
    midnightOpen.price    := open
    midnightOpen.barIndex := bar_index
    midnightOpen.barTime  := time
    midnightOpen_Arr.push(midnightOpen.copy())

if rthOpenSess
    //Reset Current Day High/Low Value Lines
    currDayHigh.price    := high
    currDayHigh.barIndex := bar_index
    currDayHigh.barTime  := time
    currDayHigh.llabel.delete()
    currDayHigh.level.delete()
    currDayLow.price     := low
    currDayLow.barIndex  := bar_index
    currDayLow.barTime   := time
    currDayLow.llabel.delete()
    currDayLow.level.delete()
    
    //for RTH stock charts use newday to filter when to save prev day prices
    if rthOnlyChart
        if prevClose_Arr.size() > 0 and prevHigh_Arr.size() > 0 and prevLow_Arr.size() > 0
            for i = 0 to prevClose_Arr.size() - 1
                closeLine       = prevClose_Arr.get(i)
                highLine        = prevHigh_Arr.get(i)
                lowLine         = prevLow_Arr.get(i)
                prevSessionLow  = sessionLowPrice[1]
                prevSessionHigh = sessionHighPrice[1]

                //Check if previous close lines have been traded through
                if prevSessionLow < closeLine.price and prevSessionHigh > closeLine.price
                    closeLine.testedInFuture := true
                //Check for if previous high lines have been tested by the last session"s highs
                if prevSessionHigh > highLine.price
                    highLine.testedInFuture := true
                //Check for if previous low lines have been tested by the last session"s lows
                if prevSessionLow < lowLine.price
                    lowLine.testedInFuture := true    

        //Daily Level Calculations for RTH Charts (i.e. strictly 9:30AM - 4PM)
        if rthOpen_Arr.size() > 2
            t2Open_Arr.push(rthOpen_Arr.get(rthOpen_Arr.size() - 2).copy())
        t2Close_Arr.push(prevDayClose.copy())
        t2High_Arr.push(prevDayHigh.copy())
        t2Low_Arr.push(prevDayLow.copy())

        //Logic needed to distinguish RTH close on futures since it closes at 4:15 PM EST
        prevDayClose.price    := close[syminfo.type == "futures" ? 4 : 1]
        prevDayClose.barIndex := bar_index[syminfo.type == "futures" ? 4 : 1]
        prevDayClose.barTime  := time[syminfo.type == "futures" ? 4 : 1]
        prevClose_Arr.push(prevDayClose.copy())

        prevDayHigh.price     := sessionHighPrice[1]
        prevDayHigh.barIndex  := sessionHighBarIndex[1]
        prevDayHigh.barTime   := sessionHighTime[1]
        prevHigh_Arr.push(prevDayHigh.copy())
        
        prevDayLow.price      := sessionLowPrice[1]
        prevDayLow.barIndex   := sessionLowBarIndex[1]
        prevDayLow.barTime    := sessionLowTime[1]
        prevLow_Arr.push(prevDayLow.copy())

        prevDayMid.price      := math.round_to_mintick((prevDayHigh.price + prevDayLow.price) / 2)
        prevDayMid.barIndex   := rthOpen.barIndex
        prevDayMid.barTime    := rthOpen.barTime
        prev50HL_Arr.push(prevDayMid.copy())

        prevDayOCMid.price    := math.round_to_mintick((prevDayClose.price + rthOpen.price) / 2)
        prevDayOCMid.barIndex := rthOpen.barIndex    
        prevDayOCMid.barTime  := rthOpen.barTime
        prev50OC_Arr.push(prevDayOCMid.copy())

        if prevWeekHigh.price < prevDayHigh.price
            prevWeekHigh := prevDayHigh.copy()
        if prevWeekLow.price > prevDayLow.price
            prevWeekLow := prevDayLow.copy()
        prevWeek50HL.price := (prevWeekHigh.price + prevWeekLow.price) / 2

        if prevMonthHigh.price < prevDayHigh.price
            prevMonthHigh    := prevDayHigh.copy()
        if prevMonthLow.price > prevDayLow.price
            prevMonthLow   := prevDayLow.copy()
        prevMonth50HL.price := (prevMonthHigh.price + prevMonthLow.price) / 2

        //Filter to determine if we are in RTH for either futures or stocks/funds, if we are, use the request security data from line 430, otherwise use the sessionHigh/Low function
        onHigh.price      := ONsessionHighPrice_RS
        onLow.price       := ONsessionLowPrice_RS        
        onHigh.barIndex   := bar_index
        onLow.barIndex    := bar_index 
        onHigh.barTime    := time
        onLow.barTime     := time
        onHigh_Arr.push(onHigh.copy())
        onLow_Arr.push(onLow.copy())

        londonOpen.price      := londonOpenPrice_RS      
        londonOpen.barIndex   := bar_index
        londonOpen.barTime    := time
        londonOpen_Arr.push(londonOpen.copy())

        midnightOpen.price      := midnightOpenPrice_RS      
        midnightOpen.barIndex   := bar_index
        midnightOpen.barTime    := time
        midnightOpen_Arr.push(midnightOpen.copy())

        if syminfo.type == "futures"
            globexOpen.price    := globexOpenPrice_RS
            globexOpen.barIndex := bar_index
            globexOpen.barTime  := time
            globexOpen_Arr.push(globexOpen.copy())
    else
        onHigh.level.delete()
        onHigh.llabel.delete()
        onLow.level.delete()
        onLow.llabel.delete()
        onHigh_Arr.push(onHigh.copy())
        onLow_Arr.push(onLow.copy())
    
    rthOpen.barIndex      := bar_index
    rthOpen.barTime       := time
    rthOpen.price         := open
    rthOpen_Arr.push(rthOpen.copy())

    //Check for new week
    if dayofweek(time, "America/New_York") == dayofweek.monday or 
         (dayofweek(prevDayMid.barTime, "America/New_York") == dayofweek.friday and 
             dayofweek(time, "America/New_York") == dayofweek.tuesday)
        rthWeekOpen_Arr.push(rthOpen.copy())

    //Check for new month
    if dayofmonth(prevDayMid.barTime, "America/New_York") >= 28 and
         dayofmonth(time, "America/New_York") < dayofmonth(prevDayMid.barTime, "America/New_York")
        rthMonthOpen_Arr.push(rthOpen.copy())

//Logic for Plotting Current Daily High/Low on each new bar
if insideUSSession and barstate.isconfirmed
    if currDayHigh.price < sessionHighPrice
        currDayHigh.barIndex := sessionHighBarIndex
        currDayHigh.barTime  := sessionHighTime
        currDayHigh.price    := sessionHighPrice
    
    if currDayLow.price > sessionLowPrice    
        currDayLow.barIndex := sessionLowBarIndex
        currDayLow.barTime  := sessionLowTime
        currDayLow.price    := sessionLowPrice
    
    if showCurrHigh
        updateIntraDayLines(currDayHigh, currHighName, labeloffsetDaily, currHighColor)
    if showCurrLow
        updateIntraDayLines(currDayLow, currLowName, labeloffsetDaily, currLowColor)

//Reset ON High/Low when new ON session starts
if newONsession
    onHigh.barIndex := bar_index
    onHigh.barTime  := time
    onHigh.price    := high
    updateLines(onHigh_Arr, numDailyPeriods - 1, false, labeloffsetDaily)
    onLow.barIndex  := bar_index
    onLow.barTime   := time
    onLow.price     := low
    updateLines(onLow_Arr, numDailyPeriods - 1, false, labeloffsetDaily)

//Monitor ON Session High/Low
if insideONSession and barstate.isconfirmed
    if onHigh.price < ONsessionHighPrice
        onHigh.barIndex := ONsessionHighBarIndex
        onHigh.barTime  := ONsessionHighTime
        onHigh.price    := ONsessionHighPrice
    
    if onLow.price > ONsessionLowPrice
        onLow.barIndex := ONsessionLowBarIndex
        onLow.barTime  := ONsessionLowTime
        onLow.price    := ONsessionLowPrice

    if showOnHigh
        updateIntraDayLines(onHigh, onHighName, labeloffsetDaily, onHighColor)
    if showOnLow
        updateIntraDayLines(onLow, onLowName, labeloffsetDaily, onLowColor)

//for ETH charts and capturing RTH close information at 4:00PM close
if endOfUSSession and not rthOnlyChart
    //Delete Current Day High/Low Lines
    currDayHigh.llabel.delete()
    currDayHigh.level.delete()
    currDayLow.llabel.delete()
    currDayLow.level.delete()

    if prevClose_Arr.size() > 0 and prevHigh_Arr.size() > 0 and prevLow_Arr.size() > 0
        for i = 0 to prevClose_Arr.size() - 1
            closeLine       = prevClose_Arr.get(i)
            highLine        = prevHigh_Arr.get(i)
            lowLine         = prevLow_Arr.get(i)
            prevSessionLow  = sessionLowPrice[1]
            prevSessionHigh = sessionHighPrice[1]

            //Check if previous close lines have been traded through
            if prevSessionLow < closeLine.price and prevSessionHigh > closeLine.price
                closeLine.testedInFuture := true
            //Check for if previous high lines have been tested by the last session"s highs
            if prevSessionHigh > highLine.price
                highLine.testedInFuture := true
            //Check for if previous low lines have been tested by the last session"s lows
            if prevSessionLow < lowLine.price
                lowLine.testedInFuture := true

    if rthOpen_Arr.size() > 2
        t2Open_Arr.push(rthOpen_Arr.get(rthOpen_Arr.size() - 2).copy())
    t2Close_Arr.push(prevDayClose.copy())
    t2High_Arr.push(prevDayHigh.copy())
    t2Low_Arr.push(prevDayLow.copy())

    prevDayClose.price    := close[1]
    prevDayClose.barIndex := bar_index[1]
    prevDayClose.barTime  := time[1]
    prevClose_Arr.push(prevDayClose.copy())

    prevDayHigh.price     := sessionHighPrice[1]
    prevDayHigh.barIndex  := sessionHighBarIndex[1]
    prevDayHigh.barTime   := sessionHighTime[1]
    prevHigh_Arr.push(prevDayHigh.copy())
    
    prevDayLow.price      := sessionLowPrice[1]
    prevDayLow.barIndex   := sessionLowBarIndex[1]
    prevDayLow.barTime    := sessionLowTime[1]
    prevLow_Arr.push(prevDayLow.copy())

    prevDayMid.price      := math.round_to_mintick((prevDayHigh.price + prevDayLow.price) / 2)
    prevDayMid.barIndex   := rthOpen.barIndex
    prevDayMid.barTime    := rthOpen.barTime
    prev50HL_Arr.push(prevDayMid.copy())

    prevDayOCMid.price    := math.round_to_mintick((prevDayClose.price + rthOpen.price) / 2)
    prevDayOCMid.barIndex := rthOpen.barIndex    
    prevDayOCMid.barTime  := rthOpen.barTime
    prev50OC_Arr.push(prevDayOCMid.copy())

    if prevWeekHigh.price < prevDayHigh.price
        prevWeekHigh   := prevDayHigh.copy()
    if prevWeekLow.price > prevDayLow.price
        prevWeekLow    := prevDayLow.copy()
    prevWeek50HL.price := (prevWeekHigh.price + prevWeekLow.price) / 2
    
    if prevMonthHigh.price < prevDayHigh.price
        prevMonthHigh  := prevDayHigh.copy()
    if prevMonthLow.price > prevDayLow.price
        prevMonthLow   := prevDayLow.copy()
    prevMonth50HL.price := (prevMonthHigh.price + prevMonthLow.price) / 2

//Weekly level Calculations
//Weekly VWAP Calculations
var string anchorWeekly = "1W"
var int    index        = 1
var float  psum         = hlc3
var float  v1           = 0
var float  mean         = psum / index

//vwapWeekly = ta.vwap(hlc3, timeframe.change(anchorWeekly))
var vwapWeekly = VWAP.new(0,0,0)

if rthOpenSess and dayofweek(time) == dayofweek.monday
    vwapWeekly := VWAP.new(hlc3 * volume, volume, (hlc3 * volume) / volume)

    index := 1
    psum  := hlc3
    mean  := psum / index
    v1    := math.pow(hlc3 - mean,2)

else if insideUSSession

    vwapWeekly.sum    := vwapWeekly.sum    + (hlc3 * volume)
    vwapWeekly.volume := vwapWeekly.volume + volume
    vwapWeekly.value  := vwapWeekly.sum/vwapWeekly.volume

    index := index + 1
    psum  := psum +  hlc3
    mean  := psum / index
    v1    := v1 + math.pow(hlc3 - mean,2)

vwapVariance = nz(v1 / (index - 1))
vwapStdDev   = math.sqrt(vwapVariance)

weeklyUpperBandValue1 = vwapWeekly.value + vwapStdDev
weeklyLowerBandValue1 = vwapWeekly.value - vwapStdDev
weeklyUpperBandValue2 = vwapWeekly.value + vwapStdDev * 2
weeklyLowerBandValue2 = vwapWeekly.value - vwapStdDev * 2
weeklyUpperBandValue3 = vwapWeekly.value + vwapStdDev * 3
weeklyLowerBandValue3 = vwapWeekly.value - vwapStdDev * 3

if newWeek
    prevWeekClose := prevDayClose.copy()

    //Get last weeks RTH value to update HL2 and OC2 barIndex/barTime
    if rthWeekOpen_Arr.size() > 1

        lastWeekRTH = rthOnlyChart ? rthWeekOpen_Arr.get(rthWeekOpen_Arr.size() - 2) : rthWeekOpen_Arr.get(rthWeekOpen_Arr.size() - 1) 
        
        prevWeek50OC.price := (prevWeekClose.price + lastWeekRTH.price) / 2
        prevWeek50HL.barIndex  := lastWeekRTH.barIndex
        prevWeek50OC.barIndex  := lastWeekRTH.barIndex
        prevWeek50HL.barTime   := lastWeekRTH.barTime
        prevWeek50OC.barTime   := lastWeekRTH.barTime
    
    //push values to their respective arrays
    prevWeekHigh_Arr.push(prevWeekHigh.copy())
    prevWeekLow_Arr.push(prevWeekLow.copy())
    prevWeekClose_Arr.push(prevWeekClose.copy())
    prevWeek50HL_Arr.push(prevWeek50HL.copy())
    prevWeek50OC_Arr.push(prevWeek50OC.copy())

    //Push VWAP values to respective arrays
    prevWeekVWAP_Arr.push(ValueLine.new(vwapWeekly.value[1], prevWeek50HL.barIndex, prevWeek50HL.barTime))
    prevWeekVWAP_UBand1_Arr.push(ValueLine.new(weeklyUpperBandValue1[1], prevWeek50HL.barIndex, prevWeek50HL.barTime))
    prevWeekVWAP_LBand1_Arr.push(ValueLine.new(weeklyLowerBandValue1[1], prevWeek50HL.barIndex, prevWeek50HL.barTime))
    prevWeekVWAP_UBand2_Arr.push(ValueLine.new(weeklyUpperBandValue2[1], prevWeek50HL.barIndex, prevWeek50HL.barTime))
    prevWeekVWAP_LBand2_Arr.push(ValueLine.new(weeklyLowerBandValue2[1], prevWeek50HL.barIndex, prevWeek50HL.barTime))
    prevWeekVWAP_UBand3_Arr.push(ValueLine.new(weeklyUpperBandValue3[1], prevWeek50HL.barIndex, prevWeek50HL.barTime))
    prevWeekVWAP_LBand3_Arr.push(ValueLine.new(weeklyLowerBandValue3[1], prevWeek50HL.barIndex, prevWeek50HL.barTime))

//Monthly Level Calculations
if newMonth
    prevMonthClose := prevDayClose.copy()

    //get last months RTH value to update HL2 and OC2 barIndex/barTime
    if rthMonthOpen_Arr.size() > 1
        lastMonthRTH = rthOnlyChart ? rthMonthOpen_Arr.get(rthMonthOpen_Arr.size() - 2) : rthMonthOpen_Arr.get(rthMonthOpen_Arr.size() - 1)
        
        prevMonth50OC.price  := (prevMonthClose.price + lastMonthRTH.price) / 2
        prevMonth50HL.barIndex  := lastMonthRTH.barIndex
        prevMonth50OC.barIndex  := lastMonthRTH.barIndex
        prevMonth50HL.barTime   := lastMonthRTH.barTime
        prevMonth50OC.barTime   := lastMonthRTH.barTime
    
    //push values to their respective arrays
    prevMonthHigh_Arr.push(prevMonthHigh.copy())
    prevMonthLow_Arr.push(prevMonthLow.copy())
    prevMonthClose_Arr.push(prevMonthClose.copy())
    prevMonth50HL_Arr.push(prevMonth50HL.copy())
    prevMonth50OC_Arr.push(prevMonth50OC.copy())

//New Session Filters for all types of tickers
//Globex Open Filter (Futures)
//End of US Session (Forex and Crypto)
//New Day filter (Securities and Indexes) when showing only RTH
//End of RTH filter (Securities and Indexes) when showing ETH
resetLineFilter = (syminfo.type == "futures" and futuresNewSession) or
                 ((syminfo.type =="crypto" or syminfo.type == "forex" or syminfo.type == "index") and endOfUSSession) or
                 (((syminfo.type == "stock" or syminfo.type == "fund" or syminfo.type == "dr") and syminfo.session == session.regular) and newDay) or
                 (((syminfo.type == "stock" or syminfo.type == "index" or syminfo.type == "fund" or syminfo.type == "dr") and syminfo.session == session.extended) and endOfUSSession)

//Updating Value Lines collected above into a label description and new line
//Only show on 30m chart or below
if showDailyLevels == true and timeframe.in_seconds() <= timeframe.in_seconds("30")
    //Globex Open
    if showGlobexOpen == true and globexOpen_Arr.size() > 0
        if futuresNewSession and syminfo.type == "futures"
            newGlobexOpen         = globexOpen_Arr.last()
            globexOpen_Name       = globexOpenName + ": " + str.tostring(newGlobexOpen.price, format.mintick)
            newGlobexOpen.llabel := showDailyLabels ? label.new(
                                     x = initialLabelOffset, 
                                     y = newGlobexOpen.price, 
                                     text = globexOpen_Name, 
                                     xloc = xloc.bar_index, 
                                     textcolor = labelColorMatchLineD ? globexOpenColor : labelColorDaily,  
                                     textalign = text.align_right, 
                                     style = label.style_none, 
                                     size = labelDailyTextSize) : na
            newGlobexOpen.level  := line.new(
                                     x1 = newGlobexOpen.barTime, 
                                     y1 = newGlobexOpen.price, 
                                     x2 = initialLineOffset, 
                                     y2 = newGlobexOpen.price, 
                                     xloc = xloc.bar_time, 
                                     extend = extendLineDaily, 
                                     color = globexOpenColor,
                                     style = lineStyleDaily, 
                                     width = linewidthDaily)
        updateLines(globexOpen_Arr, numDailyPeriods, false, labeloffsetDaily)
    
    //RTH Open
    if showRthOpen == true and rthOpen_Arr.size() > 0
        if rthOpenSess
            newRthOpen         = rthOpen_Arr.last()
            rthOpen_Name       = rthOpenName + ": " + str.tostring(newRthOpen.price, format.mintick)
            newRthOpen.llabel := showDailyLabels ? label.new(
                                 x = initialLabelOffset, 
                                 y = newRthOpen.price, 
                                 text = rthOpen_Name, 
                                 xloc = xloc.bar_index, 
                                 textcolor = labelColorMatchLineD ? rthOpenColor : labelColorDaily,  
                                 textalign = text.align_right, 
                                 style = label.style_none, 
                                 size = labelDailyTextSize) : na
            newRthOpen.level  := line.new(
                                 x1 = newRthOpen.barTime, 
                                 y1 = newRthOpen.price, 
                                 x2 = initialLineOffset, 
                                 y2 = newRthOpen.price, 
                                 xloc = xloc.bar_time, 
                                 extend = extendLineDaily, 
                                 color = rthOpenColor,
                                 style = lineStyleDaily, 
                                 width = linewidthDaily)
        updateLines(rthOpen_Arr, numDailyPeriods, false, labeloffsetDaily)

    //London Open
    if showLondonOpen == true and londonOpen_Arr.size() > 0
        if rthOnlyChart ? rthOpenSess : newLonSession
            newLondonOpen         = londonOpen_Arr.last()
            londonOpen_Name       = londonOpenName + ": " + str.tostring(newLondonOpen.price, format.mintick)
            newLondonOpen.llabel := showDailyLabels ? label.new(
                                     x = initialLabelOffset, 
                                     y = newLondonOpen.price, 
                                     text = londonOpen_Name, 
                                     xloc = xloc.bar_index, 
                                     textcolor = labelColorMatchLineD ? londonOpenColor : labelColorDaily,  
                                     textalign = text.align_right, 
                                     style = label.style_none, 
                                     size = labelDailyTextSize) : na
            newLondonOpen.level  := line.new(
                                     x1 = newLondonOpen.barTime, 
                                     y1 = newLondonOpen.price, 
                                     x2 = initialLineOffset, 
                                     y2 = newLondonOpen.price, 
                                     xloc = xloc.bar_time, 
                                     extend = extendLineDaily, 
                                     color = londonOpenColor,
                                     style = lineStyleDaily, 
                                     width = linewidthDaily)
        updateLines(londonOpen_Arr, numDailyPeriods, false, labeloffsetDaily)
    
    //Midnight Open
    if showMidNOpen == true and midnightOpen_Arr.size() > 0
        if rthOnlyChart ? rthOpenSess : midnightOpenSess
            newMidnightOpen         = midnightOpen_Arr.last()
            midnightOpen_Name       = midNOpenName + ": " + str.tostring(newMidnightOpen.price, format.mintick)
            newMidnightOpen.llabel := showDailyLabels ? label.new(
                                     x = initialLabelOffset, 
                                     y = newMidnightOpen.price, 
                                     text = midnightOpen_Name, 
                                     xloc = xloc.bar_index, 
                                     textcolor = labelColorMatchLineD ? midNOpenColor : labelColorDaily,  
                                     textalign = text.align_right, 
                                     style = label.style_none, 
                                     size = labelDailyTextSize) : na
            newMidnightOpen.level  := line.new(
                                     x1 = newMidnightOpen.barTime, 
                                     y1 = newMidnightOpen.price, 
                                     x2 = initialLineOffset, 
                                     y2 = newMidnightOpen.price, 
                                     xloc = xloc.bar_time, 
                                     extend = extendLineDaily, 
                                     color = midNOpenColor,
                                     style = lineStyleDaily, 
                                     width = linewidthDaily)
        updateLines(midnightOpen_Arr, numDailyPeriods, false, labeloffsetDaily)

    //Overnight High
    if showOnHigh == true and onHigh_Arr.size() > 0
        if rthOpenSess
            newONHigh         = onHigh_Arr.last()
            onHigh_Name       = onHighName + ": " + str.tostring(newONHigh.price, format.mintick)
            newONHigh.llabel := showDailyLabels ? label.new(
                                 x = initialLabelOffset, 
                                 y = newONHigh.price, 
                                 text = onHigh_Name, 
                                 xloc = xloc.bar_index, 
                                 textcolor =  labelColorMatchLineD ? onHighColor : labelColorDaily,  
                                 textalign = text.align_right, 
                                 style = label.style_none, 
                                 size = labelDailyTextSize) : na
            newONHigh.level  := line.new(
                                 x1 = newONHigh.barTime, 
                                 y1 = newONHigh.price, 
                                 x2 = initialLineOffset, 
                                 y2 = newONHigh.price, 
                                 xloc = xloc.bar_time, 
                                 extend = extendLineDaily, 
                                 color = onHighColor,
                                 style = lineStyleDaily, 
                                 width = linewidthDaily)
        updateLines(onHigh_Arr, numDailyPeriods, false, labeloffsetDaily)

    //Overnight Low
    if showOnLow == true and onLow_Arr.size() > 0
        if rthOpenSess
            newONLow          = onLow_Arr.last()
            onLow_Name       = onLowName + ": " + str.tostring(newONLow.price, format.mintick)
            newONLow.llabel := showDailyLabels ? label.new(
                                 x = initialLabelOffset, 
                                 y = newONLow.price, 
                                 text = onLow_Name, 
                                 xloc = xloc.bar_index, 
                                 textcolor = labelColorMatchLineD ? onLowColor : labelColorDaily,  
                                 textalign = text.align_right, 
                                 style = label.style_none, 
                                 size = labelDailyTextSize) : na
            newONLow.level  := line.new(
                                 x1 = newONLow.barTime, 
                                 y1 = newONLow.price, 
                                 x2 = initialLineOffset, 
                                 y2 = newONLow.price, 
                                 xloc = xloc.bar_time, 
                                 extend = extendLineDaily, 
                                 color = onLowColor,
                                 style = lineStyleDaily, 
                                 width = linewidthDaily)
        updateLines(onLow_Arr, numDailyPeriods, false, labeloffsetDaily)

    if showPrevHigh == true and prevHigh_Arr.size() > 0
        if resetLineFilter
            newPrevHigh         = prevHigh_Arr.last()
            prevHigh_Name       = prevHighName + ": " + str.tostring(newPrevHigh.price, format.mintick)
            newPrevHigh.llabel := showDailyLabels ? label.new(
                                     x = initialLabelOffset, 
                                     y = newPrevHigh.price, 
                                     text = prevHigh_Name, 
                                     xloc = xloc.bar_index, 
                                     textcolor = labelColorMatchLineD ? prevHighColor : labelColorDaily,  
                                     textalign = text.align_right, 
                                     style = label.style_none, 
                                     size = labelDailyTextSize) : na
            newPrevHigh.level  := line.new(
                                   x1 = newPrevHigh.barTime, 
                                   y1 = newPrevHigh.price, 
                                   x2 = initialLineOffset, 
                                   y2 = newPrevHigh.price, 
                                   xloc = xloc.bar_time, 
                                   extend = extendLineDaily, 
                                   color = prevHighColor,
                                   style = lineStyleDaily, 
                                   width = linewidthDaily)
        updateLines(prevHigh_Arr, numDailyPeriods, false, labeloffsetDaily, showUntestedHLCLevels, showInactiveHLCLevels)

    if showPrevLow == true and prevLow_Arr.size() > 0
        if resetLineFilter
            newPrevLow         = prevLow_Arr.last()
            prevLow_Name       = prevLowName + ": " + str.tostring(newPrevLow.price, format.mintick)
            newPrevLow.llabel := showDailyLabels ? label.new(
                                     x = initialLabelOffset, 
                                     y = newPrevLow.price, 
                                     text = prevLow_Name, 
                                     xloc = xloc.bar_index, 
                                     textcolor = labelColorMatchLineD ? prevLowColor : labelColorDaily,  
                                     textalign = text.align_right, 
                                     style = label.style_none, 
                                     size = labelDailyTextSize) : na
            newPrevLow.level  := line.new(
                                     x1 = newPrevLow.barTime, 
                                     y1 = newPrevLow.price, 
                                     x2 = initialLineOffset, 
                                     y2 = newPrevLow.price, 
                                     xloc = xloc.bar_time, 
                                     extend = extendLineDaily, 
                                     color = prevLowColor,
                                     style = lineStyleDaily, 
                                     width = linewidthDaily)
        updateLines(prevLow_Arr, numDailyPeriods, false, labeloffsetDaily, showUntestedHLCLevels, showInactiveHLCLevels)

    if showPrevMidHL == true and prev50HL_Arr.size() > 0
        if resetLineFilter
            newPrevMidHL         = prev50HL_Arr.last()
            prevMidHL_Name       = midHLName + ": " + str.tostring(newPrevMidHL.price, format.mintick)
            newPrevMidHL.llabel := showDailyLabels ? label.new(
                                     x = initialLabelOffset, 
                                     y = newPrevMidHL.price, 
                                     text = prevMidHL_Name, 
                                     xloc = xloc.bar_index, 
                                     textcolor = labelColorMatchLineD ? midHLColor : labelColorDaily,  
                                     textalign = text.align_right, 
                                     style = label.style_none, 
                                     size = labelDailyTextSize) : na
            newPrevMidHL.level  := line.new(
                                     x1 = newPrevMidHL.barTime, 
                                     y1 = newPrevMidHL.price, 
                                     x2 = initialLineOffset, 
                                     y2 = newPrevMidHL.price, 
                                     xloc = xloc.bar_time, 
                                     extend = extendLineDaily, 
                                     color = midHLColor,
                                     style = lineStyleDaily, 
                                     width = linewidthDaily)
        updateLines(prev50HL_Arr, numDailyPeriods, false, labeloffsetDaily)

    if showPrevMidOC == true and prev50OC_Arr.size() > 0
        if resetLineFilter
            newPrevMidOC         = prev50OC_Arr.last()
            prevMidOC_Name       = midOCName + ": " + str.tostring(newPrevMidOC.price, format.mintick)
            newPrevMidOC.llabel := showDailyLabels ? label.new(
                                     x = initialLabelOffset, 
                                     y = newPrevMidOC.price, 
                                     text = prevMidOC_Name, 
                                     xloc = xloc.bar_index, 
                                     textcolor = labelColorMatchLineD ? midOCColor : labelColorDaily,
                                     textalign = text.align_right, 
                                     style = label.style_none, 
                                     size = labelDailyTextSize) : na
            newPrevMidOC.level  := line.new(
                                     x1 = newPrevMidOC.barTime, 
                                     y1 = newPrevMidOC.price, 
                                     x2 = initialLineOffset,
                                     y2 = newPrevMidOC.price, 
                                     xloc = xloc.bar_time, 
                                     extend = extendLineDaily, 
                                     color = midOCColor,
                                     style = lineStyleDaily, 
                                     width = linewidthDaily)
        updateLines(prev50OC_Arr, numDailyPeriods, false, labeloffsetDaily)   

    if showPrevClose == true and prevClose_Arr.size() > 0
        if resetLineFilter
            newPrevClose         = prevClose_Arr.last()
            prevDayClose_Name    = prevCloseName + ": " + str.tostring(newPrevClose.price, format.mintick)
            newPrevClose.llabel := showDailyLabels ? label.new(
                                     x = initialLabelOffset, 
                                     y = newPrevClose.price, 
                                     text = prevDayClose_Name, 
                                     xloc = xloc.bar_index, 
                                     textcolor = labelColorMatchLineD ? prevCloseColor : labelColorDaily, 
                                     textalign = text.align_left, 
                                     style = label.style_none, 
                                     size = labelDailyTextSize) : na
            newPrevClose.level  := line.new(
                                     x1 = newPrevClose.barTime, 
                                     y1 = newPrevClose.price, 
                                     x2 = initialLineOffset, 
                                     y2 = newPrevClose.price, 
                                     xloc = xloc.bar_time, 
                                     extend = extendLineDaily, 
                                     color = prevCloseColor,
                                     style = lineStyleDaily, 
                                     width = linewidthDaily)
        updateLines(prevClose_Arr, numDailyPeriods, false, labeloffsetDaily, showUntestedHLCLevels, showInactiveHLCLevels) 

    // //T+2 Settlement Open/Close(settlement levels)
    if showT2Open == true and t2Open_Arr.size() > 0
        if resetLineFilter
            newt2Open         = t2Open_Arr.last()
            t2Open_Name       = t2OpenName + ": " + str.tostring(newt2Open.price, format.mintick)
            newt2Open.llabel := showDailyLabels ? label.new(
                                 x = initialLabelOffset, 
                                 y = newt2Open.price, 
                                 text = t2Open_Name, 
                                 xloc = xloc.bar_index, 
                                 textcolor =  labelColorMatchLineD ? t2OpenColor : labelColorDaily, 
                                 textalign = text.align_right, 
                                 style = label.style_none, 
                                 size = labelDailyTextSize) : na
            newt2Open.level := line.new(
                                 x1 = newt2Open.barTime, 
                                 y1 = newt2Open.price, 
                                 x2 = initialLineOffset, 
                                 y2 = newt2Open.price, 
                                 xloc = xloc.bar_time, 
                                 extend = extendLineDaily, 
                                 color = t2OpenColor,
                                 style = lineStyleDaily, 
                                 width = linewidthDaily)
        updateLines(t2Open_Arr, numDailyPeriods, false, labeloffsetDaily)

    if showT2Close == true and t2Close_Arr.size() > 0
        if resetLineFilter
            newt2Close  = t2Close_Arr.last()
            t2Close_Name = t2CloseName + ": " + str.tostring(newt2Close.price, format.mintick)
            newt2Close.llabel := showDailyLabels ? label.new(
                                 x = initialLabelOffset, 
                                 y = newt2Close.price, 
                                 text = t2Close_Name, 
                                 xloc = xloc.bar_index, 
                                 textcolor =  labelColorMatchLineD ? t2CloseColor : labelColorDaily, 
                                 textalign = text.align_right, 
                                 style = label.style_none, 
                                 size = labelDailyTextSize) : na
            newt2Close.level  := line.new(
                                  x1 = newt2Close.barTime, 
                                  y1 = newt2Close.price, 
                                  x2 = initialLineOffset, 
                                  y2 = newt2Close.price, 
                                  xloc = xloc.bar_time, 
                                  extend = extendLineDaily, 
                                  color = t2CloseColor,
                                  style = lineStyleDaily, 
                                  width = linewidthDaily)
        updateLines(t2Close_Arr, numDailyPeriods, false, labeloffsetDaily)  

    // //T+2 Settlement High/Low (settlement levels)
    if showT2High == true and t2High_Arr.size() > 0
        if resetLineFilter
            newt2High  = t2High_Arr.last()
            t2High_Name = t2HighName + ": " + str.tostring(newt2High.price, format.mintick)
            newt2High.llabel := showDailyLabels ? label.new(
                                 x = initialLabelOffset, 
                                 y = newt2High.price, 
                                 text = t2High_Name, 
                                 xloc = xloc.bar_index, 
                                 textcolor =  labelColorMatchLineD ? t2HighColor : labelColorDaily, 
                                 textalign = text.align_right, 
                                 style = label.style_none, 
                                 size = labelDailyTextSize) : na
            newt2High.level  := line.new(
                                  x1 = newt2High.barTime, 
                                  y1 = newt2High.price, 
                                  x2 = initialLineOffset, 
                                  y2 = newt2High.price, 
                                  xloc = xloc.bar_time, 
                                  extend = extendLineDaily, 
                                  color = t2HighColor,
                                  style = lineStyleDaily, 
                                  width = linewidthDaily)
        updateLines(t2High_Arr, numDailyPeriods, false, labeloffsetDaily)
        
    if showT2Low == true and t2Low_Arr.size() > 0   
        if resetLineFilter
            newt2Low  = t2Low_Arr.last()
            t2Low_Name = t2LowName + ": " + str.tostring(newt2Low.price, format.mintick)
            newt2Low.llabel := showDailyLabels ? label.new(
                                 x = initialLabelOffset, 
                                 y = newt2Low.price, 
                                 text = t2Low_Name, 
                                 xloc = xloc.bar_index, 
                                 textcolor =  labelColorMatchLineD ? t2LowColor : labelColorDaily, 
                                 textalign = text.align_right, 
                                 style = label.style_none, 
                                 size = labelDailyTextSize) : na
            newt2Low.level  := line.new(
                                  x1 = newt2Low.barTime, 
                                  y1 = newt2Low.price, 
                                  x2 = initialLineOffset, 
                                  y2 = newt2Low.price, 
                                  xloc = xloc.bar_time, 
                                  extend = extendLineDaily, 
                                  color = t2LowColor,
                                  style = lineStyleDaily, 
                                  width = linewidthDaily)   
        updateLines(t2Low_Arr, numDailyPeriods, false, labeloffsetDaily)

if showWeeklyLevels
    
    initialLabelOffset := bar_index + labeloffsetWeekly

    if rthOpenSess and (dayofweek(time, "America/New_York") == dayofweek.monday or 
         (dayofweek(prevDayMid.barTime, "America/New_York") == dayofweek.friday and 
             dayofweek(time, "America/New_York") == dayofweek.tuesday))
        if showRthWeekOpen and rthWeekOpen_Arr.size() > 0
            newrthWeekOpen   = rthWeekOpen_Arr.last()
            rthWeekOpen_Name =  wkOpenName + ": " + str.tostring(newrthWeekOpen.price, format.mintick)
            newrthWeekOpen.llabel := showWeeklyLabels ? label.new(
                                       x = initialLabelOffset, 
                                       y = newrthWeekOpen.price, 
                                       text = rthWeekOpen_Name, 
                                       xloc = xloc.bar_index, 
                                       textcolor = labelColorMatchLineW ? wkOpenColor : labelColorWeekly, 
                                       textalign = text.align_right, 
                                       style = label.style_none, 
                                       size = labelWklyTextSize) : na
            newrthWeekOpen.level  := line.new(
                                       x1 = newrthWeekOpen.barTime, 
                                       y1 = newrthWeekOpen.price, 
                                       x2 = initialLineOffset, 
                                       y2 = newrthWeekOpen.price, 
                                       xloc = xloc.bar_time, 
                                       extend = extendLineWeekly, 
                                       color = wkOpenColor,
                                       style = lineStyleWeekly, 
                                       width = linewidthWeekly) 

    if newWeek

        if showPrevWeekHigh and prevWeekHigh_Arr.size() > 0
            newPrevWeekHigh   = prevWeekHigh_Arr.last()
            prevWeekHigh_Name = prevWeekHighName + ": " + str.tostring(newPrevWeekHigh.price, format.mintick)
            newPrevWeekHigh.llabel := showWeeklyLabels ? label.new(
                                       x = initialLabelOffset, 
                                       y = newPrevWeekHigh.price, 
                                       text = prevWeekHigh_Name, 
                                       xloc = xloc.bar_index, 
                                       textcolor = labelColorMatchLineW ? wkHighColor : labelColorWeekly, 
                                       textalign = text.align_right, 
                                       style = label.style_none, 
                                       size = labelWklyTextSize) : na
            newPrevWeekHigh.level  := line.new(
                                       x1 = newPrevWeekHigh.barTime, 
                                       y1 = newPrevWeekHigh.price, 
                                       x2 = initialLineOffset, 
                                       y2 = newPrevWeekHigh.price, 
                                       xloc = xloc.bar_time, 
                                       extend = extendLineWeekly, 
                                       color = wkHighColor,
                                       style = lineStyleWeekly, 
                                       width = linewidthWeekly)
        prevWeekHigh.price := 0

        if showPrevWeekLow and prevWeekLow_Arr.size() > 0
            newPrevWeekLow   = prevWeekLow_Arr.last()
            prevWeekLow_Name = prevWeekLowName + ": " + str.tostring(newPrevWeekLow.price, format.mintick)
            newPrevWeekLow.llabel := showWeeklyLabels ? label.new(
                                       x = initialLabelOffset, 
                                       y = newPrevWeekLow.price, 
                                       text = prevWeekLow_Name, 
                                       xloc = xloc.bar_index, 
                                       textcolor = labelColorMatchLineW ? wkLowColor : labelColorWeekly, 
                                       textalign = text.align_right, 
                                       style = label.style_none, 
                                       size = labelWklyTextSize) : na
            newPrevWeekLow.level  := line.new(
                                       x1 = newPrevWeekLow.barTime, 
                                       y1 = newPrevWeekLow.price, 
                                       x2 = initialLineOffset, 
                                       y2 = newPrevWeekLow.price, 
                                       xloc = xloc.bar_time, 
                                       extend = extendLineWeekly, 
                                       color = wkLowColor,
                                       style = lineStyleWeekly, 
                                       width = linewidthWeekly) 
        prevWeekLow.price := 100000000

        if showPrevWeekHalfHL and prevWeek50HL_Arr.size() > 0
            newPrevWeek50HL   = prevWeek50HL_Arr.last()
            prevWeek50HL_Name =prevWeekHalfHLName + ": " + str.tostring(prevWeek50HL.price, format.mintick)
            newPrevWeek50HL.llabel := showWeeklyLabels ? label.new(
                                       x = initialLabelOffset, 
                                       y = newPrevWeek50HL.price, 
                                       text = prevWeek50HL_Name, 
                                       xloc = xloc.bar_index, 
                                       textcolor = labelColorMatchLineW ? wkHalfHLColor : labelColorWeekly, 
                                       textalign = text.align_right, 
                                       style = label.style_none, 
                                       size = labelWklyTextSize) : na
            newPrevWeek50HL.level  := line.new(
                                       x1 = newPrevWeek50HL.barTime, 
                                       y1 = newPrevWeek50HL.price, 
                                       x2 = initialLineOffset, 
                                       y2 = newPrevWeek50HL.price, 
                                       xloc = xloc.bar_time, 
                                       extend = extendLineWeekly, 
                                       color = wkHalfHLColor,
                                       style = lineStyleWeekly, 
                                       width = linewidthWeekly) 

        if showPrevWeekHalfOC and prevWeek50OC_Arr.size() > 0
            newPrevWeek50OC   = prevWeek50OC_Arr.last()
            prevWeek50OC_Name = prevWeekHalfOCName + ": " + str.tostring(prevWeek50OC.price, format.mintick)
            newPrevWeek50OC.llabel := showWeeklyLabels ? label.new(
                                       x = initialLabelOffset, 
                                       y = newPrevWeek50OC.price, 
                                       text = prevWeek50OC_Name, 
                                       xloc = xloc.bar_index, 
                                       textcolor = labelColorMatchLineW ? wkHalfOCColor : labelColorWeekly, 
                                       textalign = text.align_right, 
                                       style = label.style_none, 
                                       size = labelWklyTextSize) : na
            newPrevWeek50OC.level  := line.new(
                                       x1 = newPrevWeek50OC.barTime, 
                                       y1 = newPrevWeek50OC.price, 
                                       x2 = initialLineOffset, 
                                       y2 = newPrevWeek50OC.price, 
                                       xloc = xloc.bar_time, 
                                       extend = extendLineWeekly, 
                                       color = wkHalfOCColor,
                                       style = lineStyleWeekly, 
                                       width = linewidthWeekly) 

        if showPrevWeekClose and prevWeekClose_Arr.size() > 0
            newPrevWeekClose   = prevWeekClose_Arr.last()
            prevWeekClose_Name = wkCloseName + ": " + str.tostring(prevWeekClose.price, format.mintick)
            newPrevWeekClose.llabel := showWeeklyLabels ? label.new(
                                       x = initialLabelOffset, 
                                       y = newPrevWeekClose.price, 
                                       text = prevWeekClose_Name, 
                                       xloc = xloc.bar_index, 
                                       textcolor = labelColorMatchLineW ? wkCloseColor : labelColorWeekly, 
                                       textalign = text.align_right, 
                                       style = label.style_none, 
                                       size = labelWklyTextSize) : na
            newPrevWeekClose.level  := line.new(
                                       x1 = newPrevWeekClose.barTime, 
                                       y1 = newPrevWeekClose.price, 
                                       x2 = initialLineOffset, 
                                       y2 = newPrevWeekClose.price, 
                                       xloc = xloc.bar_time, 
                                       extend = extendLineWeekly, 
                                       color = wkCloseColor,
                                       style = lineStyleWeekly, 
                                       width = linewidthWeekly) 

        if showPrevWeekVWAP and prevWeekVWAP_Arr.size() > 0
            newPrevWeekVWAP   = prevWeekVWAP_Arr.last()
            prevWeekVWAP_Name = wkVWAPName + ": " + str.tostring(newPrevWeekVWAP.price, format.mintick)
            newPrevWeekVWAP.llabel := showWeeklyLabels ? label.new(
                                       x = initialLabelOffset, 
                                       y = newPrevWeekVWAP.price, 
                                       text = prevWeekVWAP_Name, 
                                       xloc = xloc.bar_index, 
                                       textcolor = labelColorMatchLineW ? wkVWAPColor : labelColorWeekly, 
                                       textalign = text.align_right, 
                                       style = label.style_none, 
                                       size = labelWklyTextSize) : na
            newPrevWeekVWAP.level  := line.new(
                                       x1 = newPrevWeekVWAP.barTime, 
                                       y1 = newPrevWeekVWAP.price, 
                                       x2 = initialLineOffset, 
                                       y2 = newPrevWeekVWAP.price, 
                                       xloc = xloc.bar_time, 
                                       extend = extendLineWeekly, 
                                       color = wkVWAPColor,
                                       style = lineStyleWeekly, 
                                       width = linewidthWeekly) 

        if showPrevWeekSD1 and prevWeekVWAP_UBand1_Arr.size() > 0
            newPrevWeekSD1   = prevWeekVWAP_UBand1_Arr.last()
            prevWeekSD1_Name = wkVSD1Name + ": " + str.tostring(newPrevWeekSD1.price, format.mintick)
            newPrevWeekSD1.llabel := showWeeklyLabels ? label.new(
                                       x = initialLabelOffset, 
                                       y = newPrevWeekSD1.price, 
                                       text = prevWeekSD1_Name, 
                                       xloc = xloc.bar_index, 
                                       textcolor = labelColorMatchLineW ? wkVSD1Color : labelColorWeekly, 
                                       textalign = text.align_right, 
                                       style = label.style_none, 
                                       size = labelWklyTextSize) : na
            newPrevWeekSD1.level  := line.new(
                                       x1 = newPrevWeekSD1.barTime, 
                                       y1 = newPrevWeekSD1.price, 
                                       x2 = initialLineOffset, 
                                       y2 = newPrevWeekSD1.price, 
                                       xloc = xloc.bar_time, 
                                       extend = extendLineWeekly, 
                                       color = wkVSD1Color,
                                       style = lineStyleWeekly, 
                                       width = linewidthWeekly)

        if showPrevWeekSD1 and prevWeekVWAP_LBand1_Arr.size() > 0
            newPrevWeekSD1   = prevWeekVWAP_LBand1_Arr.last()
            prevWeekSD1_Name = wkVSD1Name + ": " + str.tostring(newPrevWeekSD1.price, format.mintick)
            newPrevWeekSD1.llabel := showWeeklyLabels ? label.new(
                                       x = initialLabelOffset, 
                                       y = newPrevWeekSD1.price, 
                                       text = prevWeekSD1_Name, 
                                       xloc = xloc.bar_index, 
                                       textcolor = labelColorMatchLineW ? wkVSD1Color : labelColorWeekly, 
                                       textalign = text.align_right, 
                                       style = label.style_none, 
                                       size = labelWklyTextSize) : na
            newPrevWeekSD1.level  := line.new(
                                       x1 = newPrevWeekSD1.barTime, 
                                       y1 = newPrevWeekSD1.price, 
                                       x2 = initialLineOffset, 
                                       y2 = newPrevWeekSD1.price, 
                                       xloc = xloc.bar_time, 
                                       extend = extendLineWeekly, 
                                       color = wkVSD1Color,
                                       style = lineStyleWeekly, 
                                       width = linewidthWeekly)

        if showPrevWeekSD2 and prevWeekVWAP_UBand2_Arr.size() > 0
            newPrevWeekSD2   = prevWeekVWAP_UBand2_Arr.last()
            prevWeekSD2_Name = wkVSD2Name + ": " + str.tostring(newPrevWeekSD2.price, format.mintick)
            newPrevWeekSD2.llabel := showWeeklyLabels ? label.new(
                                       x = initialLabelOffset, 
                                       y = newPrevWeekSD2.price, 
                                       text = prevWeekSD2_Name, 
                                       xloc = xloc.bar_index, 
                                       textcolor = labelColorMatchLineW ? wkVSD2Color : labelColorWeekly, 
                                       textalign = text.align_right, 
                                       style = label.style_none, 
                                       size = labelWklyTextSize) : na
            newPrevWeekSD2.level  := line.new(
                                       x1 = newPrevWeekSD2.barTime, 
                                       y1 = newPrevWeekSD2.price, 
                                       x2 = initialLineOffset, 
                                       y2 = newPrevWeekSD2.price, 
                                       xloc = xloc.bar_time, 
                                       extend = extendLineWeekly, 
                                       color = wkVSD2Color,
                                       style = lineStyleWeekly, 
                                       width = linewidthWeekly)

        if showPrevWeekSD2 and prevWeekVWAP_LBand2_Arr.size() > 0
            newPrevWeekSD2   = prevWeekVWAP_LBand2_Arr.last()
            prevWeekSD2_Name = wkVSD2Name + ": " + str.tostring(newPrevWeekSD2.price, format.mintick)
            newPrevWeekSD2.llabel := showWeeklyLabels ? label.new(
                                       x = initialLabelOffset, 
                                       y = newPrevWeekSD2.price, 
                                       text = prevWeekSD2_Name, 
                                       xloc = xloc.bar_index, 
                                       textcolor = labelColorMatchLineW ? wkVSD2Color : labelColorWeekly, 
                                       textalign = text.align_right, 
                                       style = label.style_none, 
                                       size = labelWklyTextSize) : na
            newPrevWeekSD2.level  := line.new(
                                       x1 = newPrevWeekSD2.barTime, 
                                       y1 = newPrevWeekSD2.price, 
                                       x2 = initialLineOffset, 
                                       y2 = newPrevWeekSD2.price, 
                                       xloc = xloc.bar_time, 
                                       extend = extendLineWeekly, 
                                       color = wkVSD2Color,
                                       style = lineStyleWeekly, 
                                       width = linewidthWeekly)

        if showPrevWeekSD3 and prevWeekVWAP_UBand3_Arr.size() > 0
            newPrevWeekSD3   = prevWeekVWAP_UBand3_Arr.last()
            prevWeekSD3_Name = wkVSD3Name + ": " + str.tostring(newPrevWeekSD3.price, format.mintick)
            newPrevWeekSD3.llabel := showWeeklyLabels ? label.new(
                                       x = initialLabelOffset, 
                                       y = newPrevWeekSD3.price, 
                                       text = prevWeekSD3_Name, 
                                       xloc = xloc.bar_index, 
                                       textcolor = labelColorMatchLineW ? wkVSD3Color : labelColorWeekly, 
                                       textalign = text.align_right, 
                                       style = label.style_none, 
                                       size = labelWklyTextSize) : na
            newPrevWeekSD3.level  := line.new(
                                       x1 = newPrevWeekSD3.barTime, 
                                       y1 = newPrevWeekSD3.price, 
                                       x2 = initialLineOffset, 
                                       y2 = newPrevWeekSD3.price, 
                                       xloc = xloc.bar_time, 
                                       extend = extendLineWeekly, 
                                       color = wkVSD3Color,
                                       style = lineStyleWeekly, 
                                       width = linewidthWeekly)
                                       
        if showPrevWeekSD3 and prevWeekVWAP_LBand3_Arr.size() > 0
            newPrevWeekSD3   = prevWeekVWAP_LBand3_Arr.last()
            prevWeekSD3_Name = wkVSD3Name + ": " + str.tostring(newPrevWeekSD3.price, format.mintick)
            newPrevWeekSD3.llabel := showWeeklyLabels ? label.new(
                                       x = initialLabelOffset, 
                                       y = newPrevWeekSD3.price, 
                                       text = prevWeekSD3_Name, 
                                       xloc = xloc.bar_index, 
                                       textcolor = labelColorMatchLineW ? wkVSD3Color : labelColorWeekly, 
                                       textalign = text.align_right, 
                                       style = label.style_none, 
                                       size = labelWklyTextSize) : na
            newPrevWeekSD3.level  := line.new(
                                       x1 = newPrevWeekSD3.barTime, 
                                       y1 = newPrevWeekSD3.price, 
                                       x2 = initialLineOffset, 
                                       y2 = newPrevWeekSD3.price, 
                                       xloc = xloc.bar_time, 
                                       extend = extendLineWeekly, 
                                       color = wkVSD3Color,
                                       style = lineStyleWeekly, 
                                       width = linewidthWeekly)

    updateLines(prevWeekHigh_Arr       , numWklyPeriods, false, labeloffsetWeekly)
    updateLines(prevWeekLow_Arr        , numWklyPeriods, false, labeloffsetWeekly)
    updateLines(prevWeek50HL_Arr       , numWklyPeriods, false, labeloffsetWeekly)
    updateLines(prevWeek50OC_Arr       , numWklyPeriods, false, labeloffsetWeekly)
    updateLines(rthWeekOpen_Arr        , numWklyPeriods, false, labeloffsetWeekly)
    updateLines(prevWeekClose_Arr      , numWklyPeriods, false, labeloffsetWeekly)
    updateLines(prevWeekVWAP_Arr       , numWklyPeriods, false, labeloffsetWeekly)
    updateLines(prevWeekVWAP_UBand1_Arr, numWklyPeriods, false, labeloffsetWeekly)
    updateLines(prevWeekVWAP_LBand1_Arr, numWklyPeriods, false, labeloffsetWeekly)
    updateLines(prevWeekVWAP_UBand2_Arr, numWklyPeriods, false, labeloffsetWeekly)
    updateLines(prevWeekVWAP_LBand2_Arr, numWklyPeriods, false, labeloffsetWeekly)
    updateLines(prevWeekVWAP_UBand3_Arr, numWklyPeriods, false, labeloffsetWeekly)
    updateLines(prevWeekVWAP_LBand3_Arr, numWklyPeriods, false, labeloffsetWeekly) 

if showMonthlyLevels
    
    initialLabelOffset := bar_index + labeloffsetMonthly
    
    if rthOpenSess and (dayofmonth(prevDayMid.barTime, "America/New_York") >= 28 and
         dayofmonth(time, "America/New_York") < dayofmonth(prevDayMid.barTime, "America/New_York"))
        if showRthMonthOpen and rthMonthOpen_Arr.size() > 0
            newrthMonthOpen   = rthMonthOpen_Arr.last()
            rthMonthOpen_Name = monOpenName + ": " + str.tostring(newrthMonthOpen.price, format.mintick)
            newrthMonthOpen.llabel := showWeeklyLabels ? label.new(
                                       x = initialLabelOffset, 
                                       y = newrthMonthOpen.price, 
                                       text = rthMonthOpen_Name, 
                                       xloc = xloc.bar_index, 
                                       textcolor = labelColorMatchLineM ? monOpenColor : labelColorMonthly, 
                                       textalign = text.align_right, 
                                       style = label.style_none, 
                                       size = labelMonTextSize) : na
            newrthMonthOpen.level  := line.new(
                                       x1 = newrthMonthOpen.barTime, 
                                       y1 = newrthMonthOpen.price, 
                                       x2 = initialLineOffset, 
                                       y2 = newrthMonthOpen.price, 
                                       xloc = xloc.bar_time, 
                                       extend = extendLineMonthly, 
                                       color = monOpenColor,
                                       style = lineStyleMonthly, 
                                       width = linewidthMonthly) 

    if newMonth
        if showPrevMonthHigh and prevMonthHigh_Arr.size() > 0
            newPrevMonthHigh   = prevMonthHigh_Arr.last()
            prevMonthHigh_Name = monHighName + ":" + str.tostring(prevMonthHigh.price, format.mintick)
            newPrevMonthHigh.llabel := showWeeklyLabels ? label.new(
                                       x = initialLabelOffset, 
                                       y = prevMonthHigh.price, 
                                       text = prevMonthHigh_Name, 
                                       xloc = xloc.bar_index, 
                                       textcolor = labelColorMatchLineM ? monHighColor : labelColorMonthly, 
                                       textalign = text.align_right, 
                                       style = label.style_none, 
                                       size = labelMonTextSize) : na
            newPrevMonthHigh.level  := line.new(
                                       x1 = newPrevMonthHigh.barTime, 
                                       y1 = newPrevMonthHigh.price, 
                                       x2 = initialLineOffset, 
                                       y2 = newPrevMonthHigh.price, 
                                       xloc = xloc.bar_time, 
                                       extend = extendLineMonthly, 
                                       color = monHighColor,
                                       style = lineStyleMonthly, 
                                       width = linewidthMonthly)
        prevMonthHigh.price := 0
        
        if showPrevMonthLow and prevMonthLow_Arr.size() > 0
            newPrevMonthLow   = prevMonthLow_Arr.last()
            prevMonthLow_Name = monLowName + ":" + str.tostring(newPrevMonthLow.price, format.mintick)
            newPrevMonthLow.llabel := showWeeklyLabels ? label.new(
                                       x = initialLabelOffset, 
                                       y = newPrevMonthLow.price, 
                                       text = prevMonthLow_Name, 
                                       xloc = xloc.bar_index, 
                                       textcolor = labelColorMatchLineM ? monLowColor : labelColorMonthly, 
                                       textalign = text.align_right, 
                                       style = label.style_none, 
                                       size = labelMonTextSize) : na
            newPrevMonthLow.level  := line.new(
                                       x1 = newPrevMonthLow.barTime, 
                                       y1 = newPrevMonthLow.price, 
                                       x2 = initialLineOffset, 
                                       y2 = newPrevMonthLow.price, 
                                       xloc = xloc.bar_time, 
                                       extend = extendLineMonthly, 
                                       color = monLowColor,
                                       style = lineStyleMonthly, 
                                       width = linewidthMonthly)
        prevMonthLow.price := 100000000

        if showPrevMonthHalfHL and prevMonth50HL_Arr.size() > 0
            newPrevMonth50HL   = prevMonth50HL_Arr.last()
            prevMonth50HL_Name = monHalfHLName + ":" + str.tostring(newPrevMonth50HL.price, format.mintick)
            newPrevMonth50HL.llabel := showWeeklyLabels ? label.new(
                                       x = initialLabelOffset, 
                                       y = newPrevMonth50HL.price, 
                                       text = prevMonth50HL_Name, 
                                       xloc = xloc.bar_index, 
                                       textcolor = labelColorMatchLineM ? monHalfColorHL : labelColorMonthly, 
                                       textalign = text.align_right, 
                                       style = label.style_none, 
                                       size = labelMonTextSize) : na
            newPrevMonth50HL.level  := line.new(
                                       x1 = newPrevMonth50HL.barTime, 
                                       y1 = newPrevMonth50HL.price, 
                                       x2 = initialLineOffset, 
                                       y2 = newPrevMonth50HL.price, 
                                       xloc = xloc.bar_time, 
                                       extend = extendLineMonthly, 
                                       color = monHalfColorHL,
                                       style = lineStyleMonthly, 
                                       width = linewidthMonthly)

        if showPrevMonthHalfOC and prevMonth50OC_Arr.size() > 0
            newPrevMonth50OC   = prevMonth50OC_Arr.last()
            prevMonth50OC_Name = monHalfOCName + ":" + str.tostring(newPrevMonth50OC.price, format.mintick)
            newPrevMonth50OC.llabel := showWeeklyLabels ? label.new(
                                       x = initialLabelOffset, 
                                       y = newPrevMonth50OC.price, 
                                       text = prevMonth50OC_Name, 
                                       xloc = xloc.bar_index, 
                                       textcolor = labelColorMatchLineM ? monHalfOCColor : labelColorMonthly, 
                                       textalign = text.align_right, 
                                       style = label.style_none, 
                                       size = labelMonTextSize) : na
            newPrevMonth50OC.level  := line.new(
                                       x1 = newPrevMonth50OC.barTime, 
                                       y1 = newPrevMonth50OC.price, 
                                       x2 = initialLineOffset, 
                                       y2 = newPrevMonth50OC.price, 
                                       xloc = xloc.bar_time, 
                                       extend = extendLineMonthly, 
                                       color = monHalfOCColor,
                                       style = lineStyleMonthly, 
                                       width = linewidthMonthly)

        if showPrevMonthClose and prevMonthClose_Arr.size() > 0
            newPrevMonthClose   = prevMonthClose_Arr.last()
            prevMonthClose_Name = monCloseName + ":" + str.tostring(newPrevMonthClose.price, format.mintick)
            newPrevMonthClose.llabel := showWeeklyLabels ? label.new(
                                       x = initialLabelOffset, 
                                       y = newPrevMonthClose.price, 
                                       text = prevMonthClose_Name, 
                                       xloc = xloc.bar_index, 
                                       textcolor = labelColorMatchLineM ? monCloseColor : labelColorMonthly, 
                                       textalign = text.align_right, 
                                       style = label.style_none, 
                                       size = labelMonTextSize) : na
            newPrevMonthClose.level  := line.new(
                                       x1 = newPrevMonthClose.barTime, 
                                       y1 = newPrevMonthClose.price, 
                                       x2 = initialLineOffset, 
                                       y2 = newPrevMonthClose.price, 
                                       xloc = xloc.bar_time, 
                                       extend = extendLineMonthly, 
                                       color = monCloseColor,
                                       style = lineStyleMonthly, 
                                       width = linewidthMonthly)

    updateLines(prevMonthHigh_Arr , numMonPeriods, false, labeloffsetMonthly)
    updateLines(prevMonthLow_Arr  , numMonPeriods, false, labeloffsetMonthly)
    updateLines(prevMonth50HL_Arr , numMonPeriods, false, labeloffsetMonthly)
    updateLines(prevMonth50OC_Arr , numMonPeriods, false, labeloffsetMonthly)
    updateLines(rthMonthOpen_Arr  , numMonPeriods, false, labeloffsetMonthly)
    updateLines(prevMonthClose_Arr, numMonPeriods, false, labeloffsetMonthly)

//Delete Lines over the max limit
deleteLines(prevHigh_Arr    , showUntestedHLCLevels and showDailyLevels ? 1000 : numDailyPeriods + 2)
deleteLines(prevLow_Arr     , showUntestedHLCLevels and showDailyLevels ? 1000 : numDailyPeriods + 2)
deleteLines(prev50HL_Arr    , numDailyPeriods)
deleteLines(prev50OC_Arr    , numDailyPeriods)
deleteLines(t2Open_Arr      , numDailyPeriods)
deleteLines(t2Close_Arr     , numDailyPeriods)
deleteLines(t2High_Arr      , numDailyPeriods)
deleteLines(t2Low_Arr       , numDailyPeriods)
deleteLines(prevClose_Arr   , showUntestedHLCLevels and showDailyLevels ? 1000 : numDailyPeriods + 2)
deleteLines(rthOpen_Arr     , numDailyPeriods + 2)
deleteLines(globexOpen_Arr  , numDailyPeriods)
deleteLines(londonOpen_Arr  , numDailyPeriods)
deleteLines(midnightOpen_Arr, numDailyPeriods)
deleteLines(onHigh_Arr      , numDailyPeriods)
deleteLines(onLow_Arr       , numDailyPeriods)

deleteLines(prevWeekHigh_Arr       , numWklyPeriods)
deleteLines(prevWeekLow_Arr        , numWklyPeriods)
deleteLines(prevWeek50HL_Arr       , numWklyPeriods)
deleteLines(prevWeek50OC_Arr       , numWklyPeriods)
deleteLines(rthWeekOpen_Arr        , numWklyPeriods + 1)
deleteLines(prevWeekClose_Arr      , numWklyPeriods)
deleteLines(prevWeekVWAP_Arr       , numWklyPeriods)
deleteLines(prevWeekVWAP_LBand1_Arr, numWklyPeriods)
deleteLines(prevWeekVWAP_UBand1_Arr, numWklyPeriods)
deleteLines(prevWeekVWAP_LBand2_Arr, numWklyPeriods)
deleteLines(prevWeekVWAP_UBand2_Arr, numWklyPeriods)
deleteLines(prevWeekVWAP_LBand3_Arr, numWklyPeriods)
deleteLines(prevWeekVWAP_UBand3_Arr, numWklyPeriods)

deleteLines(prevMonthHigh_Arr , numMonPeriods)
deleteLines(prevMonthLow_Arr  , numMonPeriods)
deleteLines(prevMonth50HL_Arr , numMonPeriods)
deleteLines(prevMonth50OC_Arr , numMonPeriods)
deleteLines(rthMonthOpen_Arr  , numMonPeriods + 1)
deleteLines(prevMonthClose_Arr, numMonPeriods)

//////////////////////////////
// Intraday Market Breatdth //
//////////////////////////////
//variable declaration
showMarketBreadth = input.bool  (title="Show Market Breadth Table" , defval=true       , group="Market Breadth")
showUpDownVol     = input.bool  (title="Show NYSE/NASDAQ Breadth"  , defval=true       , group="Market Breadth")
showADD           = input.bool  (title="Show Advance/Decline Value", defval=true       , group="Market Breadth")
showTRIN          = input.bool  (title="Show TRIN.US"              , defval=false      , group="Market Breadth")
showTICK          = input.bool  (title="Show TICK"                 , defval=false      , group="Market Breadth")
showVIX           = input.bool  (title="Show VIX"                  , defval=false      , group="Market Breadth")
showVXN           = input.bool  (title="Show VXN"                  , defval=false      , group="Market Breadth")
showIorODay       = input.bool  (title="Show Inside/Outside Day"   , defval=false      , group="Market Breadth", tooltip="Inside Day = Current Day Range has not broken Prev Day High/Low\nOutside Day = Current Day Range broke Prev Day High/Low")
showSecurity1     = input.bool  (title=""                          , defval=false      , group="Market Breadth", inline="sym1")
security1         = input.symbol(title=""                          , defval = "ES1!"   , group="Market Breadth", inline="sym1")
showSecurity2     = input.bool  (title=""                          , defval=false      , group="Market Breadth", inline="sym2")
security2         = input.symbol(title=""                          , defval = "NQ1!"   , group="Market Breadth", inline="sym2")
showSecurity3     = input.bool  (title=""                          , defval=false      , group="Market Breadth", inline="sym3")
security3         = input.symbol(title=""                          , defval = "TVC:DXY", group="Market Breadth", inline="sym3")
showSecurity4     = input.bool  (title=""                          , defval=false      , group="Market Breadth", inline="sym4")
security4         = input.symbol(title=""                          , defval = "YM1!"   , group="Market Breadth", inline="sym4")
showSecurity5     = input.bool  (title=""                          , defval=false      , group="Market Breadth", inline="sym5")
security5         = input.symbol(title=""                          , defval = "CL1!"   , group="Market Breadth", inline="sym5")

showTPOInfo       = input.bool  (title="Show Market Profile TPO Period", defval=false, group="Market Breadth")
sizeOption        = input.string(title="Text Size", options=["Small", "Normal", "Large"], defval="Normal", group="Market Breadth", inline="mb")
textSize          = (sizeOption == "Small") ? size.small : 
                     (sizeOption == "Normal") ? size.normal :
                     size.large

//option for where you want to table to be
positionOption  = input.string(title="Position", options=["Top Right", "Top Left", "Bottom Right", "Bottom Left"], defval="Top Right", group="Market Breadth", inline="mb")
position        = (positionOption == "Top Right") ? position.top_right :
                   (positionOption == "Top Left") ? position.top_left :
                   (positionOption == "Bottom Right") ? position.bottom_right :
                   position.bottom_left
             
//Up and down VOL for NYSE and NASDAQ
UVOL = request.security("USI:UVOL","",close)
DVOL = request.security("USI:DVOL","",close)
UVOLQ = request.security("USI:UVOLQ","",close)
DVOLQ = request.security("USI:DVOLQ","",close)

//ADD data
ADVDCL = request.security("ADD","",close)

//TRIN data
TRIN = request.security("USI:TRIN.NY","",close)

//TICK
TICK = request.security("USI:TICK", "",close)

//VIX
VIX = request.security("TVC:VIX","",close)
//VXN NASDAQ Volatility Index
VXN = request.security("CBOE:VXN","",close)

//SECURITES
SEC1 = request.security(security1, "", close)
SEC2 = request.security(security2, "", close)
SEC3 = request.security(security3, "", close)
SEC4 = request.security(security4, "", close)
SEC5 = request.security(security5, "", close)

//NYSE Breadth
NYSEratio = UVOL >= DVOL ? UVOL/DVOL : -(DVOL/UVOL)

//NASDAQ Breadth
NASDAQratio = UVOLQ >= DVOLQ ? UVOLQ/DVOLQ : -(DVOLQ/UVOLQ)

//Inside or Outside Day Calc
IorODay = currDayHigh.price < prevDayHigh.price and currDayLow.price > prevDayLow.price ? "Inside Day" : "Outside Day"

//Table Creation
var table breadthTable = table.new(position, 3, 8, border_color = color.black, border_width = 1)
string breadthformat = "##.##"
string addformat = ""

//Plot Table
if barstate.islast and showMarketBreadth == true
    if showUpDownVol == true
        table.cell(breadthTable, 2, 0, str.tostring(NYSEratio, breadthformat) + " NYSE", text_size = textSize, text_color = #000000, bgcolor = NYSEratio > 0 ? color.green : color.red)
        table.cell(breadthTable, 2, 1, str.tostring(NASDAQratio, breadthformat) + " NASD", text_size = textSize, text_color = #000000, bgcolor = NASDAQratio > 0 ? color.green : color.red)
    if showADD == true
        table.cell(breadthTable, 2, 2, str.tostring(ADVDCL, addformat) + " ADD", text_size = textSize, text_color = #000000, bgcolor = ADVDCL > 0 ? color.green : color.red)
    if showVIX == true
        table.cell(breadthTable, 2, 3, str.tostring(VIX, format.mintick) + " VIX", text_size = textSize, text_color = #000000, bgcolor = VIX > VIX[1] ? color.green : color.red)
    if showVXN == true
        table.cell(breadthTable, 2, 4, str.tostring(VXN, format.mintick) + " VXN", text_size = textSize, text_color = #000000, bgcolor = VXN > VXN[1] ? color.green : color.red)
    if showTRIN == true
        table.cell(breadthTable, 2, 5, str.tostring(TRIN, format.mintick) + " TRIN", text_size = textSize, text_color = #000000, bgcolor = TRIN < 0.5 ? color.green : TRIN > 1.6 ? color.red : color.white)
    if showTICK == true
        table.cell(breadthTable, 2, 6, str.tostring(TICK, format.mintick) +" TICK", text_size = textSize, text_color = #000000, bgcolor = TICK > 0 ? color.green : color.red)
    if showIorODay
        table.cell(breadthTable, 2, 7, IorODay, text_size= textSize, text_color =  #000000, bgcolor= IorODay == "Inside Day" ? color.red : color.green )
    if showSecurity1 == true
        table.cell(breadthTable, 1, 0, str.tostring(syminfo.ticker(security1)) + " " + str.tostring(SEC1, format.mintick), text_size= textSize, text_color = #000000, bgcolor = SEC1 > SEC1[1] ? color.green : color.red)
    if showSecurity2 == true
        table.cell(breadthTable, 1, 1, str.tostring(syminfo.ticker(security2)) + " " + str.tostring(SEC2, format.mintick), text_size= textSize, text_color = #000000, bgcolor = SEC2 > SEC2[1] ? color.green : color.red)
    if showSecurity3 == true
        table.cell(breadthTable, 1, 2, str.tostring(syminfo.ticker(security3)) + " " + str.tostring(SEC3, format.mintick), text_size= textSize, text_color = #000000, bgcolor = SEC3 > SEC3[1] ? color.green : color.red)
    if showSecurity4 == true
        table.cell(breadthTable, 1, 3, str.tostring(syminfo.ticker(security4)) + " " + str.tostring(SEC4, format.mintick), text_size= textSize, text_color = #000000, bgcolor = SEC4 > SEC4[1] ? color.green : color.red)
    if showSecurity5 == true
        table.cell(breadthTable, 1, 4, str.tostring(syminfo.ticker(security5)) + " " + str.tostring(SEC5, format.mintick), text_size= textSize, text_color = #000000, bgcolor = SEC5 > SEC5[1] ? color.green : color.red)     

/////////////////////////////////////
//// Market Profile Period /////////
////////////////////////////////////
// Get seconds till 30m bar closes
timeLeft = barstate.isrealtime ?
     (time_close("30") - timenow) / 1000 :
     na

// Translate seconds left into minutes and seconds
minsLeft = math.floor(timeLeft / 60)
secsLeft = timeLeft % 60
string secsFormat = "##"

//timeframe.change(30) provides boolean when 30 min timeframe changes
TPO_DESC              = array.new<string>(0)
var int count         = 0

//TPO periods RTH A-O
//TPO periods globex P-x
array.push(TPO_DESC, "A") //RTH open
array.push(TPO_DESC, "B")
array.push(TPO_DESC, "C")
array.push(TPO_DESC, "D")
array.push(TPO_DESC, "E")
array.push(TPO_DESC, "F")
array.push(TPO_DESC, "G")
array.push(TPO_DESC, "H")
array.push(TPO_DESC, "I")
array.push(TPO_DESC, "J")
array.push(TPO_DESC, "K")
array.push(TPO_DESC, "L")
array.push(TPO_DESC, "M")
array.push(TPO_DESC, "N")
array.push(TPO_DESC, "O")
array.push(TPO_DESC, "R") //globex open period
array.push(TPO_DESC, "S")
array.push(TPO_DESC, "T")
array.push(TPO_DESC, "U")
array.push(TPO_DESC, "V")
array.push(TPO_DESC, "W")
array.push(TPO_DESC, "X")
array.push(TPO_DESC, "a")
array.push(TPO_DESC, "b")
array.push(TPO_DESC, "c")
array.push(TPO_DESC, "d")
array.push(TPO_DESC, "e")
array.push(TPO_DESC, "f")
array.push(TPO_DESC, "g")
array.push(TPO_DESC, "h")
array.push(TPO_DESC, "i")
array.push(TPO_DESC, "j")
array.push(TPO_DESC, "k")
array.push(TPO_DESC, "l")
array.push(TPO_DESC, "m")
array.push(TPO_DESC, "n")
array.push(TPO_DESC, "o")
array.push(TPO_DESC, "p")
array.push(TPO_DESC, "q")
array.push(TPO_DESC, "r")
array.push(TPO_DESC, "s")
array.push(TPO_DESC, "t")
array.push(TPO_DESC, "u")
array.push(TPO_DESC, "v")
array.push(TPO_DESC, "w")
array.push(TPO_DESC, "x")

if showTPOInfo == true and timeframe.isminutes and timeframe.multiplier < 31 and showMarketBreadth == true
    if rthOpenSess
        //reset counter back to 0
        count := 0
            
        table.cell(breadthTable, 0, 0, "TPO Period: " + array.get(TPO_DESC, count), text_size = textSize, text_color = #000000, bgcolor = color.white)
        
    //create a new line when a new 30 min time period starts
    if not rthOpenSess and (minute == 00 or minute == 30) and count < 45
        
         //increment count
        count := count + 1
        
        table.cell(breadthTable, 0, 0, "TPO Period: " + array.get(TPO_DESC, count), text_size = textSize, text_color = #000000, bgcolor = color.white)
        
    table.cell(breadthTable, 0, 1, "Time Left: " + str.tostring(minsLeft) + ":" + str.tostring(secsLeft, secsFormat), text_size = textSize, text_color = #000000, bgcolor = color.white)
