// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // © kv4coins //@version=5 //////// //// INPUTS /////////////////////////////////////////////////////////////////////////////////////////////////// vp_lookback = input(defval = 200, title = "Volume Lookback Depth [10-1000]") vp_max_bars = input(defval = 500, title = "Number of Bars [10-500]") vp_bar_mult = input(defval = 50, title = "Bar Length Multiplier [10-100]") vp_bar_offset = input( 30, title = "Bar Horizontal Offset [0-100]") vp_bar_width = input(2, title = "Bar Width [1-20]") // As suggested by @NXT2017 vp_delta_type = input("Both", title = "Delta Type") vp_poc_show = true vp_bar_color = input( color.new(color.gray, 60) , title = "Bar Color") vp_poc_color = color.orange, /////////////////////////////////////////////////////////////////////////////////////////////////// //// VARIABLES /////////////////////////////////////////////////////////////////////////////////////////////////// float vp_Vmax = 0.0 int vp_VmaxId = 0 int vp_N_BARS = vp_max_bars var int vp_first = time vp_a_P = array.new_float((vp_N_BARS + 1), 0.0) vp_a_V = array.new_float(vp_N_BARS, 0.0) vp_a_D = array.new_float(vp_N_BARS, 0.0) vp_a_W = array.new_int(vp_N_BARS, 0) /////////////////////////////////////////////////////////////////////////////////////////////////// //// CALCULATIONS /////////////////////////////////////////////////////////////////////////////////////////////////// float vp_HH = ta.highest(high, vp_lookback) float vp_LL = ta.lowest(low, vp_lookback) if barstate.islast float vp_HL = (vp_HH - vp_LL) / vp_N_BARS for j = 1 to (vp_N_BARS + 1) array.set(vp_a_P, (j-1), (vp_LL + vp_HL * j)) for i = 0 to (vp_lookback - 1) int Dc = 0 array.fill(vp_a_D, 0.0) for j = 0 to (vp_N_BARS - 1) float Pj = array.get(vp_a_P, j) if low[i] < Pj and high[i] > Pj and (vp_delta_type == "Bullish" ? close[i] >= open[i] : (vp_delta_type == "Bearish" ? close[i] <= open[i] : true)) float Dj = array.get(vp_a_D, j) float dDj = Dj + nz(volume[i]) array.set(vp_a_D, j, dDj) Dc := Dc + 1 for j = 0 to (vp_N_BARS - 1) float Vj = array.get(vp_a_V, j) float Dj = array.get(vp_a_D, j) float dVj = Vj + ((Dc > 0) ? (Dj / Dc) : 0.0) array.set(vp_a_V, j, dVj) vp_Vmax := array.max(vp_a_V) vp_VmaxId := array.indexof(vp_a_V, vp_Vmax) for j = 0 to (vp_N_BARS - 1) float Vj = array.get(vp_a_V, j) int Aj = math.round(vp_bar_mult * Vj / vp_Vmax) array.set(vp_a_W, j, Aj) /////////////////////////////////////////////////////////////////////////////////////////////////// //// PLOTING /////////////////////////////////////////////////////////////////////////////////////////////////// if barstate.isfirst vp_first := time vp_change = ta.change(time) vp_x_loc = timenow + math.round(vp_change * vp_bar_offset) f_setup_bar(n) => x1 = ((vp_VmaxId == n) and vp_poc_show) ? math.max(time[vp_lookback], vp_first) : (timenow + math.round(vp_change * (vp_bar_offset - array.get(vp_a_W, n)))) ys = array.get(vp_a_P, n) line.new(x1 = x1, y1 = ys, x2 = vp_x_loc, y2 = ys, xloc = xloc.bar_time, extend = extend.none, color = (vp_VmaxId == n ? vp_poc_color : vp_bar_color), style = line.style_solid, width = vp_bar_width) if barstate.islast for i = 0 to (vp_N_BARS - 1) by 1 f_setup_bar(i)