Indicator · Pine Script v5 · On the chart

Volume Delta | OI Delta [Kioseff Trading]

by etabebe1· code credited to KioseffTrading

This indicator visualizes volume delta, total volume, or open interest delta directly on the price chart.

View on GitHub

GitHub stars2on the repository
Pine versionv5runs as is
Lines of code1,090
Settings21inputs
LicenceNone statedfile: MPL-2.0
Last update1 year ago19 Jun 2025

Add It to Your TradingView Chart

  1. 1Copy the scriptPress Copy script above, or the copy button on the code below.
  2. 2Open the Pine EditorOpen a TradingView chart and choose Pine Editor at the bottom of the screen.
  3. 3Paste over the templateCreate a new indicator, select all of the template text and paste. Press Save and give it a name.
  4. 4Add it to the chartPress Add to chart, then adjust the settings with the gear icon next to its name.

Source Code

1,090 lines of Pine Script v5 from Volume-Profile-Volume-Delta/VPVD.txt, published under MPL-2.0 (file header). Keep the author's credit and licence lines when you reuse it.

VPVD.txt

// 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(
  
  "Volume Delta | OI Delta [Kioseff Trading]"                  , 
  precision             = 12            , 
  format                = format.volume , 
  explicit_plot_zorder  = true          ,
  max_labels_count      = 500           ,
  max_boxes_count       = 500           ,
  max_lines_count       = 500           ,
  max_bars_back         = 5000          ,


  overlay               = true      


  )


data                                   = input.string(defval = "Vol. Delta", title = "Data", options = ["Volume", "Vol. Delta", "OI Delta (BINANCE PERP FUTURES ONLY)"])

[m, m1, m2, m3, m4, m5, m6, m7]        
                                       = request.security_lower_tf(syminfo.tickerid, "1", [close, close[1], volume, high, low, hlc3, open, volume[1]])

Recalculation                          = input.string(defval = "No Recalculation", title = "No Recalculation? Or Realculate?", options = ["No Recalculation", "Recalculate"], group = "Racalculation | No Recalculation")
sess                                   = input.string(defval = "D", title = "If 'Recalculation' is Selected in the Above Setting: Recalculate After How Much Time?", group = "Racalculation | No Recalculation", tooltip = "from 1 to 1440 for minutes \nfrom 1D to 365D for days \nfrom 1W to 52W for weeks \nfrom 1M to 12M for months")


calcBy                                 = input.string(defval = "Percentages (Recommended)", title = "Calculate Levels By Tick or Percentages?", options = ["Ticks", "Percentages (Recommended)"], group = "Select How Levels Are Plotted")
perc                                   = input.float(defval = 0.25, step = 0.1, title = "Percentage Distance Between Levels (If Selected)", inline = "1", group = 'If "Percentages" is Selected') / 100
tickzz                                 = input.float(defval = 50 ,title = "Ticks (If Selected)", inline = "1", group = 'If "Ticks" is Selected')

classic                                = input.bool(defval = false, title = "Classic Look ?", group = "Classic")
barDiv                                 = input.int (defval = 10, minval = 4, title = "Divide Bars Into How Many Rows ?", group = "Classic")
assume                                 = input.bool(defval = false, title = "Use Volume Assumption ?", group = "Volume Assumption" ,tooltip = 'When This Setting Is Selected, the Script Will Not Record “0” Buy Volume or “0” Sell Volume at a Level Where Green Bars Formed and No Red Bars Formed, or Where Only Red Bars Formed and No Green Bars Formed. If a Level Were Recorded With All “Buy Volume” - The Script Will Assume 40% Of the Buy Volume Was Sell Volume. Vice Versa for a Level Where Only “Sell Volume” Was Recorded - The Script Will Assume 40% Of the “Sell Volume” Was “Buy Volume”. This Assumption May or May Not Help the Indicator Better Replicate Volume Delta Indicators on Other Charting Platforms. If You Do Not Want to Adhere to This Assumption - Simply Deselect This Setting')
lastBar                                = input.bool(defval = false, title = "Last Bar Calculation Only?", group = "Calculate on Last Bar Only")
hideAll                                = input.bool(defval = true, title = "Show End Lines and Labels ?",  group = "Show Summed Values at End of Chart (Deselect For Best Price Scaling)")
outline                                = input.bool(defval = true, title = "Show Label Color Outline ?", group = 'Show "Neon Effect"')
extend                                 = input.bool(defval = false, title = "Extend End Lines Left ?", group = "Extend Summed Value Lines Left Across Price Data (Deselect For Best Price Scaling)")
eX                                     = input.bool(defval = true, title = "Extend Highest Delta / Highest Volume Line ", group = "Extend 'POC' Left Across Price Data? (Deselect for Best Price Scaling)")
heat                                   = input.bool(defval = true, title = "Show Heatmap ?", group = "Show Chart Heatmap (Deselect for Best Price Scaling)")
heatOnly                               = input.bool(defval = false, title = "Heat Map Only", group = "Show Heatmap Only (Deselect for Best Price Scaling)")
textSize                               = input.string(defval = "Small", options = ["Tiny", "Small", "Normal", "Large", "Huge"], group = "Aesthetics (Deselect All for Best Price Scaling)")
fnt                                    = input.string(defval = "Default", title = "Font Type", options = ["Default", "Monospace"], group = "Aesthetics (Deselect All for Best Price Scaling)")


c                                       = input.color(defval = color.lime, title = 'General "Up/Buy" Color', group = 'Up/Buy Color')
c1                                      = input.color(defval = color.red, title = 'General "Down/Sell" Color', group = 'Down/Sell Color')
c2                                      = input.color(defval = color.rgb(148, 139, 57), title = 'General "POC" Color', group = '"POC" Color')


fonT = switch fnt
    
    "Default"   => font.family_default
    "Monospace" => font.family_monospace


finTim = switch Recalculation
    "No Recalculation" => heatOnly == false ? bar_index == last_bar_index - 500 : array.size(m)[1] == 0 and array.size(m) > 0
    "Recalculate" => timeframe.change(sess) and last_bar_index - bar_index <= 500

    

sz = switch textSize
    
    "Tiny"             => size.tiny
    "Small"            => size.small
    "Normal"           => size.normal
    "Large"            => size.large
    "Huge"             => size.huge

var float tickz                          = 0.0
ticks2 = array.new_float()

if Recalculation == "No Recalculation"

    tickz := tickzz 

ticks                               = array.new_float()
var float max                       = 0.0
var float min                       = 10000000
var float [] track                  = array.new_float()
var float [] heatLevels             = array.new_float()

letters = array.new_label()
lettersBox = array.new_label()
lettersBoxClassic = array.new_box()
boxCo = array.new_float()

req() => 
    switch data
        "OI Delta (BINANCE PERP FUTURES ONLY)" => syminfo.ticker+"_OI"
        => string(na)

colorChange(x, y) => 
    switch outline
        false => label.set_textcolor(x, y)
        => label.set_color(x, y)

colorChange2(x, y) => 
    box.set_bgcolor(x, y)

[clo, clo1, HIGH, LOW] = request.security_lower_tf(req(), "1", [close, close[1], high, low])

var int startHeat = 0
var float startHeat1 = 0

if array.size(m)[1] == 0 and array.size(m) > 0
    startHeat  := math.round(time)
    startHeat1 := bar_index
timeCond = heatOnly == false  ? last_bar_index - bar_index <= 500 : array.size(m) > 0
var float [] volCountUpFin = array.new_float(3000, initial_value = 0.0)
var float [] volCountDnFin = array.new_float(3000, initial_value = 0.0)


var int first                       = 0
var int firstBar                    = math.round(1e8)
levelsCount                         = array.new_float()

var string calcSince = ""

if last_bar_index - bar_index == 500 and Recalculation == "No Recalculation"
    calcSince := "Calculating Since \n" + str.tostring(month(time)) + "/" + str.tostring(dayofmonth(time)) + " - " + str.tostring(hour(time)) + ":" + str.tostring(minute(time)) + ":" + str.tostring(second(time))


if timeCond 
    


    max                                 := math.max(high, max)
    min                                 := math.min(low, min)



    if finTim
        

        if array.size(label.all) > 0
            for i = 0 to array.size(label.all) - 1
                label.delete(array.shift(label.all))
        
        for i =  0 to array.size(volCountUpFin) - 1
            array.set(volCountUpFin, i, 0)
            array.set(volCountDnFin, i, 0)
        if array.size(ticks) > 0 
            array.clear(ticks)
            array.clear(ticks2)
        if array.size(track) > 0 
            array.clear(track)


        max := high
        min := low
        
        first := math.round(time)



        firstBar := bar_index
        array.push(track, low)
        

if lastBar == false ?  bar_index >= firstBar : barstate.islast



    if array.size(track) > 0
        array.push(ticks, array.get(track, array.size(track) - 1))
        if calcBy == "Ticks"
            for i = 1 to 500
                array.push(ticks, array.get(ticks, i - 1) + (tickz * syminfo.mintick))

            array.push(ticks2, array.get(track, array.size(track) - 1) - (tickz * syminfo.mintick))
            for i = 1 to 500
                array.push(ticks2, array.get(ticks2, i - 1) - (tickz * syminfo.mintick))
        else 
            for i = 1 to 500
                array.push(ticks, array.get(ticks, i - 1) * (1 + perc))
            
            array.push(ticks2, array.get(track, array.size(track) - 1) * (1-perc))
            for i = 1 to 500
                array.push(ticks2, array.get(ticks2, i - 1) * (1-perc))



ticks3 = array.concat(ticks, ticks2)
array.sort(ticks3, order.ascending)



if array.size(ticks3) > 1
    if classic == false
        if data != "OI Delta (BINANCE PERP FUTURES ONLY)"
            if array.size(m2) > 0 
                for x = 0 to array.size(ticks3) - 1
                    if array.get(ticks3, x) <= high and array.get(ticks3, x) >= low and array.includes(levelsCount, array.get(ticks3, x)) == false 
                        array.push(levelsCount, array.get(ticks3, x))
                        array.push(boxCo, 1)
                        array.push(heatLevels, array.get(ticks3, x))
        else 
            if array.size(clo) > 0
                for x = 0 to array.size(ticks3) - 1
                    if array.get(ticks3, x) <= high and array.get(ticks3, x) >= low and array.includes(levelsCount, array.get(ticks3, x)) == false 
                        array.push(levelsCount, array.get(ticks3, x))
                        array.push(boxCo, 1)
                        array.push(heatLevels, array.get(ticks3, x))

    else 
        div = (high - low) / barDiv
        if data != "OI Delta (BINANCE PERP FUTURES ONLY)"
            if array.size(m2) > 0 
                for x = 0 to barDiv - 1
                    array.push(levelsCount, low + (x * div))
                    array.push(boxCo, 1)
                    array.push(heatLevels,  low + (x * div))
        else 
            if array.size(clo) > 0
                for x = 0 to barDiv - 1
                    array.push(levelsCount, low + (x * div))
                    array.push(boxCo, 1)
                    array.push(heatLevels,  low + (x * div))




if array.size(levelsCount) > 0
    array.sort(levelsCount, order.ascending)
    if array.size(levelsCount) > 1
        if classic == false 
            if calcBy == "Ticks"
                array.push(levelsCount, array.get(levelsCount, array.size(levelsCount) - 1) + (tickz * syminfo.mintick ))
            else 
                array.push(levelsCount, array.get(levelsCount, array.size(levelsCount) - 1) * (1+perc))
        else 
            array.push(levelsCount, array.get(levelsCount, array.size(levelsCount) - 1) + ((high - low) / barDiv))


        array.push(boxCo, 1)
    array.sort(levelsCount, order.ascending)
    if array.size(levelsCount) > 0
        if classic == false 
            for i = 0 to array.size(levelsCount) - 1
                array.push(lettersBox, label.new(bar_index, array.get(levelsCount, i),
                                     color = color.new(color.white, 100), text = "", 
                                     size = sz,
                                     textcolor = color.white, text_font_family = fonT,
                                     style = outline == true ? label.style_text_outline : label.style_none)) 
        
        else 
            array.pop(levelsCount)
            array.pop(boxCo)
            div = (high - low) / barDiv
            for i = 0 to array.size(levelsCount) - 1
                array.push(lettersBoxClassic, box.new(bar_index, array.get(levelsCount, i), bar_index + 1, array.get(levelsCount, i) + div,
                                                 bgcolor = color.new(color.white, 100), text = "", 
                                                 text_size = sz,
                                                 text_color = color.white, text_font_family = fonT,
                                                 border_color = na  ))



volCountUp = array.new_float(array.size(levelsCount), 0)
volCountDn = array.new_float(array.size(levelsCount), 0)  


if data != "OI Delta (BINANCE PERP FUTURES ONLY)" 


    if array.size(boxCo) > 1
      and array.sum(boxCo) == array.size(levelsCount)  
        boxTrack2 = array.new_float(array.size(m2), 0.0)    
        if array.size(m2) > 0
            for nx = 0 to array.size(m2) - 1
                for x = 0 to array.size(levelsCount) - 1
                    if array.get(levelsCount, x) <= array.get(m3, nx) and array.get(levelsCount, x) >= array.get(m4, nx)
                        array.set(boxTrack2, nx, array.get(boxTrack2, nx) + 1)  
            if array.sum(boxTrack2) > 0 
                for x = 0 to array.size(levelsCount) - 1
                    for nx = 0 to array.size(m2) - 1
                        if array.get(boxTrack2, nx) != 0 and array.get(levelsCount, x) <= array.get(m3, nx) and array.get(levelsCount, x) >= array.get(m4, nx)  
                            if array.get(m, nx) >= array.get(m6, nx)
                                array.set(volCountUp, x, array.get(volCountUp, x) + (array.get(m2, nx) / array.get(boxTrack2, nx))) 
                                SW = switch data    
                                    "Volume"     =>  (str.tostring(array.get(volCountUp, x), format.volume) + " | " + str.tostring(array.get(volCountDn, x), format.volume))
                                    "Vol. Delta" =>  math.sign(array.get(volCountUp, x) - array.get(volCountDn, x)) == 1                     ?
                                               "+" + (str.tostring(array.get(volCountUp, x) - array.get(volCountDn, x), "###,###,###.00"))   : 
                                                     (str.tostring(array.get(volCountUp, x) - array.get(volCountDn, x), "###,###,###.00"))
                                if classic == false and array.size(lettersBox) > 0
                                    label.set_text(array.get(lettersBox, x), SW) 
                                else if classic == true and array.size(lettersBoxClassic) > 0
                                    box.set_text(array.get(lettersBoxClassic, x), SW) 
                            else 
                                array.set(volCountDn, x, array.get(volCountDn, x) + (array.get(m2, nx) / array.get(boxTrack2, nx))) 
                                SW = switch data    
                                    "Volume"     =>  (str.tostring(array.get(volCountUp, x), format.volume) + " | " + str.tostring(array.get(volCountDn, x), format.volume))
                                    "Vol. Delta" =>  math.sign(array.get(volCountUp, x) - array.get(volCountDn, x)) == 1                     ?
                                               "+" + (str.tostring(array.get(volCountUp, x) - array.get(volCountDn, x), "###,###,###.00"))   : 
                                                     (str.tostring(array.get(volCountUp, x) - array.get(volCountDn, x), "###,###,###.00"))  
                                if array.size(lettersBox) > 0 and classic == false
                                    label.set_text(array.get(lettersBox, x), SW)    
                                else if classic == true and array.size(lettersBoxClassic) > 0
                                    box.set_text(array.get(lettersBoxClassic, x), SW) 


            for i = 1 to array.size(levelsCount) - 1
                for x = 0 to array.size(m2) - 1
                    if array.get(m3, x) < array.get(levelsCount, i) and array.get(m4, x) > array.get(levelsCount, i - 1)
                        if array.get(m, x) >= array.get(m6, x)
                            array.set(volCountUp, i - 1, array.get(volCountUp, i - 1) + array.get(m2, x))
                            if array.size(lettersBox) > 0 or array.size(lettersBoxClassic) > 0
                                SW2 = switch data   
                                    "Volume"     =>  (str.tostring(array.get(volCountUp, i - 1), format.volume) + " | " + str.tostring(array.get(volCountDn, i - 1), format.volume))
                                    "Vol. Delta" =>  math.sign(array.get(volCountUp, i - 1) - array.get(volCountDn, i - 1)) == 1                     ?
                                               "+" + (str.tostring(array.get(volCountUp, i - 1) - array.get(volCountDn, i - 1), "###,###,###.00"))   : 
                                                     (str.tostring(array.get(volCountUp, i - 1) - array.get(volCountDn, i - 1), "###,###,###.00"))  
                                if classic == false   
                                    label.set_text(array.get(lettersBox, i - 1),SW2)
                                else if classic == true 
                                    box.set_text(array.get(lettersBoxClassic, i - 1), SW2) 
                        else
                        
                            array.set(volCountDn, i - 1, array.get(volCountDn, i - 1) + array.get(m2, x))
                            if array.size(lettersBox) > 0 or array.size(lettersBoxClassic) > 0
                                SW2 = switch data   
                                    "Volume"     =>  (str.tostring(array.get(volCountUp, i - 1), format.volume) + " | " + str.tostring(array.get(volCountDn, i - 1), format.volume))
                                    "Vol. Delta" =>  math.sign(array.get(volCountUp, i - 1) - array.get(volCountDn, i - 1)) == 1                     ?
                                               "+" + (str.tostring(array.get(volCountUp, i - 1) - array.get(volCountDn, i - 1), "###,###,###.00"))   : 
                                                     (str.tostring(array.get(volCountUp, i - 1) - array.get(volCountDn, i - 1), "###,###,###.00"))  
                                if classic == false  
                                    label.set_text(array.get(lettersBox, i - 1), SW2)
                                else if classic == true 
                                    box.set_text(array.get(lettersBoxClassic, i - 1), SW2)
                            
            array.unshift(volCountUp, 0)
            array.unshift(volCountDn, 0)    
            for x = 0 to array.size(m2) - 1
                if array.get(m3, x) < array.get(levelsCount, 0) 
                    if array.get(m, x) >= array.get(m6, x)
                        array.set(volCountUp, 0, array.get(volCountUp, 0) + array.get(m2, x))
                    else    
                        array.set(volCountDn, 0, array.get(volCountDn, 0) + array.get(m2, x))   
            volCountExUp = array.new_float(1), array.set(volCountExUp, 0, array.get(volCountUp, 0) + array.get(volCountUp, 1))
            volCountExDn = array.new_float(1), array.set(volCountExDn, 0, array.get(volCountDn, 0) + array.get(volCountDn, 1))  
            array.shift(volCountUp), array.set(volCountUp, 0, array.sum(volCountExUp))
            array.shift(volCountDn), array.set(volCountDn, 0, array.sum(volCountExDn))  
            SW3 = switch data   
                "Volume"     =>  (str.tostring(array.sum(volCountExUp), format.volume) + " | " + str.tostring(array.sum(volCountExDn), format.volume))
                "Vol. Delta" =>  math.sign(array.sum(volCountExUp) - array.sum(volCountExDn)) == 1 ? 
                                 "+" + str.tostring(array.sum(volCountExUp) - array.sum(volCountExDn), "###,###,###.00") :
                                 str.tostring(array.sum(volCountExUp) - array.sum(volCountExDn), "###,###,###.00")
            if classic == false
                label.set_text(array.get(lettersBox, 0), SW3)  
            else 
                box.set_text(array.get(lettersBoxClassic, 0), SW3)
 
    if array.size(boxCo) == 1 
        for i = 0 to array.size(m2) - 1
            if array.get(m, i) >= array.get(m6, i)
                array.set(volCountUp, 0, array.get(volCountUp, 0) + array.get(m2, i))
            else    
                array.set(volCountDn, 0, array.get(volCountDn, 0) + array.get(m2, i))
        
        if array.size(lettersBox) > 0 or array.size(lettersBoxClassic) > 0
            SW4 = switch data   
                "Volume"     =>  str.tostring(array.get(volCountUp, 0), format.volume) + " | " + str.tostring(array.get(volCountDn, 0), format.volume)
                "Vol. Delta" =>  math.sign(array.get(volCountUp, 0) - array.get(volCountDn, 0)) == 1                       ? 
                                 "+" + str.tostring(array.get(volCountUp, 0) - array.get(volCountDn, 0), "###,###,###.00") :
                                 str.tostring(array.get(volCountUp, 0) - array.get(volCountDn, 0), "###,###,###.00")    
            if classic == false 
                label.set_text(array.get(lettersBox, 0), SW4 + "*")
                colorChange(array.get(lettersBox, 0), array.sum(volCountUp) > array.sum(volCountDn) ? color.new(c,outline == true ? 50 : 0) : color.new(c1,outline == true ? 50 : 0)) 

            else 
                box.set_text(array.get(lettersBoxClassic, 0), SW4 + "*")
                colorChange2(array.get(lettersBoxClassic, 0), array.sum(volCountUp) > array.sum(volCountDn) ? color.new(c,90) : color.new(c1,90)) 

    if array.size(boxCo) == 0 
      and array.size(m2) > 0 and bar_index >= firstBar and array.size(ticks3) > 1
        for i = 1 to array.size(ticks3) - 1
            if array.get(ticks3, i) > low and array.get(ticks3, i - 1) <= low
                array.push(levelsCount, array.get(ticks3, i - 1))
                break
        if classic == false 
            array.push(lettersBox, label.new(bar_index, array.get(levelsCount, 0), "", textcolor = color.white, style = outline == true ? label.style_text_outline : label.style_none, size = sz))
        else 
            calculation = switch calcBy 
                "Ticks" => array.get(levelsCount, 0) + (tickz * syminfo.mintick)
                => array.get(levelsCount, 0) * (1+perc)
            array.push(lettersBoxClassic, box.new(bar_index, calculation,
              bar_index + 1, array.get(levelsCount, 0), text = "", text_color = color.white, text_size = sz))

        array.unshift(volCountUp, 0)
        array.unshift(volCountDn, 0)
        for i = 0 to array.size(m2) - 1
            if array.get(m, i) >= array.get(m6, i) 
                array.set(volCountUp, 0, array.get(volCountUp, 0) + array.get(m2, i))
                SW5 = switch data   
                    "Volume"     =>  (str.tostring(array.sum(volCountUp), format.volume) + " | " + str.tostring(array.sum(volCountDn), format.volume))
                    "Vol. Delta" =>  math.sign(array.sum(volCountUp) - array.sum(volCountDn)) == 1                       ? 
                                     "+" + str.tostring(array.sum(volCountUp) - array.sum(volCountDn), "###,###,###.00") :
                                     str.tostring(array.sum(volCountUp)       - array.sum(volCountDn), "###,###,###.00")    
                if classic == false 
                    label.set_text(array.get(lettersBox, 0 ), SW5 + "*")
                else    
                    box.set_text(array.get(lettersBoxClassic, 0 ), SW5 + "*")


            else    
                array.set(volCountDn, 0, array.get(volCountDn, 0) + array.get(m2, i))
                SW5 = switch data   
                    "Volume"     =>  (str.tostring(array.sum(volCountUp), format.volume) + " | " + str.tostring(array.sum(volCountDn), format.volume))
                    "Vol. Delta" =>  math.sign(array.sum(volCountUp) - array.sum(volCountDn)) == 1                       ? 
                                     "+" + str.tostring(array.sum(volCountUp) - array.sum(volCountDn), "###,###,###.00") :
                                     str.tostring(array.sum(volCountUp)       - array.sum(volCountDn), "###,###,###.00")    
                if classic == false
                    label.set_text(array.get(lettersBox, 0 ), SW5 + "*")
                    colorChange(array.get(lettersBox, 0), array.sum(volCountUp) >= array.sum(volCountDn) ? color.new(c,outline == true ? 50 : 0) : color.new(c1,outline == true ? 50 : 0))    
                else 
                    box.set_text(array.get(lettersBoxClassic, 0 ), SW5 + "*")
                    colorChange2(array.get(lettersBoxClassic, 0), array.sum(volCountUp) >= array.sum(volCountDn) ? color.new(c, 90) : color.new(c1, 90))    

    if array.size(lettersBox) > 1 and classic == false or array.size(lettersBoxClassic) > 1 and classic == true
        for i = 0 to classic == false ? array.size(lettersBox) - 1 : array.size(lettersBoxClassic) - 1
            if classic == false 
                switch data
                    "Volume"     => colorChange(array.get(lettersBox, i) , array.get(volCountUp, i) < array.get(volCountDn, i) ?
                     color.new(c1,outline == true ? 50 : 0) : color.new(c,outline == true ? 50 : 0))
                    "Vol. Delta" => colorChange(array.get(lettersBox, i) , math.sign(array.get(volCountUp, i) - array.get(volCountDn, i)) == 1 ?
                     color.new(c,outline == true ? 50 : 0) : color.new(c1,outline == true ? 50 : 0))
            else
                switch data 
                    "Volume"     => colorChange2(array.get(lettersBoxClassic, i) , array.get(volCountUp, i) < array.get(volCountDn, i) ?
                     color.new(c1,90) : color.new(c,90))
                    "Vol. Delta" => colorChange2(array.get(lettersBoxClassic, i) , math.sign(array.get(volCountUp, i) - array.get(volCountDn, i)) == 1 ?
                     color.new(c,90) : color.new(c1,90))

            if classic == false 
                if label.get_text(array.get(lettersBox, i)) == "" 
                    label.set_color(array.get(lettersBox, i), na)
            else 
                if box.get_bottom(array.get(lettersBoxClassic, i)) > high  
                    box.set_bgcolor(array.get(lettersBoxClassic, i), na)
    
        maxUp = 0.0
        for i = 0 to classic == false ? array.size(lettersBox) - 1 : array.size(lettersBoxClassic) - 1
            maxUp := data == "Volume" ? math.max(maxUp, array.get(volCountUp, i), array.get(volCountDn, i)): 
             math.max(maxUp, math.abs(array.get(volCountUp, i) - array.get(volCountDn, i)))
        for i = 0 to classic == false ? array.size(lettersBox) - 1 : array.size(lettersBoxClassic) - 1
            if data == "Volume"
                if array.get(volCountUp, i) == maxUp or array.get(volCountDn, i) == maxUp
                    if classic == false 
                        colorChange(array.get(lettersBox, i), c2)
                    else 
                        box.set_bgcolor(array.get(lettersBoxClassic, i), color.new(c2, 90))
                        box.set_border_color(array.get(lettersBoxClassic, i), c2)

            else    
                if math.abs(array.get(volCountUp, i) - array.get(volCountDn, i)) == maxUp
                    if classic == false    
                        colorChange(array.get(lettersBox, i), c2)
                    else 
                        box.set_bgcolor(array.get(lettersBoxClassic, i), color.new(c2, 90))
                        box.set_border_color(array.get(lettersBoxClassic, i), c2)
                    break   
    if classic
        if array.size(levelsCount) > 1
            if array.size(m2) > 0 
                for x = 0 to array.size(m2) - 1 
                    if array.get(m4, x) > array.get(levelsCount, array.size(levelsCount) - 1)
                        if array.get(m, x) >= array.get(m6, x)
                            array.set(volCountUp, array.size(volCountUp) - 1, array.get(volCountUp, array.size(volCountUp) - 1) +  array.get(m2, x))
                            SWF = switch data
                               
                                "Volume"     =>  (str.tostring(array.get(volCountUp, array.size(volCountUp) - 1), format.volume) + " | " + 
                                                 str.tostring(array.get(volCountDn, array.size(volCountDn) - 1), format.volume))
                                "Vol. Delta" => math.sign(array.get(volCountUp, array.size(volCountUp) - 1) - array.get(volCountDn, array.size(volCountDn) - 1)) == 1   ? 
                                     "+" + str.tostring(array.get(volCountUp, array.size(volCountUp) - 1) - array.get(volCountDn, array.size(volCountDn) - 1), "###,###,###.00") :
                                     str.tostring(array.get(volCountUp, array.size(volCountUp) - 1) - array.get(volCountDn, array.size(volCountDn) - 1), "###,###,###.00")    
                            
                            box.set_text(array.get(lettersBoxClassic, array.size(lettersBoxClassic) - 1), SWF)

                        else 
                            
                            array.set(volCountDn, array.size(volCountDn) - 1, array.get(volCountDn, array.size(volCountDn) - 1) +  array.get(m2, x))
                            
                            SWF = switch data
                               
                                "Volume"     =>  (str.tostring(array.get(volCountUp, array.size(volCountUp) - 1), format.volume) + " | " + 
                                                 str.tostring(array.get(volCountDn, array.size(volCountDn) - 1), format.volume))
                                "Vol. Delta" => math.sign(array.get(volCountUp, array.size(volCountUp) - 1) - array.get(volCountDn, array.size(volCountDn) - 1)) == 1                       ? 
                                     "+" + str.tostring(array.get(volCountUp, array.size(volCountUp) - 1) - array.get(volCountDn, array.size(volCountDn) - 1), "###,###,###.00") :
                                     str.tostring(array.get(volCountUp, array.size(volCountUp) - 1) - array.get(volCountDn, array.size(volCountDn) - 1), "###,###,###.00")    
                        
                            box.set_text(array.get(lettersBoxClassic, array.size(lettersBoxClassic) - 1), SWF)


        for i = 0 to classic == false ? array.size(lettersBox) - 1 : array.size(lettersBoxClassic) - 1
            if assume == true 
                if data == "Volume" or data == "Vol. Delta"
                    if array.get(volCountUp, i) == 0 and array.get(volCountDn, i) > 0
                        array.set(volCountUp, i, array.get(volCountDn, i) * .40)
                        array.set(volCountDn, i, array.get(volCountDn, i) * .60)
                        if data == "Volume"
                            if classic == false
                                label.set_text(array.get(lettersBox, i), 
                                     (str.tostring(array.get(volCountUp, i), format.volume) + " | " + str.tostring(array.get(volCountDn, i), format.volume)))
                            else 
                                
                                box.set_text(array.get(lettersBoxClassic, i),
                                 (str.tostring(array.get(volCountUp, i), format.volume) + " | " + str.tostring(array.get(volCountDn, i), format.volume)))
                        else 

                            if classic == false
                                label.set_text(array.get(lettersBox, i),
                                 math.sign(array.get(volCountUp, i) - array.get(volCountDn, i)) == 1                            ?
                                 "+" + (str.tostring(array.get(volCountUp, i) - array.get(volCountDn, i), "###,###,###.00"))   : 
                                       (str.tostring(array.get(volCountUp, i) - array.get(volCountDn, i), "###,###,###.00"))) 
                            else 
                                box.set_text(array.get(lettersBoxClassic, i),
                                 math.sign(array.get(volCountUp, i) - array.get(volCountDn, i)) == 1                            ?
                                 "+" + (str.tostring(array.get(volCountUp, i) - array.get(volCountDn, i), "###,###,###.00"))   : 
                                       (str.tostring(array.get(volCountUp, i) - array.get(volCountDn, i), "###,###,###.00"))) 
                            
                    else if array.get(volCountUp, i) > 0 and array.get(volCountDn, i) == 0
                        array.set(volCountDn, i, array.get(volCountUp, i) * .40)
                        array.set(volCountUp, i, array.get(volCountUp, i) * .60)
                        if classic == false 
                            if data == "Volume"
                                label.set_text(array.get(lettersBox, i), 
                                 (str.tostring(array.get(volCountUp, i), format.volume) + " | " + str.tostring(array.get(volCountDn, i), format.volume)))
                            else
                                label.set_text(array.get(lettersBox, i),
                                 math.sign(array.get(volCountUp, i) - array.get(volCountDn, i)) == 1                            ?
                                 "+" + (str.tostring(array.get(volCountUp, i) - array.get(volCountDn, i), "###,###,###.00"))   : 
                                       (str.tostring(array.get(volCountUp, i) - array.get(volCountDn, i), "###,###,###.00")))
                        else 
                            if data == "Volume"
                                box.set_text(array.get(lettersBoxClassic, i), 
                                 (str.tostring(array.get(volCountUp, i), format.volume) + " | " + str.tostring(array.get(volCountDn, i), format.volume)))
                            else
                                box.set_text(array.get(lettersBoxClassic, i),
                                 math.sign(array.get(volCountUp, i) - array.get(volCountDn, i)) == 1                            ?
                                 "+" + (str.tostring(array.get(volCountUp, i) - array.get(volCountDn, i), "###,###,###.00"))   : 
                                       (str.tostring(array.get(volCountUp, i) - array.get(volCountDn, i), "###,###,###.00"))) 



    else if array.size(lettersBox) == 1 or array.size(lettersBoxClassic) == 1
        if assume == true 
            if data == "Volume" or data == "Vol. Delta"
                if array.get(volCountUp, 0) == 0 and array.get(volCountDn, 0) != 0
                    array.set(volCountUp, 0, array.get(volCountDn, 0) * .40)
                    array.set(volCountDn, 0, array.get(volCountDn, 0) * .60)
                    if classic == false 
                        if data == "Volume"
                            label.set_text(array.get(lettersBox, 0), 
                             (str.tostring(array.get(volCountUp, 0), format.volume) + " | " + str.tostring(array.get(volCountDn, 0), format.volume)))
                        else

                            label.set_text(array.get(lettersBox, 0),
                             math.sign(array.get(volCountUp, 0) - array.get(volCountDn, 0)) == 1                            ?
                             "+" + (str.tostring(array.get(volCountUp, 0) - array.get(volCountDn, 0), "###,###,###.00"))   : 
                                   (str.tostring(array.get(volCountUp, 0) - array.get(volCountDn, 0), "###,###,###.00"))) 
                    else 
                        if data == "Volume"
                            box.set_text(array.get(lettersBoxClassic, 0), 
                             (str.tostring(array.get(volCountUp, 0), format.volume) + " | " + str.tostring(array.get(volCountDn, 0), format.volume)))
                        else

                            box.set_text(array.get(lettersBoxClassic, 0),
                             math.sign(array.get(volCountUp, 0) - array.get(volCountDn, 0)) == 1                            ?
                             "+" + (str.tostring(array.get(volCountUp, 0) - array.get(volCountDn, 0), "###,###,###.00"))   : 
                                   (str.tostring(array.get(volCountUp, 0) - array.get(volCountDn, 0), "###,###,###.00"))) 

                if array.get(volCountDn, 0) == 0 and array.get(volCountUp, 0) != 0
                    array.set(volCountDn, 0, array.get(volCountUp, 0) * .40)
                    array.set(volCountUp, 0, array.get(volCountUp, 0) * .60)
                    if classic == false 
                        if data == "Volume"
                            label.set_text(array.get(lettersBox, 0), 
                             (str.tostring(array.get(volCountUp, 0), format.volume) + " | " + str.tostring(array.get(volCountDn, 0), format.volume)))

                        else

                            label.set_text(array.get(lettersBox, 0),
                             math.sign(array.get(volCountUp, 0) - array.get(volCountDn, 0)) == 1                            ?
                             "+" + (str.tostring(array.get(volCountUp, 0) - array.get(volCountDn, 0), "###,###,###.00"))   : 
                                   (str.tostring(array.get(volCountUp, 0) - array.get(volCountDn, 0), "###,###,###.00")))
                    else 
                        if data == "Volume"
                            box.set_text(array.get(lettersBoxClassic, 0), 
                             (str.tostring(array.get(volCountUp, 0), format.volume) + " | " + str.tostring(array.get(volCountDn, 0), format.volume)))
                        else 
                            box.set_text(array.get(lettersBoxClassic, 0),
                             math.sign(array.get(volCountUp, 0) - array.get(volCountDn, 0)) == 1                            ?
                             "+" + (str.tostring(array.get(volCountUp, 0) - array.get(volCountDn, 0), "###,###,###.00"))   : 
                                   (str.tostring(array.get(volCountUp, 0) - array.get(volCountDn, 0), "###,###,###.00")))

    if array.size(levelsCount) > 0 
        var label [] finalBox = array.new_label()
        SA = switch data    
            "Volume"     => str.tostring(array.sum(volCountUp), "+###,###,###.00") + " | " + str.tostring(-array.sum(volCountDn), "###,###,###.00")
            "Vol. Delta" => str.tostring(array.sum(volCountUp) - array.sum(volCountDn), array.sum(volCountUp) - array.sum(volCountDn) >= 0 ? 
             "+###,###,###.00" : "###,###,###.00")
        
        array.push(finalBox, label.new(bar_index, low, yloc = classic == false ? yloc.belowbar : yloc.abovebar, text = classic == false ?  SA + "\nTotal" : 
         "                    " + SA + "\n                    Total"  , 
             size = sz, style = outline == true ? label.style_text_outline : label.style_none, textcolor = color.white, text_font_family = fonT))
        colorChange(array.get(finalBox, array.size(finalBox) - 1), array.sum(volCountUp) - array.sum(volCountDn) >= 0 ? 
             color.new(c, outline == true ? 50 : 0) : color.new(c1, outline == true ? 50 : 0))

        if array.size(levelsCount) > 0
            for i = 0 to array.size(levelsCount) - 1
                for x = 0 to array.size(ticks3) - 1
                    if array.get(levelsCount, i) == array.get(ticks3, x)
                        array.set(volCountUpFin, x, array.get(volCountUpFin, x) + array.get(volCountUp, i))
                        array.set(volCountDnFin, x, array.get(volCountDnFin, x) + array.get(volCountDn, i))

        


if data == "OI Delta (BINANCE PERP FUTURES ONLY)" 

    if classic 
        if array.size(levelsCount) > 0
            if array.size(clo) > 0 
                for x = 0 to array.size(clo) - 1 
                    if array.get(m4, x) > array.get(levelsCount, array.size(levelsCount) - 1)
                        if array.get(clo, x) >= array.get(clo1, x)
                            array.set(volCountUp, array.size(volCountUp) - 1, array.get(volCountUp, array.size(volCountUp) - 1) + (array.get(clo, x) - array.get(clo1, x)))
                            cache = math.sign(array.get(volCountUp, array.size(volCountUp) - 1) + array.get(volCountDn, array.size(volCountUp) - 1)) == 1 ? 
                             "+" + str.tostring(array.get(volCountUp, array.size(volCountUp) - 1) + array.get(volCountDn, array.size(volCountUp) - 1), "###,###,###.00") :
                             str.tostring(array.get(volCountUp, array.size(volCountUp) - 1) + array.get(volCountDn, array.size(volCountDn) - 1), "###,###,###.00")

                            box.set_text(array.get(lettersBoxClassic, array.size(lettersBoxClassic) - 1), cache)
                        else 

                            array.set(volCountDn, array.size(volCountDn) - 1, array.get(volCountDn, array.size(volCountDn) - 1) + (array.get(clo, x) - array.get(clo1, x)))
                            
                            cache = math.sign(array.get(volCountUp, array.size(volCountUp) - 1) + array.get(volCountDn, array.size(volCountUp) - 1)) == 1 ? 
                             "+" + str.tostring(array.get(volCountUp, array.size(volCountUp) - 1) + array.get(volCountDn, array.size(volCountUp) - 1), "###,###,###.00") :
                             str.tostring(array.get(volCountUp, array.size(volCountUp) - 1) + array.get(volCountDn, array.size(volCountDn) - 1), "###,###,###.00")

                            box.set_text(array.get(lettersBoxClassic, array.size(lettersBoxClassic) - 1), cache)

    if array.size(boxCo) > 1
      and array.sum(boxCo) == array.size(levelsCount)  
        boxTrack2 = array.new_float(array.size(clo), 0.0)    

        if array.size(clo) > 0 and array.size(clo) == array.size(m2)
            for nx = 0 to array.size(clo) - 1
                for x = 0 to array.size(levelsCount) - 1
                    if array.get(levelsCount, x) <= array.get(m3, nx) and array.get(levelsCount, x) >= array.get(m4, nx)
                        array.set(boxTrack2, nx, array.get(boxTrack2, nx) + 1)  


            if array.sum(boxTrack2) > 0 
                for x = 0 to array.size(levelsCount) - 1
                    for nx = 0 to array.size(clo) - 1

                        if array.get(boxTrack2, nx) != 0 and array.get(levelsCount, x) <= array.get(m3, nx) and array.get(levelsCount, x) >= array.get(m4, nx)  

                            if array.get(clo, nx) >= array.get(clo1, nx)

                                array.set(volCountUp, x, array.get(volCountUp, x) + ((array.get(clo, nx) - array.get(clo1, nx)) / array.get(boxTrack2, nx)))

                                cache = math.sign(array.get(volCountUp, x) + array.get(volCountDn, x)) == 1 ? 
                                 "+" + str.tostring(array.get(volCountUp, x) + array.get(volCountDn, x), "###,###,###.00") :
                                 str.tostring(array.get(volCountUp, x) + array.get(volCountDn, x), "###,###,###.00")

                                if array.size(lettersBox) > 0 and classic == false 
                                    label.set_text(array.get(lettersBox, x), cache)
                                else if array.size(lettersBoxClassic) > 0 and classic == true 
                                    box.set_text(array.get(lettersBoxClassic, x), cache)

                            else
                            
                                array.set(volCountDn, x, array.get(volCountDn, x) + ((array.get(clo, nx) - array.get(clo1, nx)) / array.get(boxTrack2, nx)))

                                cache = math.sign(array.get(volCountUp, x) + array.get(volCountDn, x)) == 1 ? 
                                 "+" + str.tostring(array.get(volCountUp, x) + array.get(volCountDn, x), "###,###,###.00") :
                                 str.tostring(array.get(volCountUp, x) + array.get(volCountDn, x), "###,###,###.00")

                                if array.size(lettersBox) > 0 and classic == false
                                    label.set_text(array.get(lettersBox, x), cache)
                                else if array.size(lettersBoxClassic) > 0 and classic == true 
                                    box.set_text(array.get(lettersBoxClassic, x), cache)


            array.unshift(volCountUp, 0)
            array.unshift(volCountDn, 0)    

            for x = 0 to array.size(m2) - 1
                if array.get(m3, x) < array.get(levelsCount, 0) 

                    if array.get(clo, x) >= array.get(clo1, x)
                        array.set(volCountUp, 0, array.get(volCountUp, 0) + (array.get(clo, x) - array.get(clo1, x)))
                    else    
                        array.set(volCountDn, 0, array.get(volCountDn, 0) + (array.get(clo, x) - array.get(clo1, x)))

            volCountExUp = array.new_float(1), array.set(volCountExUp, 0, array.get(volCountUp, 0) + array.get(volCountUp, 1))
            volCountExDn = array.new_float(1), array.set(volCountExDn, 0, array.get(volCountDn, 0) + array.get(volCountDn, 1))  

            array.shift(volCountUp), array.set(volCountUp, 0, array.sum(volCountExUp))
            array.shift(volCountDn), array.set(volCountDn, 0, array.sum(volCountExDn))  

            cache = math.sign(array.sum(volCountExUp) + array.sum(volCountExDn)) == 1 ? 
                                 "+" + str.tostring(array.sum(volCountExUp) + array.sum(volCountExDn), "###,###,###.00") :
                                 str.tostring(array.sum(volCountExUp) + array.sum(volCountExDn), "###,###,###.00")

            if classic == false 
                label.set_text(array.get(lettersBox, 0), cache)   
            else 
                box.set_text(array.get(lettersBoxClassic, 0), cache)


            if array.sum(boxTrack2) > 1
                for i = 1 to array.size(levelsCount) - 1
                    for x = 0 to array.size(clo) - 1
                        if array.get(m3, x) < array.get(levelsCount, i) and array.get(m4, x) > array.get(levelsCount, i - 1)
                            if array.get(clo, x) >= array.get(clo1, x)
                                array.set(volCountUp, i - 1, array.get(volCountUp, i - 1) + (array.get(clo, x) - array.get(clo1, x)))
                                if array.size(lettersBox) > 0 or array.size(lettersBoxClassic) > 0 
                                    cache2 = math.sign(array.get(volCountUp, i - 1) + array.get(volCountDn, i - 1)) == 1 ? 
                                         "+" + str.tostring(array.get(volCountUp, i - 1) + array.get(volCountDn, i - 1), "###,###,###.00") :
                                         str.tostring(array.get(volCountUp, i - 1) + array.get(volCountDn, i - 1), "###,###,###.00")
                                    if classic == false
                                        label.set_text(array.get(lettersBox, i - 1), cache2)
                                    else    
                                        box.set_text(array.get(lettersBoxClassic, i - 1), cache2) 
                            else
                                array.set(volCountDn, i - 1, array.get(volCountDn, i - 1) + (array.get(clo, x) - array.get(clo1, x)))
                                if array.size(lettersBox) > 0 or array.size(lettersBoxClassic) > 0
                                    cache2 = math.sign(array.get(volCountUp, i - 1) + array.get(volCountDn, i - 1)) == 1 ? 
                                         "+" + str.tostring(array.get(volCountUp, i - 1) + array.get(volCountDn, i - 1), "###,###,###.00") :
                                         str.tostring(array.get(volCountUp, i - 1) + array.get(volCountDn, i - 1), "###,###,###.00")
                                    if classic == false  
                                        label.set_text(array.get(lettersBox, i - 1), cache2)
                                    else if classic == true 
                                        box.set_text(array.get(lettersBoxClassic, i - 1), cache2)



    if array.size(boxCo) == 1 and array.size(m2) == array.size(clo)
        for i = 0 to array.size(clo) - 1
            if array.get(clo, i) >= array.get(clo1, i)
                array.set(volCountUp, 0, array.get(volCountUp, 0) + (array.get(clo, i) - array.get(clo1, i)))
            else    
                array.set(volCountDn, 0, array.get(volCountDn, 0) + (array.get(clo, i) - array.get(clo1, i)))
        if array.size(lettersBox) > 0 or array.size(lettersBoxClassic) > 0

            cache = math.sign(array.get(volCountUp, 0) + array.get(volCountDn, 0)) == 1 ? 
             "+" + str.tostring(array.get(volCountUp, 0) + array.get(volCountDn, 0), "###,###,###.00") :
             str.tostring(array.get(volCountUp, 0) + array.get(volCountDn, 0), "###,###,###.00")

            if classic == false 
                label.set_text(array.get(lettersBox, 0), cache)
                colorChange(array.get(lettersBox, 0), array.sum(volCountUp) + array.sum(volCountDn) >= 0 ? color.new(c,outline == true ? 50 : 0) : color.new(c1,outline == true ? 50 : 0)) 
            else 
                box.set_text(array.get(lettersBoxClassic, 0), cache)
                colorChange2(array.get(lettersBoxClassic, 0), array.sum(volCountUp) + array.sum(volCountDn) >= 0 ? color.new(c,90) : color.new(c1,90)) 



    if array.size(boxCo) == 0 
      and array.size(m2) > 0  and array.size(m2) == array.size(clo) and bar_index >= firstBar and array.size(ticks3) > 1
        for i = 1 to array.size(ticks3) - 1
            if array.get(ticks3, i) > low and array.get(ticks3, i - 1) <= low   
                array.push(levelsCount, array.get(ticks3, i - 1))
                break
        if classic == false 
            array.push(lettersBox, label.new(bar_index, array.get(levelsCount, 0), "", textcolor = color.white, style = outline == true ? label.style_text_outline : label.style_none, size = sz))
        else
            calculation = switch calcBy 
                "Ticks" => array.get(levelsCount, 0) + (tickz * syminfo.mintick)
                => array.get(levelsCount, 0) * (1+perc)
            array.push(lettersBoxClassic, box.new(bar_index, low, bar_index + 1,
             high, text=  "", text_color = color.white, text_size = sz, bgcolor = color.new(color.white, 100)))

        array.unshift(volCountUp, 0)
        array.unshift(volCountDn, 0)
        for i = 0 to array.size(clo) - 1
            if array.get(clo, i) >= array.get(clo1, i) 
                array.set(volCountUp, 0, array.get(volCountUp, 0) + (array.get(clo, i) - array.get(clo1, i)))
                
                cache = math.sign(array.get(volCountUp, 0) + array.get(volCountDn, 0)) == 1 ? 
                 "+" + str.tostring(array.get(volCountUp, 0) + array.get(volCountDn, 0), "###,###,###.00") :
                 str.tostring(array.get(volCountUp, 0) + array.get(volCountDn, 0), "###,###,###.00")

                if classic == false 
                    label.set_text(array.get(lettersBox, 0 ), cache)
                else
                    box.set_text(array.get(lettersBoxClassic, 0), cache)

            else    
                array.set(volCountDn, 0, array.get(volCountDn, 0) + (array.get(clo, i) - array.get(clo1, i)))
                
                cache = math.sign(array.get(volCountUp, 0) + array.get(volCountDn, 0)) == 1 ? 
                 "+" + str.tostring(array.get(volCountUp, 0) + array.get(volCountDn, 0), "###,###,###.00") :
                 str.tostring(array.get(volCountUp, 0) + array.get(volCountDn, 0), "###,###,###.00")

                if classic == false 
                    label.set_text(array.get(lettersBox, 0 ), cache)
                    colorChange(array.get(lettersBox, 0), array.sum(volCountUp) + array.sum(volCountDn) >= 0 ? color.new(c,outline == true ? 50 : 0) : color.new(c1,outline == true ? 50 : 0))    
                else 
                    box.set_text(array.get(lettersBoxClassic, 0 ), cache)
                    colorChange2(array.get(lettersBoxClassic, 0), array.sum(volCountUp) + array.sum(volCountDn) >= 0 ? color.new(c,90) : color.new(c1,90))    



    if array.size(lettersBox) > 0 or array.size(lettersBoxClassic) > 0 
        for i = 0 to classic == false ? array.size(lettersBox) - 1 : array.size(lettersBoxClassic) - 1
            if classic == false 
                colorChange(array.get(lettersBox, i) , math.sign(array.get(volCountUp, i) + array.get(volCountDn, i)) == 1 ?
                     color.new(c,outline == true ? 50 : 0) : color.new(c1,outline == true ? 50 : 0))
                if label.get_text(array.get(lettersBox, i)) == ""
                    label.set_color(array.get(lettersBox, i), na)
            else
                colorChange2(array.get(lettersBoxClassic, i) , math.sign(array.get(volCountUp, i) + array.get(volCountDn, i)) == 1 ?
                     color.new(c, 90) : color.new(c1,90))
                if box.get_bottom(array.get(lettersBoxClassic, i)) > high
                    box.set_bgcolor(array.get(lettersBoxClassic, i), na)

        maxUp = 0.0
        for i = 0 to classic == false ? array.size(lettersBox) - 1 : array.size(lettersBoxClassic) - 1
            maxUp :=  
             math.max(maxUp, math.abs(array.get(volCountUp, i) + array.get(volCountDn, i)))
        for i = 0 to classic == false ? array.size(lettersBox) - 1 : array.size(lettersBoxClassic) - 1
            if math.abs(array.get(volCountUp, i) + array.get(volCountDn, i)) == maxUp   
                if classic == false 
                    label.set_color(array.get(lettersBox, i),  c2)
                else
                    box.set_bgcolor(array.get(lettersBoxClassic, i), color.new(c2, 90))
                    box.set_border_color(array.get(lettersBoxClassic, i), c2)
                break   
        for i = 0 to array.size(levelsCount) - 1
            for x = 0 to array.size(ticks3) - 1
                if array.get(levelsCount, i) == array.get(ticks3, x)
                    array.set(volCountUpFin, x, array.get(volCountUpFin, x) + array.get(volCountUp, i))
                    array.set(volCountDnFin, x, array.get(volCountDnFin, x) + array.get(volCountDn, i))
        var label [] finalBox = array.new_label()
        SA = str.tostring(array.sum(volCountUp) + array.sum(volCountDn), array.sum(volCountUp) + array.sum(volCountDn) >= 0 ? 
             "+###,###,###.00" : "###,###,###.00")

        array.push(finalBox, label.new(bar_index, low, yloc = classic == false ? yloc.belowbar : yloc.abovebar, text = classic == false ?  SA + "\nTotal" : 
         "                    " + SA + "\n                    Total" , 
             size = sz, style = outline == true ? label.style_text_outline : label.style_none, textcolor = color.white))
        colorChange(array.get(finalBox, array.size(finalBox) - 1), array.sum(volCountUp) + array.sum(volCountDn) >= 0 ? 
             color.new(c, outline == true ? 50 : 0) : color.new(c1, outline == true ? 50 : 0))





if barstate.islast and array.size(label.all) > 0 and classic == false
 and heatOnly == false or barstate.islast and array.size(volCountUpFin) > 0 
 and heatOnly == true 
    mX  = 0.0
    mX1 = 1e8
    if heatOnly == false 
        for i = 0 to array.size(label.all) - 1
            mX  := math.max(label.get_y(array.get(label.all, i)), mX)
            mX1 := math.min(label.get_y(array.get(label.all, i)), mX1)
    else
        for i = 0 to array.size(heatLevels) - 1
            mX  := math.max(array.get(heatLevels, i), mX)
            mX1 := math.min(array.get(heatLevels, i), mX1)
    var line endLine = na
    var label cs = na
    if na(endLine) and heatOnly == false
        endLine  := line.new(bar_index + 7, mX, bar_index + 7, mX1, color = c, width = 3)
        if Recalculation == "No Recalculation" and hideAll == true 
            cs := label.new(bar_index + 4, mX, text = calcSince, color = color.new(color.white, 100), textcolor = color.white, size = sz)

    var float [] set = array.new_float()
    var line  [] finBox = array.new_line()
    var box   [] finBox2 = array.new_box()

    if heatOnly == false 
        if array.size(finBox) == 0 and array.size(finBox2) == 0 
            for i = 0 to array.size(label.all) - 1
                if array.includes(set, label.get_y(array.get(label.all, i))) == false and label.get_text(array.get(label.all, i)) != ""
                    array.push(set, label.get_y(array.get(label.all, i)))
                    array.push(finBox, line.new(extend ? bar_index - 100 : bar_index + 2, label.get_y(array.get(label.all, i)), bar_index + 3, label.get_y(array.get(label.all, i)),
                     color = na))
                    array.push(finBox2, box.new(bar_index + 3, label.get_y(array.get(label.all, i)) + syminfo.mintick, bar_index + 5, label.get_y(array.get(label.all, i)),
                     bgcolor =na, border_color = color.new(color.white, 100), text = "", text_color = color.white, text_size = sz, text_font_family = fonT))
        else 
            
            
            for i = 0 to array.size(finBox) - 1
                line.set_x1(array.get(finBox, i), extend ? bar_index - 100 : bar_index + 2)
                line.set_x2(array.get(finBox, i), bar_index + 3)
                box.set_left(array.get(finBox2, i), bar_index + 3)
                box.set_right(array.get(finBox2, i), bar_index + 5)
    else 

        if array.size(finBox) == 0 

            for i = 0 to array.size(heatLevels) - 1
                if array.includes(set, array.get(heatLevels, i)) == false
                    array.push(set, array.get(heatLevels, i))
                    array.push(finBox, line.new(startHeat, array.get(heatLevels, i), time + (time - time[3]), array.get(heatLevels, i),
                     color = color.new(color.white, 100 ), xloc = xloc.bar_time))
                    array.push(finBox2, box.new(bar_index + 3, array.get(heatLevels, i) + syminfo.mintick, bar_index + 5, array.get(heatLevels, i),
                     bgcolor =na, border_color = color.new(color.white, 100), text = "", text_color = color.white, text_size = sz, text_font_family = fonT))                    
        else

            for i = 0 to array.size(finBox) - 1
                line.set_x2(array.get(finBox, i), time)
                box.set_left(array.get(finBox2, i), bar_index + 3)
                box.set_right(array.get(finBox2, i), bar_index + 5)

    fX = 0.0
    for i = 0 to array.size(set) - 1
        for x = 0 to array.size(ticks3) - 1
            if array.get(set, i) == array.get(ticks3, x)
                if data == "Volume"
                    if heatOnly == false
                        fX := math.max(array.get(volCountUpFin, x), array.get(volCountDnFin, x), fX)
                        box.set_text(array.get(finBox2, i), "+" + str.tostring(array.get(volCountUpFin, x),format.volume)
                         + " | -" +  str.tostring(array.get(volCountDnFin, x), format.volume))
                else if data == "Vol. Delta"
                    if heatOnly == false
                        fX := math.max(math.abs(array.get(volCountUpFin, x) - array.get(volCountDnFin, x)), fX)
                        box.set_text(array.get(finBox2, i), array.get(volCountUpFin, x) - array.get(volCountDnFin, x) >= 0 ?
                         "+" + str.tostring(array.get(volCountUpFin, x) - array.get(volCountDnFin, x), format.volume) : 
                          str.tostring(array.get(volCountUpFin, x) - array.get(volCountDnFin, x), format.volume))
                else if data == "OI Delta (BINANCE PERP FUTURES ONLY)"
                    if heatOnly == false
                        fX := math.max(math.abs(array.get(volCountUpFin, x) + array.get(volCountDnFin, x)), fX)
                        box.set_text(array.get(finBox2, i), array.get(volCountUpFin, x) + array.get(volCountDnFin, x) >= 0 ?
                         "+" + str.tostring(array.get(volCountUpFin, x) + array.get(volCountDnFin, x), format.volume) : 
                          str.tostring(array.get(volCountUpFin, x) + array.get(volCountDnFin, x), format.volume))
                
                
                if heatOnly == false
                    if data != "OI Delta (BINANCE PERP FUTURES ONLY)"

                        box.set_text_color(array.get(finBox2, i), array.get(volCountUpFin, x) - array.get(volCountDnFin, x) < 0 ? c1 : c)
                        line.set_color(array.get(finBox, i), array.get(volCountUpFin, x) - array.get(volCountDnFin, x) < 0 ? color.new(c1, 85) : color.new(c, 85))
                        line.set_color(array.get(finBox, i), array.get(volCountUpFin, x) - array.get(volCountDnFin, x) < 0 
                         and line.get_y1(array.get(finBox, i)) >= low and line.get_y1(array.get(finBox, i)) <= high ? c1                 :
                         array.get(volCountUpFin, x) - array.get(volCountDnFin, x) >= 0 
                         and line.get_y1(array.get(finBox, i)) >= low and line.get_y1(array.get(finBox, i)) <= high ? c                : 
                         array.get(volCountUpFin, x) - array.get(volCountDnFin, x) >= 0 and line.get_y1(array.get(finBox, i)) > high              or
                         array.get(volCountUpFin, x) - array.get(volCountDnFin, x) >= 0 and line.get_y1(array.get(finBox, i)) < low               ?
                         color.new(c, 85)                                                                                              : 
                         array.get(volCountUpFin, x) - array.get(volCountDnFin, x) < 0 and line.get_y1(array.get(finBox, i)) > high               or
                         array.get(volCountUpFin, x) - array.get(volCountDnFin, x) < 0 and line.get_y1(array.get(finBox, i)) < low                ?
                       color.new(c1, 85)                                                                                                 : 
                         na
                         )

                    else

                        box.set_text_color(array.get(finBox2, i), array.get(volCountUpFin, x) + array.get(volCountDnFin, x) < 0 ? c1 : c)
                        line.set_color(array.get(finBox, i), array.get(volCountUpFin, x) + array.get(volCountDnFin, x) < 0 ? color.new(c1, 85) : color.new(c, 85))
                        line.set_color(array.get(finBox, i), array.get(volCountUpFin, x) + array.get(volCountDnFin, x) < 0 
                         and line.get_y1(array.get(finBox, i)) >= low and line.get_y1(array.get(finBox, i)) <= high ? c1                 :
                         array.get(volCountUpFin, x) + array.get(volCountDnFin, x) >= 0 
                         and line.get_y1(array.get(finBox, i)) >= low and line.get_y1(array.get(finBox, i)) <= high ? c                : 
                         array.get(volCountUpFin, x) + array.get(volCountDnFin, x) >= 0 and line.get_y1(array.get(finBox, i)) > high              or
                         array.get(volCountUpFin, x) + array.get(volCountDnFin, x) >= 0 and line.get_y1(array.get(finBox, i)) < low               ?
                         color.new(c, 85)                                                                                              : 
                         array.get(volCountUpFin, x) + array.get(volCountDnFin, x) < 0 and line.get_y1(array.get(finBox, i)) > high               or
                         array.get(volCountUpFin, x) + array.get(volCountDnFin, x) < 0 and line.get_y1(array.get(finBox, i)) < low                ?
                       color.new(c1, 85)                                                                                                 : 
                         na
                         )

    var line [] connectOr = array.new_line()

    if heat == true and heatOnly == false
        if array.size(finBox) > 0 
            for i = 0 to array.size(finBox) - 1
                array.push(connectOr, line.new(bar_index - 200, line.get_y1(array.get(finBox, i)), bar_index + 7, line.get_y1(array.get(finBox, i)), color = na))
            if array.size(set) > 3
                for i = 2 to array.size(set) - 3
                    for x = 0 to array.size(ticks3) - 1    
                        if array.get(set, i) == array.get(ticks3, x)
                            linefill.new(array.get(connectOr, i - 2), array.get(connectOr, i + 2), color = 
                             data != "OI Delta (BINANCE PERP FUTURES ONLY)" ? array.get(volCountUpFin, x) - array.get(volCountDnFin, x) >= 0 ?
                             color.new(c, 95) : color.new(c1, 95) : array.get(volCountUpFin, x) + array.get(volCountDnFin, x) >= 0 ? 
                             color.new(c, 95) : color.new(c1, 95))

    if heatOnly == true 
     and array.size(finBox) > 0 
      and array.size(set) > 3
        for i = 2 to array.size(set) - 3
            for x = 0 to array.size(ticks3) - 1
                if array.get(set, i) == array.get(ticks3, x)
                    linefill.new(array.get(finBox, i - 2), array.get(finBox, i + 2), color = 
                     data != "OI Delta (BINANCE PERP FUTURES ONLY)" ? array.get(volCountUpFin, x) - array.get(volCountDnFin, x) >= 0 ?
                     color.new(c, 95) : color.new(c1, 95) : array.get(volCountUpFin, x) + array.get(volCountDnFin, x) >= 0 ? 
                     color.new(c, 95) : color.new(c1, 95))
    if array.size(finBox2) > 0
        for i = 0 to array.size(set) - 1
            for x = 0 to array.size(ticks3) - 1
                if array.get(set, i) == array.get(ticks3, x)
                    
                    finSW = switch data 
                    
                        "Volume"     => "+" + str.tostring(array.get(volCountUpFin, x), format.volume) + " | -" + str.tostring(array.get(volCountDnFin, x), format.volume)
                        "Vol. Delta" => str.tostring(array.get(volCountUpFin, x) - array.get(volCountDnFin, x), format.volume)
                        "OI Delta (BINANCE PERP FUTURES ONLY)"   => str.tostring(array.get(volCountUpFin, x) + array.get(volCountDnFin, x), format.volume)
                    
                    color 
                      
                      finCol = na
                    
                    strinG = "OI Delta (BINANCE PERP FUTURES ONLY)"

                    switch 
                    
                        data != strinG and array.get(volCountUpFin, x) - array.get(volCountDnFin, x) >= 0 => finCol := c
                        data != strinG and array.get(volCountUpFin, x) - array.get(volCountDnFin, x) <  0 => finCol := c1
                        data == strinG and array.get(volCountUpFin, x) + array.get(volCountDnFin, x) >= 0 => finCol := c
                        data == strinG and array.get(volCountUpFin, x) - array.get(volCountDnFin, x) >= 0 => finCol := c1


                    box.set_text(array.get(finBox2, i),  finSW)
                    box.set_text_color(array.get(finBox2, i), finCol)



    for i = 0 to array.size(set) - 1
        for x = 0 to array.size(ticks3) - 1
            if heatOnly == false 
                if array.get(set, i) == array.get(ticks3, x)    
                    if data == "Vol. Delta"
                        if math.abs(array.get(volCountUpFin, x) - array.get(volCountDnFin, x)) == fX    
                            line.set_color(array.get(finBox, i), c2)
                            box.set_text_color(array.get(finBox2, i), c2)
                            if eX == true 
                                line.set_x1(array.get(finBox, i), bar_index - 100)
                            break
                    else if data == "Volume"
                        if array.get(volCountUpFin, x) == fX or array.get(volCountDnFin, x) == fX
                            line.set_color(array.get(finBox, i), c2)
                            box.set_text_color(array.get(finBox2, i), c2)
                            if eX == true
                                line.set_x1(array.get(finBox, i), bar_index - 100)
                            break
                    else if data == "OI Delta (BINANCE PERP FUTURES ONLY)"
                        if math.abs(array.get(volCountUpFin, x) + array.get(volCountDnFin, x)) == fX    
                            line.set_color(array.get(finBox, i), c2)
                            box.set_text_color(array.get(finBox2, i), c2)
                            if eX == true 
                                line.set_x1(array.get(finBox, i), bar_index - 100)
                            break

            if hideAll == false 
                line.delete(endLine)
                if heatOnly == false  
                    line.delete(array.get(finBox, i))
                    box.delete(array.get(finBox2, i))

    if heatOnly == true 
        if array.size(label.all) > 0 
            for i = 0 to array.size(label.all) - 1
                label.delete(array.shift(label.all))



if array.size(lettersBox) == 1
    label.set_y(array.get(lettersBox, 0), ohlc4)

if array.size(lettersBoxClassic) == 1
    box.set_bottom(array.get(lettersBoxClassic, 0), low)
    box.set_top(array.get(lettersBoxClassic, 0), high)


if barstate.islast and classic == true and array.size(box.all) > 0
    miN = 1e8
    for i = 0 to array.size(box.all) - 1
        miN := math.min(miN, box.get_left(array.get(box.all, i)))
    for i = 0 to bar_index - miN    
        line.new(bar_index[i], high[i], bar_index[i], low[i], color = color.white)
        line.new(bar_index[i], close[i], bar_index[i], open[i], color = close[i] > open[i] ? color.green : color.red, width = 4)
    if array.size(label.all) > 0
        for i = 0 to array.size(label.all) - 1
            if label.get_x(array.get(label.all, i)) < miN
                label.set_color(array.get(label.all, i), na)
                label.set_textcolor(array.get(label.all, i), na)

Overview

By fetching one-minute intrabar data, it distributes buying and selling activity into price levels defined by percentages or tick sizes. It calculates delta across customizable row divisions, offers periodic recalculation options, and features a heatmap overlay to highlight high-volume zones. Settings allow users to adjust visual display options, calculation parameters, and color styling. Note that open interest delta tracking is designed specifically for Binance perpetual futures.

Details

Published by

etabebe1 on GitHub

Code credit

KioseffTrading, as written in the script's header

Type

Indicator, Pine Script v5

Draws

On the price chart

Category

Volume, Support & resistance

Markets

Crypto

Timeframes

M15-H1, H4 and above

Risk Notes

No repainting, lookahead or stacked entries were found in its code or README. That says nothing about how well it works: test it first.

Settings

The inputs you can change from the gear icon on the chart. Defaults are the author's.

SettingTypeDefaultVariable
DatastringVol. Deltadata
No Recalculation? Or Realculate?stringNo RecalculationRecalculation
If 'Recalculation' is Selected in the Above Setting: Recalculate After How Much Time?stringDsess
Calculate Levels By Tick or Percentages?stringPercentages (Recommended)calcBy
Percentage Distance Between Levels (If Selected)float0.25perc
Ticks (If Selected)float50tickzz
Classic Look ?boolfalseclassic
Divide Bars Into How Many Rows ?int10barDiv
Use Volume Assumption ?boolfalseassume
Last Bar Calculation Only?boolfalselastBar
Show End Lines and Labels ?booltruehideAll
Show Label Color Outline ?booltrueoutline
Show all 21 settings
SettingTypeDefaultVariable
Extend End Lines Left ?boolfalseextend
Extend Highest Delta / Highest Volume Line booltrueeX
Show Heatmap ?booltrueheat
Heat Map OnlyboolfalseheatOnly
textSizestringSmalltextSize
Font TypestringDefaultfnt
General "Up/Buy" Colorcolorcolor.limec
General "Down/Sell" Colorcolorcolor.redc1
General "POC" Colorcolorcolor.rgb(148, 139, 57)c2
Third-party code. ForexR did not write, test or endorse this script, and the summary above was generated automatically from its code and README. Indicators describe the past, and a strategy's backtest can look better than live trading, especially when a script repaints. Check it in the Strategy Tester and on a demo account before you rely on it.

Similar Pine Scripts

This overlay indicator draws a fixed-range volume profile on the price chart, splitting traded activity into up and down volume at each price level. It also plots a sentiment profile, a developing point of control, and value-area high and low around a configur

Indicator v5 VolumeSupport & resistance
Updated 2 months ago · MIT GitHub repository of Volume Profile and Indicator by DGT

MGIC-tracker

by Allen1212
303 stars

The MGIC-tracker is a TradingView indicator that overlays ARK Invest trade records onto stock price charts. It plots buy and sell labels at the exact timestamp of each transaction, showing share volume and ETF weight. Users select a specific ETF type via setti

Indicator v4 Support & resistanceVolume
Updated 2 years ago · None stated GitHub repository of MGIC-tracker
218 stars

Comprehensive Volume Profile is an overlay indicator that calculates and plots volume distribution across specified time ranges such as daily sessions, weekly, monthly, or custom bar lengths. It identifies key structural price levels including the Point of Con

Indicator v6 VolumeSupport & resistance
Updated 3 months ago · None stated GitHub repository of Comprehensive Volume Profile

Moon Dev GEX Arrows

by moondevonyt
92 stars

This overlay indicator plots option strike walls and an optional session VWAP on the price chart for SPY or ES. It spaces major strikes by the selected instrument, draws a set number of strikes on each side, and marks wall-trap and sweep events after a cooldow

Indicator v5 Support & resistanceSessions & time
Updated 8 weeks ago · Custom licence GitHub repository of Moon Dev GEX Arrows

More indicators

Trade Your Charts With a Regulated Broker

Compare brokers that connect to TradingView, with spreads, minimum deposits and leverage side by side.

Compare brokers