You are on page 1of 10

//@version=5

indicator('OB test', overlay=true)


tip1 = 'Indicator to help identify instituational Order Blocks (OB). OBs often signal the beginning
of a strong move. There is a high probability that OB price levels will be revisited in the future
and are interesting levels to place limit orders. Bullish Order block is the last down candle before
a sequence of up candles. Bearish Order Block is the last up candle before a sequence of down
candles.'
tip2 = '!Experimental!\nFind Order Blocks from different timeframes. Channels prices are
accurate, but arrow position is not. Most useful when selecting a timeframe higher than the
chart.'
tip3 = 'Required number of subsequent candles in the same direction to identify Order Block'
tip4 = 'Measured from from potential OB close to close of first candle in sequence'
dummy = input.bool(true, 'Hover over ( ! ) for documentation', tooltip=tip1)
colors = input.string('LIGHT', 'Color Scheme', options=['DARK', 'LIGHT'])
//res = input("","Order Block Timeframe",input.resolution,tooltip=tip2)
periods = input.int(0, 'Relevant Periods to identify OB', tooltip=tip3) // Required number of
subsequent candles in the same direction to identify Order Block
threshold = input.float(0.0, 'Min. Percent move for valid OB', step=0.1, tooltip=tip4) // Required
minimum % move (from potential OB close to last subsequent candle to identify Order Block)
bull_channels = input(2, 'Number of Bullish Channels to show') // Num of channels
bear_channels = input(2, 'Number of Bearish Channels to show') // Num of channels

//Data Curation
res = ''
[copen, chigh, clow, cclose] = request.security(syminfo.tickerid, res, [open, high, low, close],
barmerge.gaps_on, barmerge.lookahead_off)

ob_period = periods + 1 // Identify location of relevant Order Block candle


absmove = math.abs(cclose[ob_period] - cclose[1]) / cclose[ob_period] * 100 // Calculate
absolute percent move from potential OB to last candle of subsequent candles
relmove = absmove >= threshold // Identify "Relevant move" by comparing the absolute move
to the threshold

// Color Scheme
bullcolor = colors == 'DARK' ? color.rgb (255,255,255,50) : color.rgb(0,255,0,50)
bearcolor = colors == 'DARK' ? color.rgb(0,0,255,50) : color.rgb(255,0,0,50)
bullcolor2 = colors == 'DARK' ? color.white : color.green
bearcolor2 = colors == 'DARK' ? color.blue : color.red

// Bullish Order Block Identification


bullishOB = cclose[ob_period] < copen[ob_period] // Determine potential Bullish OB candle (red
candle)

int upcandles = 0
for i = 1 to periods by 1
upcandles += (cclose[i] > copen[i] ? 1 : 0) // Determine color of subsequent candles (must all
be green to identify a valid Bearish OB)
upcandles

OB_bull = bullishOB and upcandles == periods and relmove // Identification logic (red OB
candle & subsequent green candles)
OB_bull_chigh = OB_bull ? chigh[ob_period] : na // Determine OB upper limit (Open or High
depending on input)
OB_bull_clow = OB_bull ? clow[ob_period] : na // Determine OB clower limit (Low)
OB_bull_avg = (OB_bull_chigh + OB_bull_clow) / 2 // Determine OB middle line

// Bearish Order Block Identification


bearishOB = cclose[ob_period] > copen[ob_period] // Determine potential Bearish OB candle
(green candle)

int downcandles = 0
for i = 1 to periods by 1
downcandles += (cclose[i] < copen[i] ? 1 : 0) // Determine color of subsequent candles (must
all be red to identify a valid Bearish OB)
downcandles

OB_bear = bearishOB and downcandles == periods and relmove // Identification logic (green
OB candle & subsequent green candles)
OB_bear_chigh = OB_bear ? chigh[ob_period] : na // Determine OB upper limit (High)
OB_bear_clow = OB_bear ? clow[ob_period] : na // Determine OB clower limit (Open or Low
depending on input)
OB_bear_avg = (OB_bear_clow + OB_bear_chigh) / 2 // Determine OB middle line

// Plotting
plotshape(OB_bull, title='Bullish OB', style=shape.triangleup, color=bullcolor, textcolor=bullcolor,
size=size.tiny, location=location.belowbar, offset=-ob_period, text='Bull') // Bullish OB Indicator
bull1 = plot(OB_bull_chigh, title='Bullish OB High', style=plot.style_linebr, color=bullcolor,
offset=-ob_period, linewidth=2) // Bullish OB Upper Limit
bull2 = plot(OB_bull_clow, title='Bullish OB Low', style=plot.style_linebr, color=bullcolor,
offset=-ob_period, linewidth=2) // Bullish OB Lower Limit
fill(bull1, bull2, color=bullcolor, title='Bullish OB fill') // Fill Bullish OB
plotshape(OB_bull_avg, title='Bullish OB Average', style=shape.cross, color=bullcolor,
size=size.small, location=location.absolute, offset=-ob_period) // Bullish OB Average

plotshape(OB_bear, title='Bearish OB', style=shape.triangledown, color=bearcolor,


textcolor=bearcolor, size=size.tiny, location=location.abovebar, offset=-ob_period, text='Bear') //
Bearish OB Indicator
bear1 = plot(OB_bear_clow, title='Bearish OB Low', style=plot.style_linebr, color=bearcolor,
offset=-ob_period, linewidth=2) // Bearish OB Lower Limit
bear2 = plot(OB_bear_chigh, title='Bearish OB High', style=plot.style_linebr, color=bearcolor,
offset=-ob_period, linewidth=2) // Bearish OB Upper Limit
fill(bear1, bear2, color=bearcolor, title='Bearish OB fill') // Fill Bearish OB
plotshape(OB_bear_avg, title='Bearish OB Average', style=shape.cross, color=bearcolor,
size=size.small, location=location.absolute, offset=-ob_period) // Bullish OB Average

var LineBullAvg = array.new_line()


var LineBullHigh = array.new_line()
var LineBullLow = array.new_line()
var LineBearAvg = array.new_line()
var LineBearHigh = array.new_line()
var LineBearLow = array.new_line()

sync = time_close(res)

if OB_bull and bull_channels > 0


if array.size(LineBullAvg) == bull_channels
line.delete(array.get(LineBullAvg, 0))
array.remove(LineBullAvg, 0)
line.delete(array.get(LineBullHigh, 0))
array.remove(LineBullHigh, 0)
line.delete(array.get(LineBullLow, 0))
array.remove(LineBullLow, 0)

array.push(LineBullAvg, line.new(x1=sync, xloc=xloc.bar_time, y1=OB_bull_avg, x2=sync[1],


y2=OB_bull_avg, extend=extend.left, color=bullcolor, style=line.style_solid, width=1))
array.push(LineBullHigh, line.new(x1=sync, xloc=xloc.bar_time, y1=OB_bull_chigh,
x2=sync[1], y2=OB_bull_chigh, extend=extend.left, color=bullcolor, style=line.style_dashed,
width=1))
array.push(LineBullLow, line.new(x1=sync, xloc=xloc.bar_time, y1=OB_bull_clow, x2=sync[1],
y2=OB_bull_clow, extend=extend.left, color=bullcolor, style=line.style_dashed, width=1))

if OB_bear and bear_channels > 0


if array.size(LineBearAvg) == bear_channels
line.delete(array.get(LineBearAvg, 0))
array.remove(LineBearAvg, 0)
line.delete(array.get(LineBearHigh, 0))
array.remove(LineBearHigh, 0)
line.delete(array.get(LineBearLow, 0))
array.remove(LineBearLow, 0)

array.push(LineBearAvg, line.new(x1=sync, xloc=xloc.bar_time, y1=OB_bear_avg,


x2=sync[1], y2=OB_bear_avg, extend=extend.left, color=bearcolor, style=line.style_solid,
width=1))
array.push(LineBearHigh, line.new(x1=sync, xloc=xloc.bar_time, y1=OB_bear_chigh,
x2=sync[1], y2=OB_bear_chigh, extend=extend.left, color=bearcolor, style=line.style_dashed,
width=1))
array.push(LineBearLow, line.new(x1=sync, xloc=xloc.bar_time, y1=OB_bear_clow,
x2=sync[1], y2=OB_bear_clow, extend=extend.left, color=bearcolor, style=line.style_dashed,
width=1))

// Alerts for Order Blocks Detection


alertcondition(OB_bull, title='New Bullish OB detected', message='New Bullish OB detected -
This is NOT a BUY signal!')
alertcondition(OB_bear, title='New Bearish OB detected', message='New Bearish OB detected -
This is NOT a SELL signal!')

colors2 = input.string(title='Color Scheme', defval='DARK', options=['DARK', 'BRIGHT'])


periods2 = input(1, 'Relevant Periods to identify OB') // Required number of subsequent
candles in the same direction to identify Order Block
threshold2 = input.float(0.0, 'Min. Percent move to identify OB', step=0.1) // Required minimum
% move (from potential OB close to last subsequent candle to identify Order Block)
usewicks2 = input(false, 'Use whole range [High/Low] for OB marking?') // Display High/Low
range for each OB instead of Open/Low for Bullish / Open/High for Bearish
showbull2 = input(true, 'Show latest Bullish Channel?') // Show Channel for latest Bullish OB?
showbear2 = input(true, 'Show latest Bearish Channel?') // Show Channel for latest Bearish
OB?
showdocu2 = input(false, 'Show Label for documentation tooltip?') // Show Label which shows
documentation as tooltip?
info_pan2 = input(false, 'Show Latest OB Panel?') // Show Info Panel with latest OB Stats

ob_period2 = periods2 // Identify location of relevant Order Block candle


absmove2 = math.abs(close[ob_period2] - close[1]) / close[ob_period2] * 100 // Calculate
absolute percent move from potential OB to last candle of subsequent candles
relmove2 = absmove2 >= threshold2 // Identify "Relevant move" by comparing the absolute
move to the threshold

// Color Scheme
bullcolor3 = colors2 == 'DARK' ? color.white : color.green
bearcolor3 = colors2 == 'DARK' ? color.blue : color.red

// Bullish Order Block Identification


bullishOB2 = close[ob_period2] < open[ob_period2] // Determine potential Bullish OB2 candle
(red candle)

int upcandles2 = 0
for i = 0 to periods2 by 1
upcandles2 += (close[i] > open[i] ? 1 : 0) // Determine color of subsequent candles (must all
be green to identify a valid Bearish OB2)
upcandles2

OB_bull2 = bullishOB2 and upcandles2 == periods2 and relmove2 // Identification logic (red OB
candle & subsequent green candles)
OB_bull_high2 = OB_bull2 ? usewicks2 ? high[ob_period2] : open[ob_period2] : na //
Determine OB2 upper limit (Open or High depending on input)
OB_bull_low2 = OB_bull2 ? low[ob_period2] : na // Determine OB2 lower limit (Low)
OB_bull_avg2 = (OB_bull_high2 + OB_bull_low2) / 2 // Determine OB2 middle line

// Bearish Order Block Identification


bearishOB2 = close[ob_period2] > open[ob_period2] // Determine potential Bearish OB2 candle
(green candle)

int downcandles2 = 0
for i = 0 to periods2 by 1
downcandles2 += (close[i] < open[i] ? 1 : 0) // Determine color of subsequent candles (must
all be red to identify a valid Bearish OB2)
downcandles2
OB_bear2 = bearishOB2 and downcandles2 == periods2 and relmove2 // Identification logic
(green OB2 candle & subsequent green candles)
OB_bear_high2 = OB_bear2 ? high[ob_period2] : na // Determine OB2 upper limit (High)
OB_bear_low2 = OB_bear2 ? usewicks2 ? low[ob_period2] : open[ob_period2] : na //
Determine OB2 lower limit (Open or Low depending on input)
OB_bear_avg2 = (OB_bear_low2 + OB_bear_high2) / 2 // Determine OB middle line

// Plotting

plotshape(OB_bull2, title='Bullish OB2', style=shape.triangleup, color=bullcolor3,


textcolor=bullcolor3, size=size.tiny, location=location.belowbar, offset=-ob_period2, text='Bullish
OB2') // Bullish OB2 Indicator
bull3= plot(OB_bull_high2, title='Bullish OB High2', style=plot.style_linebr, color=bullcolor3,
offset=-ob_period2, linewidth=3) // Bullish OB2 Upper Limit
bull4 = plot(OB_bull_low2, title='Bullish OB Low2', style=plot.style_linebr, color=bullcolor3,
offset=-ob_period2, linewidth=3) // Bullish OB2 Lower Limit
fill(bull3, bull4, color=bullcolor3, title='Bullish OB2 fill') // Fill Bullish OB
plotshape(OB_bull_avg2, title='Bullish OB Average2', style=shape.cross, color=bullcolor3,
size=size.normal, location=location.absolute, offset=-ob_period2) // Bullish OB2 Average

plotshape(OB_bear2, title='Bearish OB2', style=shape.triangledown, color=bearcolor3,


textcolor=bearcolor4, size=size.tiny, location=location.abovebar, offset=-ob_period2,
text='Bearish OB2') // Bearish OB2 Indicator
bear3 = plot(OB_bear_low2, title='Bearish OB Low2', style=plot.style_linebr, color=bearcolor3,
offset=-ob_period2, linewidth=3) // Bearish OB2 Lower Limit
bear4 = plot(OB_bear_high2, title='Bearish OB2 High', style=plot.style_linebr, color=bearcolor3,
offset=-ob_period2, linewidth=3) // Bearish OB2 Upper Limit
fill(bear3, bear4, color=bearcolor3, title='Bearish OB2 fill') // Fill Bearish OB2
plotshape(OB_bear_avg2, title='Bearish OB2 Average', style=shape.cross, color=bearcolor4,
size=size.normal, location=location.absolute, offset=-ob_period2) // Bullish OB2 Average

if OB_bull2
alert("Buy Signal\n(Bullish Order Block):" +
str.tostring(close),freq=alert.freq_once_per_bar_close)

if OB_bear2
alert("Sell Signal\n(Bearish Order Block):" +
str.tostring(close),freq=alert.freq_once_per_bar_close)

var line linebull4 = na // Bullish OB2 average


var line linebull5 = na // Bullish OB2 open
var line linebull6 = na // Bullish OB2 low
var line linebear4 = na // Bearish OB2 average
var line linebear5 = na // Bearish OB2 high
var line linebear6 = na // Bearish OB2 open

if OB_bull2 and showbull2


line.delete(linebull4)
linebull4 := line.new(x1=bar_index, y1=OB_bull_avg2, x2=bar_index - 1, y2=OB_bull_avg2,
extend=extend.left, color=bullcolor3, style=line.style_solid, width=1)

line.delete(linebull5)
linebull5 := line.new(x1=bar_index, y1=OB_bull_high2, x2=bar_index - 1, y2=OB_bull_high2,
extend=extend.left, color=bullcolor3, style=line.style_dashed, width=1)

line.delete(linebull6)
linebull6 := line.new(x1=bar_index, y1=OB_bull_low2, x2=bar_index - 1, y2=OB_bull_low2,
extend=extend.left, color=bullcolor3, style=line.style_dashed, width=1)
linebull6

if OB_bear2 and showbear2


line.delete(linebear4)
linebear4 := line.new(x1=bar_index, y1=OB_bear_avg2, x2=bar_index - 1,
y2=OB_bear_avg2, extend=extend.left, color=bearcolor3, style=line.style_solid, width=1)

line.delete(linebear5)
linebear5 := line.new(x1=bar_index, y1=OB_bear_high2, x2=bar_index - 1,
y2=OB_bear_high2, extend=extend.left, color=bearcolor3, style=line.style_dashed, width=1)

line.delete(linebear6)
linebear6 := line.new(x1=bar_index, y1=OB_bear_low2, x2=bar_index - 1,
y2=OB_bear_low2, extend=extend.left, color=bearcolor3, style=line.style_dashed, width=1)
linebear3

// Alerts for Order Blocks Detection

// Print latest Order Blocks in Data Window

var latest_bull_high = 0.0 // Variable to keep latest Bull OB2 high


var latest_bull_avg = 0.0 // Variable to keep latest Bull OB2 average
var latest_bull_low = 0.0 // Variable to keep latest Bull OB2 low
var latest_bear_high = 0.0 // Variable to keep latest Bear OB2 high
var latest_bear_avg = 0.0 // Variable to keep latest Bear OB2 average
var latest_bear_low = 0.0 // Variable to keep latest Bear OB2 low

// Assign latest values to variables


if OB_bull_high2 > 0
latest_bull_high := OB_bull_high2
latest_bull_high

if OB_bull_avg2 > 0
latest_bull_avg := OB_bull_avg2
latest_bull_avg

if OB_bull_low2 > 0
latest_bull_low := OB_bull_low2
latest_bull_low

if OB_bear_high2 > 0
latest_bear_high := OB_bear_high2
latest_bear_high

if OB_bear_avg2 > 0
latest_bear_avg := OB_bear_avg2
latest_bear_avg

if OB_bear_low2 > 0
latest_bear_low := OB_bear_low2
latest_bear_low

// Plot invisible characters to be able to show the values in the Data Window
plotchar(latest_bull_high, char=' ', location=location.abovebar, color=color.new(#777777, 100),
size=size.tiny, title='Latest Bull High')
plotchar(latest_bull_avg, char=' ', location=location.abovebar, color=color.new(#777777, 100),
size=size.tiny, title='Latest Bull Avg')
plotchar(latest_bull_low, char=' ', location=location.abovebar, color=color.new(#777777, 100),
size=size.tiny, title='Latest Bull Low')
plotchar(latest_bear_high, char=' ', location=location.abovebar, color=color.new(#777777, 100),
size=size.tiny, title='Latest Bear High')
plotchar(latest_bear_avg, char=' ', location=location.abovebar, color=color.new(#777777, 100),
size=size.tiny, title='Latest Bear Avg')
plotchar(latest_bear_low, char=' ', location=location.abovebar, color=color.new(#777777, 100),
size=size.tiny, title='Latest Bear Low')
//InfoPanel for latest Order Blocks

draw_InfoPanel(_text, _x, _y, font_size) =>


var label la_panel = na
label.delete(la_panel)
la_panel := label.new(x=_x, y=_y, text=_text, xloc=xloc.bar_time, yloc=yloc.price,
color=color.new(#383838, 5), style=label.style_label_left, textcolor=color.white, size=font_size)
la_panel

info_panel_x = time_close + math.round(ta.change(time) * 100)


info_panel_y = close

title = 'LATEST ORDER BLOCKS'


row0 = '-----------------------------------------------------'
row1 = ' Bullish - High: ' + str.tostring(latest_bull_high, '#.##')
row2 = ' Bullish - Avg: ' + str.tostring(latest_bull_avg, '#.##')
row3 = ' Bullish - Low: ' + str.tostring(latest_bull_low, '#.##')
row4 = '-----------------------------------------------------'
row5 = ' Bearish - High: ' + str.tostring(latest_bear_high, '#.##')
row6 = ' Bearish - Avg: ' + str.tostring(latest_bear_avg, '#.##')
row7 = ' Bearish - Low: ' + str.tostring(latest_bear_low, '#.##')

panel_text = '\n' + title + '\n' + row0 + '\n' + row1 + '\n' + row2 + '\n' + row3 + '\n' + row4 + '\n\n' +
row5 + '\n' + row6 + '\n' + row7 + '\n'

if info_pan
draw_InfoPanel(panel_text, info_panel_x, info_panel_y, size.normal)

// === Label for Documentation/Tooltip ===


chper = time - time[1]
chper := ta.change(chper) > 0 ? chper[1] : chper

// === Tooltip text ===

var vartooltip = 'Indicator to help identifying instituational Order Blocks. Often these blocks signal
the beginning of a strong move, but there is a high probability, that these prices will be revisited
at a later point in time again and therefore are interesting levels to place limit orders. \nBullish
Order block is the last down candle before a sequence of up candles. \nBearish Order Block is
the last up candle before a sequence of down candles. \nIn the settings the number of required
sequential candles can be adjusted. \nFurthermore a %-threshold can be entered which the
sequential move needs to achieve in order to validate a relevant Order Block. \nChannels for
the last Bullish/Bearish Block can be shown/hidden.'
// === Print Label ===
var label l_docu = na
label.delete(l_

You might also like