Algomen12

//@version=5
indicator("Price Action Concepts Open source
π΄", "Price Action Concepts Open source
π΄"
, overlay = true
, max_labels_count = 500
, max_lines_count = 500
, max_boxes_count = 500
, max_bars_back = 500)
//-----------------------------------------------------------------------------{
//Constants
//-----------------------------------------------------------------------------{
color TRANSP_CSS = #ffffff00
//Tooltips
string MODE_TOOLTIP = 'Allows to display historical Structure or only the recent ones'
string STYLE_TOOLTIP = 'Indicator color theme'
string COLOR_CANDLES_TOOLTIP = 'Display additional candles with a color reflecting the current trend detected by structure'
string SHOW_INTERNAL = 'Display internal market structure'
string CONFLUENCE_FILTER = 'Filter non significant internal structure breakouts'
string SHOW_SWING = 'Display swing market Structure'
string SHOW_SWING_POINTS = 'Display swing point as labels on the chart'
string SHOW_SWHL_POINTS = 'Highlight most recent strong and weak high/low points on the chart'
string INTERNAL_OB = 'Display internal order blocks on the chart\n\nNumber of internal order blocks to display on the chart'
string SWING_OB = 'Display swing order blocks on the chart\n\nNumber of internal swing blocks to display on the chart'
string FILTER_OB = 'Method used to filter out volatile order blocks \n\nIt is recommended to use the cumulative mean range method when a low amount of data is available'
string SHOW_EQHL = 'Display equal highs and equal lows on the chart'
string EQHL_BARS = 'Number of bars used to confirm equal highs and equal lows'
string EQHL_THRESHOLD = 'Sensitivity threshold in a range (0, 1) used for the detection of equal highs & lows\n\nLower values will return fewer but more pertinent results'
string SHOW_FVG = 'Display fair values gaps on the chart'
string AUTO_FVG = 'Filter out non significant fair value gaps'
string FVG_TF = 'Fair value gaps timeframe'
string EXTEND_FVG = 'Determine how many bars to extend the Fair Value Gap boxes on chart'
string PED_ZONES = 'Display premium, discount, and equilibrium zones on chart'
//-----------------------------------------------------------------------------{
//Settings
//-----------------------------------------------------------------------------{
//General
//----------------------------------------{
mode = input.string("Historical", "Market Concepts Mode", options = , group = "Internal Structure")
style = 'Colored'
//----------------------------------------}
//Internal Structure
//----------------------------------------{
show_internals = input(true, 'Show Internal Structure'
, group = 'Internal Structure'
, tooltip = SHOW_INTERNAL)
show_ibull = input.string('All', 'Structure Type'
, options =
, inline = 'ibull'
, group = 'Internal Structure')
swing_ibull_css = input(#089981, ''
, inline = 'ibull'
, group = 'Internal Structure')
//Bear Structure
show_ibear = show_ibull
swing_ibear_css = input(#f23645, ''
, inline = 'ibull'
, group = 'Internal Structure')
bool structureScannerOn = input.bool(true, "Structure Scanner", inline = "ttt", group = "Internal Structure")
scannerTimeframe = input.timeframe("D", "", group = "Internal Structure", inline = "ttt")
var int internalBOS = 1
var int swingBOS = 1
show_trend = input(false, 'Color Candles'
, group = 'Internal Structure'
, tooltip = COLOR_CANDLES_TOOLTIP, inline = "testest")
purplecolor = input.color(#56328f, "", inline = "testest", group = "Internal Structure")
ifilter_confluence = false
internal_structure_size = 'Tiny'
//----------------------------------------}
//Swing Structure
//----------------------------------------{
show_Structure = input(true, 'Show Swing Structure'
, group = 'Swing Structure'
, tooltip = SHOW_SWING)
//Bull Structure
show_bull = input.string('All', 'Structure Type'
, options =
, inline = 'bull'
, group = 'Swing Structure')
swing_bull_css = input(#089981, ''
, inline = 'bull'
, group = 'Swing Structure')
//Bear Structure
show_bear = show_bull
swing_bear_css = input(#f23645, ''
, inline = 'bull'
, group = 'Swing Structure')
swing_structure_size = 'Small'
//Swings
show_swings = input(false, 'Show Swings Points'
, inline = 'swings'
, group = 'Swing Structure'
, tooltip = SHOW_SWING_POINTS)
length = input.int(50, ''
, minval = 10
, inline = 'swings'
, group = 'Swing Structure')
show_hl_swings = input(false, 'Show Strong/Weak High/Low'
, group = 'Swing Structure'
, tooltip = SHOW_SWHL_POINTS)
showEntryZones = input(false, "Show Entry Zones", group = "Swing Structure", tooltip = "Show Fibonacci Entry Zones")
showInvalidated = false
OBsEnabled = true
orderBlockVolumetricInfo = true
obEndMethod = input.string("Wick", "Mitigation Method", options = , group = "Volumetric Orderblocks", display = display.none)
combineOBs = true
maxATRMult = 10.
swingLength = input.int(10, 'Construction Length', minval = 3, tooltip="Swing length is used when finding order block formations. Smaller values will result in finding smaller order blocks.",group = "Volumetric Orderblocks", display = display.none, inline = "obColor")
bullOrderBlockColor = input(#22a08a, '', inline = 'obColor', group = 'Volumetric Orderblocks', display = display.none)
bearOrderBlockColor = input(#f23847, '', inline = 'obColor', group = 'Volumetric Orderblocks', display = display.none)
transp = 80
bullishOrderBlocks = input.int(5, "Zone Count", group = "Volumetric Orderblocks")
bearishOrderBlocks = bullishOrderBlocks
timeframe1Enabled = input.bool(true, "Timeframe 1", inline ="7", group = "Volumetric Orderblocks")
timeframe1 = input.timeframe("240", "", inline = "7", group = "Volumetric Orderblocks")
timeframe2Enabled = input.bool(true, "Timeframe 2", inline ="8", group = "Volumetric Orderblocks")
timeframe2 = input.timeframe("15", "", inline = "8", group = "Volumetric Orderblocks")
timeframe3Enabled = input.bool(true, "Timeframe 3", inline ="9", group = "Volumetric Orderblocks")
timeframe3 = input.timeframe("1", "", inline = "9", group = "Volumetric Orderblocks")
show_sd = showEntryZones
premium_css = swing_bear_css
eq_css = #b2b5be
discount_css = swing_bull_css
//----------------------------------------}
//Order Blocks
//----------------------------------------{
var int candlecolor = 0
//----------------------------------------}
//Price Action Concepts
//----------------------------------------{
activateliquidity = input.bool(false, inline = "Sweeps", group = "Liquidity Concepts", title = "Liquidity Sweeps")
len12345 = input.int(3, '', options = , group = 'Liquidity Concepts', inline = "Sweeps")
opt = 'Only Wicks'
len12345 := len12345 * 2
colBl = input.color(#0044ff, "", inline = "Sweeps", group = "Liquidity Concepts")
colBr = input.color(#ff2b00, "", inline = "Sweeps", group = "Liquidity Concepts")
colBl2 = colBl
colBr2 = colBr
extend = false
maxB = 300
colBl3 = colBl
colBr3 = colBr
oW = opt == 'Only Wicks'
oO = opt == 'Only Outbreaks & Retest'
WO = opt == 'Wicks + Outbreaks & Retest'
n = bar_index
//-----------------------------------------------------------------------------}
//UDT's
//-----------------------------------------------------------------------------{
type piv
float prc // price
int bix // bar_index
bool brk // broken
bool mit // mitigated
bool tak // taken
bool wic // wick
line lin
type boxBr
box bx
line ln
bool br
int dr
//-----------------------------------------------------------------------------}
//Variables
//-----------------------------------------------------------------------------{
var array< piv >aPivH = array.new< piv >(1, piv.new ())
var array< piv >aPivL = array.new< piv >(1, piv.new ())
var array<boxBr>aBoxBr = array.new<boxBr>(1, boxBr.new())
//-----------------------------------------------------------------------------}
//Methods - functions
//-----------------------------------------------------------------------------{
method n(float piv) => bool out = not na(piv)
method p(piv piv, float val) => float out = (100 / piv.prc * val) - 100
method l(piv get, color c, string s='sd') =>
style = switch s
'dt' => line.style_dotted
'ds' => line.style_dashed
=> line.style_solid
line.new(get.bix, get.prc, n, get.prc, color=c, style = style)
method br(piv get, color c3, color c, int d) =>
y1 = d == 1 ? high : get.prc
y2 = d == 1 ? get.prc : low
boxBr.new(
box.new(n -1, y1, n +1, y2
, border_color
= color.new(
na, na )
, bgcolor=c3)
, line.new(n , y1, n, y2, color=c, width=3)
, false
, d)
lnDot(y, c) => line.new(n, y, n+3, y, color=c, style=line.style_dotted)
//-----------------------------------------------------------------------------}
//Execution
//-----------------------------------------------------------------------------{
ph = ta.pivothigh(len12345, len12345)
pl = ta.pivotlow (len12345, len12345)
if ph.n()
aPivH.unshift(piv.new(ph, n -len12345, false, false, false, false))
if pl.n()
aPivL.unshift(piv.new(pl, n -len12345, false, false, false, false))
bool bullcandle = false
bool bearcandle = false
for i = aPivH.size() -1 to 0
get = aPivH.get(i)
if not get.mit
if not get.brk
if close > get.prc
if not oW
get.brk := true
else
get.mit := true
if not oO and not get.wic
if high > get.prc and close < get.prc
bearcandle := true
get.wic := true
else
if close < get.prc
get.mit := true
if not oW and low < get.prc and close > get.prc
get.tak := true
if n - get.bix > 2000 or get.mit or get.tak
aPivH.remove(i).lin.delete()
for i = aPivL.size() -1 to 0
get = aPivL.get(i)
if not get.mit
if not get.brk
if close < get.prc
if not oW
get.brk := true
else
get.mit := true
if not oO and not get.wic
if low < get.prc and close > get.prc
bullcandle := true
get.wic := true
else
if close > get.prc
get.mit := true
if not oW and high > get.prc and close < get.prc
get.tak := true
if n - get.bix > 2000 or get.mit or get.tak
aPivL.remove(i).lin.delete()
plotcandle(math.max(close, open), high, math.max(close, open), high, "", color(na), color(na), bordercolor = bearcandle and activateliquidity ? colBr3 : color(na), editable = false)
plotcandle(math.min(close, open), math.min(close, open), low, low, "", color(na), color(na), false, bordercolor = bullcandle and activateliquidity? colBl3 : color(na))
if extend
for bx in aBoxBr
if not bx.br and n - bx.bx.get_left() -1 <= maxB
bx.bx.set_right(bar_index)
if bx.dr == -1 and close < bx.bx.get_bottom()
bx.br := true
if bx.dr == 1 and close > bx.bx.get_top ()
bx.br := true
//-----------------------------------------------------------------------------}
activateLiq = input.bool(false, "Trendline Liquidity", inline = "a", group = "Liquidity Concepts")
len123 = input.int (3 , "" , inline = "a", group = "Liquidity Concepts", options = )
cup = input.color(#0044ff, "" , "" , inline = "a", group = "Liquidity Concepts")
cdn = input.color(#ff2b00, "" , "" , inline = "a", group = "Liquidity Concepts")
space = len123 + 1
shs = false
len123 := len123 * 2
phhh = ta.pivothigh(high, len123, len123)
plll = ta.pivotlow (low , len123, len123)
type store
float src
int n
type bar
float o = open
float h = high
float l = low
float c = close
int n = bar_index
float v = volume
type draw
line upln
line dnln
var store upbin = array.new<store>()
var store dnbin = array.new<store>()
var draw d = draw.new(array.new<line>(), array.new<line>())
bar b = bar.new()
atr = ta.atr(200)
method slope(line ln) =>
x = ln.get_x2() - ln.get_x1()
y = ln.get_y2() - ln.get_y1()
y / x
vol() =>
math.min(atr * 0.1, close * (0.1/100))
var bool broken = false
color active = na
bool plup = false
bool pldn = false
if phhh and activateLiq
bool remove = false
var bool valid = false
upbin.unshift(store.new(b.h, b.n))
if upbin.size() > 1
current = upbin.get(0)
before = upbin.get(1)
if current.src < before.src
if broken
valid := true
else
valid := false
if upbin.size() > 3
pastold = upbin.get(3)
pastcur = upbin.get(2)
now = upbin.get(1)
late = upbin.get(0)
if now.src < pastcur.src and now.src < pastold.src and late.src < pastcur.src and late.src < pastold.src
valid := true
else
valid := false
else
valid := false
if valid
d.upln.unshift(line.new(x1 = before.n, x2 = current.n, y1 = before.src , y2 = current.src , color = cdn))
d.upln.unshift(line.new(x1 = before.n, x2 = current.n, y1 = before.src - vol() * space, y2 = current.src - vol() * space, color = cdn))
ln = d.upln.get(1)
for i = 0 to (b.n - before.n)
slope = ln.slope()
ln.set_x2(b.n)
ln.set_y2(ln.get_y2() - slope)
if low > ln.get_y2()
remove := true
break
if remove
d.upln.get(0).delete()
d.upln.get(1).delete()
d.upln .clear()
upbin .clear()
broken := true
else
d.upln.get(0).delete()
d.upln.get(1).delete()
d.upln .clear ()
d.upln.unshift(line.new(x1 = before.n, x2 = current.n, y1 = before.src , y2 = current.src , color = cdn))
d.upln.unshift(line.new(x1 = before.n, x2 = current.n, y1 = before.src - vol() * space, y2 = current.src - vol() * space, color = cdn))
linefill.new(d.upln.get(0), d.upln.get(1), color = color.new(cdn, 75))
upbin.clear()
broken := false
if d.upln.size() > 1
btm = d.upln.get(0)
top = d.upln.get(1)
if b.l > top.get_y2()
d.upln.clear()
broken := true
upbin.clear()
plup := true
if d.upln.size() > 1
slup = top.slope()
sldn = btm.slope()
top.set_x2(b.n)
top.set_y2(top.get_y2() + slup)
btm.set_x2(b.n)
btm.set_y2(btm.get_y2() + sldn)
if plll and activateLiq
bool remove = false
var bool valid = false
dnbin.unshift(store.new(b.l, b.n))
if dnbin.size() > 1
current = dnbin.get(0)
before = dnbin.get(1)
if current.src > before.src
if broken
valid := true
else
valid := false
if dnbin.size() > 3
pastold = dnbin.get(3)
pastcur = dnbin.get(2)
now = dnbin.get(1)
late = dnbin.get(0)
if now.src > pastcur.src and now.src > pastold.src and late.src > pastcur.src and late.src > pastold.src
valid := true
else
valid := false
else
valid := false
if valid
d.dnln.unshift(line.new(x1 = before.n, x2 = current.n, y1 = before.src , y2 = current.src , color = cup))
d.dnln.unshift(line.new(x1 = before.n, x2 = current.n, y1 = before.src + vol() * space, y2 = current.src + vol() * space, color = cup))
ln = d.dnln.get(1)
for i = 0 to (b.n - before.n)
slope = ln.slope()
ln.set_x2(b.n)
ln.set_y2(ln.get_y2() - slope)
if high < ln.get_y2()
remove := true
break
if remove
d.dnln.get(0).delete()
d.dnln.get(1).delete()
d.dnln .clear ()
dnbin .clear ()
broken := true
else
d.dnln.get(0).delete()
d.dnln.get(1).delete()
d.dnln .clear ()
d.dnln.unshift(line.new(x1 = before.n, x2 = current.n, y1 = before.src, y2 = current.src, color = cup))
d.dnln.unshift(line.new(x1 = before.n, x2 = current.n, y1 = before.src + vol() * space, y2 = current.src + vol() * space, color = cup))
linefill.new(d.dnln.get(0), d.dnln.get(1), color = color.new(cup, 75))
dnbin.clear()
broken := false
if d.dnln.size() > 1
btm = d.dnln.get(0)
top = d.dnln.get(1)
if b.h < btm.get_y2()
d.dnln.clear()
broken := true
dnbin.clear()
pldn := true
if d.dnln.size() > 1
slup = top.slope()
sldn = btm.slope()
top.set_x2(b.n)
top.set_y2(top.get_y2() + slup)
btm.set_x2(b.n)
btm.set_y2(btm.get_y2() + sldn)
plotshape(pldn and shs ? b.h : na, "Breaking Down", shape.triangledown, location = location.abovebar, color = cdn , offset = -1, size = size.tiny)
plotshape(plup and shs ? b.l : na, "Breaking Up" , shape.triangleup , location = location.belowbar, color = cup, offset = -1, size = size.tiny)
show_eq = input(false, 'Equal Highs/Lows'
, group = 'Price Action Concepts'
, tooltip = SHOW_EQHL, inline = "test")
eq_len = input.int(3, ''
, options =
, group = 'Price Action Concepts'
, tooltip = EQHL_BARS, inline = "test")
eq_threshold = 0.1*(6-eq_len)
if eq_len == 5
eq_threshold == 0.05
eq_size = 'Tiny'
bool ontrendline = input.bool(true, "Auto-Trendlines", group = "Price Action Concepts", inline = "133")
atr10 = ta.atr(200)/2
int autotrendlinesens = input.int(3, "", , group = "Price Action Concepts", inline = "133")
length11111 = 5*autotrendlinesens+5
length111112 = 5*autotrendlinesens+5
astart = 2
aend = 0
bstart = 2
bend = 0
csrcsrcsrc = false
srcsrcsrc = close
//Conditions
upupup = ta.pivothigh(csrcsrcsrc ? srcsrcsrc : high, length11111, length11111)
dndndn = ta.pivotlow(csrcsrcsrc ? srcsrcsrc : low, length111112, length111112)
a1 = ta.valuewhen(not na(upupup), n, astart)
b1 = ta.valuewhen(not na(dndndn), n, bstart)
a2 = ta.valuewhen(not na(upupup), n, aend)
b2 = ta.valuewhen(not na(dndndn), n, bend)
//Colors
color111 = #a53e48
color222 = #5b8d5e
//Plots
if ontrendline
line upupupper1 = line.new(n, upupup+atr10, n, upupup+atr10, extend=extend.right, color=color.new(color111, 10),width=1)
line lower1 = line.new(n, dndndn, n, dndndn, extend=extend.right, color=color.new(color222, 10), width=1)
line upupupper2 = line.new(n, upupup, n, upupup, extend=extend.right, color=color.new(color111, 10), width=1)
line lower2 = line.new(n, dndndn-atr10, n, dndndn-atr10, extend=extend.right, color=color.new(color222, 10), width=1)
linefill t = linefill.new(upupupper1, upupupper2, color.new(color111, 75))
linefill y = linefill.new(lower1, lower2, color.new(color222, 75))
line.delete(upupupper1)
line.delete(lower1)
line.delete(upupupper2)
line.delete(lower2)
//----------------------------------------}
//Fair Value Gaps
//----------------------------------------{
//----------------------------------------}
//Previous day/week high/low
//----------------------------------------{
//Daily
show_pdhl = input(false, 'Daily'
, inline = 'daily'
, group = 'Highs & Lows MTF')
pdhl_style = input.string('⎯⎯⎯', ''
, options =
, inline = 'daily'
, group = 'Highs & Lows MTF')
pdhl_css = input(#2157f3, ''
, inline = 'daily'
, group = 'Highs & Lows MTF')
//Weekly
show_pwhl = input(false, 'Weekly'
, inline = 'weekly'
, group = 'Highs & Lows MTF')
pwhl_style = input.string('⎯⎯⎯', ''
, options =
, inline = 'weekly'
, group = 'Highs & Lows MTF')
pwhl_css = input(#2157f3, ''
, inline = 'weekly'
, group = 'Highs & Lows MTF')
//Monthly
show_pmhl = input(false, 'Monthly'
, inline = 'monthly'
, group = 'Highs & Lows MTF')
pmhl_style = input.string('⎯⎯⎯', ''
, options =
, inline = 'monthly'
, group = 'Highs & Lows MTF')
pmhl_css = input(#2157f3, ''
, inline = 'monthly'
, group = 'Highs & Lows MTF')
//----------------------------------------}
//Premium/Discount zones
//----------------------------------------{
//-----------------------------------------------------------------------------}
//Functions
//-----------------------------------------------------------------------------{
//n = bar_index
cmean_range = ta.cum(high - low) / n
//HL Output function
hl() =>
//Get ohlc values function
get_ohlc()=> [close, open, high, low, high, low]
//Display Structure function
display_Structure(x, y, txt, css, dashed, down, lbl_size)=>
structure_line = line.new(x, y, n, y
, color = css
, style = dashed ? line.style_dashed : line.style_solid)
structure_lbl = label.new(int(math.avg(x, n)), y, txt
, color = TRANSP_CSS
, textcolor = css
, style = down ? label.style_label_down : label.style_label_up
, size = lbl_size)
if mode == 'Present'
line.delete(structure_line)
label.delete(structure_lbl)
//Swings detection/measurements
swings(len)=>
var os = 0
upper = ta.highest(len)
lower = ta.lowest(len)
os := high > upper ? 0 : low < lower ? 1 : os
top = os == 0 and os != 0 ? high : 0
btm = os == 1 and os != 1 ? low : 0
//Line Style function
get_line_style(style) =>
out = switch style
'⎯⎯⎯' => line.style_solid
'----' => line.style_dashed
'····' => line.style_dotted
//Set line/labels function for previous high/lows
phl(h, l, tf, css)=>
var line high_line = line.new(na,na,na,na
, xloc = xloc.bar_time
, color = css
, style = get_line_style(pdhl_style))
var label high_lbl = label.new(na,na
, xloc = xloc.bar_time
, text = str.format('P{0}H', tf)
, color = TRANSP_CSS
, textcolor = css
, size = size.small
, style = label.style_label_left)
var line low_line = line.new(na,na,na,na
, xloc = xloc.bar_time
, color = css
, style = get_line_style(pdhl_style))
var label low_lbl = label.new(na,na
, xloc = xloc.bar_time
, text = str.format('P{0}L', tf)
, color = TRANSP_CSS
, textcolor = css
, size = size.small
, style = label.style_label_left)
hy = ta.valuewhen(h != h, h, 1)
hx = ta.valuewhen(h == high, time, 1)
ly = ta.valuewhen(l != l, l, 1)
lx = ta.valuewhen(l == low, time, 1)
if barstate.islast
ext = time + (time - time)*20
//High
line.set_xy1(high_line, hx, hy)
line.set_xy2(high_line, ext, hy)
label.set_xy(high_lbl, ext, hy)
//Low
line.set_xy1(low_line, lx, ly)
line.set_xy2(low_line, ext, ly)
label.set_xy(low_lbl, ext, ly)
//-----------------------------------------------------------------------------}
//Global variables
//-----------------------------------------------------------------------------{
var trend = 0, var itrend = 0
var top_y = 0., var top_x = 0
var btm_y = 0., var btm_x = 0
var itop_y = 0., var itop_x = 0
var ibtm_y = 0., var ibtm_x = 0
var trail_up = high, var trail_dn = low
var trail_up_x = 0, var trail_dn_x = 0
var top_cross = true, var btm_cross = true
var itop_cross = true, var ibtm_cross = true
var txt_top = '', var txt_btm = ''
//Alerts
bull_choch_alert = false
bull_bos_alert = false
bear_choch_alert = false
bear_bos_alert = false
bull_ichoch_alert = false
bull_ibos_alert = false
bear_ichoch_alert = false
bear_ibos_alert = false
bull_iob_break = false
bear_iob_break = false
bull_ob_break = false
bear_ob_break = false
eqh_alert = false
eql_alert = false
//Structure colors
var bull_css = style == 'Monochrome' ? #b2b5be
: swing_bull_css
var bear_css = style == 'Monochrome' ? #b2b5be
: swing_bear_css
var ibull_css = style == 'Monochrome' ? #b2b5be
: swing_ibull_css
var ibear_css = style == 'Monochrome' ? #b2b5be
: swing_ibear_css
//Labels size
var internal_structure_lbl_size = internal_structure_size == 'Tiny'
? size.tiny
: internal_structure_size == 'Small'
? size.small
: size.normal
var swing_structure_lbl_size = swing_structure_size == 'Tiny'
? size.tiny
: swing_structure_size == 'Small'
? size.small
: size.normal
var eqhl_lbl_size = eq_size == 'Tiny'
? size.tiny
: eq_size == 'Small'
? size.small
: size.normal
//Swings
= swings(length)
= swings(5)
//-----------------------------------------------------------------------------}
//Pivot High
//-----------------------------------------------------------------------------{
var line extend_top = na
var label extend_top_lbl = label.new(na, na
, color = TRANSP_CSS
, textcolor = bear_css
, style = label.style_label_down
, size = size.tiny)
if top
top_cross := true
txt_top := top > top_y ? 'HH' : 'LH'
if show_swings
top_lbl = label.new(n-length, top, txt_top
, color = TRANSP_CSS
, textcolor = bear_css
, style = label.style_label_down
, size = swing_structure_lbl_size)
if mode == 'Present'
label.delete(top_lbl)
//Extend recent top to last bar
line.delete(extend_top)
if show_hl_swings
extend_top := line.new(n-length, top, n, top , color = bear_css)
top_y := top
top_x := n - length
trail_up := top
trail_up_x := n - length
if itop
itop_cross := true
itop_y := itop
itop_x := n - 5
//Trailing maximum
trail_up := math.max(high, trail_up)
trail_up_x := trail_up == high ? n : trail_up_x
//Set top extension label/line
if barstate.islast and show_hl_swings
line.set_xy1(extend_top, trail_up_x, trail_up)
line.set_xy2(extend_top, n + 20, trail_up)
label.set_x(extend_top_lbl, n + 20)
label.set_y(extend_top_lbl, trail_up)
label.set_text(extend_top_lbl, trend < 0 ? 'Strong High' : 'Weak High')
//-----------------------------------------------------------------------------}
//Pivot Low
//-----------------------------------------------------------------------------{
var line extend_btm = na
var label extend_btm_lbl = label.new(na, na
, color = TRANSP_CSS
, textcolor = bull_css
, style = label.style_label_up
, size = size.tiny)
if btm
btm_cross := true
txt_btm := btm < btm_y ? 'LL' : 'HL'
if show_swings
btm_lbl = label.new(n - length, btm, txt_btm
, color = TRANSP_CSS
, textcolor = bull_css
, style = label.style_label_up
, size = swing_structure_lbl_size)
if mode == 'Present'
label.delete(btm_lbl)
//Extend recent btm to last bar
line.delete(extend_btm)
if show_hl_swings
extend_btm := line.new(n - length, btm, n, btm , color = bull_css)
btm_y := btm
btm_x := n-length
trail_dn := btm
trail_dn_x := n-length
if ibtm
ibtm_cross := true
ibtm_y := ibtm
ibtm_x := n - 5
//Trailing minimum
trail_dn := math.min(low, trail_dn)
trail_dn_x := trail_dn == low ? n : trail_dn_x
//Set btm extension label/line
if barstate.islast and show_hl_swings
line.set_xy1(extend_btm, trail_dn_x, trail_dn)
line.set_xy2(extend_btm, n + 20, trail_dn)
label.set_x(extend_btm_lbl, n + 20)
label.set_y(extend_btm_lbl, trail_dn)
label.set_text(extend_btm_lbl, trend > 0 ? 'Strong Low' : 'Weak Low')
//-----------------------------------------------------------------------------}
//Order Blocks Arrays
//-----------------------------------------------------------------------------{
var iob_top = array.new_float(0)
var iob_btm = array.new_float(0)
var iob_left = array.new_int(0)
var iob_type = array.new_int(0)
var ob_top = array.new_float(0)
var ob_btm = array.new_float(0)
var ob_left = array.new_int(0)
var ob_type = array.new_int(0)
//-----------------------------------------------------------------------------}
//Pivot High BOS/CHoCH
//-----------------------------------------------------------------------------{
//Filtering
var bull_concordant = true
if ifilter_confluence
bull_concordant := high - math.max(close, open) > math.min(close, open - low)
//Detect internal bullish Structure
swingtrend = 1
if ta.crossover(close, itop_y) and itop_cross and top_y != itop_y and bull_concordant
bool choch = na
if itrend < 0
choch := true
candlecolor := 0
bull_ichoch_alert := true
else
bull_ibos_alert := true
candlecolor := 1
txt = choch ? 'CHoCH' : 'BOS'
if choch
internalBOS := 1
else
internalBOS += 1
if show_internals
if show_ibull == 'All' or (show_ibull == 'BOS' and not choch) or (show_ibull == 'CHoCH' and choch)
display_Structure(itop_x, itop_y, txt, ibull_css, true, true, internal_structure_lbl_size)
itop_cross := false
itrend := 1
//Detect bullish Structure
if ta.crossover(close, top_y) and top_cross
bool choch = na
if trend < 0
choch := true
bull_choch_alert := true
else
bull_bos_alert := true
txt = choch ? 'CHoCH' : 'BOS'
if choch
swingBOS := 1
else
swingBOS += 1
if show_Structure
if show_bull == 'All' or (show_bull == 'BOS' and not choch) or (show_bull == 'CHoCH' and choch)
display_Structure(top_x, top_y, txt, bull_css, false, true, swing_structure_lbl_size)
//Order Block
top_cross := false
trend := 1
swingtrend := 1
//-----------------------------------------------------------------------------}
//Pivot Low BOS/CHoCH
//-----------------------------------------------------------------------------{
var bear_concordant = true
if ifilter_confluence
bear_concordant := high - math.max(close, open) < math.min(close, open - low)
//Detect internal bearish Structure
if ta.crossunder(close, ibtm_y) and ibtm_cross and btm_y != ibtm_y and bear_concordant
bool choch = false
if itrend > 0
choch := true
bear_ichoch_alert := true
candlecolor := 0
else
bear_ibos_alert := true
candlecolor := -1
txt = choch ? 'CHoCH' : 'BOS'
if choch
internalBOS := -1
else
internalBOS -= 1
if show_internals
if show_ibear == 'All' or (show_ibear == 'BOS' and not choch) or (show_ibear == 'CHoCH' and choch)
display_Structure(ibtm_x, ibtm_y, txt, ibear_css, true, false, internal_structure_lbl_size)
ibtm_cross := false
itrend := -1
//Internal Order Block
//Detect bearish Structure
if ta.crossunder(close, btm_y) and btm_cross
bool choch = na
if trend > 0
choch := true
bear_choch_alert := true
else
bear_bos_alert := true
txt = choch ? 'CHoCH' : 'BOS'
if choch
swingBOS := -1
else
swingBOS -=1
if show_Structure
if show_bear == 'All' or (show_bear == 'BOS' and not choch) or (show_bear == 'CHoCH' and choch)
display_Structure(btm_x, btm_y, txt, bear_css, false, false, swing_structure_lbl_size)
//Order Block
btm_cross := false
trend := -1
swingtrend := -1
//-----------------------------------------------------------------------------}
//Order Blocks
//-----------------------------------------------------------------------------{
//Set order blocks
const bool DEBUG = false
const int maxBoxesCount = 500
const float overlapThresholdPercentage = 0
const int maxDistanceToLastBar = 1750 // Affects Running Time
const int maxOrderBlocks = 30
textColor = color.white
extendZonesBy = DEBUG ? input.int(15, "Extend Zones", group = "Style", minval = 1, maxval = 30, inline = "ExtendZones") : 15
extendZonesDynamic = DEBUG ? input.bool(true, "Dynamic", group = "Style", inline = "ExtendZones") : true
combinedText = DEBUG ? input.bool(false, "Combined Text", group = "Style", inline = "CombinedColor") : false
volumeBarsPlace = DEBUG ? input.string("Left", "Show Volume Bars At", options = , group = "Style", inline = "volumebars") : "Left"
mirrorVolumeBars = DEBUG ? input.bool(true, "Mirror Volume Bars", group = "Style", inline = "volumebars") : true
volumeBarsLeftSide = (volumeBarsPlace == "Left")
extendZonesByTime = extendZonesBy * timeframe.in_seconds(timeframe.period) * 1000
atrt = ta.atr(10)
type orderBlockInfo
float top
float bottom
float obVolume
string obType
int startTime
float bbVolume
float obLowVolume
float obHighVolume
bool breaker
int breakTime
string timeframeStr
bool disabled = false
string combinedTimeframesStr = na
bool combined = false
type orderBlock
orderBlockInfo info
bool isRendered = false
box orderBox = na
box breakerBox = na
line orderBoxLineTop = na
line orderBoxLineBottom = na
line breakerBoxLineTop = na
line breakerBoxLineBottom = na
//
box orderBoxText = na
box orderBoxPositive = na
box orderBoxNegative = na
line orderSeperator = na
line orderTextSeperator = na
createOrderBlock (orderBlockInfo orderBlockInfoF) =>
orderBlock newOrderBlock = orderBlock.new(orderBlockInfoF)
newOrderBlock
safeDeleteOrderBlock (orderBlock orderBlockF) =>
orderBlockF.isRendered := false
box.delete(orderBlockF.orderBox)
box.delete(orderBlockF.breakerBox)
box.delete(orderBlockF.orderBoxText)
box.delete(orderBlockF.orderBoxPositive)
box.delete(orderBlockF.orderBoxNegative)
line.delete(orderBlockF.orderBoxLineTop)
line.delete(orderBlockF.orderBoxLineBottom)
line.delete(orderBlockF.breakerBoxLineTop)
line.delete(orderBlockF.breakerBoxLineBottom)
line.delete(orderBlockF.orderSeperator)
line.delete(orderBlockF.orderTextSeperator)
type timeframeInfo
int index = na
string timeframeStr = na
bool isEnabled = false
orderBlockInfo bullishOrderBlocksList = na
orderBlockInfo bearishOrderBlocksList = na
newTimeframeInfo (index, timeframeStr, isEnabled) =>
newTFInfo = timeframeInfo.new()
newTFInfo.index := index
newTFInfo.isEnabled := isEnabled
newTFInfo.timeframeStr := timeframeStr
newTFInfo
type obSwing
int x = na
float y = na
float swingVolume = na
bool crossed = false
// ____ TYPES END ____
var timeframeInfo timeframeInfos = array.from(newTimeframeInfo(1, timeframe1, timeframe1Enabled), newTimeframeInfo(2, timeframe2, timeframe2Enabled), newTimeframeInfo(3, timeframe3, timeframe3Enabled))
var bullishOrderBlocksList = array.new<orderBlockInfo>(0)
var bearishOrderBlocksList = array.new<orderBlockInfo>(0)
var allOrderBlocksList = array.new<orderBlock>(0)
moveLine(_line, _x, _y, _x2) =>
line.set_xy1(_line, _x, _y)
line.set_xy2(_line, _x2, _y)
moveBox (_box, _topLeftX, _topLeftY, _bottomRightX, _bottomRightY) =>
box.set_lefttop(_box, _topLeftX, _topLeftY)
box.set_rightbottom(_box, _bottomRightX, _bottomRightY)
isTimeframeLower (timeframe1F, timeframe2F) =>
timeframe.in_seconds(timeframe1F) < timeframe.in_seconds(timeframe2F)
tfe (timeframe1F, timeframe2F) =>
timeframe.in_seconds(timeframe1F) <= timeframe.in_seconds(timeframe2F)
getMinTimeframe (timeframe1F, timeframe2F) =>
if isTimeframeLower(timeframe1F, timeframe2F)
timeframe1F
else
timeframe2F
getMaxTimeframe (timeframe1F, timeframe2F) =>
if isTimeframeLower(timeframe1F, timeframe2F)
timeframe2F
else
timeframe1F
formatTimeframeString (formatTimeframe) =>
timeframeF = formatTimeframe == "" ? timeframe.period : formatTimeframe
if str.contains(timeframeF, "D") or str.contains(timeframeF, "W") or str.contains(timeframeF, "S") or str.contains(timeframeF, "M")
timeframeF
else
seconds = timeframe.in_seconds(timeframeF)
if seconds >= 3600
hourCount = int(seconds / 3600)
str.tostring(hourCount) + " Hour" + (hourCount > 1 ? "s" : "")
else
timeframeF + " Min"
betterCross(s1, s2) =>
string ret = na
if s1 >= s2 and s1 < s2
ret := "Bull"
if s1 < s2 and s1 >= s2
ret := "Bear"
ret
colorWithTransparency (colorF, transparencyX) =>
color.new(colorF, color.t(colorF) * transparencyX)
createOBBox (boxColor, transparencyX = 1.0, xlocType = xloc.bar_time) =>
box.new(na, na, na, na, text_size = size.normal, xloc = xlocType, extend = extend.none, bgcolor = color.new(boxColor, transparencyX), text_color = textColor, text_halign = text.align_center, border_color = #00000000)
renderOrderBlock (orderBlock ob) =>
orderBlockInfo info = ob.info
ob.isRendered := true
orderColor = ob.info.obType == "Bull" ? bullOrderBlockColor : bearOrderBlockColor
if OBsEnabled and (not false or not (false and info.breaker)) and not (not showInvalidated and info.breaker) and ob.info.disabled == false
ob.orderBox := createOBBox(orderColor, transp)
box.set_extend(ob.orderBox, extend.right)
if ob.info.combined
ob.orderBox.set_bgcolor(color.new(orderColor, transp))
ob.orderBoxText := createOBBox(orderColor)
if orderBlockVolumetricInfo
ob.orderBoxPositive := createOBBox(bullOrderBlockColor, 30)
ob.orderBoxNegative := createOBBox(bearOrderBlockColor, 30)
ob.orderSeperator := line.new(na,na,na,na,xloc.bar_time,extend.none,orderColor,line.style_dashed,1)
//ob.orderTextSeperator := line.new(na,na, na,na,xloc.bar_index,extend.none,orderColor,line.style_solid,1)
zoneSize = extendZonesDynamic ? na(info.breakTime) ? extendZonesByTime : (info.breakTime - info.startTime) : extendZonesByTime
if na(info.breakTime)
zoneSize := (time + 1) - info.startTime
startX = volumeBarsLeftSide ? info.startTime : info.startTime + zoneSize - zoneSize / 3
maxEndX = info.startTime + zoneSize
moveBox(ob.orderBox, info.startTime, info.top, info.startTime + zoneSize, info.bottom)
moveBox(ob.orderBoxText, volumeBarsLeftSide ? maxEndX : info.startTime, info.top, volumeBarsLeftSide ? info.startTime + zoneSize : startX, info.bottom)
percentage = int((math.min(info.obHighVolume, info.obLowVolume) / math.max(info.obHighVolume, info.obLowVolume)) * 100.0)
OBText = (na(ob.info.combinedTimeframesStr) ? formatTimeframeString(ob.info.timeframeStr) : ob.info.combinedTimeframesStr) + " OB"
box.set_text(ob.orderBoxText, (orderBlockVolumetricInfo ? str.tostring(ob.info.obVolume, format.volume) + " (" + str.tostring(percentage) + "%)" : "") + " " + formatTimeframeString(info.timeframeStr))
box.set_text_halign(ob.orderBoxText, text.align_left)
box.set_text_size(ob.orderBoxText, size.small)
box.set_text_color(ob.orderBoxText, ob.info.obType == "Bull" ? bullOrderBlockColor : bearOrderBlockColor)
if orderBlockVolumetricInfo
showHighLowBoxText = false
curEndXHigh = int(math.ceil((info.obHighVolume / info.obVolume) * (maxEndX - startX) + startX))
curEndXLow = int(math.ceil((info.obLowVolume / info.obVolume) * (maxEndX - startX) + startX))
moveBox(ob.orderBoxPositive, mirrorVolumeBars ? startX : curEndXLow, info.top, mirrorVolumeBars ? curEndXHigh : maxEndX, (info.bottom + info.top) / 2)
box.set_text(ob.orderBoxPositive, showHighLowBoxText ? str.tostring(info.obHighVolume, format.volume) : "")
moveBox(ob.orderBoxNegative, mirrorVolumeBars ? startX : curEndXHigh, info.bottom, mirrorVolumeBars ? curEndXLow : maxEndX, (info.bottom + info.top) / 2)
box.set_text(ob.orderBoxNegative, showHighLowBoxText ? str.tostring(info.obLowVolume, format.volume) : "")
moveLine(ob.orderSeperator, volumeBarsLeftSide ? startX : maxEndX, (info.bottom + info.top) / 2, volumeBarsLeftSide ? maxEndX : startX)
//line.set_xy1(ob.orderTextSeperator, barstate.isconfirmed ? bar_index+1 : bar_index+1, info.top)
//line.set_xy2(ob.orderTextSeperator, barstate.isconfirmed ? bar_index+1 : bar_index+1, info.bottom)
//line.set_color(ob.orderTextSeperator, orderColor)
findOBSwings(len) =>
var swingType = 0
var obSwing top = obSwing.new(na, na)
var obSwing bottom = obSwing.new(na, na)
upper = ta.highest(len)
lower = ta.lowest(len)
swingType := high > upper ? 0 : low < lower ? 1 : swingType
if swingType == 0 and swingType != 0
top := obSwing.new(bar_index, high, volume)
if swingType == 1 and swingType != 1
bottom := obSwing.new(bar_index, low, volume)
findOrderBlocks () =>
if bar_index > last_bar_index - maxDistanceToLastBar
= findOBSwings(swingLength)
useBody = false
max = useBody ? math.max(close, open) : high
min = useBody ? math.min(close, open) : low
// Bullish Order Block
bullishBreaked = 0
if bullishOrderBlocksList.size() > 0
for i = bullishOrderBlocksList.size() - 1 to 0
currentOB = bullishOrderBlocksList.get(i)
if not currentOB.breaker
if (obEndMethod == "Wick" ? low : math.min(open, close)) < currentOB.bottom
currentOB.breaker := true
currentOB.breakTime := time
currentOB.bbVolume := volume
else
if high > currentOB.top
bullishOrderBlocksList.remove(i)
else if i < bullishOrderBlocks and top.y < currentOB.top and top.y > currentOB.bottom
bullishBreaked := 1
if close > top.y and not top.crossed
top.crossed := true
boxBtm = max
boxTop = min
boxLoc = time
for i = 1 to (bar_index - top.x) - 1
boxBtm := math.min(min, boxBtm)
boxTop := boxBtm == min ? max : boxTop
boxLoc := boxBtm == min ? time : boxLoc
newOrderBlockInfo = orderBlockInfo.new(boxTop, boxBtm, volume + volume + volume, "Bull", boxLoc)
newOrderBlockInfo.obLowVolume := volume
newOrderBlockInfo.obHighVolume := volume + volume
obSize = math.abs(newOrderBlockInfo.top - newOrderBlockInfo.bottom)
if obSize <= atrt * maxATRMult
bullishOrderBlocksList.unshift(newOrderBlockInfo)
if bullishOrderBlocksList.size() > maxOrderBlocks
bullishOrderBlocksList.pop()
// Bearish Order Block
bearishBreaked = 0
if bearishOrderBlocksList.size() > 0
for i = bearishOrderBlocksList.size() - 1 to 0
currentOB = bearishOrderBlocksList.get(i)
if not currentOB.breaker
if (obEndMethod == "Wick" ? high : math.max(open, close)) > currentOB.top
currentOB.breaker := true
currentOB.breakTime := time
currentOB.bbVolume := volume
else
if low < currentOB.bottom
bearishOrderBlocksList.remove(i)
else if i < bearishOrderBlocks and btm.y > currentOB.bottom and btm.y < currentOB.top
bearishBreaked := 1
if close < btm.y and not btm.crossed
btm.crossed := true
boxBtm = min
boxTop = max
boxLoc = time
for i = 1 to (bar_index - btm.x) - 1
boxTop := math.max(max, boxTop)
boxBtm := boxTop == max ? min : boxBtm
boxLoc := boxTop == max ? time : boxLoc
newOrderBlockInfo = orderBlockInfo.new(boxTop, boxBtm, volume + volume + volume, "Bear", boxLoc)
newOrderBlockInfo.obLowVolume := volume + volume
newOrderBlockInfo.obHighVolume := volume
obSize = math.abs(newOrderBlockInfo.top - newOrderBlockInfo.bottom)
if obSize <= atrt * maxATRMult
bearishOrderBlocksList.unshift(newOrderBlockInfo)
if bearishOrderBlocksList.size() > maxOrderBlocks
bearishOrderBlocksList.pop()
true
areaOfOB (orderBlockInfo OBInfoF) =>
float XA1 = OBInfoF.startTime
float XA2 = na(OBInfoF.breakTime) ? time + 1 : OBInfoF.breakTime
float YA1 = OBInfoF.top
float YA2 = OBInfoF.bottom
float edge1 = math.sqrt((XA2 - XA1) * (XA2 - XA1) + (YA2 - YA2) * (YA2 - YA2))
float edge2 = math.sqrt((XA2 - XA2) * (XA2 - XA2) + (YA2 - YA1) * (YA2 - YA1))
float totalArea = edge1 * edge2
totalArea
isOBValid (orderBlockInfo OBInfo) =>
valid = true
if OBInfo.disabled
valid := false
valid
doOBsTouch (orderBlockInfo OBInfo1, orderBlockInfo OBInfo2) =>
float XA1 = OBInfo1.startTime
float XA2 = na(OBInfo1.breakTime) ? time + 1 : OBInfo1.breakTime
float YA1 = OBInfo1.top
float YA2 = OBInfo1.bottom
float XB1 = OBInfo2.startTime
float XB2 = na(OBInfo2.breakTime) ? time + 1 : OBInfo2.breakTime
float YB1 = OBInfo2.top
float YB2 = OBInfo2.bottom
float intersectionArea = math.max(0, math.min(XA2, XB2) - math.max(XA1, XB1)) * math.max(0, math.min(YA1, YB1) - math.max(YA2, YB2))
float unionArea = areaOfOB(OBInfo1) + areaOfOB(OBInfo2) - intersectionArea
float overlapPercentage = (intersectionArea / unionArea) * 100.0
if overlapPercentage > overlapThresholdPercentage
true
else
false
combineOBsFunc () =>
if allOrderBlocksList.size() > 0
lastCombinations = 999
while lastCombinations > 0
lastCombinations := 0
for i = 0 to allOrderBlocksList.size() - 1
curOB1 = allOrderBlocksList.get(i)
for j = 0 to allOrderBlocksList.size() - 1
curOB2 = allOrderBlocksList.get(j)
if i == j
continue
if not isOBValid(curOB1.info) or not isOBValid(curOB2.info)
continue
if curOB1.info.obType != curOB2.info.obType
continue
if doOBsTouch(curOB1.info, curOB2.info)
if curOB1.info.bottom < curOB2.info.top and curOB1.info.top > curOB2.info.top
curOB2.info.top := curOB1.info.bottom
lastCombinations := lastCombinations + 1
if curOB1.info.top >= curOB2.info.top and curOB1.info.bottom <= curOB2.info.bottom
curOB2.info.disabled := true
lastCombinations := lastCombinations + 1
reqSeq (timeframeStr) =>
= request.security(syminfo.tickerid, timeframeStr, )
getTFData (timeframeInfo timeframeInfoF, timeframeStr) =>
if not isTimeframeLower(timeframeInfoF.timeframeStr, timeframe.period) and timeframeInfoF.isEnabled
= reqSeq(timeframeStr)
else
handleTimeframeInfo (timeframeInfo timeframeInfoF, bullishOrderBlocksListF, bearishOrderBlocksListF) =>
if not isTimeframeLower(timeframeInfoF.timeframeStr, timeframe.period) and timeframeInfoF.isEnabled
timeframeInfoF.bullishOrderBlocksList := bullishOrderBlocksListF
timeframeInfoF.bearishOrderBlocksList := bearishOrderBlocksListF
handleOrderBlocksFinal () =>
if DEBUG
log.info("Bullish OB Count " + str.tostring(bullishOrderBlocksList.size()))
log.info("Bearish OB Count " + str.tostring(bearishOrderBlocksList.size()))
if allOrderBlocksList.size () > 0
for i = 0 to allOrderBlocksList.size() - 1
safeDeleteOrderBlock(allOrderBlocksList.get(i))
allOrderBlocksList.clear()
for i = 0 to timeframeInfos.size() - 1
curTimeframe = timeframeInfos.get(i)
if na(curTimeframe)
continue
if not curTimeframe.isEnabled
continue
if na(curTimeframe.bullishOrderBlocksList)
continue
if curTimeframe.bullishOrderBlocksList.size() > 0
while curTimeframe.bullishOrderBlocksList.size() > bullishOrderBlocks
curTimeframe.bullishOrderBlocksList.pop()
for j = 0 to math.min(curTimeframe.bullishOrderBlocksList.size() - 1, bullishOrderBlocks - 1)
bool overlapped = false
orderBlockInfoF = curTimeframe.bullishOrderBlocksList.get(j)
orderBlockInfoF.timeframeStr := curTimeframe.timeframeStr
if allOrderBlocksList.size() > 0
for t = 0 to allOrderBlocksList.size()-1
if doOBsTouch(orderBlockInfoF, allOrderBlocksList.get(t).info)
overlapped := true
if overlapped == false
allOrderBlocksList.unshift(createOrderBlock(orderBlockInfo.copy(orderBlockInfoF)))
if not na(curTimeframe.bearishOrderBlocksList) and curTimeframe.bearishOrderBlocksList.size() > 0
while curTimeframe.bearishOrderBlocksList.size() > bearishOrderBlocks
curTimeframe.bearishOrderBlocksList.pop()
for j = 0 to math.min(curTimeframe.bearishOrderBlocksList.size() - 1, bearishOrderBlocks - 1)
orderBlockInfoF = curTimeframe.bearishOrderBlocksList.get(j)
orderBlockInfoF.timeframeStr := curTimeframe.timeframeStr
bool overlapped = false
if allOrderBlocksList.size() > 0
for t = 0 to allOrderBlocksList.size()-1
bt1 = orderBlockInfoF.bottom
tp1 = orderBlockInfoF.top
bt2 = allOrderBlocksList.get(t).info.bottom
tp2 = allOrderBlocksList.get(t).info.top
if tp2 >= tp1 and bt2 <= bt1
overlapped := true
if overlapped == false
allOrderBlocksList.unshift(createOrderBlock(orderBlockInfo.copy(orderBlockInfoF)))
if combineOBs
combineOBsFunc()
if allOrderBlocksList.size() > 0
for i = 0 to allOrderBlocksList.size() - 1
curOB = allOrderBlocksList.get(i)
if isOBValid(curOB.info)
renderOrderBlock(curOB)
findOrderBlocks()
currentTF = timeframe.period
= getTFData(timeframeInfos.get(0), timeframe1)
= getTFData(timeframeInfos.get(1), "15")
= getTFData(timeframeInfos.get(2), "1")
if barstate.isconfirmed
if tfe(currentTF, timeframe1)
handleTimeframeInfo(timeframeInfos.get(0), bullishOrderBlocksListTimeframe1, bearishOrderBlocksListTimeframe1)
if tfe(currentTF, "15")
handleTimeframeInfo(timeframeInfos.get(1), bullishOrderBlocksListTimeframe2, bearishOrderBlocksListTimeframe2)
if tfe(currentTF, "1")
handleTimeframeInfo(timeframeInfos.get(2), bullishOrderBlocksListTimeframe3, bearishOrderBlocksListTimeframe3)
handleOrderBlocksFinal()
//-----------------------------------------------------------------------------}
//Price Action Concepts
//-----------------------------------------------------------------------------{
var eq_prev_top = 0.
var eq_top_x = 0
var eq_prev_btm = 0.
var eq_btm_x = 0
if show_eq
eq_top = ta.pivothigh(eq_len, eq_len)
eq_btm = ta.pivotlow(eq_len, eq_len)
if eq_top
max = math.max(eq_top, eq_prev_top)
min = math.min(eq_top, eq_prev_top)
if max < min + atr * eq_threshold
eqh_line = line.new(eq_top_x, eq_prev_top, n-eq_len, eq_top
, color = bear_css
, style = line.style_dotted)
eqh_lbl = label.new(int(math.avg(n-eq_len, eq_top_x)), eq_top, 'EQH'
, color = #00000000
, textcolor = bear_css
, style = label.style_label_down
, size = eqhl_lbl_size)
if mode == 'Present'
line.delete(eqh_line)
label.delete(eqh_lbl)
eqh_alert := true
eq_prev_top := eq_top
eq_top_x := n-eq_len
if eq_btm
max = math.max(eq_btm, eq_prev_btm)
min = math.min(eq_btm, eq_prev_btm)
if min > max - atr * eq_threshold
eql_line = line.new(eq_btm_x, eq_prev_btm, n-eq_len, eq_btm
, color = bull_css
, style = line.style_dotted)
eql_lbl = label.new(int(math.avg(n-eq_len, eq_btm_x)), eq_btm, 'EQL'
, color = #00000000
, textcolor = bull_css
, style = label.style_label_up
, size = eqhl_lbl_size)
eql_alert := true
if mode == 'Present'
line.delete(eql_line)
label.delete(eql_lbl)
eq_prev_btm := eq_btm
eq_btm_x := n-eq_len
//-----------------------------------------------------------------------------}
//Fair Value Gaps
//-----------------------------------------------------------------------------{
var bullish_fvg_max = array.new_box(0)
var bullish_fvg_min = array.new_box(0)
var bearish_fvg_max = array.new_box(0)
var bearish_fvg_min = array.new_box(0)
float bullish_fvg_avg = na
float bearish_fvg_avg = na
bullish_fvg_cnd = false
bearish_fvg_cnd = false
//-----------------------------------------------------------------------------}
//Previous day/week high/lows
//-----------------------------------------------------------------------------{
//Daily high/low
= request.security(syminfo.tickerid, 'D', hl()
, lookahead = barmerge.lookahead_on)
//Weekly high/low
= request.security(syminfo.tickerid, 'W', hl()
, lookahead = barmerge.lookahead_on)
//Monthly high/low
= request.security(syminfo.tickerid, 'M', hl()
, lookahead = barmerge.lookahead_on)
//Display Daily
if show_pdhl
phl(pdh, pdl, 'D', pdhl_css)
//Display Weekly
if show_pwhl
phl(pwh, pwl, 'W', pwhl_css)
//Display Monthly
if show_pmhl
phl(pmh, pml, 'M', pmhl_css)
//-----------------------------------------------------------------------------}
//Premium/Discount/Equilibrium zones
//-----------------------------------------------------------------------------{
var premium = box.new(na, na, na, na
, bgcolor = color.new(premium_css, 80)
, border_color = na)
var premium_lbl = label.new(na, na
, text = 'Premium'
, color = TRANSP_CSS
, textcolor = premium_css
, style = label.style_label_down
, size = size.small)
var eq = box.new(na, na, na, na
, bgcolor = color.rgb(120, 123, 134, 80)
, border_color = na)
var eq_lbl = label.new(na, na
, text = 'Equilibrium'
, color = TRANSP_CSS
, textcolor = eq_css
, style = label.style_label_left
, size = size.small)
var discount = box.new(na, na, na, na
, bgcolor = color.new(discount_css, 80)
, border_color = na)
var discount_lbl = label.new(na, na
, text = 'Discount'
, color = TRANSP_CSS
, textcolor = discount_css
, style = label.style_label_up
, size = size.small)
var e = box.new(na, na, na, na
, bgcolor = color.rgb(120, 123, 134, 80)
, border_color = color.rgb(120, 123, 134))
var e_lbl = label.new(na, na
, text = 'Entry Zone'
, color = TRANSP_CSS
, textcolor = eq_css
, style = label.style_label_left
, size = size.small)
//Show Premium/Discount Areas
var l = line.new(na, na, na, na, color=color.rgb(120, 123, 134), style=line.style_dashed, width=1)
fib1 = 0.618
fib2 = 0.786
fib3 = (fib1+fib2)/2
fib1 := 1-fib1
fib2 := 1-fib2
fib3 := 1-fib3
//timeLeft = math.max(top_x, btm_x)
price1 = swingBOS < 0 ? trail_up : trail_dn
price2 = swingBOS < 0 ? trail_dn : trail_up
diff = price2-price1
fib1level = price1+diff*fib1
fib2level = price1+diff*fib2
fib3level = price1+diff*fib3
//Show Premium/Discount Areas
if barstate.islast and show_sd
line.set_xy1(l, math.max(top_x, btm_x), fib3level)
line.set_xy2(l, bar_index, fib3level)
box.set_lefttop(e, math.max(top_x, btm_x), fib1level)
box.set_rightbottom(e, bar_index, fib2level)
label.set_xy(e_lbl, bar_index, fib3level)
avg = math.avg(trail_up, trail_dn)
box.set_lefttop(premium, math.max(top_x, btm_x), trail_up)
box.set_rightbottom(premium, n, .95 * trail_up + .05 * trail_dn)
label.set_xy(premium_lbl, int(math.avg(math.max(top_x, btm_x), n)), trail_up)
box.set_lefttop(eq, math.max(top_x, btm_x), .525 * trail_up + .475*trail_dn)
box.set_rightbottom(eq, n, .525 * trail_dn + .475 * trail_up)
label.set_xy(eq_lbl, n, avg)
box.set_lefttop(discount, math.max(top_x, btm_x), .95 * trail_dn + .05 * trail_up)
box.set_rightbottom(discount, n, trail_dn)
label.set_xy(discount_lbl, int(math.avg(math.max(top_x, btm_x), n)), trail_dn)
//-----------------------------------------------------------------------------}
//Trend
//-----------------------------------------------------------------------------{
var color trend_css = na
if show_trend
if style == 'Colored'
trend_css := candlecolor == 1 ? bull_css : candlecolor == 0 ? purplecolor : bear_css
else if style == 'Monochrome'
trend_css := itrend == 1 ? #b2b5be : #5d606b
barcolor(trend_css)
//-----------------------------------------------------------------------------}
//Alerts
//-----------------------------------------------------------------------------{
//Internal Structure
alertcondition(bull_ibos_alert, 'Internal Bullish BOS', 'Internal Bullish BOS formed')
alertcondition(bull_ichoch_alert, 'Internal Bullish CHoCH', 'Internal Bullish CHoCH formed')
alertcondition(bear_ibos_alert, 'Internal Bearish BOS', 'Internal Bearish BOS formed')
alertcondition(bear_ichoch_alert, 'Internal Bearish CHoCH', 'Internal Bearish CHoCH formed')
//Swing Structure
alertcondition(bull_bos_alert, 'Bullish BOS', 'Internal Bullish BOS formed')
alertcondition(bull_choch_alert, 'Bullish CHoCH', 'Internal Bullish CHoCH formed')
alertcondition(bear_bos_alert, 'Bearish BOS', 'Bearish BOS formed')
alertcondition(bear_choch_alert, 'Bearish CHoCH', 'Bearish CHoCH formed')
//order Blocks
alertcondition(bull_iob_break, 'Bullish Internal OB Breakout', 'Price broke bullish internal OB')
alertcondition(bear_iob_break, 'Bearish Internal OB Breakout', 'Price broke bearish internal OB')
alertcondition(bull_ob_break, 'Bullish Swing OB Breakout', 'Price broke bullish swing OB')
alertcondition(bear_ob_break, 'Bearish Swing OB Breakout', 'Price broke bearish swing OB')
//Price Action Concepts
alertcondition(eqh_alert, 'Equal Highs', 'Equal highs detected')
alertcondition(eql_alert, 'Equal Lows', 'Equal lows detected')
//FVG
alertcondition(bullish_fvg_cnd, 'Bullish FVG', 'Bullish FVG formed')
alertcondition(bearish_fvg_cnd, 'Bearish FVG', 'Bearish FVG formed')
//-----------------------------------------------------------------------------}
tb = table.new(position.top_right, 5, 5, bgcolor = #1e222d , border_color = #373a46 , border_width = 1 , frame_color = #373a46 , frame_width = 1)
dashboardGreenText =#42bda8
squeezegreent = #0a907a
dashboardRedText = #ee787d
squeezeredt = #ed3544
dashboardGreenBackground = #284444
squeezegreenbg = #1a3a3e
dashboardRedBackground = #49343e
squeezeredbg = #482632
swingBOS1 = request.security(syminfo.ticker, scannerTimeframe, swingBOS)
internalBOS1 = request.security(syminfo.ticker, scannerTimeframe, internalBOS)
string swingText = swingBOS1 == 1 or swingBOS1 == -1 ? "CHoCH" : "BOS (" + str.tostring(math.abs(swingBOS1)-1) + ")"
string internalText = internalBOS1 == 1 or internalBOS1 == -1 ? "CHoCH" : "BOS (" + str.tostring(math.abs(internalBOS1)-1) + ")"
swingTextColor = swingBOS1 > 0 ? dashboardGreenText : dashboardRedText
swingBackground = swingBOS1 > 0 ? squeezegreenbg : squeezeredbg
iTextColor = internalBOS1 > 0 ? dashboardGreenText : dashboardRedText
iBackground = internalBOS1 > 0 ? squeezegreenbg : squeezeredbg
if structureScannerOn
if barstate.islast
tb.cell(0, 0, "Structure Scanner (" + formatTimeframeString(scannerTimeframe) + ')', text_size = size.small, text_color = #9399a2)
tb.cell(0, 1, internalText, text_color = iTextColor, bgcolor = iBackground, text_size = size.small)
tb.cell(0, 2,swingText, text_color = swingTextColor, bgcolor = swingBackground, text_size = size.small)
if barstate.isfirst
var table errorBox = table.new(position.bottom_right, 1, 1, bgcolor = color.new(#363a45, 100))
table.cell(errorBox, 0, 0, "SDK © Algoman.life", text_color = color.gray, text_halign = text.align_center, text_size = size.normal)
No comments:
Post a Comment