(Quartile Vol.; Vol. Aggregation; Range US Bars; Gaps) [Kioseff]
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © KioseffTrading

//@version=5
indicator("(Quartile Volume; Volume Aggregation; US Range Bars; Gaps) [Kioseff Trading]", overlay          = true, 
                                                                                          max_labels_count = 500 ,
                                                                                          max_boxes_count  = 500 ,
                                                                                          max_lines_count  = 500 , 
                                                                                          max_bars_back    = 500
                                                                                          )

//  ________________________________________________
// |                                               |  
// |       ---------------------------------       | 
// |      | K̲ i̲ o̲ s̲ e̲ f̲ f̲     T̲ r̲ a̲ d̲ i̲ n̲ g |      | 
// |      |                                 |      |  
// |      | ƃ u ᴉ p ɐ ɹ ꓕ     ⅎ ⅎ ǝ s o ᴉ ꓘ |      |  
// |       --------------------------------        |  
// |                                               | 
// |_______________________________________________|

// _______________________________________________________
//
// Inputs
// _______________________________________________________  


//                                                                     => Range US Params <=
 
show                    = input.string(defval = "Quartile Volume", title = "Dataset", options = ["Range US", "Volume Aggregation", "Gaps", "Quartile Volume"]                                                                      )
fast                    = input.bool  (defval = false      , title = "Improve Loading Time?" , tooltip = "Selecting This Box Improves Load Times; However, Data More Than 7,500 Bars Old Will Not be Calculated. This Setting Does Not Improve Initial Compilation Time.")                  
tra                     = input.string(defval = "Auto"    , title = "Auto Range US Candles? Or User-Defined?"        , group = "Range US",  options = ["Auto", "Custom"]                                                           )
rev                     = input.float (defval = 22        , title = "Reverse Candle Price Move"                      , group = "Range US", minval = 0.0000000001                                                                   )
tre                     = input.float (defval = 44        , title = "Trend Candle Price Move"                        , group = "Range US", minval = 0.0000000001                                                                   )
ranShow                 = input.bool  (defval = false     , title = "Segment Range US Bars By Date?"                 , group = "Range US"                                                                                          )
levShow                 = input.bool  (defval = true      , title = "Show Trend/Reverse Levels?"                     , group = "Range US"                                                                                          )
warn1                   = input.bool  (defval = true      , title = "Show Warning?"                                  , group = "Range US"                                                                                          )
sz                      = input.string(defval = "Tiny"    , title = "Box Text Size (Auto Increases Chart Lag)"       , group = "Range US", tooltip = "Box Text Size for Range US Candles.'Auto' Size May Cause Chart Lag"          ,      
                                                                                                                     options = ["Auto", "Tiny", "Small", "Normal", "Large", "Huge"]                                                )
treShow                 = input.int(defval= 7            , title = "Number of Congestion Areas to Show (0 = None)"   , group = "Range US",  minval = 0                                                                             )     
move                    = input.bool(defval = true       , title = "Move Current Range US Bar to Levels Section?"    , group = "Range US")
//                                                                 => Volume Aggregation Params <=

tra1                     = input.string(defval = "Auto"   , title = "Auto Volume Aggregation Candles? Or User-Defined?", group = "Volume Aggregation",  options = ["Auto", "Custom"]                                               )
volInt                  = input.int   (defval = 1000000   , title = "Required Volume", step = 10000                  , group = "Volume Aggregation"                                                                                )
vShow                   = input.bool  (defval = false     , title = "Segment Vol. Aggregation Bars By Date?"         , group = "Volume Aggregation"                                                                                )
sz1                     = input.string(defval = "Tiny"    , title = "Box Text Size (Auto Increases Chart Lag)"       , group = "Volume Aggregation", tooltip = "Box Text Size for Range US Candles.'Auto' Size May Cause Chart Lag",      
                                                                                                                       options = ["Auto", "Tiny", "Small", "Normal", "Large", "Huge"]                                              )
showAl                  = input.bool  (defval = true      , title = "Show Largest Increases and Decreases?"          , group = "Volume Aggregation"                                                                                )
showUp                  = input.int   (defval = 15        , title = "Number of Largest Volume Agg. Increases to Show", group = "Volume Aggregation", minval = 1,maxval = 20                                                        )
showDn                  = input.int   (defval = 15        , title = "Number of Largest Volume Agg. Decreases to Show", group = "Volume Aggregation", minval = 1,maxval = 20                                                        )
warn                    = input.bool  (defval = true      , title = "Show Warning?"                                  , group = "Volume Aggregation"                                                                                )
//                                                                       => Gaps Params <=

perG                    = input.float (defval = 0         , title = "Percentage Difference For Gap to Appear"        , group = "Gaps", step = 0.1, minval = 0                                                                      ) /100
old                     = input.float (defval = -1        , title = "Hide Gaps When Price Deviates by Percentage"    , group = "Gaps", minval = -1, tooltip = "Configuring This Setting to “-1” Will Keep All Gaps on the Chart. Configuring This Setting at or Above “0” Will Hide Gap Boxes if Price Moves the Percentage Amount Away From the Box. The “Percentage Amount” Is the Number in Defined for This Setting.") / 100
del                     = input.bool  (defval = false     , title = "Delete Filled Gaps?"                            , group = "Gaps"                                                                                              )
vis                     = input.bool  (defval = false     , title = "Visualize Gaps?"                                , group = "Gaps"                                                                                              )
rec                     = input.int   (defval = 5         , title = "Recent Unfilled Gaps to Show (Table)"           , group = "Gaps", minval = 0                                                                                  )

//                                                                   => Quartile Volume Params <=

colE                    = input.color (defval = color.red , title = "Low Volume Quartile Volume Color" ,inline = "1" , group = "Quartile Volume"                                                                                   )
colE1                   = input.color (defval = color.lime, title = "High Volume Quartile Volume Color",inline = "1" , group = "Quartile Volume"                                                                                   )
pCalculation            = input.int   (defval = 10        , title = "% Gain / Loss After 'n' Bars for Exceeded 90th Percentile" , group = "Quartile Volume" , minval = 2                                                           )
log                     = input.bool  (defval = true      , title = "Use Log Returns?"                               , group = "Quartile Volume"                                                                                   )
la                      = input.bool  (defval = false     , title = "Show Quartile on Bar?"                          , group = "Quartile Volume"                                                                                   )
quar                    = input.bool  (defval = false     , title = "Color Bars by Volume Quartiles"                 , group = "Quartile Volume"                                                                                   )
c1                      = input.color (defval = #a5d6a7   , title = "First Quartile Color"                           , group = "Quartile Volume"                                                                                   )
c2                      = input.color (defval = #81c784   , title = "Second Quartile Color"                          , group = "Quartile Volume"                                                                                   )
c3                      = input.color (defval = #66bb6a   , title = "Third Quartile Color"                           , group = "Quartile Volume"                                                                                   )
c4                      = input.color (defval = #388e3c   , title = "90th Percentile"                                , group = "Quartile Volume"                                                                                   )
c5                      = input.color (defval = #1b5e20   , title = "Fourth Quartile Color"                          , group = "Quartile Volume"                                                                                   )
showIns                 = input.bool  (defval = true      , title = "Show Instructions?"                             , group = "Quartile Volume"                                                                                   )
anch                    = input.bool  (defval = true      , title = "Show Anchored VWAP"                             , group = "Quartile Volume", tooltip = "Adjust Start and End Times Below to Show Anchored VWAP - Drag & Drop the Time Bars On the Chart For Quick Configuration"  )
s                       = input.time  (defval = timestamp("20 Jul 1872 00:00 +0300"), title = "Anchored VWAP Start"  , group = "Quartile Volume"                                                                                   )
e                       = input.time  (defval = timestamp("20 Jul 2023 00:00 +0300"), title = "Anchored VWAP End"    , group = "Quartile Volume"                                                                                   )


// _______________________________________________________
//
// Prerequisite Calculations
// _______________________________________________________  


var color    colCond               = color.yellow
var color    finCol                = na
var float [] xz                    = array.new_float()
var float [] vol                   = array.new_float()

lin() => 

    array.push(xz, close)
    
    if array.size(xz) > 50
        array.shift(xz)
    
    X = array.sum(xz) / array.size(xz) - 
         (ta.linreg(close, array.size(xz), 0) - 
             ta.linreg(close, array.size(xz), 1)) * 
                 math.floor(array.size(xz) / 2) + 0.5 * 
                     (ta.linreg(close, array.size(xz), 0) - 
                         ta.linreg(close, array.size(xz), 1))        
    
    Y  = (array.sum(xz) / array.size(xz) - 
         (ta.linreg(close, array.size(xz), 0) - 
             ta.linreg(close, array.size(xz), 1)) * 
                 math.floor(array.size(xz) / 2))  + 
                     (ta.linreg(close, array.size(xz), 0) - 
                         ta.linreg(close, array.size(xz), 1)) * 
                             (array.size(xz) - 1)
    
    
    float stDev = ta.stdev(X, array.size(xz) > 0 ? array.size(xz) : 1) * 2

    
    [X, Y, stDev]
    
[X, Y, stDev]                               = lin()
atr                                         = ta.atr(14)
tvsVol                                      = request.security(syminfo.ticker + "_SHORT_VOLUME", "D", close, ignore_invalid_symbol = true)
var int loopCount                           = 0

start() => 
    s <= e ? time >= s and time <= e: time <= s and time >= e


var int [] tim = array.new_int(2), var int timFin = 0

if barstate.isfirst
    
    array.set(tim, 0, 
         math.round(timestamp(year, month, dayofmonth, hour, minute, second)))

if bar_index == 1
    
    array.set(tim, 1, 
         math.round(timestamp(year, month, dayofmonth, hour, minute, second)))
    
    timFin := array.get(tim, 1) - array.get(tim, 0)


bool loadFast = switch fast
    
    false => bar_index > -1
    true  => last_bar_index - bar_index <= 7500

// _______________________________________________________
//
// Range US Bars
// _______________________________________________________  

[lowClose, lowHigh, lowLow, lowOpen, lowVol, lowATR] = request.security_lower_tf(syminfo.ticker, "1", [close, high, low, open, volume, atr])



if show == "Range US" and loadFast
    
    var float  [] trCandle                  = array.new_float ()
    var box    [] boxTr                     = array.new_box()
    
    bool cond                               = year(time) == year(timenow) 
                                                 and month(time) == month(timenow) 
                                                     and dayofmonth(time) == dayofmonth(timenow)


    if array.size(lowClose) != 0 

        var float clo                        = 0.0

        float revFin = switch tra 
             
            "Custom" => rev 
            "Auto"   => clo / 150
        
        float treFin = switch tra 
            
            "Custom" => tre 
            "Auto"   => clo /  75


        var int    []            trCount  = array.new_int(initial_value = 0)
        var color  []            col      = array.new_color ()
        var string []            dNp      = array.new_string()

        if array.size(trCandle) > 500
            for i = 0 to array.size(trCandle) - 500
                
                array.shift(trCandle)
                array.shift(trCount)
                array.shift(col)
                array.shift(dNp)    
    
        if na(array.size(lowClose)[1])
            
            array.push(trCandle, array.get(lowHigh, 0))
            array.push(col, color(na))
            array.push(trCount, 0)
            array.push(dNp, "Start")

            clo := close
       
        varip dayCount = array.new_float ()

        if array.size(trCandle) > 0
            
            string dStri  = "\n" + 
                                         str.tostring(year, "###")  + "/" + 
                                         str.tostring(month, "###") + "/" + 
                                         str.tostring(dayofmonth,    "###")

            for i = 0 to array.size(lowClose) - 1
                
                if array.get(trCount, array.size(trCount) - 1) == 0
                
                    if array.size(trCandle) == 1
                       
                        if array.get(lowHigh, i) > array.get(trCandle, array.size(trCandle) - 1) + treFin 

                            array.push(trCandle, array.get(trCandle, array.size(trCandle) - 1)   + treFin)   
                            array.push(col, color(na))
                            array.push(trCount, 0)
                            array.push(dNp, "+ " + str.tostring(treFin, "###.##") + dStri)
                            
                            if cond
                                array.push(dayCount, timFin)
                        
                        if array.get(lowLow, i) < array.get(trCandle, array.size(trCandle) - 1) - revFin
                            
                            array.push(trCandle, array.get(trCandle, array.size(trCandle) - 1)  - revFin)
                            array.push(trCount, 1)
                            array.push(col, color(na))
                            array.push(dNp, "- " + str.tostring(revFin, "###.##") + dStri)
                            
                            if cond
                                array.push(dayCount, timFin)
                                
                    else if array.size(trCandle) > 1
                        
                        if array.get(lowHigh, i) >= array.get(trCandle, array.size(trCandle) - 1) + treFin 
                            
                            array.push(trCandle, array.get(trCandle, array.size(trCandle) - 1)    + treFin)   
                            array.push(col, color.new(color.lime, 50))
                            array.push(trCount, 0)
                            array.push(dNp, "+ " + str.tostring(treFin, "###.##") + dStri)
                            
                            if cond
                                array.push(dayCount, timFin)
                       
                        if array.get(lowLow, i) < array.get(trCandle, array.size(trCandle) - 1) - revFin 

                            array.push(trCandle, array.get(trCandle, array.size(trCandle) - 1)  - revFin)
                            array.push(col, color.new(color.red, 50))
                            array.push(trCount, 1)
                            array.push(dNp, "- " + str.tostring(revFin, "###.##") + dStri)
                            
                            if cond
                                array.push(dayCount, timFin)
                                
                                
                if array.get(trCount, array.size(trCount) - 1) == 1 
                    if array.get(lowLow, i) <= array.get(trCandle, array.size(trCandle) - 1) - treFin 
                        
                        array.push(trCandle, array.get(trCandle, array.size(trCandle) - 1)   - treFin)   
                        array.push(col, color.new(color.red, 50))
                        array.push(trCount, 1)
                        array.push(dNp, "- " + str.tostring(treFin, "###.##") + dStri)
       
                        if cond
                            array.push(dayCount, timFin)
               
                    if array.get(lowHigh, i) > array.get(trCandle, array.size(trCandle) - 1) + revFin 

                        array.push(trCandle, array.get(trCandle, array.size(trCandle) - 1)   + revFin)
                        array.push(col, color.new(color.lime, 50))
                        array.push(trCount, 0)
                        array.push(dNp, "+ " + str.tostring(revFin, "###.##") + dStri)
       
                        if cond
                            array.push(dayCount, timFin)

        if barstate.islast and array.size(trCandle) > 1
        
            var line [] dayCon               = array.new_line  ()
            color    [] colCopy              = array.new_color ()
            float    [] trCandleCopy         = array.new_float ()
            int      [] trCountCopy          = array.new_int   ()
            string   [] dNpCopy              = array.new_string()
                

            for i = array.size(trCandle) - 1 to 0
                
                array.push(colCopy, array.get(col, i))
                array.push(trCandleCopy, array.get(trCandle, i))
                array.push(trCountCopy, array.get(trCount, i))
                array.push(dNpCopy, array.get(dNp, i))


            if array.size(boxTr) > 0 
                for i = 0 to array.size(boxTr) - 1
                    
                    box.delete(array.shift(boxTr))
            
            var string [] finReq1             = array.new_string()
            array.reverse(finReq1)


            string txtSz = switch sz
                
                "Auto"                              => size.auto
                "Tiny"                              => size.tiny
                "Small"                             => size.small
                "Normal"                            => size.normal
                "Large"                             => size.large
                "Huge"                              => size.huge


            for i = 1 to math.min(array.size(trCandleCopy) - 1, 500)


                array.push(finReq1, str.substring(array.get(dNpCopy, i - 1), str.pos(array.get(dNpCopy, i - 1), "/") - 4))
                array.push(boxTr, box.new(bar_index[i + 1], 
                                                         
                                                         array.get(trCandleCopy, i - 1) > array.get(trCandleCopy, i) ? array.get(trCandleCopy, i - 1) : array.get(trCandleCopy, i), 
                                                         bar_index[i],
                                                         array.get(trCandleCopy, i - 1) > array.get(trCandleCopy, i) ? array.get(trCandleCopy, i) : array.get(trCandleCopy, i - 1), 
                                                         bgcolor = array.get(colCopy, i - 1), 
                                                         border_color = color.white,
                                                         border_width = 1, 
                                                         xloc         = xloc.bar_index,
                                                         text         = array.get(dNpCopy, i - 1), 
                                                         text_color   = color.white, 
                                                         text_size    = txtSz

                                                         ))
                                                         
                                                         
                                                         

            var float [] cong = array.new_float()
            
            if array.size(boxTr) > 5 
                for n = 5 to array.size(boxTr) - 1
                    if math.avg(box.get_top(array.get(boxTr, n)), box.get_bottom(array.get(boxTr, n))) == 
                     math.avg(box.get_top(array.get(boxTr, n - 5)), box.get_bottom(array.get(boxTr, n - 5)))
                      and array.includes(cong, math.avg(box.get_top(array.get(boxTr, n)), box.get_bottom(array.get(boxTr, n)))) == false
                        array.push(cong, math.avg(box.get_top(array.get(boxTr, n)), box.get_bottom(array.get(boxTr, n))))
                        

            if ranShow == true
             and array.size(finReq1) > 1
                var linefill [] dayFill = array.new_linefill()
                for n = 1 to array.size(finReq1) - 1
                    if array.get(finReq1, n - 1) != array.get(finReq1, n)
                        array.push(dayCon, line.new(box.get_left(array.get(boxTr, n)) + 1, 
                         
                         close[n], 
                         box.get_left(array.get(boxTr, n)) + 1, 
                         close[n] + syminfo.mintick, 
                         extend =   extend.both, 
                         xloc   =   xloc.bar_index, 
                         color  =   color.new(color.yellow, 50)
                         
                         ))
    
                if array.size(dayCon) > 1
                    for x = 1 to array.size(dayCon) - 1
                        array.push(dayFill, linefill.new(array.get(dayCon, x), array.get(dayCon, x - 1), color.new(color.yellow, 90))) 
                    
                    

                    
                else
                
                        
                        

                        
                    z = line.new(box.get_left(array.get(boxTr, array.size(boxTr) - 1)), 
                                      close, 
                                      box.get_left(array.get(boxTr, array.size(boxTr) - 1)),
                                      close + syminfo.mintick, 
                                      color = color.new(color.yellow, 90)
                                      )
                    z1 = line.new(bar_index, 
                                      close, 
                                      bar_index,
                                      close + syminfo.mintick, 
                                      color = color.new(color.yellow, 90)
                                      )
                    linefill.new(z, z1, color.new(color.yellow, 90))

                                        
            var line     [] x  = array.new_line    (2)
            var linefill [] xf = array.new_linefill(2)
            var label    [] xl = array.new_label   (1)
           

            if array.size(finReq1) > 0
                indexStop = 0
                for i = 1 to array.size(finReq1) - 1
                    if array.get(finReq1, i - 1 ) ==  
                                         str.tostring(year(timenow), "###")  + "/" + 
                                         str.tostring(month(timenow), "###") + "/" + 
                                         str.tostring(dayofmonth(timenow),    "###")
                         and array.get(finReq1, i) != array.get(finReq1, i - 1)
                        
                        indexStop := i + 1
                        
                        break

                if indexStop != 0 
                    
                    array.set(x, 0, line.new(bar_index - indexStop,
                                             close, 
                                             bar_index - indexStop,
                                             close + syminfo.mintick, color = color.white, extend = extend.both, xloc = xloc.bar_index
                                             
                                                 ))
                
                    array.set(x,  1, line.new(bar_index + 1, close, bar_index + 1, close + syminfo.mintick, color = color.white,
                                                 
                                                 extend = extend.both, 
                                                 xloc   = xloc.bar_index
                                                 
                                                 ))
                    
                    array.set(xf, 0, linefill.new(array.get(x, 0), array.get(x, 1), color.new(color.white, 95)))
                    array.set(xl, 0, label.new(math.round(math.avg(line.get_x1(array.get(x, 0)), 
                                    
                                  line.get_x1(array.get(x, 1)))), 
                                  close, 
                                  text      = "Recent Price Action", 
                                  xloc      = xloc.bar_index, 
                                  color     = na, 
                                  textcolor = color.white, 
                                  size      = size.huge, 
                                  yloc      = yloc.abovebar
                                   
                                  ))
            
                    if array.size(dayCon) > 0
                        array.set(xf, 1, linefill.new(array.get(dayCon, 0), array.get(x, 0), color.new(color.yellow, 90)))
            
            var box        []            finBox         = array.new_box(0)
            var line       []            levels         = array.new_line()
            var label      []            levelLabels    = array.new_label()
            var linefill   []            levelsFill     = array.new_linefill()

            bool cX = array.get(trCountCopy, 0) == 0 and close >= box.get_top(array.get(boxTr, 0))
            bool cY = array.get(trCountCopy, 0) == 0 and close <  box.get_top(array.get(boxTr, 0))
            bool cZ = array.get(trCountCopy, 0) == 1 and close >= box.get_bottom(array.get(boxTr, 0))                    
            
            
            
            if array.size(finBox) == 0 
                    
                array.push(finBox, box.new(move == false ? bar_index - 1 : bar_index + 4,
                         cX ? close : 
                         cY ? box.get_top(   array.get(boxTr, 0)) :
                         cZ ? close : 
                         box.get_bottom  (   array.get(boxTr, 0)) ,
                         move == false ? bar_index : bar_index + 5, 
                         cX ? box.get_top(   array.get(boxTr, 0)) : 
                         cY ? close :
                         cZ ? box.get_bottom(array.get(boxTr, 0)) : 
                         close, 
                         border_color = color.white,
                         text_color   = color.white,
                         bgcolor = 
                         cX ? color.new(color.lime, 50) :
                         cY ? color.new(color.red,  50) :
                         cZ ? color.new(color.lime, 50) :
                              color.new(color.red,  50) ,
                         text = 
                         cX ? "+ "  + str.tostring(close - box.get_top(array.get(boxTr, 0)),    format.mintick) :
                         cY ?         str.tostring(close - box.get_top(array.get(boxTr, 0)),    format.mintick) :
                         cZ ? "+ "  + str.tostring(close - box.get_bottom(array.get(boxTr, 0)), format.mintick) :
                                      str.tostring(close - box.get_bottom(array.get(boxTr, 0)), format.mintick) ,
                        
                         xloc      = xloc.bar_index
                         
                             
                             ))
            
        
            
            else
            
                box.set_left(array.get(finBox, 0) , box.get_right(array.get(finBox , 0))    )
                box.set_right(array.get(finBox, 0), box.get_right(array.get(finBox , 0)) + 1)

            
                box.set_top(array.get(finBox, 0), 
                         cX ? close : 
                         cY ? box.get_top(   array.get(boxTr, 0)) :
                         cZ ? close : 
                         box.get_bottom  (   array.get(boxTr, 0))
                         )
                box.set_bottom(array.get(finBox, 0), 
                         cX ? box.get_top(   array.get(boxTr, 0)) : 
                         cY ? close :
                         cZ ? box.get_bottom(array.get(boxTr, 0)) : 
                         close
                         )       
                box.set_bgcolor(array.get(finBox, 0),
                         cX ? color.new(color.lime, 50)   :
                         cY ? color.new(color.red,  50)   :
                         cZ ? color.new(color.lime, 50)   :
                              color.new(color.red,  50)
                         )
                box.set_text(array.get(finBox, 0),
                         cX ? "+ "  + str.tostring(close - box.get_top(array.get(boxTr, 0   )), format.mintick) :
                         cY ?         str.tostring(close - box.get_top(array.get(boxTr, 0   )), format.mintick) :
                         cZ ? "+ "  + str.tostring(close - box.get_bottom(array.get(boxTr, 0)), format.mintick) :
                                      str.tostring(close - box.get_bottom(array.get(boxTr, 0)), format.mintick) 
                        
                         )            
            

            if array.size(cong) > 0 and treShow > 0
                
                str = ""
                
                for n = 0 to math.min(array.size(cong) - 2, treShow - 1)
                    
                    str := array.get(cong, n) >= array.get(cong, n + 1) ? 
                         str + str.tostring(array.get(cong, n), format.mintick) + " △\n" 
                     :   str + str.tostring(array.get(cong, n), format.mintick) + " ▼\n" 
                    
                    if n == math.min(array.size(cong) - 2, treShow - 1)
                        str := str + str.tostring(array.get(cong, n + 1), format.mintick) 
                         + "\n"

                
                var table upRight = table.new(position.top_right, 10, 10, frame_color = color.white, border_color = color.white, frame_width = 1, border_width = 1)
                table.cell(upRight, 0, 0, text = "Congestion Areas \n(Reversed Order of Occurrence)", text_color = #00ffff, bgcolor = color.new(#000000, 75))
                table.cell(upRight, 0, 1, text = str, text_color = color.red, bgcolor = color.new(#000000, 75))
                if tra == "Custom" and warn1 == true
                    if rev < array.get(lowATR, array.size(lowATR) - 1) * 1.9 or tre < array.get(lowATR, array.size(lowATR) - 1) * 1.9
                        table.cell(upRight, 1, 1, bgcolor = color.new(#000000, 75), text_color = color.red, text_size = size.small, text = "This Chart Type Is Using 1 Minute OHLC Data; \nNo Tick Data Is Used. \nIf You’re Seeing This Message: \nYour Configurations for a Trend Candle or Reversal Candle Are Likely Too Low. \nFor Instance, if You Set Trend Candles to $1 Then Trend Candles Will \nForm Subsequent a $1 Price Move. This Is Sufficient for Lower Priced Assets; \nHowever, if You Were Trading, for Instance, Bitcoin - \nA $1 Price Move Can Happen Numerous Times in One Minute. \nThis Script Can’t Plot Bars and Record Data Until a 1-Minute \nBar Closes and a New 1-Minute Bar Opens. \nTry Adjusting the Trend Candle and Reversal Candle Settings to Price Level \nThat’s Unlikely to Be Exceeded Numerous Times per Minute. \nThis Message Will Dissapear if \n You Adjust the Price Levels to\n" + str.tostring(array.get(lowATR, array.size(lowATR) - 1) * 2 , format.mintick) + " or Greater")
                        table.cell(upRight, 1, 0, bgcolor = color.new(#000000, 75), text_color = color.red, text_size = size.normal, text = "Warning")

            var table stats = table.new(position.bottom_right, 10, 10, frame_color = color.white, border_color = color.white, frame_width = 1, border_width = 1)
            table.cell(stats, 0, 0, "Range US🛈",  bgcolor = color.new(#ffffff, 75), text_color = color.white, tooltip = "A Range US Chart Operates Irrespective of Time and Volume - Simply - Bars Move After a User-Defined Price Move Is Achieved/Exceeded in either Direction. A Range US Chart Produces: \n1. “Trend Candles” \n2. “Reversal Candles” \nA Reversal Candle Always Moves Against the Most Immediate Bar; A Trend Candle Always Moves in Favor of the Most Immediate Bar. The User Defines the Dollar Amount Price Must Travel Up/Down for a Trend Candle to Fulfill, and for a Reversal Candle to Fulfill. Note, if a “Down Reversal” Candle (Red) Is Produced, It’s *Impossible* For the Next Candle to Also Be a Down Reversal Candle - For the Downside Move to Continue the Criteria for a Down Trend Candle Must Be Fulfilled. Similarly, if an “Up Reversal” Candle (Green) Is Produced, It’s Impossible for the Next Candle to Also Be an Up Reversal Candle - For the Upside Move to Continue, the Criteria for an Uptrend Trend Candle Must Be Fulfilled. Consequently, Range US Bars Frequently Trade at the Same Level for Extended Periods. This Is Intentional, as This Chart Type Is Theorized to “Filter Noise” - Whether Range US Charts Fulfill This Theory Is to Your Discretion. Lastly, if a Green (Up) Trend Candle Is Produced, the Next Candle Cannot Be up a Reversal Up Candle - Only a Trend Up Candle or Reversal Down Candle Can Produce - Vice Versa for a Trend Down Candle (The Subsequent Candle Cannot Be a Reversal Down Candle). In This Sense, an Uptrend Continues on Successive Trend Up Candles; A Down Trend Continues on Successive Trend Down Candles.")
            table.cell(stats, 0, 1, "🛈",  bgcolor = color.new(#ffffff, 75), text_color = color.lime, tooltip = "The Dollar Amount Prices Must Increase for a Green Trend Candle to Form - The Precise Price Level Is Included in Parenthesis. Note: If the Current Range Us Bar Is a Trend Down Bar or Down Reverse Bar, an Up Reverse Bar Must First Produce.")
            table.cell(stats, 0, 2, "🛈",  bgcolor = color.new(#ffffff, 75), text_color = color.lime, tooltip = "The Dollar Amount Prices Must Decrease for a Red Trend Candle to Form - The Precise Price Level Is Included in Parenthesis. Note: If the Current Range Us Bar Is a Trend Up Bar or Up Reverse Bar, a Down Reverse Bar Must First Produce.")
            table.cell(stats, 0, 3, "🛈",  bgcolor = color.new(#ffffff, 75), text_color = color.lime, tooltip = array.get(trCountCopy, 0) == 0 ? "The Dollar Amount Prices Must Decrease for a Down Reverse Candle to Form - The Precise Price Level Is Included in Parenthesis." : "The Dollar Amount Prices Must Increase for an Up Reverse Candle to Form - The Precise Price Level Is Included in Parenthesis. ")

            table.cell(stats, 2, 1, "Trending After $"  + str.tostring(treFin, format.mintick) + " Price Move", text_color = color.lime, bgcolor = color.new(#000000, 75))
            table.cell(stats, 2, 2, "Reversing After $" + str.tostring(revFin, format.mintick) + " Price Move", text_color = color.lime, bgcolor = color.new(#131722, 75))
            
            table.cell(stats, 1, 1, "$ for Trend Up: "  + str.tostring( 
                                             (box.get_top(array.get(boxTr, 0)) + treFin) - close, format.mintick) + " Price Move ($" 
                                             + str.tostring((box.get_top(array.get(boxTr, 0)) + treFin), format.mintick) + ")" ,
                                             text_color = color.lime, 
                                             bgcolor = color.new(#2a2e39, 75)
                                             )
            
    
            table.cell(stats, 1, 2, "$ for Trend Down: "  + str.tostring( 
                                             (box.get_bottom(array.get(boxTr, 0)) - treFin) - close, format.mintick) + " Price Move ($" 
                                             + str.tostring((box.get_bottom(array.get(boxTr, 0)) - treFin), format.mintick) + ")" ,
                                             text_color = color.lime, 
                                             bgcolor = color.new(#434651, 75)
                                             )
                                             
                                             
                                             
                                                  
                                             
            if array.get(trCountCopy, 0) == 0
                
                table.cell(stats, 1, 3, "$ for Reverse Down: "  + str.tostring( 
                                             (box.get_top(array.get(boxTr, 0)) - revFin) - close, format.mintick) + " Price Move ($" 
                                             + str.tostring((box.get_top(array.get(boxTr, 0)) - revFin), format.mintick) + ")" ,
                                             text_color = color.lime, 
                                             bgcolor = color.new(#5d606b, 75)
                                             )

                if levShow == true
                    

                    array.push(levels, line.new( bar_index + 2, 
                                         box.get_top(array.get(boxTr, 0)) - revFin, 
                                         bar_index + 8, 
                                         box.get_top(array.get(boxTr, 0)) - revFin, 
                                         color = color.orange
                                         ))
                                         
                    array.push(levels, line.new( bar_index + 2, 
                                                 math.avg(box.get_top(array.get(boxTr, 0)) - revFin, box.get_bottom(array.get(boxTr, 0)) - treFin), 
                                                 bar_index + 8, 
                                                 math.avg(box.get_top(array.get(boxTr, 0)) - revFin, box.get_bottom(array.get(boxTr, 0)) - treFin), 
                                                 color = na
                                                 ))           

                    
                    array.push(levelLabels, label.new(bar_index + 8, box.get_top(array.get(boxTr, 0)) - revFin, 
                                                     "Reverse Down", textcolor = color.orange, color = color.new(color.white, 100), 
                                                     size = size.small, style = label.style_label_left  ))
                                                             

            
            else 
        
               
               
                table.cell(stats, 1, 3, "$ for Reverse Up: "  + str.tostring( 
                                             (box.get_bottom(array.get(boxTr, 0)) + revFin) - close, format.mintick) + " Price Move ($" 
                                             + str.tostring((box.get_bottom(array.get(boxTr, 0)) + revFin), format.mintick) + ")" ,
                                             text_color = color.lime, 
                                             bgcolor = color.new(#5d606b, 75)  )
                
                if levShow == true
                    
                    array.push(levels, line.new( bar_index + 2, 
                                                 box.get_bottom(array.get(boxTr, 0)) + revFin, 
                                                 bar_index + 8, 
                                                 box.get_bottom(array.get(boxTr, 0)) + revFin, 
                                                 color = color.blue
                                                 ))         
                    
                    
                    array.push(levels, line.new( bar_index + 2, 
                                                 math.avg(box.get_bottom(array.get(boxTr, 0)) + revFin, box.get_bottom(array.get(boxTr, 0)) - treFin), 
                                                 bar_index + 8, 
                                                 math.avg(box.get_bottom(array.get(boxTr, 0)) + revFin, box.get_bottom(array.get(boxTr, 0)) - treFin), 
                                                 color = na
                                                 ))           

                    array.push(levelLabels, label.new(bar_index + 8, box.get_bottom(array.get(boxTr, 0)) + revFin, 
                                                     "Reverse Up", textcolor = color.blue, color = color.new(color.white, 100), 
                                                     style = label.style_label_left,
                                                     size = size.small))
                                                             
                
            if array.size(cong) > 0    
                table.cell(stats, 2, 3, "Most Recent Congestion Area: $" + str.tostring(array.get(cong, 0), format.mintick),
                                         text_color = color.lime, 
                                         bgcolor = color.new(#5d606b, 75))
            
            table.merge_cells(stats, 0, 0, 2, 0)
                
            if levShow == true
                
                
                array.push(levels, line.new( bar_index + 2, 
                                             box.get_top(array.get(boxTr, 0)) + treFin,
                                             bar_index + 8, 
                                             box.get_top(array.get(boxTr, 0)) + treFin, 
                                             color = color.lime
                                             ))                
                
                array.push(levelLabels, label.new(bar_index + 8, box.get_top(array.get(boxTr, 0)) + treFin, 
                                                     "Trend Up", textcolor = color.lime, color = color.new(color.white, 100), 
                                                     style = label.style_label_left,
                                                     size = size.small))
                
                array.push(levels, line.new( bar_index + 2, 
                                             box.get_bottom(array.get(boxTr, 0)) - treFin,
                                             bar_index + 8, 
                                             box.get_bottom(array.get(boxTr, 0)) - treFin, 
                                             color = color.red
                                             ))       
                                    
                array.push(levelLabels, label.new(bar_index + 8, box.get_bottom(array.get(boxTr, 0)) - treFin, 
                                                     "Trend Down", textcolor = color.red, color = color.new(color.white, 100), 
                                                     style = label.style_label_left, size = size.small))
                                                    
                array.push(levels, line.new( bar_index + 2, 
                                                 math.avg(line.get_y1(array.get(levels, 0)), line.get_y1(array.get(levels, 2))),
                                                 bar_index + 8, 
                                                 math.avg(line.get_y1(array.get(levels, 0)), line.get_y1(array.get(levels, 2))),
                                                 color = na
                                                 ))           


                if array.size(levels) > 5
                    
                    for i = 0 to 4
                        line.delete(array.shift(levels))
                
                if array.size(levels) == 5
                    
                    array.push(levelsFill, linefill.new(array.get(levels, 0), array.get(levels, 2), color.new(color.lime, 90)))
                    array.push(levelsFill, linefill.new(array.get(levels, 0), array.get(levels, 4), color.new(array.get(trCount, 0) == 0 ? color.orange : color.blue, 90)))
                    array.push(levelsFill, linefill.new(array.get(levels, 0), array.get(levels, 3), color.new(array.get(trCount, 0) == 0 ? color.orange : color.blue, 90)))
                    array.push(levelsFill, linefill.new(array.get(levels, 1), array.get(levels, 3), color.new(color.red, 90)))

                if array.size(levelsFill) > 4
                    for i = 0 to 3
                        linefill.delete(array.shift(levelsFill))
                
                if array.size(levelLabels) > 3
                    for i = 0 to 2
                        label.delete(array.shift(levelLabels))

// _______________________________________________________
//
// Volume Aggregation Bars
// _______________________________________________________  


if show == "Volume Aggregation" and loadFast

    var box       finBox        = na
    var float  [] cumVol        = array.new_float()
    var float  [] volC          = array.new_float()
    var string [] date          = array.new_string()
    var line   [] dayCon        = array.new_line()
    var float  [] volMed        = array.new_float()
    array.push(volMed, volume)
    float volIn                 = tra1 == "Auto" ? array.percentile_linear_interpolation(volMed, 90) : volInt

    string txtSz = switch sz1
        
        "Auto"                              => size.auto
        "Tiny"                              => size.tiny
        "Small"                             => size.small
        "Normal"                            => size.normal
        "Large"                             => size.large
        "Huge"                              => size.huge

    array.push(cumVol, array.size(cumVol) == 0 ? volume : array.get(cumVol, array.size(cumVol) - 1) + volume)
    
    if array.size(cumVol) > 0 
        if array.get(cumVol, array.size(cumVol) - 1) > volIn
            var float calc = 0.0
            calc := array.get(cumVol, array.size(cumVol) - 1) - volIn
            array.clear(cumVol)
            array.push(cumVol, calc)
            array.push(volC, close)
            array.push(date, 
                         str.tostring(year)            + "/" 
                         + str.tostring(month)         + "/" 
                         + str.tostring(dayofmonth)    + "\n$" 
                         + str.tostring(close, format.mintick))

            
    if array.size(volC) > 0
        

        if array.size(volC) > 502
            
            array.shift(volC)
            array.shift(date)
            array.shift(volMed)



        if barstate.islast
            
            
            var string [] finReq1   = array.new_string()
            var float  [] max       = array.new_float()
            var box    [] volBox    = array.new_box()
    
            float [] volCopy = array.new_float()
            string [] dateCopy = array.new_string()

            for i = array.size(volC) - 1 to 0
                array.push(volCopy, array.get(volC, i))
                array.push(dateCopy, array.get(date, i))

            if array.size(volBox) > 0
                for i = 0 to array.size(volBox) - 1
                    box.delete(array.shift(volBox))
            
            if array.size(finReq1) > 0
                array.clear(finReq1)
            
            if array.size(max) > 0
                array.clear(max)



            for i = 0 to math.min(array.size(volC) - 2, 500)
                
                array.push(max, i == 0 ? 0 : array.get(volCopy, i) / array.get(volCopy, i + 1) - 1)
                array.push(finReq1, str.substring(array.get(dateCopy, i),0, str.pos(array.get(dateCopy, i), "\n")))
                

                array.push(volBox, box.new(bar_index[i + 1], 
                                         
                                         array.get(volCopy, i) > array.get(volCopy, i + 1) ? array.get(volCopy, i) : array.get(volCopy, i + 1), 
                                         bar_index[i], 
                                         array.get(volCopy, i) > array.get(volCopy, i + 1) ? array.get(volCopy, i + 1) : array.get(volCopy, i), 
                                         bgcolor = array.get(volCopy, i) > array.get(volCopy, i + 1) ? 
                                         color.new(color.green, 50) : 
                                         color.new(color.red,   50) ,
                                         border_color = color.white , 
                                         text         = array.get(dateCopy, i) + "\nMoves On \n" + 
                                         str.tostring(volIn, format.volume) + " Volume"          ,
                                         text_color   = color.white ,
                                         text_size    = txtSz        

                                         ))


                box.delete(finBox)        
               
                finBox := box.new(bar_index, array.get(volCopy, 0) > array.get(volCopy, 1) ? array.get(volCopy, 0) : close, 
                                         
                                         bar_index + 1, 
                                         array.get(volCopy, 0) > array.get(volCopy, 1) ? close : array.get(volCopy, 0), 
                                         bgcolor      = close > array.get(volCopy, 0) ? color.new(color.green, 50) : color.new(color.red, 50),
                                         border_color = color.white, 
                                         text         = str.tostring(year, "###") + "/" + str.tostring(month, "###") + "/" + str.tostring(dayofmonth, "###") + "\n" +
                                         str.tostring(array.get(cumVol, array.size(cumVol) - 1), format.volume) + " Volume", 
                                         text_color   = color.white

                                         )
            if vShow == true 
             and array.size(finReq1) > 1
                var linefill [] dayFill = array.new_linefill()
                for n = 1 to array.size(finReq1) - 1
                    if array.get(finReq1, n - 1) != array.get(finReq1, n)
                        array.push(dayCon, line.new(box.get_left(array.get(volBox, n)) + 1, 
                         
                         close[n], 
                         box.get_left(array.get(volBox, n)) + 1, 
                         close[n] + syminfo.mintick, 
                         extend = extend.both, 
                         xloc = xloc.bar_index, 
                         color = color.new(color.yellow, 50)
                         
                         ))
                    
            
                    
                if array.size(dayCon) > 1
                    for x = 1 to array.size(dayCon) - 1
                        array.push(dayFill, linefill.new(array.get(dayCon, x), array.get(dayCon, x - 1), color.new(color.yellow, 90))) 
                

            var table stats = table.new(position.bottom_right, 10, 10,  frame_color = color.white, border_color = color.white, frame_width = 1, border_width = 1)
            table.cell(stats, 0, 0, text = "Volume Aggregation🛈", text_color = color.red, text_size = size.normal, bgcolor = color.new(#000000, 50)
                                             , tooltip = "Volume Aggregation Bars Aren’t Bound to a Time-Axis; The Bars Form After a User-Defined, Cumulative Amount of Volume Is Achieved or Exceeded. Consequently, Once the Cumulative Amount of Volume Is Achieved or Exceeded - A Bar Is Produced No Matter the Price. Underlying Theory: The Chat Type Is Conducive to Identifying Price Levels Where Traders Are “Trapped”." )
            table.cell(stats, 0, 1, text = "Moving On " + str.tostring(volIn, format.volume) + " Volume", text_color = color.red, text_size = size.normal, 
                                             bgcolor = color.new(#000000, 50) 
                                              )
            table.cell(stats, 0, 2, text = "Largest Upside Move:  " + str.tostring(array.max(max)* 100, format.percent), text_color = color.red, text_size = size.normal, 
                                             bgcolor = color.new(#000000, 50) 
                                              )                        
            table.cell(stats, 0, 3, text = "Largest Downside Move:  " + str.tostring(array.min(max)* 100, format.percent), text_color = color.red, text_size = size.normal, 
                                             bgcolor = color.new(#000000, 50) 
                                              )    
            
                
            if showAl == true
                
                maxStrCop  = array.new_string(array.size(finReq1))
                maxCop     = array.copy(max)
                
                if array.size(max) == array.size(finReq1) and array.size(max) > 1
                    array.sort(maxCop, order.descending)
                    
                    for i = 0 to array.size(max) - 1
                        finCop = array.get(finReq1, array.indexof(max, array.get(maxCop, i)) > 0 ? array.indexof(max, array.get(maxCop, i)) : 0)
                        array.set(maxStrCop, i, finCop)                
                    
                string str = ""
                string str1 = ""    
                                                                
                if array.size(maxCop) > 0
                    for i = 0 to math.min(array.size(maxCop) - 1, showUp - 1)
                        str := str + str.tostring(array.get(maxCop, i) * 100, format.percent) + "(" + array.get(maxStrCop, i) + ")\n"
                    if array.size(maxCop) > showDn 
                        for i = array.size(maxCop) - 1 to array.size(maxCop) - showDn 
                            str1 := str1 + str.tostring(array.get(maxCop, i) * 100, format.percent) + "(" + array.get(maxStrCop, i) + ")\n"
                            
                var table upRight = table.new(position.top_right, 10, 10, frame_color = color.white, border_color = color.white, frame_width = 1, border_width = 1 )
                table.cell(upRight, 0, 0, "Largest Upside Moves", text_color = color.lime, bgcolor = color.new(color.green, 75))
                table.cell(upRight, 0, 1, str, text_color = color.white, bgcolor = color.new(color.green, 75), text_halign = text.align_left)
                table.cell(upRight, 0, 2, "Largest Downside Moves", text_color = color.red, bgcolor = color.new(color.red, 75))
                table.cell(upRight, 0, 3, str1, text_color = color.white, bgcolor = color.new(color.red, 75), text_halign = text.align_left)
                if tra1 == "Custom" and warn == true
                    if volInt < array.percentile_linear_interpolation(volMed, 90)
                        table.cell(upRight, 1, 0, bgcolor = color.new(#000000, 75), text_color = color.red, text_size = size.small, text = "This Data Set Uses the OHLC Data \nFrom the Timeframe on Your Chart; \nNo Tick Data Is Used. \nIf You’re Seeing This Message: \nYour Configurations for Required Volume Are Likely Too Low. \nWhile This Script Calculates Cumulative Volume \nand Remainders Are Carried Over When the Volume Limit Is Exceeded, \nSetting the Volume Requirement Too Low May Result in Missed \nPrice Moves - Should the Cumulative Volume Threshold Be \nExceeded Twice in One Bar. \nSetting the Volume Requirement to " + str.tostring(array.percentile_linear_interpolation(volMed, 90)) + " \nor Deselcting the 'Show Warning' Option \nin the Input Settings Will Hide This Message.")
                        table.merge_cells(upRight, 1, 0, 1, 3)

// _______________________________________________________
// 
// Gaps
// _______________________________________________________  


if show == "Gaps" and loadFast

    bool gDn                               = high < low[1] and math.abs(low[1] / high - 1) > perG
    bool gUp                               = low > high[1] and math.abs(low / high[1] - 1) > perG
    
    var float  []  gArray                  = array.new_float()
    var box    []  gBox                    = array.new_box()
    var color  []  col                     = array.new_color()
    var string []  dNp                     = array.new_string()
    var float  []  sli                     = array.new_float()
    var box    []  boxGpD                  = array.new_box()
    var box    []  boxGpU                  = array.new_box()
    var int    []  boxCountD               = array.new_int()
    var int    []  boxCountU               = array.new_int()
    var float  []  minU                    = array.new_float()
    var float  []  maxD                    = array.new_float()
    var int    []  avgU                    = array.new_int()
    var int    []  avgD                    = array.new_int()

    if array.size(gArray) > 500
        
        for i = 0 to array.size(gArray) - 500
            
            array.shift(gArray)
            array.shift(col)
    
    if gUp

        array.push(gArray, array.size(gArray) == 0 ? low : array.get(gArray, array.size(gArray) - 1) + low - high[1])
        array.push(sli, (low / high[1] - 1) * 100)
        array.push(col, color.new(color.green, 50))
        array.push(dNp, str.tostring(low - high[1], format.mintick) + "\n" + 
                                     str.tostring(year, "###") + "/" + 
                                     str.tostring(month, "###") + "/" + 
                                     str.tostring(dayofmonth, "###"))
                                     
                                     
        array.push(boxGpU, box.new(math.round(time),low, math.round(time) + timFin,high[1], 
                                     text = str.tostring((close / low - 1) * 100, format.percent) + " To Fill", xloc = xloc.bar_time, bgcolor = color.new(color.lime, 50),
                                     border_color = color.lime, text_color = color.white, text_halign = text.align_right))
        array.push(boxCountU, 0), array.push(minU, 1e+13), array.push(avgU, bar_index)

    if gDn

        array.push(gArray, array.size(gArray) == 0 ? high : array.get(gArray, array.size(gArray) - 1) + high - low[1])
        array.push(sli, (high / low[1] - 1) * 100)
        array.push(col, color.new(color.red, 50))
        array.push(dNp, str.tostring(high - low[1], format.mintick) + "\n" + 
                                     str.tostring(year, "###") + "/" + 
                                     str.tostring(month, "###") + "/" + 
                                     str.tostring(dayofmonth, "###"))
        array.push(boxGpD, box.new(math.round(time), low[1], math.round(time) + timFin, high, xloc = xloc.bar_time, 
                                     text = str.tostring((close / high - 1) * 100, format.percent) + " To Fill", bgcolor = color.new(color.red, 50), 
                                     border_color = color.white, text_color = color.white, text_halign = text.align_right))
        array.push(boxCountD, 0), array.push(avgD, bar_index), array.push(maxD, 0)


    var float [] finAvgU = array.new_float()

    if array.size(boxGpU) > 0
        for n = 0 to array.size(boxGpU) - 1
            if low < box.get_bottom(array.get(boxGpU, n)) 
                if array.get(boxCountU, n) != 1 and array.get(boxCountU, n) != 3
                    box.set_text(array.get(boxGpU, n), gDn ? "New Gap" : "Filled")
                    box.set_bgcolor(array.get(boxGpU, n), color.new(color.lime, 90))
                    box.set_border_color(array.get(boxGpU, n), color.new(color.lime, 90))
                    array.push(finAvgU, bar_index - array.get(avgU, n))
                    
                    if del == false 
                        array.set(boxCountU, n, 1)
                    else 
                        array.set(boxCountU, n, 3)

            else if low < box.get_top(array.get(boxGpU, n)) and low > box.get_bottom(array.get(boxGpU, n)) and array.get(boxCountU, n) == 0
                array.set(boxCountU, n, 2)
            
            if array.get(boxCountU, n) != 1 and array.get(boxCountU, n) != 3
                
                array.set(minU, n, math.min(low, array.get(minU, n)))
                box.set_right(array.get(boxGpU, n), math.round(time + timFin))
                box.set_text(array.get(boxGpU, n),array.get(boxCountU, n) == 0 ?
                     
                     str.tostring((box.get_bottom(array.get(boxGpU, n))   / close  - 1) * 100, format.percent) + " Decrease To Fill"
                     : str.tostring((box.get_bottom(array.get(boxGpU, n)) / close  - 1) * 100, format.percent) + " To Fill \n(Partially Filled " + 
                     str.tostring     (((   array.get(minU, n) 
                     - box.get_top    (     array.get(boxGpU, n))) * 100) 
                     / (box.get_bottom(     array.get(boxGpU, n)) 
                     - box.get_top    (     array.get(boxGpU, n))), 
                     format.percent) + ")"                       )
    
        if del == true
            for i = 0 to array.size(boxGpU) - 1
                if i < array.size(boxGpU) 
                    if array.get(boxCountU, i) == 3
                        box.delete(array.remove(boxGpU, i))
                        array.remove(minU, i)
                        array.remove(boxCountU, i)
                     
        else
            if array.size(boxGpU) > 250
                for i = 0 to array.size(boxGpU) - 1
                    if array.get(boxCountU, i) == 1
                        box.delete(array.remove(boxGpU, i))
                        array.remove(minU, i)
                        array.remove(boxCountU, i)
                        break                 
                 
                    
        if old >= 0 and array.size(boxGpU) > 0
            for x = 0 to array.size(boxGpU) - 1
                if array.get(boxCountU, x) != 1 and array.get(boxCountU, x) != 3
                    if close >= box.get_top(array.get(boxGpU, x)) * (1 + old)
                        box.set_bgcolor(array.get(boxGpU, x), na)
                        box.set_border_color(array.get(boxGpU, x), na)
                        box.set_right(array.get(boxGpU, x), box.get_left(array.get(boxGpU, x)))
                    else 
                        
                        box.set_bgcolor(array.get(boxGpU, x), color.new(color.lime, 50))
                        box.set_border_color(array.get(boxGpU, x), color.new(color.lime, 50))                    
                    
    var float [] finAvgD = array.new_float()

    if array.size(boxGpD) > 0
        for n = 0 to array.size(boxGpD) - 1
            if high > box.get_top(array.get(boxGpD, n))
                if array.get(boxCountD, n) != 1 and array.get(boxCountD, n) != 3
                    array.push(finAvgD, bar_index - array.get(avgD, n))
                    box.set_text(array.get(boxGpD, n), gUp ? "New Gap" : "Filled")
                    box.set_bgcolor(array.get(boxGpD, n), color.new(color.red, 90))
                    box.set_border_color(array.get(boxGpD, n), color.new(color.red, 90))
                    
                    if del == false 
                        array.set(boxCountD,n, 1)
                    else     
                        array.set(boxCountD,n, 3)
        
            else if high < box.get_top(array.get(boxGpD, n)) and high > box.get_bottom(array.get(boxGpD, n)) and array.get(boxCountD, n) == 0
                array.set(boxCountD, n, 2)
            
                    
            if array.get(boxCountD, n) != 1 and array.get(boxCountD, n) != 3
                
                array.set(maxD, n, math.max(high, array.get(maxD, n)))
                box.set_right(array.get(boxGpD, n), math.round(time) + timFin)
                box.set_text(array.get(boxGpD, n), array.get(boxCountD, n) == 0 ? 
                     
                     str.tostring((box.get_top(array.get(boxGpD, n)) / close  - 1) * 100, format.percent) + " Increase To Fill" :
                     str.tostring((box.get_top(array.get(boxGpD, n)) / close  - 1) * 100, format.percent) + " To Fill \n(Partially Filled " + 
                     str.tostring(((array.get(maxD, n) 
                     - box.get_bottom(array.get(boxGpD, n))) * 100) 
                     / (box.get_top(array.get(boxGpD, n)) 
                     - box.get_bottom(array.get(boxGpD, n))), 
                     format.percent) + ")") 
            
        if del == true 
            for i = 0 to array.size(boxGpD) - 1
                if i < array.size(boxGpD) 
                    if  array.get(boxCountD, i) == 3
                        box.delete(array.remove(boxGpD, i))
                        array.remove(maxD, i)
                        array.remove(boxCountD, i)
        else
            if array.size(boxGpD) > 250
                for i = 0 to array.size(boxGpD) - 1
                    if array.get(boxCountD, i) == 1
                        box.delete(array.remove(boxGpD, i))
                        array.remove(maxD, i)
                        array.remove(boxCountD, i)
                        break
                        
        if old >= 0 and array.size(boxGpD) > 0
            for x = 0 to array.size(boxGpD) - 1
                if array.get(boxCountD, x) != 1 and array.get(boxCountD, x) != 3
                    if close <= box.get_bottom(array.get(boxGpD, x)) * (1 - old)
                        box.set_bgcolor(array.get(boxGpD, x), na)
                        box.set_border_color(array.get(boxGpD, x), na)
                        box.set_right(array.get(boxGpD, x), box.get_left(array.get(boxGpD, x)))
                    
                    else 
                        
                        box.set_bgcolor(array.get(boxGpD, x), color.new(color.red, 50))
                        box.set_border_color(array.get(boxGpD, x), color.new(color.red, 50))                
    
    if barstate.islast

        var int [] hold = array.new_int(1, 0)
        if array.get(hold, 0) == 0
            
            array.reverse(gArray)
            array.reverse(col)
            array.reverse(dNp)
            array.set(hold, 0, 1)
            

        if array.size(gArray) > 0
         
            if  vis == true
         
                for i = 0 to math.min(500, array.size(gArray) - 2)  
                    
                    array.push(gBox, box.new(bar_index[i + 1], 
                                 
                                 array.get(gArray, i)  > array.get(gArray, i + 1) ? array.get(gArray, i) :  array.get(gArray, i + 1) ,
                                 bar_index[i], 
                                 array.get(gArray, i)  > array.get(gArray, i + 1) ?  array.get(gArray, i + 1) :  array.get(gArray, i),
                                 bgcolor = array.get(col, i),
                                 border_color = color.white, 
                                 text = array.get(dNp, i), 
                                 text_color = color.white
                                 
                                 
                                 ))            
                
                
                
            array.sort(sli, order.ascending)
            
            
            var float [] dn                             = array.new_float()
            var float [] up                             = array.new_float()
            
            for x = 1 to array.size(sli) - 1
                
                
                if array.get(sli, 0) < 0
                    if array.get(sli, array.size(sli) - 1) > 0
                        if array.get(sli, x - 1) < 0 and array.get(sli, x) > 0
                        
                            for n = 0 to x - 1
                                array.push(dn, array.get(sli, n))
                            for n = x to array.size(sli) - 1
                                array.push(up, array.get(sli, n))
                            
                            break
                    
                else if array.get(sli, 0) > 0 
                    if x != array.size(sli) - 1
                        array.push(up, array.get(sli, x - 1))
                    
                    else
                        
                        if array.size(sli) > 1
                            array.push(up, array.get(sli, x))
                            array.push(up, array.get(sli, x - 1))

                if array.get(sli, array.size(sli) - 1) < 0 
                    if x != array.size(sli) - 1 
                        array.push(dn, array.get(sli, x - 1))
                    
                    else 
                    
                        if array.size(sli) > 1
                            array.push(up, array.get(sli, x))
                            array.push(up, array.get(sli, x - 1))
            

            var table stats = table.new(position.bottom_right, 10, 10, border_color = color.white, frame_color= color.white, border_width = 1, frame_width = 1)
            table.cell(stats, 0, 0, "# of Gaps: " + str.tostring(array.size(sli))    ,    text_color = color.lime, bgcolor = color.new(#000000, 75))
            table.cell(stats, 0, 1, "Gaps Up: "   + str.tostring(array.size(up))        , text_color = color.lime, bgcolor = color.new(#000000, 75))
            table.cell(stats, 0, 2, "Gaps Down: " + str.tostring(array.size(dn))        , text_color = color.lime, bgcolor = color.new(#000000, 75))
            table.cell(stats, 1, 1, "Cumulative Increase: " + str.tostring(array.sum(up), format.percent)        , text_color = color.lime, bgcolor = color.new(#000000, 75))
            table.cell(stats, 2, 1, "Cumulative Decrease: " + str.tostring(array.sum(dn), format.percent)        , text_color = color.lime, bgcolor = color.new(#000000, 75))
            table.cell(stats, 1, 2, "Avg. Increase: " + str.tostring(array.avg(up), format.percent)        , text_color = color.lime, bgcolor = color.new(#000000, 75))
            table.cell(stats, 2, 2, "Avg. Decrease: " + str.tostring(array.avg(dn), format.percent)        , text_color = color.lime, bgcolor = color.new(#000000, 75))
    
            strUp = ""
            strDn = ""
            
            if array.size(boxGpU) > 0 and rec > 0 
                upCou                           = 0
                for n = array.size(boxGpU) - 1 to 0
                    if upCou == rec
                        break
                    if array.get(boxCountU, n) != 1 and array.get(boxCountU, n) != 3
                        strUp := strUp + str.tostring(box.get_bottom(array.get(boxGpU, n)), format.mintick) + " - " + str.tostring(box.get_top(array.get(boxGpU, n)), format.mintick) +
                         " (Distance: " + str.tostring((close - box.get_bottom(array.get(boxGpU, n))) * -1, format.mintick) + ")" +
                         "\n"
                        upCou += 1
            
            if array.size(boxGpD) > 0 and rec > 0
                dnCou                           = 0
                for n = array.size(boxGpD) - 1 to 0
                    if dnCou == rec
                        break
                    if array.get(boxCountD, n) != 1 and array.get(boxCountD, n) != 3
                        strDn := strDn + str.tostring(box.get_bottom(array.get(boxGpD, n)), format.mintick) + " - " + str.tostring(box.get_top(array.get(boxGpD, n)), format.mintick) + 
                         " (Distance: +" + str.tostring((close - box.get_top(array.get(boxGpD, n))) * -1, format.mintick) + ")" +
                         "\n"
                        dnCou += 1 


            var table upRight =  table.new(position.top_right, 10, 10, border_color = color.white, frame_color= color.white, border_width = 1, frame_width = 1)

            if rec > 0 
                
                if strUp != ""
                    table.cell(upRight, 0, 0, "Unfilled Up Gaps", bgcolor = color.new(#000000, 75), text_color = color.lime)
                    table.cell(upRight, 0, 1, strUp,  bgcolor = color.new(#000000, 75), text_color = color.lime)                 
                if strDn != ""
                    table.cell(upRight, 0, 2, "Unfilled Down Gaps", bgcolor = color.new(#000000, 75), text_color = color.red)                 
                    table.cell(upRight, 0, 3, strDn, bgcolor = color.new(#000000, 75), text_color = color.red)                 
    
            if del == false
                
                table.cell(stats, 1, 0, "Avg. Bars to Fill Up Gap: " + str.tostring(math.round(array.avg(finAvgU)), "#"), text_color = color.lime, bgcolor = color.new(#000000, 75))
                table.cell(stats, 2, 0, "Avg. Bars to Fill Down Gap: " + str.tostring(math.round(array.avg(finAvgD)), "#") , text_color = color.lime, bgcolor = color.new(#000000, 75))
                
            else
                
                table.merge_cells(stats, 0, 0, 2, 0)
       
        else
        
            runtime.error("No Gaps Detected - Change Assets or Plot a Different Dataset")

        

// _______________________________________________________
//
// Quartile Volume
// _______________________________________________________  


if show == "Quartile Volume" and loadFast

    var line    [] xy                       = array.new_line    (2)
    var linefill[] xyfill                   = array.new_linefill(2)
    var label   [] miniLab                  = array.new_label    ()
    var float   [] volSub                   = array.new_float    ()
    var int     [] hold                     = array.new_int      ()
    var float   [] rang                     = array.new_float    ()
    var float   [] sVol                     = array.new_float    ()
    var float   [] pNl                      = array.new_float    ()
    var int     [] bar                      = array.new_int      ()
    var bool    [] binTra                   = array.new_bool     (1, false)
    var float   [] fin                      = array.new_float    ()
    var table      tab                      = na

    array.push(vol, volume)
    
    if array.size(vol) > 250
        array.shift(vol)

    if array.size(vol) >= 2
        
        colCond := color.from_gradient(
                 
                 volume, 
                 array.percentile_linear_interpolation(vol, 25), 
                 array.percentile_linear_interpolation(vol, 75), 
                 colE, colE1
                 
                 )
    
    var float Q1 = 0.0, var float Q2 = 0.0
    var float Q3 = 0.0
    var float p9 = 0.0, var float Q4 = 0.0    
    
    
    if array.size(vol) >= 5 and array.size(hold) == 0
        
        if array.size(xz) > 0
            
            array.clear(xz)
            array.clear(volSub)
            array.clear(rang)

            if array.size(sVol) > 0 
                array.clear(sVol)
        

        for n = 0 to 4 + loopCount

            array.push(xz, close[n])
            array.push(volSub, volume[n])
            array.push(rang, high[n])
            array.push(rang, low[n])
            
        for n = 4 + loopCount to 0
        
            if not na(tvsVol)
                array.push(sVol, tvsVol[n])
       
        if array.size(vol) > 25 and array.get(binTra, 0) == false
            if array.get(vol, array.size(vol) - 1) >= array.percentile_linear_interpolation(vol, 90)
                
                array.push(pNl, close)
                array.push(bar, bar_index)
                array.set(binTra, 0, true)

        if array.get(binTra, 0) == true
            if bar_index == array.get(bar, array.size(bar) - 1) + pCalculation
                
                ret = switch log
                    
                    true  => math.log(close / array.get(pNl, array.size(pNl) - 1))
                    false => (close / array.get(pNl, array.size(pNl) - 1) - 1)
                
                array.push(fin, ret * 100)
                array.set(binTra, 0, false)
                    
        for i = array.size(vol) - 1 to array.size(vol) - 5 - loopCount
            
            if array.get(vol, i) >= array.percentile_linear_interpolation(vol, 90)
                array.push(hold, 1)
        
            if i == array.size(vol) - 5 - loopCount
                if array.sum(hold) == 5 + loopCount
                    if loopCount == 0

                        array.push(xy, line.new(bar_index - array.size(xz) + 1, X + stDev, bar_index, Y + stDev, color = #00ffff))
                        array.push(xy, line.new(bar_index - array.size(xz) + 1, X - stDev, bar_index, Y - stDev, color = #00ffff))
                        array.push(xy, line.new(bar_index - array.size(xz) + 1, X + stDev, bar_index - array.size(xz) + 1, X - stDev, color = #00ffff))
                        array.push(xy, line.new(bar_index, Y + stDev, bar_index, Y - stDev, color = #00ffff))
                        array.push(xyfill, linefill.new(array.get(xy, array.size(xy) - 1), array.get(xy, array.size(xy) - 2), color.new(#00ffff, 75)))
                        
                        array.push(miniLab, label.new(bar_index[2], math.max(X + stDev, Y + stDev) + atr, text = "Volume: " + str.tostring(array.sum(volSub), format.volume)
                                                     
                                                     + "\nσ: "    + str.tostring(array.stdev(xz, false), format.mintick) 
                                                     + "\nHigh: " + str.tostring(array.max  (rang), format.mintick) 
                                                     + "\nLow: "  + str.tostring(array.min  (rang), format.mintick)
                                                     +"\nRange: " + str.tostring(array.range(rang), format.mintick),
                                                     style = label.style_label_center, 
                                                     color = color.new(#00ffff, 50), 
                                                     textcolor = color.white,
                                                     size = size.small
                                                     
                                                     ))
                        
                        if array.sum(sVol) != 0 

                            label.set_text(array.get(miniLab, array.size(miniLab) - 1), label.get_text(array.get(miniLab, array.size(miniLab) - 1)) + 
                                 "\nShort Volume: " + str.tostring(array.sum(sVol), format.volume))
    
                        loopCount += 1
                    
                    else

                        line.set_xy1(array.get(xy, array.size(xy) - 4), bar_index - array.size(xz) + 1, X + stDev)
                        line.set_xy2(array.get(xy, array.size(xy) - 4), bar_index, Y + stDev)
                        line.set_xy1(array.get(xy, array.size(xy) - 3), bar_index - array.size(xz) + 1, X - stDev)
                        line.set_xy2(array.get(xy, array.size(xy) - 3), bar_index, Y - stDev)
                        line.set_xy1(array.get(xy, array.size(xy) - 2), bar_index - array.size(xz) + 1, X + stDev)
                        line.set_xy2(array.get(xy, array.size(xy) - 2), bar_index - array.size(xz) + 1, X - stDev)
                        line.set_xy1(array.get(xy, array.size(xy) - 1), bar_index, Y + stDev)
                        line.set_xy2(array.get(xy, array.size(xy) - 1), bar_index, Y - stDev)
                        label.set_xy(array.get(miniLab, array.size(miniLab) - 1), math.round(math.avg(bar_index - array.size(xz) + 1, bar_index)), math.max(X + stDev, Y + stDev) + atr)
                        
                        label.set_text(array.get(miniLab, array.size(miniLab) - 1), "Volume: " + str.tostring(array.sum(volSub), format.volume) 
                                             
                                             + "\nσ: "    + str.tostring(array.stdev(xz, false), format.mintick)                                                     
                                             + "\nHigh: " + str.tostring(array.max(rang), format.mintick) 
                                             + "\nLow: "  + str.tostring(array.min(rang), format.mintick)
                                             +"\nRange: " + str.tostring(array.max(rang) - array.min(rang), format.mintick)

                                             )
                        
                        if array.sum(sVol) != 0 
                        
                            label.set_text(array.get(miniLab, array.size(miniLab) - 1), label.get_text(array.get(miniLab, array.size(miniLab) - 1)) + 
                                 "\nShort Volume: " + str.tostring(array.sum(sVol), format.volume))


                        
                        loopCount += 1
                
                if array.size(hold) > 0
                    array.clear(hold)
    

            
    if loopCount == loopCount[5]
        loopCount := 0

    if array.size(vol) > 1
        
        
        Q1 := array.percentile_linear_interpolation(vol, 25)
        Q2 := array.median(vol)
        Q3 := array.percentile_linear_interpolation(vol, 75)
        p9 := array.percentile_linear_interpolation(vol, 90)
        Q4 := array.max(vol)


        bool v1 =                  volume < Q1
        bool v2 = volume >= Q1 and volume < Q2
        bool v3 = volume >= Q2 and volume < Q3
        bool v4 = volume >= Q3 and volume < p9
        var label [] quarLab = array.new_label()
        
        array.push(quarLab, label.new(bar_index, close >= open ? high : low, 
            
             v1                           ?  "1"  :
             v2                           ?  "2"  :
             v3                           ?  "3"  :
             v4                           ?  "p9" :
                                             "4"  ,
             
             color = color.new(color.white, 100), 
             style = close >= open ? label.style_label_down : label.style_label_up, 
             textcolor =                 
             
             v1                           ?  c1  :
             v2                           ?  c2  :
             v3                           ?  c3  :
             v4                           ?  c4  :
                                             c5  
            
            
             ))
        
        if la == false
            if array.size(quarLab) > 15
                label.delete(array.shift(quarLab))


        
    if barstate.islastconfirmedhistory

        array.sort(fin, order.ascending)
        var float [] dn = array.new_float()
        var float [] up = array.new_float()
        

        if array.size(fin) > 0
            if array.get(fin, 0) <= 0
                for i = 1 to array.size(fin) - 1
                    if array.get(fin, i - 1) <= 0 and array.get(fin, i) > 0
                        for x = 0 to i - 1
                            array.push(dn, array.get(fin, x))
                        for x = i to array.size(fin) - 1
                            array.push(up, array.get(fin, x))
                            
                        break
            
            else if array.get(fin, 0) > 0 
                for i = 0 to array.size(fin) - 1
                    array.push(up, array.get(fin, i) )
            else if array.get(fin, array.size(fin) - 1) <= 0
                for i = 0 to array.size(fin) - 1
                    array.push(dn, array.get(fin, i) )                   
                    
            
        if array.size(dn) > 0
            for n = 0 to array.size(dn) - 1
                if n < array.size(dn) - 1
                    if array.get(dn, n) == 0
                        array.remove(dn, n)
        
        
        var table stats = na
        
        
        tab := table.new(position.top_right, 1, 1, border_color = color.white, frame_color = color.white, border_width = 1, frame_width = 1)
        stats := table.new(position.bottom_right, 50, 50, border_width = 1, frame_width = 1, border_color = color.white, frame_color = color.white)
        
        condQuar = showIns == false
        
        table.cell(stats, 0, 0, text = "Volume Percentiles " , bgcolor = color.new(color.white, 50), text_color = #000000)
        table.cell(stats, 0, 1, text = "First Quartile: "  + str.tostring(array.percentile_linear_interpolation(vol, 25), format.volume),  bgcolor = color.new(c1, 50), text_color = color.white)
        table.cell(stats, 0, 2, text = "Second Quartile: " + str.tostring(array.median(vol), format.volume),  bgcolor = color.new(c2, 50), text_color = color.white)
        table.cell(stats, 0, 3, text = "Third Quartile: "  + str.tostring(array.percentile_linear_interpolation(vol, 75), format.volume),  bgcolor = color.new(c3, 50), text_color = color.white)
        table.cell(stats, 0, 4, text = "90 Percentile : "  + str.tostring(array.percentile_linear_interpolation(vol, 90), format.volume),  bgcolor = color.new(c4, 50), text_color = color.white)
        table.cell(stats, 0, 5, text = "Fourth Quartile : " + str.tostring(math.round(array.max(vol)), format.volume),                     bgcolor = color.new(c5, 50), text_color = color.white)

        table.cell(stats, condQuar ? 0 : 1, condQuar ? 6  : 0, text = "Dispersion" , bgcolor = color.new(color.white, 50), text_color = #000000)
        table.cell(stats, condQuar ? 0 : 1, condQuar ? 7  : 1, text = "Q2 - Q1: " + str.tostring(Q2 - Q1, format.volume), bgcolor = color.new(#5d606b, 50), text_color = color.white, text_halign = text.align_left)
        table.cell(stats, condQuar ? 0 : 1, condQuar ? 8  : 2, text = "Q3 - Q2: " + str.tostring(Q3 - Q2, format.volume), bgcolor = color.new(#434651, 50), text_color = color.white, text_halign = text.align_left)
        table.cell(stats, condQuar ? 0 : 1, condQuar ? 9  : 3, text = "Q4 - Q3: " + str.tostring(Q4 - Q3, format.volume), bgcolor = color.new(#2a2e39, 50), text_color = color.white, text_halign = text.align_left)
        table.cell(stats, condQuar ? 0 : 1, condQuar ? 10 : 4, text = "Quartile Deviation: "  + str.tostring((Q3 - Q1) / 2, format.volume), bgcolor = color.new(#131722, 50), text_color = color.white, text_halign = text.align_left)
        table.cell(stats, condQuar ? 0 : 1, condQuar ? 11 : 5, text = "Interquartile Range: " + str.tostring(Q3 - Q1, format.volume), bgcolor = color.new(#000000, 50), text_color = color.white, text_halign = text.align_left)

        table.cell(stats, condQuar ? 0 : 2, condQuar ? 12 : 0, text = "If Volume Exceeds 90th Percentile \n(Flat Returns Excluded)" , bgcolor = color.new(color.white, 50), text_color = #000000)
        table.cell(stats, condQuar ? 0 : 2, condQuar ? 13 : 1, text = "Avg. " + str.tostring(pCalculation, "#") + " Bar PnL: " + str.tostring(array.avg(fin), format.percent) , bgcolor = color.new(#5d606b, 50), text_color = color.white, text_halign = text.align_left)
        table.cell(stats, condQuar ? 0 : 2, condQuar ? 14 : 2, text = "Avg. " + str.tostring(pCalculation, "#") + " Bar Pos. Return: " + str.tostring(array.avg(up), format.percent) , bgcolor = color.new(#434651, 50), text_color = color.white, text_halign = text.align_left)
        table.cell(stats, condQuar ? 0 : 2, condQuar ? 15 : 3, text = "Avg. " + str.tostring(pCalculation, "#") + " Bar Neg. Return: " + str.tostring(array.avg(dn), format.percent) , bgcolor = color.new(#2a2e39, 50), text_color = color.white, text_halign = text.align_left)
        table.cell(stats, condQuar ? 0 : 2, condQuar ? 16 : 4, text = "# of Pos. Returns: " + str.tostring(array.size(up), "#") + " (" + str.tostring(array.size(up) / array.size(fin) * 100, format.percent) + ")", bgcolor = color.new(#131722, 50), text_color = color.white, text_halign = text.align_left)
        table.cell(stats, condQuar ? 0 : 2, condQuar ? 17 : 5, text = "# of Neg. Returns: " + str.tostring(array.size(dn), "#") + " (" + str.tostring(array.size(dn) / array.size(fin) * 100, format.percent) + ")", bgcolor = color.new(#000000, 50), text_color = color.white, text_halign = text.align_left)


        if showIns == true 
            if quar == false
                var table midRight = table.new(position.middle_right, 10, 10, bgcolor = na)
                table.cell(midRight, 0, 0, text = "▮ = Higher Volume" ,  text_color = color.lime)
                table.cell(midRight, 0, 1, text = "▮ = Lower Volume " ,  text_color = color.red)
            table.cell(tab, 0, 0, text = "In Chart Settings, Hide TradingView Plotted Candlesticks ↑", text_size = size.small, bgcolor = color.new(#f06292, 50), text_color = color.white)


    if barstate.islast
        
        
        var label [] y  = array.new_label()
        var line  [] y1 = array.new_line()
        color        c  =   
                
                 volume < Q1                   ? color.new(c1, 75) :
                 volume >= Q1 and volume < Q2  ? color.new(c2, 75) : 
                 volume >= Q2 and volume < Q3  ? color.new(c3, 75) :
                 volume >= Q3 and volume < p9  ? color.new(c4, 75) :
                                                 color.new(c5, 75) 
        
        
        color cFin = switch quar
        
            false                                => colCond
            true                                 => c
        
        if array.size(y) == 0
        
        
            array.push(y, label.new(bar_index + 2, close >= open ? high : low, color = color.new(cFin, 75),
                
                 text      = "This Bar Has Higher Volume Than \n" + str.tostring(array.percentrank(vol, array.size(vol) - 1), format.percent)
                                     + "\n Of Intervals",
                 style     = label.style_label_left,
                 textcolor = color.white           , 
                 size      = size.small            ,
                 tooltip   = str.tostring(100 - array.percentrank(vol, array.size(vol) - 1), format.percent)
                                     + " Of Intervals Had Greater Volume Than This Bar (:"
                 
                     ))
                     
            array.push(y1, line.new(bar_index, label.get_y(array.get(y, array.size(y) - 1)), 
                                             bar_index + 2, 
                                             label.get_y(array.get(y,   array.size(y) - 1)),
                                             style = line.style_dashed, 
                                             color = color.new(cFin, 75)
                                             
                                             ))
            
        else 
            
            label.set_xy     ( array.get(y, array.size(y)  - 1), bar_index + 2, close >= open ? high : low)
            label.set_color  ( array.get(y, array.size(y)  - 1), color.new(cFin, 75))
            line.set_xy1     ( array.get(y1,array.size(y1) - 1), bar_index, label.get_y(array.get(y, array.size(y) - 1)))
            line.set_xy2     ( array.get(y1,array.size(y1) - 1), bar_index + 2, label.get_y(array.get(y, array.size(y) - 1)))
            line.set_color   ( array.get(y1,array.size(y1) - 1), color.new(cFin, 75))
            label.set_tooltip( array.get(y, array.size(y1) - 1), str.tostring(100 - array.percentrank(vol, array.size(vol) - 1), format.percent)
                                     + " Of Intervals Had Greater Volume Than This Bar (:")
            label.set_text   ( array.get(y, array.size(y) - 1), "This Bar Has Higher Volume Than \n" + str.tostring(array.percentrank(vol, array.size(vol) - 1), format.percent)
                                     + "\n Of Intervals")
                                     
        var line     [] sten     = array.new_line()
        var linefill [] stenfill = array.new_linefill()
        
        

        
        if start() 
         and anch == true 
          and s >= array.get(tim, 0)
                    
            array.push(sten, line.new(math.round(s), close, math.round(s), close + syminfo.mintick, xloc = xloc.bar_time, color = color.white, width = 2, extend = extend.both))
            array.push(sten, line.new(math.round(e), close, math.round(e), close + syminfo.mintick, xloc = xloc.bar_time, color = color.white, width = 2, extend = extend.both))
            array.push(stenfill, linefill.new(array.get(sten, array.size(sten) - 1), array.get(sten, array.size(sten) - 2), color.new(color.white, 95)))
            if array.size(sten) > 2
                line.delete(array.shift(sten))
            
            if array.size(stenfill) > 1
                linefill.delete(array.get(stenfill, array.size(stenfill) - 1))
        

finCol() => 
    

    
    if array.size(vol) > 1
    
        q1 = array.percentile_linear_interpolation(vol, 25)
        q2 = array.median(vol)
        q3 = array.percentile_linear_interpolation(vol, 75)
        p9 = array.percentile_linear_interpolation(vol, 90)
        q4 = array.max(vol)
        
        if volume >= 0       and volume < q1
            c1
        else if volume >= q1 and volume < q2
            c2
        else if volume >= q2 and volume < q3
            c3
        else if volume >= q3 and volume < p9
            c4
        else if volume >= p9 and volume <= q4
            c5

VWAP() =>
    

	var float  y  = na
	var float  y1 = na
    var float  y2 = na
    
    if start()[1] == false
        
        if start() == true 
    
	        y  := hlc3 * volume            
	        y1 := volume                
	        y2 := volume * math.pow(hlc3, 2)

    if start()[1] == true
       
        y  := hlc3 * volume + y[1]
        y1 := volume + y1[1]
        y2 := volume * math.pow(hlc3, 2) + y2[1]

	float middle = y / y1
	
	float vaR = y2 / y1 - math.pow(middle, 2)
	
	vaR := vaR < 0 ? 0 : vaR
	
	float stDevX = math.sqrt(vaR)
	
	float upper = middle + stDevX * 2
	
	float lower = middle - stDevX * 2
	
    [middle, upper, lower]

[m,u,l] = VWAP()

Z  = plot(anch == true ? m : na, title = "Anchored VWAP", color = start() ? color.orange : na)
Z1 = plot(anch == true ? u : na, title = "Upper Band",    color = start() ? color.lime   : na)
Z2 = plot(anch == true ? l : na, title = "Lower Band",    color = start() ? color.lime   : na)
fill(Z1, Z2, color = anch == true and start() ?  color.new(color.lime, 80) : na)


color colr = switch show 
    
    "Quartile Volume" => colCond
    =>                            na
    
color colF = switch quar
    
    false => colr
    true  => finCol()
    
plotcandle (

         open, 
         high, 
         low, 
         close, 
         color       = show == "Gaps" and close >= open ? color.lime : show == "Gaps" and close < open ? color.red : colF,
         wickcolor   = show == "Gaps" and close >= open ? color.lime : show == "Gaps" and close < open ? color.red : colF,
         bordercolor = show == "Gaps" and close >= open ? color.lime : show == "Gaps" and close < open ? color.red : colF
         
         )

