//@version=5
indicator("RoyalPrince SMC", "RoyalPrince SMC"
, 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 = [Link]('Historical'
, options = ['Historical', 'Present']
, group = 'Smart Money Concepts'
, tooltip = MODE_TOOLTIP)
style = [Link]('Colored'
, options = ['Colored', 'Monochrome']
, group = 'Smart Money Concepts'
, tooltip = STYLE_TOOLTIP)
show_trend = input(false, 'Color Candles'
, group = 'Smart Money Concepts'
, tooltip = COLOR_CANDLES_TOOLTIP)
//----------------------------------------}
//Internal Structure
//----------------------------------------{
show_internals = input(true, 'Show Internal Structure'
, group = 'Real Time Internal Structure'
, tooltip = SHOW_INTERNAL)
show_ibull = [Link]('All', 'Bullish Structure'
, options = ['All', 'BOS', 'CHoCH']
, inline = 'ibull'
, group = 'Real Time Internal Structure')
swing_ibull_css = input(#089981, ''
, inline = 'ibull'
, group = 'Real Time Internal Structure')
//Bear Structure
show_ibear = [Link]('All', 'Bearish Structure'
, options = ['All', 'BOS', 'CHoCH']
, inline = 'ibear'
, group = 'Real Time Internal Structure')
swing_ibear_css = input(#f23645, ''
, inline = 'ibear'
, group = 'Real Time Internal Structure')
ifilter_confluence = input(false, 'Confluence Filter'
, group = 'Real Time Internal Structure'
, tooltip = CONFLUENCE_FILTER)
internal_structure_size = [Link]('Tiny', 'Internal Label Size'
, options = ['Tiny', 'Small', 'Normal']
, group = 'Real Time Internal Structure')
//----------------------------------------}
//Swing Structure
//----------------------------------------{
show_Structure = input(true, 'Show Swing Structure'
, group = 'Real Time Swing Structure'
, tooltip = SHOW_SWING)
//Bull Structure
show_bull = [Link]('All', 'Bullish Structure'
, options = ['All', 'BOS', 'CHoCH']
, inline = 'bull'
, group = 'Real Time Swing Structure')
swing_bull_css = input(#089981, ''
, inline = 'bull'
, group = 'Real Time Swing Structure')
//Bear Structure
show_bear = [Link]('All', 'Bearish Structure'
, options = ['All', 'BOS', 'CHoCH']
, inline = 'bear'
, group = 'Real Time Swing Structure')
swing_bear_css = input(#f23645, ''
, inline = 'bear'
, group = 'Real Time Swing Structure')
swing_structure_size = [Link]('Small', 'Swing Label Size'
, options = ['Tiny', 'Small', 'Normal']
, group = 'Real Time Swing Structure')
//Swings
show_swings = input(false, 'Show Swings Points'
, inline = 'swings'
, group = 'Real Time Swing Structure'
, tooltip = SHOW_SWING_POINTS)
length = [Link](50, ''
, minval = 10
, inline = 'swings'
, group = 'Real Time Swing Structure')
show_hl_swings = input(true, 'Show Strong/Weak High/Low'
, group = 'Real Time Swing Structure'
, tooltip = SHOW_SWHL_POINTS)
//----------------------------------------}
//Order Blocks
//----------------------------------------{
show_iob = input(true, 'Internal Order Blocks'
, inline = 'iob'
, group = 'Order Blocks'
, tooltip = INTERNAL_OB)
iob_showlast = [Link](5, ''
, minval = 1
, inline = 'iob'
, group = 'Order Blocks')
show_ob = input(false, 'Swing Order Blocks'
, inline = 'ob'
, group = 'Order Blocks'
, tooltip = SWING_OB)
ob_showlast = [Link](5, ''
, minval = 1
, inline = 'ob'
, group = 'Order Blocks')
ob_filter = [Link]('Atr', 'Order Block Filter'
, options = ['Atr', 'Cumulative Mean Range']
, group = 'Order Blocks'
, tooltip = FILTER_OB)
ibull_ob_css = [Link]([Link](#3179f5, 80), 'Internal Bullish OB'
, group = 'Order Blocks')
ibear_ob_css = [Link]([Link](#f77c80, 80), 'Internal Bearish OB'
, group = 'Order Blocks')
bull_ob_css = [Link]([Link](#1848cc, 80), 'Bullish OB'
, group = 'Order Blocks')
bear_ob_css = [Link]([Link](#b22833, 80), 'Bearish OB'
, group = 'Order Blocks')
//----------------------------------------}
//EQH/EQL
//----------------------------------------{
show_eq = input(true, 'Equal High/Low'
, group = 'EQH/EQL'
, tooltip = SHOW_EQHL)
eq_len = [Link](3, 'Bars Confirmation'
, minval = 1
, group = 'EQH/EQL'
, tooltip = EQHL_BARS)
eq_threshold = [Link](0.1, 'Threshold'
, minval = 0
, maxval = 0.5
, step = 0.1
, group = 'EQH/EQL'
, tooltip = EQHL_THRESHOLD)
eq_size = [Link]('Tiny', 'Label Size'
, options = ['Tiny', 'Small', 'Normal']
, group = 'EQH/EQL')
//----------------------------------------}
//Fair Value Gaps
//----------------------------------------{
show_fvg = input(false, 'Fair Value Gaps'
, group = 'Fair Value Gaps'
, tooltip = SHOW_FVG)
fvg_auto = input(true, "Auto Threshold"
, group = 'Fair Value Gaps'
, tooltip = AUTO_FVG)
fvg_tf = [Link]('', "Timeframe"
, group = 'Fair Value Gaps'
, tooltip = FVG_TF)
bull_fvg_css = [Link]([Link](#00ff68, 70), 'Bullish FVG'
, group = 'Fair Value Gaps')
bear_fvg_css = [Link]([Link](#ff0008, 70), 'Bearish FVG'
, group = 'Fair Value Gaps')
fvg_extend = [Link](1, "Extend FVG"
, minval = 0
, group = 'Fair Value Gaps'
, tooltip = EXTEND_FVG)
//----------------------------------------}
//Previous day/week high/low
//----------------------------------------{
//Daily
show_pdhl = input(false, 'Daily'
, inline = 'daily'
, group = 'Highs & Lows MTF')
pdhl_style = [Link]('⎯⎯⎯', ''
, 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 = [Link]('⎯⎯⎯', ''
, 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 = [Link]('⎯⎯⎯', ''
, options = ['⎯⎯⎯', '----', '····']
, inline = 'monthly'
, group = 'Highs & Lows MTF')
pmhl_css = input(#2157f3, ''
, inline = 'monthly'
, group = 'Highs & Lows MTF')
//----------------------------------------}
//Premium/Discount zones
//----------------------------------------{
show_sd = input(false, 'Premium/Discount Zones'
, group = 'Premium & Discount Zones'
, tooltip = PED_ZONES)
premium_css = [Link](#f23645, 'Premium Zone'
, group = 'Premium & Discount Zones')
eq_css = [Link](#b2b5be, 'Equilibrium Zone'
, group = 'Premium & Discount Zones')
discount_css = [Link](#089981, 'Discount Zone'
, group = 'Premium & Discount Zones')
//-----------------------------------------------------------------------------}
//Functions
//-----------------------------------------------------------------------------{
n = bar_index
atr = [Link](200)
cmean_range = [Link](high - low) / n
//HL Output function
hl() => [high, low]
//Get ohlc values function
get_ohlc()=> [close[1], open[1], high, low, high[2], low[2]]
//Display Structure function
display_Structure(x, y, txt, css, dashed, down, lbl_size)=>
structure_line = [Link](x, y, n, y
, color = css
, style = dashed ? line.style_dashed : line.style_solid)
structure_lbl = [Link](int([Link](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'
[Link](structure_line[1])
[Link](structure_lbl[1])
//Swings detection/measurements
swings(len)=>
var os = 0
upper = [Link](len)
lower = [Link](len)
os := high[len] > upper ? 0 : low[len] < lower ? 1 : os[1]
top = os == 0 and os[1] != 0 ? high[len] : 0
btm = os == 1 and os[1] != 1 ? low[len] : 0
[top, btm]
//Order block coordinates function
ob_coord(use_max, loc, target_top, target_btm, target_left, target_type)=>
min = 99999999.
max = 0.
idx = 1
ob_threshold = ob_filter == 'Atr' ? atr : cmean_range
//Search for highest/lowest high within the structure interval and get range
if use_max
for i = 1 to (n - loc)-1
if (high[i] - low[i]) < ob_threshold[i] * 2
max := [Link](high[i], max)
min := max == high[i] ? low[i] : min
idx := max == high[i] ? i : idx
else
for i = 1 to (n - loc)-1
if (high[i] - low[i]) < ob_threshold[i] * 2
min := [Link](low[i], min)
max := min == low[i] ? high[i] : max
idx := min == low[i] ? i : idx
[Link](target_top, max)
[Link](target_btm, min)
[Link](target_left, time[idx])
[Link](target_type, use_max ? -1 : 1)
//Set order blocks
display_ob(boxes, target_top, target_btm, target_left, target_type, show_last,
swing, size)=>
for i = 0 to [Link](show_last-1, size-1)
get_box = [Link](boxes, i)
box.set_lefttop(get_box, [Link](target_left, i), [Link](target_top,
i))
box.set_rightbottom(get_box, [Link](target_left, i),
[Link](target_btm, i))
box.set_extend(get_box, [Link])
color css = na
if swing
if style == 'Monochrome'
css := [Link](target_type, i) == 1 ? [Link](#b2b5be, 80) :
[Link](#5d606b, 80)
border_css = [Link](target_type, i) == 1 ? #b2b5be : #5d606b
box.set_border_color(get_box, border_css)
else
css := [Link](target_type, i) == 1 ? bull_ob_css : bear_ob_css
box.set_border_color(get_box, css)
box.set_bgcolor(get_box, css)
else
if style == 'Monochrome'
css := [Link](target_type, i) == 1 ? [Link](#b2b5be, 80) :
[Link](#5d606b, 80)
else
css := [Link](target_type, i) == 1 ? ibull_ob_css : ibear_ob_css
box.set_border_color(get_box, css)
box.set_bgcolor(get_box, css)
//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 = [Link](na,na,na,na
, xloc = xloc.bar_time
, color = css
, style = get_line_style(pdhl_style))
var label high_lbl = [Link](na,na
, xloc = xloc.bar_time
, text = [Link]('P{0}H', tf)
, color = TRANSP_CSS
, textcolor = css
, size = [Link]
, style = label.style_label_left)
var line low_line = [Link](na,na,na,na
, xloc = xloc.bar_time
, color = css
, style = get_line_style(pdhl_style))
var label low_lbl = [Link](na,na
, xloc = xloc.bar_time
, text = [Link]('P{0}L', tf)
, color = TRANSP_CSS
, textcolor = css
, size = [Link]
, style = label.style_label_left)
hy = [Link](h != h[1], h, 1)
hx = [Link](h == high, time, 1)
ly = [Link](l != l[1], l, 1)
lx = [Link](l == low, time, 1)
if [Link]
ext = time + (time - time[1])*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'
? [Link]
: internal_structure_size == 'Small'
? [Link]
: [Link]
var swing_structure_lbl_size = swing_structure_size == 'Tiny'
? [Link]
: swing_structure_size == 'Small'
? [Link]
: [Link]
var eqhl_lbl_size = eq_size == 'Tiny'
? [Link]
: eq_size == 'Small'
? [Link]
: [Link]
//Swings
[top, btm] = swings(length)
[itop, ibtm] = swings(5)
//-----------------------------------------------------------------------------}
//Pivot High
//-----------------------------------------------------------------------------{
var line extend_top = na
var label extend_top_lbl = [Link](na, na
, color = TRANSP_CSS
, textcolor = bear_css
, style = label.style_label_down
, size = [Link])
if top
top_cross := true
txt_top := top > top_y ? 'HH' : 'LH'
if show_swings
top_lbl = [Link](n-length, top, txt_top
, color = TRANSP_CSS
, textcolor = bear_css
, style = label.style_label_down
, size = swing_structure_lbl_size)
if mode == 'Present'
[Link](top_lbl[1])
//Extend recent top to last bar
[Link](extend_top[1])
extend_top := [Link](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 := [Link](high, trail_up)
trail_up_x := trail_up == high ? n : trail_up_x
//Set top extension label/line
if [Link] 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 = [Link](na, na
, color = TRANSP_CSS
, textcolor = bull_css
, style = label.style_label_up
, size = [Link])
if btm
btm_cross := true
txt_btm := btm < btm_y ? 'LL' : 'HL'
if show_swings
btm_lbl = [Link](n - length, btm, txt_btm
, color = TRANSP_CSS
, textcolor = bull_css
, style = label.style_label_up
, size = swing_structure_lbl_size)
if mode == 'Present'
[Link](btm_lbl[1])
//Extend recent btm to last bar
[Link](extend_btm[1])
extend_btm := [Link](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 := [Link](low, trail_dn)
trail_dn_x := trail_dn == low ? n : trail_dn_x
//Set btm extension label/line
if [Link] 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 - [Link](close, open) > [Link](close, open - low)
//Detect internal bullish Structure
if [Link](close, itop_y) and itop_cross and top_y != itop_y and
bull_concordant
bool choch = na
if itrend < 0
choch := true
bull_ichoch_alert := true
else
bull_ibos_alert := true
txt = choch ? 'CHoCH' : 'BOS'
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
//Internal Order Block
if show_iob
ob_coord(false, itop_x, iob_top, iob_btm, iob_left, iob_type)
//Detect bullish Structure
if [Link](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 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
if show_ob
ob_coord(false, top_x, ob_top, ob_btm, ob_left, ob_type)
top_cross := false
trend := 1
//-----------------------------------------------------------------------------}
//Pivot Low BOS/CHoCH
//-----------------------------------------------------------------------------{
var bear_concordant = true
if ifilter_confluence
bear_concordant := high - [Link](close, open) < [Link](close, open - low)
//Detect internal bearish Structure
if [Link](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
else
bear_ibos_alert := true
txt = choch ? 'CHoCH' : 'BOS'
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
if show_iob
ob_coord(true, ibtm_x, iob_top, iob_btm, iob_left, iob_type)
//Detect bearish Structure
if [Link](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 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
if show_ob
ob_coord(true, btm_x, ob_top, ob_btm, ob_left, ob_type)
btm_cross := false
trend := -1
//-----------------------------------------------------------------------------}
//Order Blocks
//-----------------------------------------------------------------------------{
//Set order blocks
var iob_boxes = array.new_box(0)
var ob_boxes = array.new_box(0)
//Delete internal order blocks box coordinates if top/bottom is broken
for element in iob_type
index = [Link](iob_type, element)
if close < [Link](iob_btm, index) and element == 1
[Link](iob_top, index)
[Link](iob_btm, index)
[Link](iob_left, index)
[Link](iob_type, index)
bull_iob_break := true
else if close > [Link](iob_top, index) and element == -1
[Link](iob_top, index)
[Link](iob_btm, index)
[Link](iob_left, index)
[Link](iob_type, index)
bear_iob_break := true
//Delete internal order blocks box coordinates if top/bottom is broken
for element in ob_type
index = [Link](ob_type, element)
if close < [Link](ob_btm, index) and element == 1
[Link](ob_top, index)
[Link](ob_btm, index)
[Link](ob_left, index)
[Link](ob_type, index)
bull_ob_break := true
else if close > [Link](ob_top, index) and element == -1
[Link](ob_top, index)
[Link](ob_btm, index)
[Link](ob_left, index)
[Link](ob_type, index)
bear_ob_break := true
iob_size = [Link](iob_type)
ob_size = [Link](ob_type)
if [Link]
if show_iob
for i = 0 to iob_showlast-1
[Link](iob_boxes, [Link](na,na,na,na, xloc = xloc.bar_time))
if show_ob
for i = 0 to ob_showlast-1
[Link](ob_boxes, [Link](na,na,na,na, xloc = xloc.bar_time))
if iob_size > 0
if [Link]
display_ob(iob_boxes, iob_top, iob_btm, iob_left, iob_type, iob_showlast,
false, iob_size)
if ob_size > 0
if [Link]
display_ob(ob_boxes, ob_top, ob_btm, ob_left, ob_type, ob_showlast, true,
ob_size)
//-----------------------------------------------------------------------------}
//EQH/EQL
//-----------------------------------------------------------------------------{
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 = [Link](eq_len, eq_len)
eq_btm = [Link](eq_len, eq_len)
if eq_top
max = [Link](eq_top, eq_prev_top)
min = [Link](eq_top, eq_prev_top)
if max < min + atr * eq_threshold
eqh_line = [Link](eq_top_x, eq_prev_top, n-eq_len, eq_top
, color = bear_css
, style = line.style_dotted)
eqh_lbl = [Link](int([Link](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'
[Link](eqh_line[1])
[Link](eqh_lbl[1])
eqh_alert := true
eq_prev_top := eq_top
eq_top_x := n-eq_len
if eq_btm
max = [Link](eq_btm, eq_prev_btm)
min = [Link](eq_btm, eq_prev_btm)
if min > max - atr * eq_threshold
eql_line = [Link](eq_btm_x, eq_prev_btm, n-eq_len, eq_btm
, color = bull_css
, style = line.style_dotted)
eql_lbl = [Link](int([Link](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'
[Link](eql_line[1])
[Link](eql_lbl[1])
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
[src_c1, src_o1, src_h, src_l, src_h2, src_l2] =
[Link]([Link], fvg_tf, get_ohlc())
if show_fvg
delta_per = (src_c1 - src_o1) / src_o1 * 100
change_tf = [Link](fvg_tf)
threshold = fvg_auto ? [Link]([Link](change_tf ? delta_per : 0)) / n * 2
: 0
//FVG conditions
bullish_fvg_cnd := src_l > src_h2
and src_c1 > src_h2
and delta_per > threshold
and change_tf
bearish_fvg_cnd := src_h < src_l2
and src_c1 < src_l2
and -delta_per > threshold
and change_tf
//FVG Areas
if bullish_fvg_cnd
[Link](bullish_fvg_max, [Link](n-1, src_l, n + fvg_extend,
[Link](src_l, src_h2)
, border_color = bull_fvg_css
, bgcolor = bull_fvg_css))
[Link](bullish_fvg_min, [Link](n-1, [Link](src_l, src_h2), n +
fvg_extend, src_h2
, border_color = bull_fvg_css
, bgcolor = bull_fvg_css))
if bearish_fvg_cnd
[Link](bearish_fvg_max, [Link](n-1, src_h, n + fvg_extend,
[Link](src_h, src_l2)
, border_color = bear_fvg_css
, bgcolor = bear_fvg_css))
[Link](bearish_fvg_min, [Link](n-1, [Link](src_h, src_l2), n +
fvg_extend, src_l2
, border_color = bear_fvg_css
, bgcolor = bear_fvg_css))
for bx in bullish_fvg_min
if low < box.get_bottom(bx)
[Link](bx)
[Link]([Link](bullish_fvg_max, [Link](bullish_fvg_min,
bx)))
for bx in bearish_fvg_max
if high > box.get_top(bx)
[Link](bx)
[Link]([Link](bearish_fvg_min, [Link](bearish_fvg_max,
bx)))
//-----------------------------------------------------------------------------}
//Previous day/week high/lows
//-----------------------------------------------------------------------------{
//Daily high/low
[pdh, pdl] = [Link]([Link], 'D', hl()
, lookahead = barmerge.lookahead_on)
//Weekly high/low
[pwh, pwl] = [Link]([Link], 'W', hl()
, lookahead = barmerge.lookahead_on)
//Monthly high/low
[pmh, pml] = [Link]([Link], '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 = [Link](na, na, na, na
, bgcolor = [Link](premium_css, 80)
, border_color = na)
var premium_lbl = [Link](na, na
, text = 'Premium'
, color = TRANSP_CSS
, textcolor = premium_css
, style = label.style_label_down
, size = [Link])
var eq = [Link](na, na, na, na
, bgcolor = [Link](120, 123, 134, 80)
, border_color = na)
var eq_lbl = [Link](na, na
, text = 'Equilibrium'
, color = TRANSP_CSS
, textcolor = eq_css
, style = label.style_label_left
, size = [Link])
var discount = [Link](na, na, na, na
, bgcolor = [Link](discount_css, 80)
, border_color = na)
var discount_lbl = [Link](na, na
, text = 'Discount'
, color = TRANSP_CSS
, textcolor = discount_css
, style = label.style_label_up
, size = [Link])
//Show Premium/Discount Areas
if [Link] and show_sd
avg = [Link](trail_up, trail_dn)
box.set_lefttop(premium, [Link](top_x, btm_x), trail_up)
box.set_rightbottom(premium, n, .95 * trail_up + .05 * trail_dn)
label.set_xy(premium_lbl, int([Link]([Link](top_x, btm_x), n)), trail_up)
box.set_lefttop(eq, [Link](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, [Link](top_x, btm_x), .95 * trail_dn + .05 *
trail_up)
box.set_rightbottom(discount, n, trail_dn)
label.set_xy(discount_lbl, int([Link]([Link](top_x, btm_x), n)), trail_dn)
//-----------------------------------------------------------------------------}
//Trend
//-----------------------------------------------------------------------------{
var color trend_css = na
if show_trend
if style == 'Colored'
trend_css := itrend == 1 ? bull_css : bear_css
else if style == 'Monochrome'
trend_css := itrend == 1 ? #b2b5be : #5d606b
plotcandle(open, high, low, close
, color = trend_css
, wickcolor = trend_css
, bordercolor = trend_css
, editable = false)
//-----------------------------------------------------------------------------}
//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')
//EQH/EQL
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')
//-----------------------------------------------------------------------------}
k = [Link](1.,'Slope',minval=0,step=.1)
method = [Link]('Atr','Slope Calculation Method',
options=['Atr','Stdev','Linreg'])
show = input(true,'Show Only Confirmed Breakouts')
//----
upper = 0.,lower = 0.
slope_ph = 0.,slope_pl = 0.
src = close
//----
ama = 0.
hh = [Link]([Link]([Link]([Link](length))), 0)
ll = [Link]([Link]([Link]([Link](length)) * -1), 0)
tc = [Link]([Link](hh or ll ? 1 : 0, length), 2)
ama := nz(ama[1] + tc * (src - ama[1]), src)
plot(ama, 'Plot', [Link](#ff1100, 0), 2)
//----
ph = [Link](length,length)
pl = [Link](length,length)
slope = switch method
'Atr' => [Link](length)/length*k
'Stdev' => [Link](src,length)/length*k
'Linreg' => [Link]([Link](src*bar_index,length)-
[Link](src,length)*[Link](bar_index,length))/[Link](n,length)/2*k
slope_ph := ph ? slope : slope_ph[1]
slope_pl := pl ? slope : slope_pl[1]
upper := ph ? ph : upper[1] - slope_ph
lower := pl ? pl : lower[1] + slope_pl
//----
single_upper = 0
single_lower = 0
single_upper := src[length] > upper ? 0 : ph ? 1 : single_upper[1]
single_lower := src[length] < lower ? 0 : pl ? 1 : single_lower[1]
upper_breakout = single_upper[1] and src[length] > upper and (show ? src >
src[length] : 1)
lower_breakout = single_lower[1] and src[length] < lower and (show ? src <
src[length] : 1)
plotshape(upper_breakout ? low[length] : na,"Upper
Break",[Link],[Link],#26a69a,-
length,text="B",textcolor=[Link],size=[Link])
plotshape(lower_breakout ? high[length] : na,"Lower
Break",[Link],[Link],#ef5350,-
length,text="B",textcolor=[Link],size=[Link])
//----
var line up_l = na
var line dn_l = na
var label recent_up_break = na
var label recent_dn_break = na
if ph[1]
[Link](up_l[1])
[Link](recent_up_break[1])
up_l := [Link](n-length-1,ph[1],n-length,upper,color=#26a69a,
extend=[Link],style=line.style_dashed)
if pl[1]
[Link](dn_l[1])
[Link](recent_dn_break[1])
dn_l := [Link](n-length-1,pl[1],n-length,lower,color=#ef5350,
extend=[Link],style=line.style_dashed)
if [Link](src,upper-slope_ph*length)
[Link](recent_up_break[1])
recent_up_break := [Link](n,low,'B',color=#26a69a,
textcolor=[Link],style=label.style_label_up,size=[Link])
if [Link](src,lower+slope_pl*length)
[Link](recent_dn_break[1])
recent_dn_break := [Link](n,high,'B',color=#ef5350,
textcolor=[Link],style=label.style_label_down,size=[Link])
//----
plot(upper,'Upper',color = ph ? na : #26a69a,offset=-length)
plot(lower,'Lower',color = pl ? na : #ef5350,offset=-length)
alertcondition([Link](src,upper-slope_ph*length),'Upper Breakout','Price
broke upper trendline')
alertcondition([Link](src,lower+slope_pl*length),'Lower Breakout','Price
broke lower trendline')