Volume Profile Segment Difference «NoaTrader»
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © NoaTrader

//@version=5
indicator("Volume Profile Segment Difference «NoaTrader»","VPSD",overlay = true,format = format.volume,max_lines_count = 500)
var seg = input.float(1000,"Each Volume Profile's Range",tooltip = "For example 1000$ for BTCUSD, 50$ for XAUUSD, 0.01$ for EURUSD...",group = "Calculation")
src = input.source(hlcc4,"Candle's calculation source",group = "Calculation")
var start_time_input = input.time(timestamp("1990-01-01"),"Start of the segment",confirm = true)
var end_time_input = input.time(timestamp("1990-01-01"),"End of the segment",confirm = true)

var shape_width = input.int(200,"Width",tooltip = "Volume Profile Max Width on the chart",group = "Display")
var plot_offset = input.int(300,"Offset",tooltip = "Distance of the plot from the last candle on the chart",group = "Display")
var line_width = input.int(7,"Each Volume Profile line's Width",group = "Display")
var min_color = input.color(color.yellow,"Minimum volume's color",group = "Display")
var max_color = input.color(color.red,"Maximum volume's color",group = "Display")
var selected_color = input.color(color.blue,"Selected segment's color",group = "Display")
var selected_transp = input.int(90,"Selected segment transparency",group = "Display")

var all = map.new<int,float>()
var selected = map.new<int,float>()

var selection_box = box.new(left= bar_index,top=high,right=bar_index+100,bottom=low,bgcolor = color.red)


key = int(src/seg)

the_vol = volume
prev_vol = all.contains(key) ? all.get(key) : 0
all.put(key,the_vol + prev_vol)

var box_max = high
var box_min = low

if time >= start_time_input and not (time[1] >= start_time_input)
    selection_box.set_left(bar_index)
    selection_box.set_right(bar_index)
    box_max := high
    box_min := low
if not (time <= end_time_input) and time[1] <= end_time_input 
    selection_box.set_right(bar_index)
    selection_box.set_top(box_max)
    selection_box.set_bottom(box_min)
    selection_box.set_bgcolor(color.new(selected_color,selected_transp))
    


if time >= start_time_input and time <= end_time_input
    if high > box_max
        box_max := high
    if low < box_min
        box_min := low

    selected_prev_vol = selected.contains(key) ? selected.get(key) : 0
    selected.put(key,the_vol + selected_prev_vol)

if bar_index == last_bar_index
    max_vol = array.max(all.values())
    min_vol = array.min(all.values())
    keys =  all.keys()
    for i = 0 to keys.size() - 1
        k = array.get(keys,i)
        v = all.get(k)
        if v != 0
            v_len = int((v / max_vol) * shape_width)
            if selected.contains(k)
                s_v = selected.get(k)
                s_v_len = int((s_v/max_vol) * shape_width)
                line.new(x1=bar_index+plot_offset-s_v_len,y1=k*seg,x2=bar_index+plot_offset,y2=k*seg,color = selected_color,width=line_width)
                line.new(x1=bar_index+plot_offset-v_len,y1=k*seg,x2=bar_index+plot_offset-s_v_len,y2=k*seg,color = color.from_gradient(v,min_vol,max_vol,min_color,max_color),width=line_width)
            else
                line.new(x1=bar_index+plot_offset-v_len,y1=k*seg,x2=bar_index+plot_offset,y2=k*seg,color = color.from_gradient(v,min_vol,max_vol,min_color,max_color),width=line_width)
            