Volume Profile Fixed Range Support and Resistance Levels
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// origianl script © LonesomeTheBlue
// additions @ vranabanana 

// to use the script as a support and resistance tool just untick "Boxes" and "Labels" in the "Style" section 

//@version=5
indicator('VPFR Support and Resistance Levels', overlay=true, max_boxes_count=200, max_bars_back=1000)
bbars = input.int(title='Number of Bars', defval=30, minval=1, maxval=1000)
cnum = input.int(title='Row Size', defval=24, minval=5, maxval=100)
percent = input.float(70., title='Value Area Volume %', minval=0, maxval=100)
poc_color = input(defval=color.new(color.red, 80), title='POC Color', inline='poc')
poc_width = input.int(defval=2, title='Width', minval=1, maxval=5, inline='poc')
vup_color = input(defval=color.new(color.blue, 50), title='Value Area Up')
vdown_color = input(defval=color.new(color.orange, 50), title='Value Area Down')
up_color = input(defval=color.new(color.blue, 80), title='UP Volume')
down_color = input(defval=color.new(color.orange, 80), title='Down Volume')
show_poc = input.bool(defval = true, title = "Show POC Label")
show_va_lines = input.bool(defval = true, title = "Show VA Start/End Lines")
va_start_color = input.color(defval=color.new(#46b7c9e6, 1), title='VA Start Line Color')
va_end_color = input.color(defval=color.new(#46b7c9e6, 1), title='VA End Line Color')

top = ta.highest(bbars)
bot = ta.lowest(bbars)
dist = (top - bot) / 500
step = (top - bot) / cnum

// calculate/keep channel levels
levels = array.new_float(cnum + 1)
for x = 0 to cnum by 1
    array.set(levels, x, bot + step * x)

// get the volume if there is intersection
get_vol(y11, y12, y21, y22, height, vol) =>
    nz(math.max(math.min(math.max(y11, y12), math.max(y21, y22)) - math.max(math.min(y11, y12), math.min(y21, y22)), 0) * vol / height)

if barstate.islast
    // calculate/get volume for each channel and candle
    volumes = array.new_float(cnum * 2, 0.)
    for bars = 0 to bbars - 1 by 1
        body_top = math.max(close[bars], open[bars])
        body_bot = math.min(close[bars], open[bars])
        itsgreen = close[bars] >= open[bars]

        topwick = high[bars] - body_top
        bottomwick = body_bot - low[bars]
        body = body_top - body_bot

        bodyvol = body * volume[bars] / (2 * topwick + 2 * bottomwick + body)
        topwickvol = 2 * topwick * volume[bars] / (2 * topwick + 2 * bottomwick + body)
        bottomwickvol = 2 * bottomwick * volume[bars] / (2 * topwick + 2 * bottomwick + body)
        for x = 0 to cnum - 1 by 1
            array.set(volumes, x, array.get(volumes, x) + (itsgreen ? get_vol(array.get(levels, x), array.get(levels, x + 1), body_bot, body_top, body, bodyvol) : 0) + get_vol(array.get(levels, x), array.get(levels, x + 1), body_top, high[bars], topwick, topwickvol) / 2 + get_vol(array.get(levels, x), array.get(levels, x + 1), body_bot, low[bars], bottomwick, bottomwickvol) / 2)
            array.set(volumes, x + cnum, array.get(volumes, x + cnum) + (itsgreen ? 0 : get_vol(array.get(levels, x), array.get(levels, x + 1), body_bot, body_top, body, bodyvol)) + get_vol(array.get(levels, x), array.get(levels, x + 1), body_top, high[bars], topwick, topwickvol) / 2 + get_vol(array.get(levels, x), array.get(levels, x + 1), body_bot, low[bars], bottomwick, bottomwickvol) / 2)

    totalvols = array.new_float(cnum, 0.)
    for x = 0 to cnum - 1 by 1
        array.set(totalvols, x, array.get(volumes, x) + array.get(volumes, x + cnum))

    int poc = array.indexof(totalvols, array.max(totalvols))

    // calculate value area
    totalmax = array.sum(totalvols) * percent / 100.
    va_total = array.get(totalvols, poc)
    int up = poc
    int down = poc
    for x = 0 to cnum - 1 by 1
        if va_total >= totalmax
            break
        uppervol = up < cnum - 1 ? array.get(totalvols, up + 1) : 0.
        lowervol = down > 0 ? array.get(totalvols, down - 1) : 0.
        if uppervol == 0 and lowervol == 0
            break
        if uppervol >= lowervol
            va_total += uppervol
            up += 1
            up
        else
            va_total += lowervol
            down -= 1
            down

    maxvol = array.max(totalvols)
    for x = 0 to cnum * 2 - 1 by 1
        array.set(volumes, x, array.get(volumes, x) * bbars / (3 * maxvol))


    // Draw VP rows
    var vol_bars = array.new_box(cnum * 2, na)
    for x = 0 to cnum - 1 by 1
        box.delete(array.get(vol_bars, x))
        box.delete(array.get(vol_bars, x + cnum))
        array.set(vol_bars, x, box.new(bar_index - bbars + 1, 
                                       array.get(levels, x + 1) - dist, 
                                       bar_index - bbars + 1 + math.round(array.get(volumes, x)), 
                                       array.get(levels, x) + dist, 
                                       border_width=0, 
                                       bgcolor=x >= down and x <= up ? vup_color : up_color))
        array.set(vol_bars, x + cnum, box.new(bar_index - bbars + 1 + math.round(array.get(volumes, x)), 
                                              array.get(levels, x + 1) - dist, 
                                              bar_index - bbars + 1 + math.round(array.get(volumes, x)) + math.round(array.get(volumes, x + cnum)), 
                                              array.get(levels, x) + dist, 
                                              border_width=0, 
                                              bgcolor=x >= down and x <= up ? vdown_color : down_color))

    // Draw POC line and label
    poc_level = (array.get(levels, poc) + array.get(levels, poc + 1)) / 2
    var line poc_line = na
    line.delete(poc_line)
    poc_line := line.new(bar_index - bbars + 1, poc_level, bar_index - bbars + 2, poc_level, extend=extend.right, style= line.style_dashed, color=poc_color, width=poc_width)
    
    if show_poc
        var label poc_label = na
        label.delete(poc_label)
        poc_label := label.new(bar_index + 15, poc_level, 
                               text = "POC: " + str.tostring(math.round_to_mintick(poc_level)),
                               style = close >= poc_level ? label.style_label_up : label.style_label_down)

    var line va_start_line = na
    var line va_end_line = na
    line.delete(va_start_line)
    line.delete(va_end_line)
    va_start_line := line.new(bar_index - bbars + 1, array.get(levels, down), bar_index - bbars + 2, array.get(levels, down), extend=extend.right, color=va_start_color)
    va_end_line := line.new(bar_index - bbars + 1, array.get(levels, up + 1), bar_index - bbars + 2, array.get(levels, up + 1), extend=extend.right, color=va_end_color)

//-------------------------------------------


// Second VPFR indicator
bbars1 = input.int(title='Number of Bars 1', defval=60, minval=1, maxval=1000)
cnum1 = input.int(title='Row Size 1', defval=24, minval=5, maxval=100)
percent1 = input.float(70., title='Value Area Volume % 1', minval=0, maxval=100)
poc_color1 = input(defval=color.new(color.red, 80), title='POC Color 1', inline='poc1')
poc_width1 = input.int(defval=2, title='Width 1', minval=1, maxval=5, inline='poc1')
vup_color1 = input(defval=color.new(color.blue, 50), title='Value Area Up 1')
vdown_color1 = input(defval=color.new(color.orange, 50), title='Value Area Down 1')
up_color1 = input(defval=color.new(color.blue, 80), title='UP Volume 1')
down_color1 = input(defval=color.new(color.orange, 80), title='Down Volume 1')
show_poc1 = input.bool(defval = true, title = "Show POC Label 1")
show_va_lines1 = input.bool(defval = true, title = "Show VA Start/End Lines 1")
va_start_color1 = input.color(defval=color.new(#c442d2, 1), title='VA Start Line Color 1')
va_end_color1 = input.color(defval=color.new(#c442d2, 1), title='VA End Line Color 1')

top1 = ta.highest(bbars1)
bot1 = ta.lowest(bbars1)
dist1 = (top1 - bot1) / 500
step1 = (top1 - bot1) / cnum1

// calculate/keep channel levels
levels1 = array.new_float(cnum1 + 1)
for x = 0 to cnum1 by 1
    array.set(levels1, x, bot1 + step1 * x)

// get the volume if there is intersection
get_vol1(y11, y12, y21, y22, height, vol) =>
    nz(math.max(math.min(math.max(y11, y12), math.max(y21, y22)) - math.max(math.min(y11, y12), math.min(y21, y22)), 0) * vol / height)

if barstate.islast
    volumes1 = array.new_float(cnum1 * 2, 0.)
    for bars = 0 to bbars1 - 1 by 1
        body_top = math.max(close[bars], open[bars])
        body_bot = math.min(close[bars], open[bars])
        itsgreen = close[bars] >= open[bars]

        topwick = high[bars] - body_top
        bottomwick = body_bot - low[bars]
        body = body_top - body_bot

        bodyvol = body * volume[bars] / (2 * topwick + 2 * bottomwick + body)
        topwickvol = 2 * topwick * volume[bars] / (2 * topwick + 2 * bottomwick + body)
        bottomwickvol = 2 * bottomwick * volume[bars] / (2 * topwick + 2 * bottomwick + body)
        for x = 0 to cnum1 - 1 by 1
            array.set(volumes1, x, array.get(volumes1, x) + (itsgreen ? get_vol1(array.get(levels1, x), array.get(levels1, x + 1), body_bot, body_top, body, bodyvol) : 0) + get_vol1(array.get(levels1, x), array.get(levels1, x + 1), body_top, high[bars], topwick, topwickvol) / 2 + get_vol1(array.get(levels1, x), array.get(levels1, x + 1), body_bot, low[bars], bottomwick, bottomwickvol) / 2)
            array.set(volumes1, x + cnum1, array.get(volumes1, x + cnum1) + (itsgreen ? 0 : get_vol1(array.get(levels1, x), array.get(levels1, x + 1), body_bot, body_top, body, bodyvol)) + get_vol1(array.get(levels1, x), array.get(levels1, x + 1), body_top, high[bars], topwick, topwickvol) / 2 + get_vol1(array.get(levels1, x), array.get(levels1, x + 1), body_bot, low[bars], bottomwick, bottomwickvol) / 2)

    totalvols1 = array.new_float(cnum1, 0.)
    for x = 0 to cnum1 - 1 by 1
        array.set(totalvols1, x, array.get(volumes1, x) + array.get(volumes1, x + cnum1))

    int poc1 = array.indexof(totalvols1, array.max(totalvols1))

// calculate value area
    totalmax1 = array.sum(totalvols1) * percent1 / 100.
    va_total1 = array.get(totalvols1, poc1)
    int up1 = poc1
    int down1 = poc1
    for x = 0 to cnum1 - 1 by 1
        if va_total1 >= totalmax1
            break
        uppervol1 = up1 < cnum1 - 1 ? array.get(totalvols1, up1 + 1) : 0.
        lowervol1 = down1 > 0 ? array.get(totalvols1, down1 - 1) : 0.
        if uppervol1 == 0 and lowervol1 == 0
            break
        if uppervol1 >= lowervol1
            va_total1 += uppervol1
            up1 += 1
            up1
        else
            va_total1 += lowervol1
            down1 -= 1
            down1

    maxvol1 = array.max(totalvols1)
    for x = 0 to cnum1 * 2 - 1 by 1
        array.set(volumes1, x, array.get(volumes1, x) * bbars1 / (3 * maxvol1))

    // Draw VP rows
    var vol_bars1 = array.new_box(cnum1 * 2, na)
    for x = 0 to cnum1 - 1 by 1
        box.delete(array.get(vol_bars1, x))
        box.delete(array.get(vol_bars1, x + cnum1))
        array.set(vol_bars1, x, box.new(bar_index - bbars1 + 1, 
                                       array.get(levels1, x + 1) - dist1, 
                                       bar_index - bbars1 + 1 + math.round(array.get(volumes1, x)), 
                                       array.get(levels1, x) + dist1, 
                                       border_width=0, 
                                       bgcolor=x >= down1 and x <= up1 ? vup_color1 : up_color1))
        array.set(vol_bars1, x + cnum1, box.new(bar_index - bbars1 + 1 + math.round(array.get(volumes1, x)), 
                                              array.get(levels1, x + 1) - dist1, 
                                              bar_index - bbars1 + 1 + math.round(array.get(volumes1, x)) + math.round(array.get(volumes1, x + cnum1)), 
                                              array.get(levels1, x) + dist1, 
                                              border_width=0, 
                                              bgcolor=x >= down1 and x <= up1 ? vdown_color1 : down_color1))


    // Draw POC line and label
    poc_level1 = (array.get(levels1, poc1) + array.get(levels1, poc1 + 1)) / 2
    var line poc_line1 = na
    line.delete(poc_line1)
    poc_line1 := line.new(bar_index - bbars1 + 1, poc_level1, bar_index - bbars1 + 2, poc_level1, extend=extend.right, style= line.style_dashed, color=poc_color1, width=poc_width1)
    
    if show_poc1
        var label poc_label1 = na
        label.delete(poc_label1)
        poc_label1 := label.new(bar_index + 15, poc_level1, 
                               text = "POC: " + str.tostring(math.round_to_mintick(poc_level1)),
                               style = close >= poc_level1 ? label.style_label_up : label.style_label_down)

    var line va_start_line1 = na
    var line va_end_line1 = na
    line.delete(va_start_line1)
    line.delete(va_end_line1)
    va_start_line1 := line.new(bar_index - bbars1 + 1, array.get(levels1, down1), bar_index - bbars1 + 2, array.get(levels1, down1), extend=extend.right, color=va_start_color1)
    va_end_line1 := line.new(bar_index - bbars1 + 1, array.get(levels1, up1 + 1), bar_index - bbars1 + 2, array.get(levels1, up1 + 1), extend=extend.right, color=va_end_color1)

// Third VPFR indicator

bbars2 = input.int(title='Number of Bars 2', defval=180, minval=1, maxval=1000)
cnum2 = input.int(title='Row Size 2', defval=24, minval=5, maxval=100)
percent2 = input.float(70., title='Value Area Volume % 2', minval=0, maxval=100)
poc_color2 = input(defval=color.new(color.red, 80), title='POC Color 2', inline='poc2')
poc_width2 = input.int(defval=2, title='Width 2', minval=1, maxval=5, inline='poc2')
vup_color2 = input(defval=color.new(color.blue, 50), title='Value Area Up 2')
vdown_color2 = input(defval=color.new(color.orange, 50), title='Value Area Down 2')
up_color2 = input(defval=color.new(color.blue, 80), title='UP Volume 2')
down_color2 = input(defval=color.new(color.orange, 80), title='Down Volume 2')
show_poc2 = input.bool(defval = true, title = "Show POC Label 2")
show_va_lines2 = input.bool(defval = true, title = "Show VA Start/End Lines 2")
va_start_color2 = input.color(defval=color.new(#b7552c, 1), title='VA Start Line Color 2')
va_end_color2 = input.color(defval=color.new(#b7552c, 1), title='VA End Line Color 2')

top2 = ta.highest(bbars2)
bot2 = ta.lowest(bbars2)
dist2 = (top2 - bot2) / 500
step2 = (top2 - bot2) / cnum2

// calculate/keep channel levels
levels2 = array.new_float(cnum2 + 1)
for x = 0 to cnum2 by 1
    array.set(levels2, x, bot2 + step2 * x)

// get the volume if there is intersection
get_vol12(y11, y12, y21, y22, height, vol) =>
    nz(math.max(math.min(math.max(y11, y12), math.max(y21, y22)) - math.max(math.min(y11, y12), math.min(y21, y22)), 0) * vol / height)

if barstate.islast
    volumes2 = array.new_float(cnum2 * 2, 0.)
    for bars = 0 to bbars2 - 1 by 1
        body_top = math.max(close[bars], open[bars])
        body_bot = math.min(close[bars], open[bars])
        itsgreen = close[bars] >= open[bars]

        topwick = high[bars] - body_top
        bottomwick = body_bot - low[bars]
        body = body_top - body_bot

        bodyvol = body * volume[bars] / (2 * topwick + 2 * bottomwick + body)
        topwickvol = 2 * topwick * volume[bars] / (2 * topwick + 2 * bottomwick + body)
        bottomwickvol = 2 * bottomwick * volume[bars] / (2 * topwick + 2 * bottomwick + body)
        for x = 0 to cnum2 - 1 by 1
            array.set(volumes2, x, array.get(volumes2, x) + (itsgreen ? get_vol1(array.get(levels2, x), array.get(levels2, x + 1), body_bot, body_top, body, bodyvol) : 0) + get_vol1(array.get(levels2, x), array.get(levels2, x + 1), body_top, high[bars], topwick, topwickvol) / 2 + get_vol1(array.get(levels2, x), array.get(levels2, x + 1), body_bot, low[bars], bottomwick, bottomwickvol) / 2)
            array.set(volumes2, x + cnum2, array.get(volumes2, x + cnum2) + (itsgreen ? 0 : get_vol1(array.get(levels2, x), array.get(levels2, x + 1), body_bot, body_top, body, bodyvol)) + get_vol1(array.get(levels2, x), array.get(levels2, x + 1), body_top, high[bars], topwick, topwickvol) / 2 + get_vol1(array.get(levels2, x), array.get(levels2, x + 1), body_bot, low[bars], bottomwick, bottomwickvol) / 2)

    totalvols2 = array.new_float(cnum2, 0.)
    for x = 0 to cnum2 - 1 by 1
        array.set(totalvols2, x, array.get(volumes2, x) + array.get(volumes2, x + cnum2))

    int poc2 = array.indexof(totalvols2, array.max(totalvols2))

// calculate value area
    totalmax2 = array.sum(totalvols2) * percent2 / 100.
    va_total2 = array.get(totalvols2, poc2)
    int up2 = poc2
    int down2 = poc2
    for x = 0 to cnum2 - 1 by 1
        if va_total2 >= totalmax2
            break
        uppervol2 = up2 < cnum2 - 1 ? array.get(totalvols2, up2 + 1) : 0.
        lowervol2 = down2 > 0 ? array.get(totalvols2, down2 - 1) : 0.
        if uppervol2 == 0 and lowervol2 == 0
            break
        if uppervol2 >= lowervol2
            va_total2 += uppervol2
            up2 += 1
            up2
        else
            va_total2 += lowervol2
            down2 -= 1
            down2

    maxvol2 = array.max(totalvols2)
    for x = 0 to cnum2 * 2 - 1 by 1
        array.set(volumes2, x, array.get(volumes2, x) * bbars2 / (3 * maxvol2))

    // Draw VP rows
    var vol_bars2 = array.new_box(cnum2 * 2, na)
    for x = 0 to cnum2 - 1 by 1
        box.delete(array.get(vol_bars2, x))
        box.delete(array.get(vol_bars2, x + cnum2))
        array.set(vol_bars2, x, box.new(bar_index - bbars2 + 1, 
                                       array.get(levels2, x + 1) - dist2, 
                                       bar_index - bbars2 + 1 + math.round(array.get(volumes2, x)), 
                                       array.get(levels2, x) + dist2, 
                                       border_width=0, 
                                       bgcolor=x >= down2 and x <= up2 ? vup_color2 : up_color2))
        array.set(vol_bars2, x + cnum2, box.new(bar_index - bbars2 + 1 + math.round(array.get(volumes2, x)), 
                                              array.get(levels2, x + 1) - dist2, 
                                              bar_index - bbars2 + 1 + math.round(array.get(volumes2, x)) + math.round(array.get(volumes2, x + cnum2)), 
                                              array.get(levels2, x) + dist2, 
                                              border_width=0, 
                                              bgcolor=x >= down2 and x <= up2 ? vdown_color2 : down_color2))


    // Draw POC line and label
    poc_level2 = (array.get(levels2, poc2) + array.get(levels2, poc2 + 1)) / 2
    var line poc_line2 = na
    line.delete(poc_line2)
    poc_line2 := line.new(bar_index - bbars2 + 1, poc_level2, bar_index - bbars2 + 2, poc_level2, extend=extend.right, style= line.style_dashed, color=poc_color2, width=poc_width2)
    
    if show_poc2
        var label poc_label2 = na
        label.delete(poc_label2)
        poc_label2 := label.new(bar_index + 15, poc_level2, 
                               text = "POC: " + str.tostring(math.round_to_mintick(poc_level2)),
                               style = close >= poc_level2 ? label.style_label_up : label.style_label_down)

    var line va_start_line2 = na
    var line va_end_line2 = na
    line.delete(va_start_line2)
    line.delete(va_end_line2)
    va_start_line2 := line.new(bar_index - bbars2 + 1, array.get(levels2, down2), bar_index - bbars2 + 2, array.get(levels2, down2), extend=extend.right, color=va_start_color2)
    va_end_line2 := line.new(bar_index - bbars2 + 1, array.get(levels2, up2 + 1), bar_index - bbars2 + 2, array.get(levels2, up2 + 1), extend=extend.right, color=va_end_color2)


// Third VPFR indicator

bbars3 = input.int(title='Number of Bars 3', defval=7, minval=1, maxval=1000)
cnum3 = input.int(title='Row Size 3', defval=24, minval=5, maxval=100)
percent3 = input.float(70., title='Value Area Volume % 3', minval=0, maxval=100)
poc_color3 = input(defval=color.new(color.red, 80), title='POC Color 3', inline='poc3')
poc_width3 = input.int(defval=2, title='Width 3', minval=1, maxval=5, inline='poc3')
vup_color3 = input(defval=color.new(color.blue, 50), title='Value Area Up 3')
vdown_color3 = input(defval=color.new(color.orange, 50), title='Value Area Down 3')
up_color3 = input(defval=color.new(color.blue, 80), title='UP Volume 3')
down_color3 = input(defval=color.new(color.orange, 80), title='Down Volume 3')
show_poc3 = input.bool(defval = true, title = "Show POC Label 3")
show_va_lines3 = input.bool(defval = true, title = "Show VA Start/End Lines 3")
va_start_color3 = input.color(defval=color.new(#2eb72c, 1), title='VA Start Line Color 3')
va_end_color3 = input.color(defval=color.new(#2eb72c, 1), title='VA End Line Color 3')

top3 = ta.highest(bbars3)
bot3 = ta.lowest(bbars3)
dist3 = (top3 - bot3) / 500
step3 = (top3 - bot3) / cnum3

// calculate/keep channel levels
levels3 = array.new_float(cnum3 + 1)
for x = 0 to cnum3 by 1
    array.set(levels3, x, bot3 + step3 * x)

// get the volume if there is intersection
get_vol13(y11, y12, y21, y22, height, vol) =>
    nz(math.max(math.min(math.max(y11, y12), math.max(y21, y22)) - math.max(math.min(y11, y12), math.min(y21, y22)), 0) * vol / height)

if barstate.islast
    volumes3 = array.new_float(cnum3 * 2, 0.)
    for bars = 0 to bbars3 - 1 by 1
        body_top = math.max(close[bars], open[bars])
        body_bot = math.min(close[bars], open[bars])
        itsgreen = close[bars] >= open[bars]

        topwick = high[bars] - body_top
        bottomwick = body_bot - low[bars]
        body = body_top - body_bot

        bodyvol = body * volume[bars] / (2 * topwick + 2 * bottomwick + body)
        topwickvol = 2 * topwick * volume[bars] / (2 * topwick + 2 * bottomwick + body)
        bottomwickvol = 2 * bottomwick * volume[bars] / (2 * topwick + 2 * bottomwick + body)
        for x = 0 to cnum3 - 1 by 1
            array.set(volumes3, x, array.get(volumes3, x) + (itsgreen ? get_vol13(array.get(levels3, x), array.get(levels3, x + 1), body_bot, body_top, body, bodyvol) : 0) + get_vol13(array.get(levels3, x), array.get(levels3, x + 1), body_top, high[bars], topwick, topwickvol) / 2 + get_vol13(array.get(levels3, x), array.get(levels3, x + 1), body_bot, low[bars], bottomwick, bottomwickvol) / 2)
            array.set(volumes3, x + cnum3, array.get(volumes3, x + cnum3) + (itsgreen ? 0 : get_vol13(array.get(levels3, x), array.get(levels3, x + 1), body_bot, body_top, body, bodyvol)) + get_vol13(array.get(levels3, x), array.get(levels3, x + 1), body_top, high[bars], topwick, topwickvol) / 2 + get_vol13(array.get(levels3, x), array.get(levels3, x + 1), body_bot, low[bars], bottomwick, bottomwickvol) / 2)

    totalvols3 = array.new_float(cnum3, 0.)
    for x = 0 to cnum3 - 1 by 1
        array.set(totalvols3, x, array.get(volumes3, x) + array.get(volumes3, x + cnum3))

    int poc3 = array.indexof(totalvols3, array.max(totalvols3))

// calculate value area
    totalmax3 = array.sum(totalvols3) * percent3 / 100.
    va_total3 = array.get(totalvols3, poc3)
    int up3 = poc3
    int down3 = poc3
    for x = 0 to cnum3 - 1 by 1
        if va_total3 >= totalmax3
            break
        uppervol3 = up3 < cnum3 - 1 ? array.get(totalvols3, up3 + 1) : 0.
        lowervol3 = down3 > 0 ? array.get(totalvols3, down3 - 1) : 0.
        if uppervol3 == 0 and lowervol3 == 0
            break
        if uppervol3 >= lowervol3
            va_total3 += uppervol3
            up3 += 1
            up3
        else
            va_total3 += lowervol3
            down3 -= 1
            down3

    maxvol3 = array.max(totalvols3)
    for x = 0 to cnum3 * 2 - 1 by 1
        array.set(volumes3, x, array.get(volumes3, x) * bbars3 / (3 * maxvol3))

    // Draw VP rows
    var vol_bars3 = array.new_box(cnum3 * 2, na)
    for x = 0 to cnum3 - 1 by 1
        box.delete(array.get(vol_bars3, x))
        box.delete(array.get(vol_bars3, x + cnum3))
        array.set(vol_bars3, x, box.new(bar_index - bbars3 + 1, 
                                       array.get(levels3, x + 1) - dist3, 
                                       bar_index - bbars3 + 1 + math.round(array.get(volumes3, x)), 
                                       array.get(levels3, x) + dist3, 
                                       border_width=0, 
                                       bgcolor=x >= down3 and x <= up3 ? vup_color3 : up_color3))
        array.set(vol_bars3, x + cnum3, box.new(bar_index - bbars3 + 1 + math.round(array.get(volumes3, x)), 
                                              array.get(levels3, x + 1) - dist3, 
                                              bar_index - bbars3 + 1 + math.round(array.get(volumes3, x)) + math.round(array.get(volumes3, x + cnum3)), 
                                              array.get(levels3, x) + dist3, 
                                              border_width=0, 
                                              bgcolor=x >= down3 and x <= up3 ? vdown_color3 : down_color3))


    // Draw POC line and label
    poc_level3 = (array.get(levels3, poc3) + array.get(levels3, poc3 + 1)) / 2
    var line poc_line3 = na
    line.delete(poc_line3)
    poc_line3 := line.new(bar_index - bbars3 + 1, poc_level3, bar_index - bbars3 + 2, poc_level3, extend=extend.right, style= line.style_dashed, color=poc_color3, width=poc_width3)
    
    if show_poc3
        var label poc_label3 = na
        label.delete(poc_label3)
        poc_label3 := label.new(bar_index + 15, poc_level3, 
                               text = "POC: " + str.tostring(math.round_to_mintick(poc_level3)),
                               style = close >= poc_level3 ? label.style_label_up : label.style_label_down)

    var line va_start_line3 = na
    var line va_end_line3 = na
    line.delete(va_start_line3)
    line.delete(va_end_line3)
    va_start_line3 := line.new(bar_index - bbars3 + 1, array.get(levels3, down3), bar_index - bbars3 + 2, array.get(levels3, down3), extend=extend.right, color=va_start_color3)
    va_end_line3 := line.new(bar_index - bbars3 + 1, array.get(levels3, up3 + 1), bar_index - bbars3 + 2, array.get(levels3, up3 + 1), extend=extend.right, color=va_end_color3)

// Fourth VPFR indicator

bbars4 = input.int(title='Number of Bars 4', defval=365, minval=1, maxval=1000)
cnum4 = input.int(title='Row Size 4', defval=24, minval=5, maxval=100)
percent4 = input.float(70., title='Value Area Volume % 4', minval=0, maxval=100)
poc_color4 = input(defval=color.new(color.red, 80), title='POC Color 4', inline='poc4')
poc_width4 = input.int(defval=2, title='Width 4', minval=1, maxval=5, inline='poc4')
vup_color4 = input(defval=color.new(color.blue, 50), title='Value Area Up 4')
vdown_color4 = input(defval=color.new(color.orange, 50), title='Value Area Down 4')
up_color4 = input(defval=color.new(color.blue, 80), title='UP Volume 4')
down_color4 = input(defval=color.new(color.orange, 80), title='Down Volume 4')
show_poc4 = input.bool(defval = true, title = "Show POC Label 4")
show_va_lines4 = input.bool(defval = true, title = "Show VA Start/End Lines 4")
va_start_color4 = input.color(defval=color.new(color.white, 20), title='VA Start Line Color 4')
va_end_color4 = input.color(defval=color.new(color.white, 20), title='VA End Line Color 4')

top4 = ta.highest(bbars4)
bot4 = ta.lowest(bbars4)
dist4 = (top4 - bot4) / 500
step4 = (top4 - bot4) / cnum4

// calculate/keep channel levels
levels4 = array.new_float(cnum4 + 1)
for x = 0 to cnum4 by 1
    array.set(levels4, x, bot4 + step4 * x)

// get the volume if there is intersection
get_vol14(y11, y12, y21, y22, height, vol) =>
    nz(math.max(math.min(math.max(y11, y12), math.max(y21, y22)) - math.max(math.min(y11, y12), math.min(y21, y22)), 0) * vol / height)

if barstate.islast
    volumes4 = array.new_float(cnum4 * 2, 0.)
    for bars = 0 to bbars4 - 1 by 1
        body_top = math.max(close[bars], open[bars])
        body_bot = math.min(close[bars], open[bars])
        itsgreen = close[bars] >= open[bars]

        topwick = high[bars] - body_top
        bottomwick = body_bot - low[bars]
        body = body_top - body_bot

        bodyvol = body * volume[bars] / (2 * topwick + 2 * bottomwick + body)
        topwickvol = 2 * topwick * volume[bars] / (2 * topwick + 2 * bottomwick + body)
        bottomwickvol = 2 * bottomwick * volume[bars] / (2 * topwick + 2 * bottomwick + body)
        for x = 0 to cnum4 - 1 by 1
            array.set(volumes4, x, array.get(volumes4, x) + (itsgreen ? get_vol14(array.get(levels4, x), array.get(levels4, x + 1), body_bot, body_top, body, bodyvol) : 0) + get_vol14(array.get(levels4, x), array.get(levels4, x + 1), body_top, high[bars], topwick, topwickvol) / 2 + get_vol14(array.get(levels4, x), array.get(levels4, x + 1), body_bot, low[bars], bottomwick, bottomwickvol) / 2)
            array.set(volumes4, x + cnum4, array.get(volumes4, x + cnum4) + (itsgreen ? 0 : get_vol14(array.get(levels4, x), array.get(levels4, x + 1), body_bot, body_top, body, bodyvol)) + get_vol14(array.get(levels4, x), array.get(levels4, x + 1), body_top, high[bars], topwick, topwickvol) / 2 + get_vol14(array.get(levels4, x), array.get(levels4, x + 1), body_bot, low[bars], bottomwick, bottomwickvol) / 2)

    totalvols4 = array.new_float(cnum4, 0.)
    for x = 0 to cnum4 - 1 by 1
        array.set(totalvols4, x, array.get(volumes4, x) + array.get(volumes4, x + cnum4))

    int poc4 = array.indexof(totalvols4, array.max(totalvols4))

// calculate value area
    totalmax4 = array.sum(totalvols4) * percent4 / 100.
    va_total4 = array.get(totalvols4, poc4)
    int up4 = poc4
    int down4 = poc4
    for x = 0 to cnum4 - 1 by 1
        if va_total4 >= totalmax4
            break
        uppervol4 = up4 < cnum4 - 1 ? array.get(totalvols4, up4 + 1) : 0.
        lowervol4 = down4 > 0 ? array.get(totalvols4, down4 - 1) : 0.
        if uppervol4 == 0 and lowervol4 == 0
            break
        if uppervol4 >= lowervol4
            va_total4 += uppervol4
            up4 += 1
            up4
        else
            va_total4 += lowervol4
            down4 -= 1
            down4

    maxvol4 = array.max(totalvols4)
    for x = 0 to cnum4 * 2 - 1 by 1
        array.set(volumes4, x, array.get(volumes4, x) * bbars4 / (3 * maxvol4))

    // Draw VP rows
    var vol_bars4 = array.new_box(cnum4 * 2, na)
    for x = 0 to cnum4 - 1 by 1
        box.delete(array.get(vol_bars4, x))
        box.delete(array.get(vol_bars4, x + cnum4))
        array.set(vol_bars4, x, box.new(bar_index - bbars4 + 1, 
                                       array.get(levels4, x + 1) - dist4, 
                                       bar_index - bbars4 + 1 + math.round(array.get(volumes4, x)), 
                                       array.get(levels4, x) + dist4, 
                                       border_width=0, 
                                       bgcolor=x >= down4 and x <= up4 ? vup_color4 : up_color4))
        array.set(vol_bars4, x + cnum4, box.new(bar_index - bbars4 + 1 + math.round(array.get(volumes4, x)), 
                                              array.get(levels4, x + 1) - dist4, 
                                              bar_index - bbars4 + 1 + math.round(array.get(volumes4, x)) + math.round(array.get(volumes4, x + cnum4)), 
                                              array.get(levels4, x) + dist4, 
                                              border_width=0, 
                                              bgcolor=x >= down4 and x <= up4 ? vdown_color4 : down_color4))


    // Draw POC line and label
    poc_level4 = (array.get(levels4, poc4) + array.get(levels4, poc4 + 1)) / 2
    var line poc_line4 = na
    line.delete(poc_line4)
    poc_line4 := line.new(bar_index - bbars4 + 1, poc_level4, bar_index - bbars4 + 2, poc_level4, extend=extend.right,style= line.style_dashed, color=poc_color4, width=poc_width4)
    
    if show_poc4
        var label poc_label4 = na
        label.delete(poc_label4)
        poc_label4 := label.new(bar_index + 15, poc_level4, 
                               text = "POC: " + str.tostring(math.round_to_mintick(poc_level4)),
                               style = close >= poc_level4 ? label.style_label_up : label.style_label_down)

    var line va_start_line4 = na
    var line va_end_line4 = na
    line.delete(va_start_line4)
    line.delete(va_end_line4)
    va_start_line4 := line.new(bar_index - bbars4 + 1, array.get(levels4, down4), bar_index - bbars4 + 2, array.get(levels4, down4), extend=extend.right, color=va_start_color4)
    va_end_line4 := line.new(bar_index - bbars4 + 1, array.get(levels4, up4 + 1), bar_index - bbars4 + 2, array.get(levels4, up4 + 1), extend=extend.right, color=va_end_color4)
