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


// This experimental Indicator helps identifying instituational Order Blocks.
// Often these blocks signal the beginning of a strong move, but there is a significant probability that these price levels will be revisited at a later point in time again.
// Therefore these are interesting levels to place limit orders (Buy Orders for Bullish OB / Sell Orders for Bearish OB).
//
// A Bullish Order block is defined as the last down candle before a sequence of up candles. (Relevant price range "Open" to "Low" is marked) / Optionally full range "High" to "Low"
// A Bearish Order Block is defined as the last up candle before a sequence of down candles. (Relevant price range "Open" to "High" is marked) / Optionally full range "High" to "Low"
//
// In the settings the number of required sequential candles can be adjusted.
// Furthermore a %-threshold can be entered. It defines which %-change the sequential move needs to achieve in order to identify a relevant Order Block.
// Channels for the last Bullish/Bearish Block can be shown/hidden.
//
// In addition to the upper/lower limits of each Order Block, also the equlibrium (average value) is marked as this is an interesting area for price interaction.


//version=4
study("BEAST OB Finder", overlay = true)

colors = input(title = "Color Scheme", defval="DARK", options=["DARK", "BRIGHT"])
periods = input(5, "Relevant Periods to identify OB") // Required number of subsequent candles in the same direction to identify Order Block
threshold = input(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)
usewicks = 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
showbull = input(true, "Show latest Bullish Channel?") // Show Channel for latest Bullish OB?
showbear = input(true, "Show latest Bearish Channel?") // Show Channel for latest Bearish OB?
showdocu = input(true, "Show Label for documentation tooltip?") // Show Label which shows documentation as tooltip?

ob_period = periods + 1 // Identify location of relevant Order Block candle
absmove = ((abs(close[ob_period] - close[1]))/close[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.white : color.green
bearcolor = colors == "DARK"? color.blue : color.red

// Bullish Order Block Identification
bullishOB = close[ob_period] < open[ob_period] // Determine potential Bullish OB candle (red candle)

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

OB_bull = bullishOB and (upcandles == (periods)) and relmove // Identification logic (red OB candle & subsequent green candles)
OB_bull_high = OB_bull? usewicks? high[ob_period] : open[ob_period] : na // Determine OB upper limit (Open or High depending on input)
OB_bull_low = OB_bull? low[ob_period] : na // Determine OB lower limit (Low)
OB_bull_avg = (OB_bull_high + OB_bull_low)/2 // Determine OB middle line


// Bearish Order Block Identification
bearishOB = close[ob_period] > open[ob_period] // Determine potential Bearish OB candle (green candle)

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

OB_bear = bearishOB and (downcandles == (periods)) and relmove // Identification logic (green OB candle & subsequent green candles)
OB_bear_high = OB_bear? high[ob_period] : na // Determine OB upper limit (High)
OB_bear_low = OB_bear? usewicks? low[ob_period] : open[ob_period] : na // Determine OB lower limit (Open or Low depending on input)
OB_bear_avg = (OB_bear_low + OB_bear_high)/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 = "Bullish OB") // Bullish OB Indicator
bull1 = plot(OB_bull_high, title="Bullish OB open", style = plot.style_linebr, color = bullcolor, offset = -ob_period, linewidth = 3) // Bullish OB Upper Limit
bull2 = plot(OB_bull_low, title="Bullish OB low", style = plot.style_linebr, color = bullcolor, offset = -ob_period, linewidth = 3) // Bullish OB Lower Limit
fill(bull1, bull2, color=bullcolor, transp = 0, title = "Bullish OB fill") // Fill Bullish OB
plotshape(OB_bull_avg, title="Bullish OB Average", style = shape.cross, color = bullcolor, size = size.normal, 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 = "Bearish OB") // Bearish OB Indicator
bear1 = plot(OB_bear_low, title="Bearish OB open", style = plot.style_linebr, color = bearcolor, offset = -ob_period, linewidth = 3) // Bearish OB Lower Limit
bear2 = plot(OB_bear_high, title="Bearish OB high", style = plot.style_linebr, color = bearcolor, offset = -ob_period, linewidth = 3) // Bearish OB Upper Limit
fill(bear1, bear2, color=bearcolor, transp = 0, title = "Bearish OB fill") // Fill Bearish OB
plotshape(OB_bear_avg, title="Bearish OB Average", style = shape.cross, color = bearcolor, size = size.normal, location = location.absolute, offset = -ob_period) // Bullish OB Average

var line linebull1 = na // Bullish OB average
var line linebull2 = na // Bullish OB open
var line linebull3 = na // Bullish OB low
var line linebear1 = na // Bearish OB average
var line linebear2 = na // Bearish OB high
var line linebear3 = na // Bearish OB open


if OB_bull and showbull
line.delete(linebull1)
linebull1 := line.new(x1 = bar_index, y1 = OB_bull_avg, x2 = bar_index - 1, y2 = OB_bull_avg, extend = extend.left, color = bullcolor, style = line.style_solid, width = 1)

line.delete(linebull2)
linebull2 := line.new(x1 = bar_index, y1 = OB_bull_high, x2 = bar_index - 1, y2 = OB_bull_high, extend = extend.left, color = bullcolor, style = line.style_dashed, width = 1)

line.delete(linebull3)
linebull3 := line.new(x1 = bar_index, y1 = OB_bull_low, x2 = bar_index - 1, y2 = OB_bull_low, extend = extend.left, color = bullcolor, style = line.style_dashed, width = 1)

if OB_bear and showbear
line.delete(linebear1)
linebear1 := line.new(x1 = bar_index, y1 = OB_bear_avg, x2 = bar_index - 1, y2 = OB_bear_avg, extend = extend.left, color = bearcolor, style = line.style_solid, width = 1)

line.delete(linebear2)
linebear2 := line.new(x1 = bar_index, y1 = OB_bear_high, x2 = bar_index - 1, y2 = OB_bear_high, extend = extend.left, color = bearcolor, style = line.style_dashed, width = 1)

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


// === Label for Documentation/Tooltip ===
chper = time - time[1]
chper := 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_docu)

if showdocu
l_docu := label.new(x = time + chper * 35, y = close, text = "DOCU OB", color=color.gray, textcolor=color.white, style=label.style_label_center, xloc = xloc.bar_time, yloc=yloc.price, size=size.tiny, textalign = text.align_left, tooltip = vartooltip)

//plot(OB_bull ? 1.0 : OB_bear ? -1.0 : 0.0, "Output", transp=100)
loveSupply and DemandSupport and Resistancewith

Clause de non-responsabilité