Institutional OrderBlock Pressure

OrderBlocks are areas where Banks take a Short or Long position. So they create a movement that they would like to hide from us, but luckily for us they cannot. Take the example of Banks opening Short position for x reason. The Trend is already Bearish. The Price will fall and then make a Reversal
(most often to the price where they opened their positions) and it is at this precise moment that they will again resume a Short position twice as large because for the moment, following this example it is not in their interest that the Price exceeds a certain Price since they are Seller.
As a result they create a solid Resistance (the strongest it is). There are several ways to interpret this logic, we can try to follow the movement of Banks or on the contrary take advantage of the recovery of the course. Note that not having level 2 and access to the order book from TradingView we can only make a rough estimate of the “OrderBlocks” through VPOC.

Institutional OrderBlock Pressure in action on Dow Jones Index.

Screenshot taken from the Settings menu of Institutional OrderBlock Pressure.

Here is the complete list of features present in this indicator :

  • Full Indicator Customization
  • OB Detection Type : Price Action or Volume
  • OrderBlock Lines automatically plotted when an OB is detected until the line is cross.
  • Full OB Range (High/Low) for Bearish/Bullish OB
  • Extend Lines
  • Last Levels Price
  • Use Wick
  • OrderBlock Arrow Labels
  • Price Action Offset (Set to 5 by default)
  • Volume Ratio (Set to 89 by default)
  • Possibility to plot Price or Volume Ratio Labels
  • OrderBooks

This indicator contain Alerts, you can set them by choosing the ‘Any Alerts Function Call‘ to automatically configure them.

Rate this Indicator?

Click on a star to rate it!

Average rating 5 / 5. Vote count: 2

No votes so far! Be the first to rate this Indicator.

5
(2)

Or copy / paste the source code into your pine editor :

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © RickSimpson

//@version=4
study("Institutional OrderBlock Pressure", "IOBP", true, max_bars_back=300, max_labels_count=300)

//═════ CUSTOMIZATION ═════

chartcolor = input(defval="Light",     title="Chart Type ?",       type=input.string, options=['Light','Dark'], group="Chart Customization")
cuscolor   = input(defval=false,       title="Use Custom Colors?", type=input.bool,                             group="Chart Customization")
highcolor  = input(defval=color.red,   title="High Zones Color",   type=input.color,  inline='customcolor',     group="Chart Customization")
lowcolor   = input(defval=color.green, title="Low Zones Color",    type=input.color,  inline='customcolor',     group="Chart Customization")

//Background Color Function

get_black_or_white_color() =>
    black_or_white = color(na)

    if (chartcolor == "Dark")
        black_or_white := color(color.white)
    else
        black_or_white := color(color.black)

    black_or_white

highzonescolor  = color(na)
lowzonescolor   = color(na)
highzonescolor := cuscolor ? highcolor : get_black_or_white_color()
lowzonescolor  := cuscolor ? lowcolor  : get_black_or_white_color()

////////////////////////////
//        OrderBlock      //
////////////////////////////

//Inputs

obtype     = input(defval="Price Action", title="OB Detection Type",           type=input.string,  options=['Price Action','Volume'],   group="OrderBlock Settings",          tooltip="OrderBlocks are areas where Banks take a Short or Long position. So they create a movement that they would like to hide from us, but luckily for us they cannot. Take the example of Banks opening Short position for x reason. The Trend is already Bearish. The Price will fall and then make a Reversal (most often to the price where they opened their positions) and it is at this precise moment that they will again resume a Short position twice as large because for the moment, following this example it is not in their interest that the Price exceeds a certain Price since they are Seller. As a result they create a solid Resistance (the strongest it is). There are several ways to interpret this logic, we can try to follow the movement of Banks or on the contrary take advantage of the recovery of the course.")
obline     = input(defval=true,           title="Display OB Lines",            type=input.bool,                                         group="OrderBlock Settings",          tooltip="Displays White Line (by default) according to detected OrderBlock Candle. These lines can indicate a potential recovery area.")
fullzones  = input(defval=false,          title="Full OB Range?",              type=input.bool,                                         group="OrderBlock Settings")
linestyle  = input(defval="Solid",        title="Style",                       type=input.string,  options=['Solid','Dotted','Dashed'], group="OrderBlock Settings",          inline='lines')
linessize  = input(defval=2,              title="Size",                        type=input.integer, minval=1, maxval=2,                  group="OrderBlock Settings",          inline='lines')
maxlines   = input(defval=10,             title="Maximum Lines Displayed",     type=input.integer, minval=1, maxval=100,                group="OrderBlock Settings")
extend     = input(defval=false,          title="Extend Lines?",               type=input.bool,                                         group="OrderBlock Settings",          tooltip="Extend all Lines with more transparency on them. This can be usefull to see area already recovered while keeping in mind that they can still have an impact on the current Trend even if they are less important.")
transp     = input(defval=50,             title="Extended Lines Transparency", type=input.integer, minval=1, maxval=100,                group="OrderBlock Settings")
showprice  = input(defval=true,           title="Show Last Levels Price?",     type=input.bool,                                         group="OrderBlock Settings")
usewick    = input(defval=true,           title="Use Wick?",                   type=input.bool,                                         group="OrderBlock Settings")
showlabels = input(defval=true,           title="Show OrderBlock Labels?",     type=input.bool,                                         group="OrderBlock Settings",          tooltip="Will display a «Red Arrow» for Bearish OrderBlock and a «Green Arrow» for Bullish OrderBlock. Note that you should not in any way interpret these «Arrows» as Signals to Buy or Sell.")
delay      = input(defval=5,              title="Price Action Offset",         type=input.integer, minval=1,                            group="Advanced OrderBlock Settings", tooltip="Number of Subsequent Candles to count to search for the potential OrderBlock. (Price Action must be selected in the «OB Detection Type» scrolling menu)")
vr         = input(defval=89,             title="Volume Ratio",                type=input.integer, minval=1,                            group="Advanced OrderBlock Settings", tooltip="Highest Volume Ratio to search for the potential OrderBlock. (Volume must be selected in the «OB Detection Type» scrolling menu)")
showtost   = input(defval=false,          title="Show Price/Ratio Labels?",    type=input.bool,                                         group="Advanced OrderBlock Settings", tooltip="Will display the Price or the Volume Ratio as Labels on detected OrderBlock Candles according to the selected option in the «OB Detection Type» scrolling menu (Price Action or Volume).")

//Color Call Function

f_obcallc(obcolor, _call) =>
    c1 = color.r(obcolor)
    c2 = color.g(obcolor)
    c3 = color.b(obcolor)
    color.rgb(c1, c2, c3, _call)

//Round Function

round_f(x) => round(x / syminfo.mintick) * syminfo.mintick

//Constant Price Variables

int offset = delay + 1
close_     = obtype == 'Price Action' ? close[offset]     : obtype == 'Volume' ? close     : na
low_       = obtype == 'Price Action' ? low[offset]       : obtype == 'Volume' ? low       : na
high_      = obtype == 'Price Action' ? high[offset]      : obtype == 'Volume' ? high      : na
open_      = obtype == 'Price Action' ? open[offset]      : obtype == 'Volume' ? open      : na
bar_index_ = obtype == 'Price Action' ? bar_index[offset] : obtype == 'Volume' ? bar_index : na

//═════ Price Action ═════ - Original Script : ('Order Block Finder (Experimental)') By Wugamlo => https://tradingview.com/script/R8g2YHdg-Order-Block-Finder-Experimental/

//Constant Price Action Variables

int bearcandle = 0
int bullcandle = 0
int po         = obtype == "Price Action" ? -offset : obtype == "Volume" ? 0 : na

//Bearish/Bullish Candle Detection

for i = 1 to delay
    bullcandle := bullcandle + (close[i] > open[i] ? 1 : 0)
for i = 1 to delay
    bearcandle := bearcandle + (close[i] < open[i] ? 1 : 0)

//Price Action Calculation

abs       = ((abs(close[offset] - close[1])) / close[offset]) * 100
pabeardir = close[offset] > open[offset]
pabulldir = close[offset] < open[offset]

//Conditions

bearpa = pabeardir and (bearcandle == (delay)) and abs
bullpa = pabulldir and (bullcandle == (delay)) and abs

//Converting Boolean Conditions to Float

var float bearpaprice = na
if bearpa
    bearpaprice := close_
var float bullpaprice = na
if bullpa
    bullpaprice := close_

//Price Labels Conditions

if obtype == "Price Action" and showtost
    l = change(bearpaprice) ? label.new(bar_index_, bearpaprice[1]+0.01, tostring(round_f(bearpaprice)), color=color.new(color.red, 100), textcolor=color.red, style=label.style_labeldown, yloc=yloc.abovebar, size=size.small) : change(bullpaprice) ? label.new(bar_index_, bullpaprice[1]-0.01, tostring(round_f(bullpaprice)), color=color.new(color.green, 100), textcolor=color.green, style=label.style_labelup, yloc=yloc.belowbar, size=size.small) : na

//═════ Volume ═════
 
//Volume Calculation

hv         = highest(volume, vr)
vabs       = volume * 100 / hv * 4 / 5
smoothing  = ema(vabs, 21)
equal      = vabs - smoothing
cz         = highest(equal, vr) * 0.618
cum        = equal > 0 and equal >= cz
volbeardir = close < open
volbulldir = close > open

//Conditions

bearvol = volbeardir and cum ? -1 : 0
bullvol = volbulldir and cum ?  1 : 0

//Price Labels Conditions

if obtype == "Volume" and showtost
    l = crossunder(bearvol, 0) ? label.new(bar_index, bearvol[1]+0.01, tostring(round(vabs)), color=color.new(color.red, 100), textcolor=color.red, style=label.style_labeldown, yloc=yloc.abovebar, size=size.small) : crossover(bullvol, 0) ? label.new(bar_index, bullvol[1]-0.01, tostring(round(vabs)), color=color.new(color.green, 100), textcolor=color.green, style=label.style_labelup, yloc=yloc.belowbar, size=size.small) : na

//OB Type Conditions

bearob = obtype == "Price Action" ? bearpa : obtype == "Volume" ? bearvol == -1 : na
bullob = obtype == "Price Action" ? bullpa : obtype == "Volume" ? bullvol ==  1 : na

//Conditions Call For Lines Drawings

pivothigh = bearob
pivotlow  = bullob

//Bar Color Setup

obc = pivothigh ? color.new(highzonescolor, 0) : pivotlow ? color.new(lowzonescolor, 0) : na

//Lines Variables

var int     numberofline         = maxlines
var float   bearcandlehigh       = na
var float   bearcandlelow        = na
var float   bullcandlehigh       = na
var float   bullcandlelow        = na
var line[]  bearcandlehighline   = array.new_line(0, na)
var line[]  bearcandlelowline    = array.new_line(0, na)
var line[]  bullcandlehighline   = array.new_line(0, na)
var line[]  bullcandlelowline    = array.new_line(0, na)
var line    bearcandlehigharea   = na
var line    bearcandlelowarea    = na
var line    bullcandlehigharea   = na
var line    bullcandlelowarea    = na
var bool[]  pivhighareaok        = array.new_bool(0, false)
var bool[]  pivlowareaok         = array.new_bool(0, false)
var bool    pivhighok            = false
var bool    pivlowok             = false
var bool    pivtrue              = true
var color   callpivhighc         = highzonescolor
var color   callpivlowc          = lowzonescolor
var label[] fpivhigharray        = array.new_label(0, na)
var label[] fpivlowarray         = array.new_label(0, na)
var label   fbearcandlehigharray = na
var label   fbullcandlelowarray  = na

//Box Variables

var box[] bearboxarray       = array.new_box()
var box[] bullboxarray       = array.new_box()
var color bearboxcolor       = color.new(callpivhighc, transp)
var color bullboxcolor       = color.new(callpivlowc,  transp)
var color bearborderboxcolor = color.new(callpivhighc, transp)
var color bullborderboxcolor = color.new(callpivlowc,  transp)

//tine Styles Function

f_linestyle(_style) =>
    _style == "Solid" ? line.style_solid : _style == "Dotted" ? line.style_dotted : line.style_dashed

//Bearish OB Lines Calculation

if pivothigh and obline
    bearcandlehigh       := obtype == 'Price Action' ? usewick ? high_ : close_ : obtype == "Volume" ? usewick ? high_ : open_ : na
    bearcandlelow        := close_ < open_ ? close_ : open_
    bearcandlelowarea    := fullzones ? line.new(bar_index_, bearcandlelow,  bar_index, bearcandlelow,  width=linessize) : na
    bearcandlehigharea   := pivtrue   ? line.new(bar_index_, bearcandlehigh, bar_index, bearcandlehigh, width=linessize) : line.new(bar_index_, (bearcandlehigh + bearcandlelow) / 2, bar_index, (bearcandlehigh + bearcandlelow) / 2, width=linessize)
    fbearcandlehigharray := showprice ? label.new(bar_index, pivtrue ? bearcandlehigh : (bearcandlehigh + bearcandlelow) / 2, text=tostring(bar_index - bar_index_), textcolor=callpivhighc, style=label.style_none) : na
    bearbox               = box.new(bar_index_, extend ? bearcandlehigh : na, bar_index, extend ? bearcandlehigh : na, bgcolor=bearboxcolor, border_style=line.style_dotted, border_color=bearborderboxcolor)
    if array.size(bearcandlehighline) > numberofline
        line.delete(array.shift(bearcandlehighline))
        line.delete(array.shift(bearcandlelowline))
        array.shift(pivhighareaok)
        label.delete(array.shift(fpivhigharray))
        box.delete(array.shift(bearboxarray))
    array.push(bearcandlehighline, bearcandlehigharea)
    array.push(bearcandlelowline,  bearcandlelowarea)
    array.push(pivhighareaok, false)
    array.push(fpivhigharray, fbearcandlehigharray)
    array.push(bearboxarray,  bearbox)
if array.size(bearcandlelowline) > 0
    for i = 0 to array.size(bearcandlelowline) -1
        line  highlinedelete = array.get(bearcandlehighline, i)
        line  lowlinedelete  = array.get(bearcandlelowline,  i)
        label flinearray     = array.get(fpivhigharray,      i)
        bool  linearrayok    = array.get(pivhighareaok,      i)
        boxextend            = array.get(bearboxarray,       i)
        line.set_style(highlinedelete, f_linestyle(linestyle))
        line.set_style(lowlinedelete,  f_linestyle(linestyle))
        line.set_color(highlinedelete,  color.from_gradient(i, 1, numberofline, f_obcallc(callpivhighc, 00), f_obcallc(callpivhighc, 00)))
        line.set_color(lowlinedelete,   color.from_gradient(i, 1, numberofline, f_obcallc(callpivhighc, 00), f_obcallc(callpivhighc, 00)))
        label.set_textcolor(flinearray, color.from_gradient(i, 1, numberofline, f_obcallc(callpivhighc, 00), callpivhighc))
        label.set_text(flinearray, tostring(round_f(line.get_y1(highlinedelete))))
        label.set_x(flinearray, bar_index)
        box.set_right(array.get(bearboxarray, i), bar_index)
        crossbear   = obtype == "Price Action" ? usewick ? high > line.get_y1(highlinedelete) : close > line.get_y1(highlinedelete) : obtype == "Volume" ? usewick ? high > line.get_y1(highlinedelete) : close > line.get_y1(highlinedelete) : na
        oblinecross = crossbear
        if oblinecross and not linearrayok
            array.set(pivhighareaok, i, true)
            label.delete(flinearray)
        else if not linearrayok
            line.set_x2(highlinedelete, bar_index)
            array.set(bearcandlehighline, i, highlinedelete)
            line.set_x2(lowlinedelete,  bar_index)
            array.set(bearcandlelowline,  i, lowlinedelete)

//Bullish OB Lines Calculation

if pivotlow and obline
    bullcandlelow       := obtype == 'Price Action' ? usewick ? low_ : close_ : obtype == "Volume" ? usewick ? low_ : open_ : na
    bullcandlehigh      := close_ < open_ ? open_ : close_
    bullcandlehigharea  := fullzones ? line.new(bar_index_, bullcandlehigh, bar_index, bullcandlehigh, width=linessize) : na
    bullcandlelowarea   := pivtrue   ? line.new(bar_index_, bullcandlelow,  bar_index, bullcandlelow,  width=linessize) : line.new(bar_index_, (bullcandlehigh + bullcandlelow) / 2, bar_index, (bullcandlehigh + bullcandlelow) / 2, width=linessize)
    fbullcandlelowarray := showprice ? label.new(bar_index, pivtrue ? bullcandlelow : (bullcandlehigh + bullcandlelow) / 2 , text=tostring(bar_index - bar_index_), textcolor=callpivlowc, style=label.style_none) : na
    bullbox              = box.new(bar_index_, extend ? bullcandlelow : na, bar_index, extend ? bullcandlelow : na, bgcolor=bullboxcolor, border_style=line.style_dotted, border_color=bullborderboxcolor)
    if array.size(bullcandlehighline) > numberofline
        line.delete(array.shift(bullcandlehighline))
        line.delete(array.shift(bullcandlelowline))
        array.shift(pivlowareaok)
        label.delete(array.shift(fpivlowarray))
        box.delete(array.shift(bullboxarray))
    array.push(bullcandlehighline, bullcandlehigharea)
    array.push(bullcandlelowline,  bullcandlelowarea)
    array.push(pivlowareaok, false)
    array.push(fpivlowarray, fbullcandlelowarray)
    array.push(bullboxarray, bullbox)
if array.size(bullcandlelowline) > 0
    for i = 0 to array.size(bullcandlelowline) -1
        line  highlinedelete = array.get(bullcandlehighline, i)
        line  lowlinedelete  = array.get(bullcandlelowline,  i)
        label flinearray     = array.get(fpivlowarray,       i)
        bool  linearrayok    = array.get(pivlowareaok,       i)
        boxextend            = array.get(bullboxarray,       i)
        line.set_style(highlinedelete, f_linestyle(linestyle))
        line.set_style(lowlinedelete,  f_linestyle(linestyle))
        line.set_color(highlinedelete,  color.from_gradient(i, 1, numberofline, f_obcallc(callpivlowc, 00), f_obcallc(callpivlowc, 00)))
        line.set_color(lowlinedelete,   color.from_gradient(i, 1, numberofline, f_obcallc(callpivlowc, 00), f_obcallc(callpivlowc, 00)))
        label.set_textcolor(flinearray, color.from_gradient(i, 1, numberofline, f_obcallc(callpivlowc, 00), callpivlowc))
        label.set_text(flinearray, tostring(round_f(line.get_y1(lowlinedelete))))
        label.set_x(flinearray, bar_index)
        box.set_right(array.get(bullboxarray, i), bar_index)
        crossbull   = obtype == "Price Action" ? usewick ? low < line.get_y1(lowlinedelete) : close < line.get_y1(lowlinedelete) : obtype == "Volume" ? usewick ? low < line.get_y1(lowlinedelete) : close < line.get_y1(lowlinedelete) : na
        oblinecross = crossbull
        if oblinecross and not linearrayok
            array.set(pivlowareaok, i, true)
            label.delete(flinearray)
        else if not linearrayok
            line.set_x2(highlinedelete, bar_index)
            array.set(bullcandlehighline, i, highlinedelete)
            line.set_x2(lowlinedelete,  bar_index)
            array.set(bullcandlelowline,  i, lowlinedelete)

//Plotting

plotshape(showlabels ? pivothigh : na, title="Bearish OrderBlock", style=shape.triangledown, location=location.abovebar, color=color.new(color.red,   0), size=size.tiny, offset=po)
plotshape(showlabels ? pivotlow  : na, title="Bullish OrderBlock", style=shape.triangleup,   location=location.belowbar, color=color.new(color.green, 0), size=size.tiny, offset=po)
barcolor(obc, offset=po)

//═════ OrderBooks ═════ - Original Script : ('Tape') By [LucF] => https://www.tradingview.com/script/8mVFTxPg-Tape-LucF/

//Constants

var string GP1               = "Tape"
var string ON                = "On"
var string OFF               = "Off"
var string TOP               = "Top"
var string BOT               = "Bottom"
var string CL0               = "None"
var string CL1               = "Text"
var string CL2               = "Background"
var string TD1               = "Longs"
var string TD2               = "Shorts"
var string TD3               = "Longs and Shorts"
bool       i_tapeTopToBottom = TOP == "Top"
bool       i_tapeTime        = ON  == "On"
var color  C_TAPE_BULL       = color.new(color.green,  00)
var color  C_TAPE_BEAR       = color.new(color.red,    00)
var color  C_TAPE_NEUTRAL    = color.new(color.gray,   00)
var color  C_TAPE_DIV        = color.new(color.orange, 00)
var color  C_TAPE_BULL_BG    = color.new(color.green,  90)
var color  C_TAPE_BEAR_BG    = color.new(color.red,    90)
var color  C_TAPE_NEUTRAL_BG = color.new(color.gray,   90)
var color  C_TAPE_DIV_BG     = color.new(color.orange, 90)

//Inputs

orderbooks       = input(defval=false,   title="Display OrderBooks?",     type=input.bool,                                                             group="OrderBooks", tooltip="Displays the Time, Price and Volume of each update of the Chart Feed. It also calculates Volume Delta for the Bar. As it calculates from realtime information, it will not display information on historical Bars. These updates do not necessarily correspond to Ticks from the originating Broker/Exchange's matching engine. Multiple Broker/Exchange Ticks are often aggregated in one Chart update.")
i_timeOffset     = input(defval=0,       title="Timezone",                type=input.float,   minval=-12.0, maxval=14.0, step=0.5,                     group="OrderBooks") * 1000 * 60 * 60
i_tapeVolumePrec = input(defval=8,       title="Volume Precision",        type=input.integer, minval=0, maxval=16,                                     group="OrderBooks")
i_tapeLinesMax   = input(defval=25,      title="Maximum Lines Displayed", type=input.integer, minval=0, maxval=25,                                     group="OrderBooks")
i_tapeTextSize   = input(defval="small", title="Text Size",               type=input.string,  options=['tiny','small','normal','large','huge','auto'], group="OrderBooks")

//Locked Inputs

float   i_ignoreVol       = 0
string  i_tapeColor       = CL1
color   i_c_tapeBull      = C_TAPE_BULL
color   i_c_tapeBear      = C_TAPE_BEAR
color   i_c_tapeNeutral   = C_TAPE_NEUTRAL
color   i_c_tapeDiv       = C_TAPE_DIV
color   i_c_tapeBullBg    = C_TAPE_BULL_BG
color   i_c_tapeBearBg    = C_TAPE_BEAR_BG
color   i_c_tapeNeutralBg = C_TAPE_NEUTRAL_BG
color   i_c_tapeDivBg     = C_TAPE_DIV_BG
float   i_marker2Val      = 1000000.
float   i_marker3Val      = 1000000.
string  i_markerDir       = TD3
var bool doLongs          = (i_markerDir == TD1 or i_markerDir == TD3)
var bool doShorts         = (i_markerDir == TD2 or i_markerDir == TD3)

//Functions

f_tickFormat() =>
    string _s = tostring(syminfo.mintick)
    _s := str.replace_all(_s, "25", "00")
    _s := str.replace_all(_s, "5",  "0")
    _s := str.replace_all(_s, "1",  "0")

f_stringOf(_count, _string) =>
    string _return = array.join(array.new_string(_count, _string))

f_addTextIf(_cond, _msg, _text) =>
    string _return = _cond ? _msg + (_msg != "" ? ", " : "") + _text : _msg

f_roundedToTickOC() =>
    float _op = round(open  / syminfo.mintick) * syminfo.mintick
    float _cl = round(close / syminfo.mintick) * syminfo.mintick
    [_op, _cl]

f_dvUpDn(_open, _close) =>
    varip bool _dvUp = false
    varip bool _dvDn = false
    varip float _prevClose = _open
    if barstate.isrealtime
        bool _flat = _close == _prevClose
        _dvUp := _flat ? _dvUp : _close > _prevClose
        _dvDn := _flat ? _dvDn : _close < _prevClose
    else
        bool _flat = _close == _open
        _dvUp := not _flat ? _close > _open : _close == _prevClose ? _dvUp : _close > _prevClose
        _dvDn := not _dvUp
    _prevClose := _close
    [_dvUp, _dvDn]

//Calculation

[op, cl]                         = f_roundedToTickOC()
[updUp, updDn]                   = f_dvUpDn(op, cl)
varip string[] column0           = array.new_string()
varip string[] column1           = array.new_string()
varip string[] column2           = array.new_string()
varip bool[]   directions        = array.new_bool()
varip float lastPrice            = na
varip float lastVolume           = 0.
varip float deltaVolume          = 0.
varip int   linesInTape          = 0
float       newVolume            = 0.
var string TICK_FORMAT           = f_tickFormat()
var string TAPE_VOLUME_PRECISION = "0" + (i_tapeVolumePrec == 0 ? "" : ".") + f_stringOf(i_tapeVolumePrec, "0")
var string COLUMN0_HEADER        = "TIME"
var string COLUMN1_HEADER        = "PRICE"
var string COLUMN2_HEADER        = "VOLUME"

//Volume Delta Variables

bool dvDiv      = na
bool barDvUp    = na
bool barDvDn    = na
bool barDvDiv   = na
bool marker1Up  = na
bool marker1Dn  = na
bool marker2Up  = na
bool marker2Dn  = na
bool marker3Up  = na
bool marker3Dn  = na

//Plotting

if barstate.isrealtime
    table _tape = table.new("middle" + "_" + "right", 3, i_tapeLinesMax + 3)
    if barstate.isnew or na(lastPrice)
        lastVolume    := 0.
        deltaVolume   := 0.
    float _updDirection = updUp ? 1 : updDn ? -1 : 0
    newVolume   := nz(volume) - lastVolume
    deltaVolume := deltaVolume +  (newVolume * _updDirection)
    bool _noPriceChange = cl == lastPrice
    if i_tapeLinesMax > 0 and orderbooks
        if newVolume >= i_ignoreVol
            string _column0NewLine = str.format("{0,time,HH:mm:ss}", timenow + i_timeOffset)
            string _column1NewLine = tostring(cl, TICK_FORMAT) + (_noPriceChange ? "" : updUp ? "+" : updDn ? "-" : "")
            string _column2NewLine = (barstate.isnew ? "↻ " : "") + (marker3Up ? "▲" : marker3Dn ? "▼" : "") + tostring(newVolume, TAPE_VOLUME_PRECISION)
            if i_tapeTopToBottom
                array.unshift(column0, _column0NewLine)
                array.unshift(column1, _column1NewLine)
                array.unshift(column2, _column2NewLine)
                array.unshift(directions, updUp)
                linesInTape += 1
                if linesInTape > i_tapeLinesMax
                    array.pop(column0)
                    array.pop(column1)
                    array.pop(column2)
                    array.pop(directions)
                    linesInTape -= 1
            else
                array.push(column0, _column0NewLine)
                array.push(column1, _column1NewLine)
                array.push(column2, _column2NewLine)
                array.push(directions, updUp)
                linesInTape += 1
                if linesInTape > i_tapeLinesMax
                    array.shift(column0)
                    array.shift(column1)
                    array.shift(column2)
                    array.shift(directions)
                    linesInTape -= 1
        if i_tapeTime
            table.cell(_tape, 0, 0, COLUMN0_HEADER, text_color=i_c_tapeNeutral, text_size=i_tapeTextSize)
        table.cell(_tape, 1, 0, COLUMN1_HEADER,     text_color=i_c_tapeNeutral, text_size=i_tapeTextSize)
        table.cell(_tape, 2, 0, COLUMN2_HEADER,     text_color=i_c_tapeNeutral, text_size=i_tapeTextSize)
        color _c_text = na
        color _c_bg   = na
        if array.size(column0) > 0
            for _i = 0 to linesInTape - 1
                bool _dirUp = array.get(directions, _i)
                _c_bg   := i_tapeColor == CL2 ? _dirUp ? i_c_tapeBullBg : i_c_tapeBearBg : na
                _c_text := i_tapeColor == CL1 ? _dirUp ? i_c_tapeBull   : i_c_tapeBear   : i_c_tapeNeutral
                if i_tapeTime
                    table.cell(_tape, 0, _i + 1, array.get(column0, _i), bgcolor=_c_bg, text_color=i_c_tapeNeutral, text_size=i_tapeTextSize)
                table.cell(_tape, 1, _i + 1, array.get(column1, _i), bgcolor=_c_bg, text_color=_c_text, text_size=i_tapeTextSize, text_halign=text.align_left)
                table.cell(_tape, 2, _i + 1, array.get(column2, _i), bgcolor=_c_bg, text_color=_c_text, text_size=i_tapeTextSize, text_halign=text.align_right)
        float  _priceDirection = sign(cl - op)
        string _column0Footer  = str.format("{0,time,HH:mm:ss}", timeframe.isintraday ? timenow - time : 0)
        string _column1Footer  = tostring(abs(cl - op), TICK_FORMAT) + (na(lastPrice) ? "" : _priceDirection > 0 ? "+" : _priceDirection < 0 ? "-" : "")
        string _column2Footer  = tostring(deltaVolume, TAPE_VOLUME_PRECISION)
        table.cell(_tape, 1, linesInTape + 1, " ", text_color=i_c_tapeNeutral, text_size=i_tapeTextSize, text_halign=text.align_left)
        if i_tapeTime
            _c_bg   := i_tapeColor == CL2 and _priceDirection != sign(deltaVolume) ? i_c_tapeDivBg : na
            _c_text := i_tapeColor == CL1 and _priceDirection != sign(deltaVolume) ? i_c_tapeDiv   : i_c_tapeNeutral
            table.cell(_tape, 0, linesInTape + 2, _column0Footer, bgcolor=_c_bg, text_color=_c_text, text_size=i_tapeTextSize)
        _c_bg   := i_tapeColor == CL2 ? _priceDirection > 0 ? i_c_tapeBullBg : _priceDirection < 0 ? i_c_tapeBearBg : i_c_tapeNeutralBg : na
        _c_text := i_tapeColor == CL1 ? _priceDirection > 0 ? i_c_tapeBull   : _priceDirection < 0 ? i_c_tapeBear   : i_c_tapeNeutral   : i_c_tapeNeutral
        table.cell(_tape, 1, linesInTape + 2, _column1Footer, bgcolor=_c_bg, text_color=_c_text, text_size=i_tapeTextSize, text_halign=text.align_left)
        _c_bg   := i_tapeColor == CL2 ? deltaVolume > 0 ? i_c_tapeBullBg : deltaVolume < 0 ? i_c_tapeBearBg : i_c_tapeNeutral : na
        _c_text := i_tapeColor == CL1 ? deltaVolume > 0 ? i_c_tapeBull   : deltaVolume < 0 ? i_c_tapeBear   : i_c_tapeNeutral : i_c_tapeNeutral
        table.cell(_tape, 2, linesInTape + 2, _column2Footer, bgcolor=_c_bg, text_color=_c_text, text_size=i_tapeTextSize, text_halign=text.align_right)
    lastPrice     := cl
    lastVolume    := nz(volume)
plotchar(barstate.isrealtime ? deltaVolume : na, "Volume Delta", "", location.top, barDvDiv ? i_c_tapeDiv : barDvUp ? i_c_tapeBull : i_c_tapeBear)

//Alerts

if bearob
    alert("Bearish OB Detected! At " + tostring(close), alert.freq_once_per_bar)
if bullob
    alert("Bullish OB Detected! At " + tostring(close), alert.freq_once_per_bar)

The content covered on this website is NOT investment advice and I am not a financial advisor.