Volume Profile - Bear
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © thebearfib
//
//@version=5
//
indicator('Volume Profile Outline - Bear',shorttitle = 'VP cool- [BeaR]',
  overlay           =true,
  max_bars_back     =1000,
  max_lines_count   =500, max_labels_count=500)

//~ https://www.tradingview.com/script/7poJ0BTX-HSV-and-HSL-gradient-Tools-Built-in-Drop-in-replacement/
import kaigouthro/hsvColor/15 as HSV
import HeWhoMustNotBeNamed/arraymethods/1
_Xxz        = input(false,'═══════  ᴘʀᴏғɪʟᴇ ᴄᴏʟᴏʀs   ═════════════════════')
color vp_poc_color   =input.color(defval =  color.rgb(255, 0, 0),       title = 'Volume Profile POC COLOR')
color vp_color_start =input.color(defval =  color.rgb(8, 4, 247, 55),   title = 'Volume Profile HISTOGRAM Start')
color vp_color_end   =input.color(defval =  color.rgb(239, 0, 252, 55), title = 'Volume Profile HISTOGRAM End')

_Xxzz        = input(false,'═══════  ᴘʀᴏғɪʟᴇ sᴇᴛᴛɪɴɢs   ═════════════════════')
bool outlineOnly= input.bool(true,          'Outline Only')
int  wid        = input.int (2,             'Outline Width',                    minval=1, maxval=4)
bool flip       = input.bool(true,          'Flip Histogram')
int _moveP      = input.int(68,             'Move Profile Sideways',            minval=1, maxval=1000) 
int bar         = input.int(150,            'Row Size',                         minval=1, maxval=500)
int bar_width   = input.int(5,              'Bar Width')
int width       = input.int(15,             'Width (% of the box)',             minval=1, maxval=100)
int vp_len      = input.int(400,            'Lookback [No. Periods/bars]',      minval=1, maxval=1000)
int vp_poc_width   = input.int(3,           'POC Thickness',                    minval=1, maxval=5)


var a       = array.new_line()
var b       = array.new_line()

if barstate.isfirst
    for i = 0 to bar - 1 by 1
        array.push(a, line.new(na, na, na, na, style=  line.style_solid, width=4))
    array.push(b, line.new(na, na, na, na, width=1))

int    _bi                = bar_index
int    _bi_mP             = _bi + _moveP
float  _volm              = volume

var   Alvl                = 0.
var   Blvl                = 0.
var   current_num_conf    = 0
var   current_num_cont    = 0
line  _l                  = na
line  vp_poc              = na
bool _bs_Lst              =  barstate.islast

float vp_high             = ta.highest(vp_len)
float vp_low              = ta.lowest (vp_len)

vp_levels                 = array.new_float(0)
all_v                     = array.new_float(0)


if _bs_Lst
    for i = 0 to bar by 1
        array.push(vp_levels, vp_low + i / bar * (vp_high - vp_low))
    for j = 0 to bar - 1 by 1
        all      = 0.
        for k    = 0 to vp_len - 1 by 1
            all := high[k] > array.get(vp_levels, j) and low[k] < array.get(vp_levels, j + 1) ? all + _volm[k] : all
            all
        array.push(all_v, all)
    for j = 0 to bar - 1 by 1
        mult = array.get(all_v, j) / array.max(all_v)
        _l   := array.get(a, j)
        get  = array.get(vp_levels, j)


        if flip
            line.set_xy1(_l, _bi_mP, get)
            line.set_xy2(_l, _bi_mP - math.round(vp_len * width / 100 * mult), array.get(vp_levels, j))
        else
            line.set_xy1(_l, _bi_mP - vp_len + 1, get)
            line.set_xy2(_l, _bi_mP - vp_len + math.round(vp_len * width / 100 * mult), array.get(vp_levels, j))

        vp_hist_color =HSV.hsv_gradient(j,1, bar, vp_color_start, vp_color_end)    

        line.set_color(_l, vp_hist_color)
        line.set_width(_l, bar_width)

        if mult == 1
            vp_poc := array.get(b, 0)
            avg = math.avg(get, array.get(vp_levels, j + 1))
            if flip
                line.set_xy1(vp_poc, _bi_mP, avg)
                line.set_xy2(vp_poc, _bi_mP - vp_len + 1, avg)
            else
                line.set_xy1(vp_poc, _bi_mP - vp_len + 1, avg)
                line.set_xy2(vp_poc, _bi_mP, avg)
            line.set_color(vp_poc, vp_poc_color)
            line.set_style(vp_poc, line.style_solid)
            line.set_width(vp_poc, vp_poc_width)


_Xxd        = input(false,'═══════  sᴛᴀᴛs ᴛᴀʙʟᴇ   ═════════════════════')

showxA       = input.bool(defval = true, title = "🧮 Stats  Main")

position3b   = input.string("Bottom Right","- Table Position",
  options  = ["Top Right", "Top Center", "Top Left", "Middle Right", "Middle Center", "Middle Left", "Bottom Right", "Bottom Center", "Bottom Left"])
 
tableposGo2 = switch position3b
    
    "Top Right"     => position.top_right
    "Top Center"    => position.top_center
    "Top Left"      => position.top_left
    "Middle Right"  => position.middle_right
    "Middle Center" => position.middle_center
    "Middle Left"   => position.middle_left
    "Bottom Right"  => position.bottom_right
    "Bottom Center" => position.bottom_center
    "Bottom Left"   => position.bottom_left

if barstate.islast or barstate.islastconfirmedhistory

    var outline = array.new_line()
    outline.flush()

    outline.push(line.new(a.first().get_x1(), a.first().get_y1(), a.first().get_x2(), a.first().get_y2(),color = color.rgb(8, 4, 247), width = wid))
    if a.size() > 0 
        for i = 0 to a.size() - 1  
            HSVcol = HSV.hsv_gradient(i, 0, a.size() - 1, color.rgb(8, 4, 247), color.rgb(239, 0, 252))

            outline.push(line.new(outline.last().get_x2(), outline.last().get_y2(), a.get(i).get_x2(), a.get(i).get_y2(), color = HSVcol, width = wid))
            if outlineOnly
                a.get(i).set_color(#00000000)

    outline.push(line.new(outline.last().get_x2(), outline.last().get_y2(), a.last().get_x1(), a.last().get_y1(), color = color.rgb(239, 0, 252), width = wid))
    outline.push(line.new(outline.last().get_x2(), outline.last().get_y2(), outline.first().get_x1(), outline.get(math.round(outline.size() / 2)).get_y1(), color = color.rgb(239, 0, 252), width = 1))
    outline.push(line.new(outline.first().get_x1(), outline.first().get_y1(), outline.first().get_x1(), outline.get(math.round(outline.size() / 2)).get_y1(), color = color.rgb(8, 4, 247), width = 1))

    var table tab = table.new(tableposGo2, 99, 99,
      bgcolor = color.rgb(255, 255, 255, 100),
      frame_color=color.rgb(255, 255, 255, 100),
      frame_width = 1,  
      border_color =color.rgb(255, 255, 255, 100),
      border_width = 1)

    if showxA       
        table.cell(tab, 1, 7, "ɴᴏ. ʙᴀʀs sʜᴏᴡɴ:",text_halign = text.align_left, text_color = color.white)
        table.cell(tab, 2, 7, str.tostring(vp_len), text_color = color.white,  text_halign = text.align_left)


