0% found this document useful (0 votes)
1K views58 pages

Smart Money Concepts Plus

This document contains a Pine Script™ code for an indicator named 'Smart Money Concepts by TrunkXiao', designed for use in financial charting. It includes various customizable features such as displaying market structures, order blocks, and fair value gaps, along with options for visual styling and filtering. The script is structured to allow users to toggle different indicators and settings to suit their trading strategies.

Uploaded by

xizhongxiao83
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
1K views58 pages

Smart Money Concepts Plus

This document contains a Pine Script™ code for an indicator named 'Smart Money Concepts by TrunkXiao', designed for use in financial charting. It includes various customizable features such as displaying market structures, order blocks, and fair value gaps, along with options for visual styling and filtering. The script is structured to allow users to toggle different indicators and settings to suit their trading strategies.

Uploaded by

xizhongxiao83
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 58

// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.

0
at https://mozilla.org/MPL/2.0/
// © DrunkXiao

//@version=5

indicator("Smart Money Concepts by TrunkXiao", "Smart Money Concepts by TrunkXiao"


, overlay = true
, max_labels_count = 500
, max_lines_count = 500
, max_boxes_count = 500
, max_bars_back = 1000)
//-----------------------------------------------------------------------------{
//Constants
//-----------------------------------------------------------------------------{
color TRANSP_CSS = #ffffff00

switchboard_group = "████ Turn On/Off Overlay Indicators ████"

switch_pvsra = input.bool (false, "PVSRA", group=switchboard_group,


inline='Switch1')
switch_ema = input.bool (true, "EMA", group=switchboard_group, inline='Switch1')
switch_halftrend= input.bool (true, "Half Trend", group=switchboard_group,
inline='Switch1')

switch_Reversal= input.bool (true, "Reversal Signals", group=switchboard_group,


inline='Switch1')

//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'
, options = ['Historical', 'Present']
, group = 'Smart Money Concepts'
, tooltip = MODE_TOOLTIP)

style = input.string('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 = input.string('All', 'Bullish Structure'


, options = ['All', 'BOS', 'CHoCH']
, inline = 'ibull'
, group = 'Real Time Internal Structure')

swing_ibull_css = input(#00bcd4, ''


, inline = 'ibull'
, group = 'Real Time Internal Structure')

//Bear Structure
show_ibear = input.string('All', 'Bearish Structure'
, options = ['All', 'BOS', 'CHoCH']
, inline = 'ibear'
, group = 'Real Time Internal Structure')

swing_ibear_css = input(#e91e63, ''


, inline = 'ibear'
, group = 'Real Time Internal Structure')

ifilter_confluence = input(false, 'Confluence Filter'


, group = 'Real Time Internal Structure'
, tooltip = CONFLUENCE_FILTER)

internal_structure_size = input.string('Small', '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 = input.string('All', 'Bullish Structure'
, options = ['All', 'BOS', 'CHoCH']
, inline = 'bull'
, group = 'Real Time Swing Structure')

swing_bull_css = input(#00bcd4, ''


, inline = 'bull'
, group = 'Real Time Swing Structure')

//Bear Structure
show_bear = input.string('All', 'Bearish Structure'
, options = ['All', 'BOS', 'CHoCH']
, inline = 'bear'
, group = 'Real Time Swing Structure')

swing_bear_css = input(#e91e63, ''


, inline = 'bear'
, group = 'Real Time Swing Structure')

swing_structure_size = input.string('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 = input.int(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(false, 'Internal Order Blocks'
, inline = 'iob'
, group = 'Order Blocks'
, tooltip = INTERNAL_OB)

iob_showlast = input.int(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 = input.int(5, ''


, minval = 1
, inline = 'ob'
, group = 'Order Blocks')

ob_filter = input.string('Atr', 'Order Block Filter'


, options = ['Atr', 'Cumulative Mean Range']
, group = 'Order Blocks'
, tooltip = FILTER_OB)

ibull_ob_css = input.color(color.new(#2962ff, 85), 'Internal Bullish OB'


, group = 'Order Blocks')

ibear_ob_css = input.color(color.new(#E20061, 85), 'Internal Bearish OB'


, group = 'Order Blocks')

bull_ob_css = input.color(color.new(#2962ff, 100), 'Bullish OB'


, group = 'Order Blocks')

bear_ob_css = input.color(color.new(#E20061, 100), 'Bearish OB'


, group = 'Order Blocks')

//----------------------------------------}
//EQH/EQL
//----------------------------------------{
show_eq = input(true, 'Equal High/Low'
, group = 'EQH/EQL'
, tooltip = SHOW_EQHL)

eq_len = input.int(3, 'Bars Confirmation'


, minval = 1
, group = 'EQH/EQL'
, tooltip = EQHL_BARS)

eq_threshold = input.float(0.1, 'Threshold'


, minval = 0
, maxval = 0.5
, step = 0.1
, group = 'EQH/EQL'
, tooltip = EQHL_THRESHOLD)

eq_size = input.string('Small', 'Label Size'


, options = ['Tiny', 'Small', 'Normal']
, group = 'EQH/EQL')

//----------------------------------------}
//Fair Value Gaps
//----------------------------------------{
show_fvg = input(true, '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 = input.timeframe('', "Timeframe"
, group = 'Fair Value Gaps'
, tooltip = FVG_TF)

bull_fvg_css = input.color(color.new(#00e676, 92), 'Bullish FVG'


, group = 'Fair Value Gaps')

bear_fvg_css = input.color(color.new(#f23645, 92), 'Bearish FVG'


, group = 'Fair Value Gaps')

fvg_extend = input.int(30, "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 = 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
//----------------------------------------{
show_sd = input(false, 'Premium/Discount Zones'
, group = 'Premium & Discount Zones'
, tooltip = PED_ZONES)

premium_css = input.color(#f23645, 'Premium Zone'


, group = 'Premium & Discount Zones')

eq_css = input.color(#b2b5be, 'Equilibrium Zone'


, group = 'Premium & Discount Zones')

discount_css = input.color(#089981, 'Discount Zone'


, group = 'Premium & Discount Zones')

//-----------------------------------------------------------------------------}
//Functions
//-----------------------------------------------------------------------------{
n = bar_index

atr = ta.atr(200)
cmean_range = ta.cum(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 = 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[1])
label.delete(structure_lbl[1])

//Swings detection/measurements
swings(len)=>
var os = 0

upper = ta.highest(len)
lower = ta.lowest(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 := math.max(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 := math.min(low[i], min)
max := min == low[i] ? high[i] : max
idx := min == low[i] ? i : idx

array.unshift(target_top, max)
array.unshift(target_btm, min)
array.unshift(target_left, time[idx])
array.unshift(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 math.min(show_last-1, size-1)
get_box = array.get(boxes, i)

box.set_lefttop(get_box, array.get(target_left, i), array.get(target_top,


i))
box.set_rightbottom(get_box, array.get(target_left, i),
array.get(target_btm, i))
box.set_extend(get_box, extend.right)

color css = na

if swing
if style == 'Monochrome'
css := array.get(target_type, i) == 1 ? color.new(#b2b5be, 80) :
color.new(#5d606b, 80)
border_css = array.get(target_type, i) == 1 ? #b2b5be : #5d606b
box.set_border_color(get_box, border_css)
else
css := array.get(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 := array.get(target_type, i) == 1 ? color.new(#b2b5be, 80) :
color.new(#5d606b, 80)
else
css := array.get(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 = 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[1], h, 1)
hx = ta.valuewhen(h == high, time, 1)

ly = ta.valuewhen(l != l[1], l, 1)
lx = ta.valuewhen(l == low, time, 1)

if barstate.islast
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'
? 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
[top, btm] = swings(length)

[itop, ibtm] = 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[1])

//Extend recent top to last bar


line.delete(extend_top[1])
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[1])

//Extend recent btm to last bar


line.delete(extend_btm[1])
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


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
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 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 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 - 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
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 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 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 = array.indexof(iob_type, element)

if close < array.get(iob_btm, index) and element == 1


array.remove(iob_top, index)
array.remove(iob_btm, index)
array.remove(iob_left, index)
array.remove(iob_type, index)
bull_iob_break := true

else if close > array.get(iob_top, index) and element == -1


array.remove(iob_top, index)
array.remove(iob_btm, index)
array.remove(iob_left, index)
array.remove(iob_type, index)
bear_iob_break := true

//Delete internal order blocks box coordinates if top/bottom is broken


for element in ob_type
index = array.indexof(ob_type, element)

if close < array.get(ob_btm, index) and element == 1


array.remove(ob_top, index)
array.remove(ob_btm, index)
array.remove(ob_left, index)
array.remove(ob_type, index)
bull_ob_break := true

else if close > array.get(ob_top, index) and element == -1


array.remove(ob_top, index)
array.remove(ob_btm, index)
array.remove(ob_left, index)
array.remove(ob_type, index)
bear_ob_break := true

iob_size = array.size(iob_type)
ob_size = array.size(ob_type)

if barstate.isfirst
if show_iob
for i = 0 to iob_showlast-1
array.push(iob_boxes, box.new(na,na,na,na, xloc = xloc.bar_time))
if show_ob
for i = 0 to ob_showlast-1
array.push(ob_boxes, box.new(na,na,na,na, xloc = xloc.bar_time))

if iob_size > 0
if barstate.islast
display_ob(iob_boxes, iob_top, iob_btm, iob_left, iob_type, iob_showlast,
false, iob_size)

if ob_size > 0
if barstate.islast
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 = 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[1])
label.delete(eqh_lbl[1])

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[1])
label.delete(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] =


request.security(syminfo.tickerid, fvg_tf, get_ohlc())

if show_fvg
delta_per = (src_c1 - src_o1) / src_o1 * 100

change_tf = timeframe.change(fvg_tf)

threshold = fvg_auto ? ta.cum(math.abs(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
array.unshift(bullish_fvg_max, box.new(n-1, src_l, n + fvg_extend,
math.avg(src_l, src_h2)
, border_color = bull_fvg_css
, bgcolor = bull_fvg_css))

array.unshift(bullish_fvg_min, box.new(n-1, math.avg(src_l, src_h2), n +


fvg_extend, src_h2
, border_color = bull_fvg_css
, bgcolor = bull_fvg_css))

if bearish_fvg_cnd
array.unshift(bearish_fvg_max, box.new(n-1, src_h, n + fvg_extend,
math.avg(src_h, src_l2)
, border_color = bear_fvg_css
, bgcolor = bear_fvg_css))

array.unshift(bearish_fvg_min, box.new(n-1, math.avg(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)
box.delete(bx)
box.delete(array.get(bullish_fvg_max, array.indexof(bullish_fvg_min,
bx)))

for bx in bearish_fvg_max
if high > box.get_top(bx)
box.delete(bx)
box.delete(array.get(bearish_fvg_min, array.indexof(bearish_fvg_max,
bx)))

//-----------------------------------------------------------------------------}
//Previous day/week high/lows
//-----------------------------------------------------------------------------{
//Daily high/low
[pdh, pdl] = request.security(syminfo.tickerid, 'D', hl()
, lookahead = barmerge.lookahead_on)

//Weekly high/low
[pwh, pwl] = request.security(syminfo.tickerid, 'W', hl()
, lookahead = barmerge.lookahead_on)
//Monthly high/low
[pmh, pml] = 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)

//Show Premium/Discount Areas


if barstate.islast and show_sd
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 := 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')

//HTF FVG D/W/M [TrunkXiao]


///////////////////////////////////////////////////////////////////////////////////
//////////////////////////// MTF FVG (price overlay)
tfinput2 = input.timeframe(defval="Weekly", title=' Timeframe ',
options=["Daily", "Weekly", "Monthly"], group = 'HTF FVG Settings', inline='1')
upcol1 = input.color(color.new(#ffffff, 94), 'Box/Border/Text - UP',
inline='appup', group = 'HTF FVG Settings')
upbordercol = input.color(color.rgb(76, 175, 79, 100), '', inline='appup',
group = 'HTF FVG Settings')
uptextcol = input.color(color.new(color.yellow,0), '', inline='appup', group
= 'HTF FVG Settings')
downcol1 = input.color(color.new(#ffffff, 94), 'Box/Border/Text - DOWN',
inline='appdown', group = 'HTF FVG Settings')
downbordercol = input.color(color.rgb(255, 82, 82, 100), '', inline='appdown',
group = 'HTF FVG Settings')
downtextcol = input.color(color.new(color.yellow, 0), '', inline='appdown',
group = 'HTF FVG Settings')
showboxtext = input.bool(defval=true, title="Text", inline='appdown2', group =
'HTF FVG Settings')
showboxes = input.bool(true, 'Show Boxes', inline='appdown2', group = 'HTF
FVG Settings')
extendtilfilled = input.bool(true, '', group = 'HTF FVG Settings', inline='fill')
filledtype = input.string('Full Fill', 'Fill Condition ',
options=['Touch', 'Full Fill', 'Half Fill'], group = 'HTF FVG Settings',
inline='fill')
hidefilled = input.bool(true, 'Hide Filled Levels', group = 'HTF FVG
Settings', inline='fill2')
lookbackm = input.bool(true, '', inline='lb', group = 'HTF FVG Settings')
fvgdaysBack = input.float(30, 'Lookback (D) ', group = 'HTF FVG
Settings',inline='lb')
maxBoxes = input.int(defval=4, title="Maximum Boxes", minval=0, maxval=499,
step=1, group = 'HTF FVG Settings',inline='lc')
conditiontype = 'None'
nmbars = 3500
linestylem = input.string(defval='Dotted', title="25/50/75% Style",
options=['Dotted', 'Solid', 'Dashed'], inline='he', group='HTF FVG Settings')
lineCol = input.color(color.new(color.silver,0), title='', inline='he',
group='HTF FVG Settings')
wdth = input.int(defval=1, title="Width", minval=0, maxval=4, step=1,
group = 'HTF FVG Settings',inline='he')
nbars = 4

//convert timeframe inputs


tfinput = ''
if tfinput2 == "Daily"
tfinput := "D"
if tfinput2 == "Weekly"
tfinput := "W"
if tfinput2 == "Monthly"
tfinput := "M"

// Requesting HTF data


[o, h, l, c] = request.security(syminfo.tickerid, tfinput, [open, high, low,
close])
[o1, h1, l1, c1] = request.security(syminfo.tickerid, tfinput, [open[1], high[1],
low[1], close[1]])
[o2, h2, l2, c2] = request.security(syminfo.tickerid, tfinput, [open[2], high[2],
low[2], close[2]])
t = request.security(syminfo.tickerid, tfinput, time)
bool new = ta.change(time(tfinput))

clear = color.rgb(0,0,0,100)
color upcol = showboxes ? upcol1 : clear
color downcol = showboxes ? downcol1 : clear

MSPD = 24 * 60 * 60 * 1000
lastBarDate = timestamp(year(timenow), month(timenow), dayofmonth(timenow),
hour(timenow), minute(timenow), second(timenow))
thisBarDate = timestamp(year, month, dayofmonth, hour, minute, second)
daysLeft = math.abs(math.floor((lastBarDate - thisBarDate) / MSPD))
inRange = lookbackm ? (daysLeft < fvgdaysBack) : true

// Timeframe labels
timeframelabel(tfinput) =>
switch tfinput
'' => timeframe.period + (timeframe.isminutes ? 'm' : na)
'1' => '1m'
'2' => '2m'
'3' => '3m'
'4' => '4m'
'5' => '5m'
'10' => '10m'
'15' => '15m'
'30' => '30m'
'60' => '1 Hr'
'120' => '2 Hr'
'240' => '4 Hr'
'480' => '8 Hr'
'720' => '12 Hr'
=> tfinput

// Box Text
var string imbboxtext = na, var string gapboxtext = na, var string wickboxtext
= na

if showboxtext //and textType == 'Labels + Timeframe'


imbboxtext := str.tostring(timeframelabel(tfinput) + ' ' +
str.tostring("FVG"))

// Line style and text label appearance


lineStyle(x) =>
switch x
'Solid' => line.style_solid
'Dashed' => line.style_dashed
'Dotted' => line.style_dotted
// Conditions for Imbalances, Gaps and Wicks
var bool condition = na, var bool condition2 = na, var bool condition3 = na, var
bool condition4 = na, var bool condition5 = na, var bool condition6 = na

if conditiontype == 'None'
condition := true
condition2 := true
condition3 := true
condition4 := true
condition5 := true
condition6 := true

// Drawing Boxes and Lines


var boxes = array.new_box(), var topLines = array.new_line(), var
middleLines = array.new_line(), var bottomLines = array.new_line()

if (l > h2) and condition and inRange and new //and fvg1hr
imbboxUP = box.new(t[2], l, time, h2, bgcolor = upcol,
border_color=upbordercol,border_width = 1, text=imbboxtext, text_size = size.small,
text_halign = text.align_right, text_valign = text.align_center, text_color =
uptextcol,xloc = xloc.bar_time)
topLine = line.new(t[2], (((l + h2)/2) + l)/2, time, (((l + h2)/2) + l)/2,
color=lineCol, style=lineStyle(linestylem), xloc = xloc.bar_time, width=wdth)
bottomLine = line.new(t[2], (((l + h2)/2) + h2)/2, time, (((l + h2)/2) + h2)/2,
color=lineCol, style=lineStyle(linestylem), xloc = xloc.bar_time, width=wdth)
middleLine = line.new(t[2], (l + h2)/2, last_bar_time, (l + h2)/2,
color=lineCol, style=lineStyle(linestylem), xloc = xloc.bar_time, width=wdth)
array.push(topLines, topLine)
array.push(middleLines, middleLine)
array.push(bottomLines, bottomLine)
array.push(boxes, imbboxUP)
if (h < l2) and condition2 and inRange and new //and fvg1hr
imbboxDOWN = box.new(t[2], h, time, l2, bgcolor = downcol,
border_color=downbordercol,border_width = 1, text=imbboxtext, text_size =
size.small, text_halign = text.align_right, text_valign = text.align_center,
text_color = downtextcol, xloc = xloc.bar_time)
topLine = line.new(t[2], (((l2 + h)/2) + l2)/2, time, (((l2 + h)/2) +
l2)/2, color=lineCol, style=lineStyle(linestylem), xloc = xloc.bar_time,
width=wdth)
bottomLine = line.new(t[2], (((l2 + h)/2) + h)/2, time, (((l2 + h)/2) + h)/2,
color=lineCol, style=lineStyle(linestylem), xloc = xloc.bar_time, width=wdth)
middleLine = line.new(t[2], (h+l2)/2, last_bar_time, (h+l2)/2, color=lineCol,
style=lineStyle(linestylem), xloc = xloc.bar_time, width=wdth)
array.push(topLines, topLine)
array.push(middleLines, middleLine)
array.push(bottomLines, bottomLine)
array.push(boxes, imbboxDOWN)

// Looping over the arrays and updating objects


size = array.size(boxes)
if size > 0
for i = 0 to size - 1
j = size - 1 - i
box = array.get(boxes, j)
topLine = array.get(topLines, j)
middleLine = array.get(middleLines, j)
bottomLine = array.get(bottomLines, j)
level = box.get_bottom(box)
level2 = box.get_top(box)
level3 = (level2+level)/2
// Defining fill conditions for zones and lines
var bool filled = na
unifill = (high > level and low < level) or (high > level2 and low <
level2)
if filledtype == 'Touch'
filled := (high > level and low < level) or (high > level2 and low <
level2)
if filledtype == 'Half Fill'
filled := (high > level3 and low < level3)
if filledtype == 'Full Fill'
for imbboxUP in boxes
filled := (high > level2 and low < level2)
for imbboxDOWN in boxes
filled := (high > level and low < level)
if hidefilled and filled
line.delete(topLine)
line.delete(middleLine)
line.delete(bottomLine)
box.delete(box)
array.remove(boxes, j)
array.remove(topLines, j)
array.remove(middleLines, j)
array.remove(bottomLines, j)
continue
if filled and extendtilfilled
array.remove(boxes, j)
array.remove(topLines, j)
array.remove(middleLines, j)
array.remove(bottomLines, j)
continue

box.set_right(box, last_bar_time)
line.set_x2(topLine, last_bar_time)
line.set_x2(middleLine, last_bar_time)
line.set_x2(bottomLine, last_bar_time)

if not filled and not extendtilfilled


array.remove(boxes, j)
array.remove(topLines, j)
array.remove(middleLines, j)
array.remove(bottomLines, j)
continue
box.set_right(box, time+nbars)
line.set_x2(topLine, time+nbars)
line.set_x2(middleLine, time+nbars)
line.set_x2(bottomLine, time+nbars)
continue
box.set_right(box, time)
line.set_x2(topLine, time)
line.set_x2(middleLine, time)
line.set_x2(bottomLine, time)

// Deleting if the array is too big


if array.size(boxes) >= maxBoxes
int i = 0
while array.size(boxes) >= maxBoxes
box = array.get(boxes, i)
topLine = array.get(topLines, i)
middleLine = array.get(middleLines, i)
bottomLine = array.get(bottomLines, i)

line.delete(topLine)
line.delete(middleLine)
line.delete(bottomLine)
box.delete(box)
array.remove(boxes, i)
array.remove(topLines, i)
array.remove(middleLines, i)
array.remove(bottomLines, i)
i += 1

// Session 1 - user inputs


showAsian = input.bool(true, '', inline='Asian', group='Sessions')
stringAsian = input.string('Asian', '', inline='Asian', group='Sessions')
AsianTimeX = input.session(defval="0000-0400", title=' ', inline='Asian2',
group='Sessions', tooltip = 'If you want to change the start/end time of the
session, just make sure they are in UTC. There is no need to change the timezone of
your Tradingview chart or to change the Timezone input below, because the sessions
will be plotted correctly as long as the start/end time is set in UTC.')
AsianCol = input.color(color.rgb(255, 255, 255, 94), '' , inline='Asian',
group='Sessions')
// Session 2 - user inputs
showLondon = input.bool(true, '', inline='London', group='Sessions')
stringLondon = input.string('LO-KZ', '', inline='London', group='Sessions')
LondonTimeX = input.session(defval="0700-1000", title=' ', inline='London2',
group='Sessions', tooltip = 'If you want to change the start/end time of the
session, just make sure they are in UTC. There is no need to change the timezone of
your Tradingview chart or to change the Timezone input below, because the sessions
will be plotted correctly as long as the start/end time is set in UTC.')
LondonCol = input.color(color.rgb(255, 255, 255, 94), '' , inline='London',
group='Sessions')
// Session 3 - user inputs
showNewYork = input.bool(true, title='', inline='New York', group='Sessions')
stringNewYork = input.string('NY-KZ', '', inline='New York', group='Sessions')
NewYorkTimeX = input.session(defval="1230-1530", title=' ', inline='New
York2', group='Sessions', tooltip = 'If you want to change the start/end time of
the session, just make sure they are in UTC. There is no need to change the
timezone of your Tradingview chart or to change the Timezone input below, because
the sessions will be plotted correctly as long as the start/end time is set in
UTC.')
NewYorkCol = input.color(color.rgb(255, 255, 255, 94), '', inline='New York',
group='Sessions')
// Session 4 - user inputs
showSydney = input.bool(false, title='', inline='Sydney', group='Sessions')
stringSydney = input.string('Sydney', '', inline='Sydney', group='Sessions')
SydneyTimeX = input.session(defval="2100-0600", title=' ', inline='Sydney2',
group='Sessions', tooltip = 'If you want to change the start/end time of the
session, just make sure they are in UTC. There is no need to change the timezone of
your Tradingview chart or to change the Timezone input below, because the sessions
will be plotted correctly as long as the start/end time is set in UTC.')
SydneyCol = input.color(color.rgb(255, 255, 255, 94), '', inline='Sydney',
group='Sessions')
// Additional tools and settings - user inputs
pipChange = input.bool(false, 'Change (Pips) ', inline='0', group =
'Additional Tools and Settings')
percentChange = input.bool(false, 'Change (%)', inline='0', group = 'Additional
Tools and Settings')
merge = input.bool(false, 'Merge Overlaps', inline='2', group =
'Additional Tools and Settings')
hideWeekends = input.bool(true, 'Hide Weekends', inline='2', group = 'Additional
Tools and Settings')
sessionOC = input.bool(false, 'Open/Close Line', inline='3', group =
'Additional Tools and Settings')
halfline = input.bool(false, 'Session 0.5 Level', inline='3', group =
'Additional Tools and Settings')
colorcandles = input.bool(false, 'Color Candles ', inline='4', group =
'Additional Tools and Settings')
showScreener = input.bool(false, 'Screener (Soon)', inline='4', group =
'Additional Tools and Settings')
displayType = input.string('Boxes', 'Display Type', options = ['Boxes',
'Zones','Timeline', 'Candles'], group='Additional Tools and Settings',
tooltip='Choose whether the scripts should plot session in the for of boxes or
colored background zones.')
daysBack = input.float(150, 'Lookback (Days)', group='Additional Tools and
Settings', tooltip= 'This inputs defines the lookback period for plotting sessions.
Eg. If it is set to 1, only the sessions of the past day will appear')
changeType = input.string('Session High/Low','Change (%/Pips) Source', options
= ['Session High/Low', 'Session Open/Close'], group='Additional Tools and
Settings', tooltip='Choose whether the Change (%) and Change (Pips) should measure
the distance between Session High and Session Low or the distance between Session
Open and Session Close.')
SessionZone = input.string("UTC", title="Input Timezone", group='Additional
Tools and Settings', tooltip = 'This input is defining the timezone for the session
times selected above. It has nothing to do with the timezone of your chart, because
the sessions will be plotted correctly even if your chart is not set to UTC.')
// Appearance - user inputs
borderWidth = input.int(1, 'Box Border', inline='border', group='Appearance')
borderStyle = input.string('Dotted', '', ['Solid', 'Dashed', 'Dotted'] ,
inline='border', group='Appearance', tooltip='Select the width and style of session
box borders')
levelsStyle = input.string('Dotted', 'Line Style', ['Solid', 'Dashed',
'Dotted'], group='Appearance', tooltip='Select the style of 0.5 and Open/Close
lines.')
labelSize = input.string('Normal', 'Label Size', options = ['Auto', 'Tiny',
'Small', 'Normal'], group='Appearance', tooltip='Select the size of text labels.')
showLabels = input.bool(false, 'Session Labels ', inline='00', group =
'Appearance')
colorBoxes = input.bool(false, 'Box Background', inline='00', group =
'Appearance')

// Excluding or Including Weekends


var AsianTime = hideWeekends ? AsianTimeX+":123456" : AsianTimeX+":1234567"
var LondonTime = hideWeekends ? LondonTimeX+":123456" : LondonTimeX+":1234567"
var NewYorkTime = hideWeekends ? NewYorkTimeX+":123456" : NewYorkTimeX+":1234567"
var SydneyTime = hideWeekends ? SydneyTimeX+":123456" : SydneyTimeX+":1234567"

// Defining Line Style and Label Size Variables


//lineStyle(x) =>
// switch x
// 'Solid' => line.style_solid
// 'Dashed' => line.style_dashed
// 'Dotted' => line.style_dotted
labelStyle(x) =>
switch x
'Auto' => size.auto
'Tiny' => size.tiny
'Small' => size.small
'Normal' => size.normal

// Calculating inRange, used for lookback


//MSPD = 24 * 60 * 60 * 1000
//lastBarDate = timestamp(year(timenow), month(timenow), dayofmonth(timenow),
hour(timenow), minute(timenow), second(timenow))
//thisBarDate = timestamp(year, month, dayofmonth, hour, minute, second)
//daysLeft = math.abs(math.floor((lastBarDate - thisBarDate) / MSPD))
//inRange = daysLeft < daysBack

// Session Time
InAsian(AsianTime, AsianTimeZone=syminfo.timezone) =>
not na(time(timeframe.period, AsianTime, SessionZone))
InLondon(LondonTime, LondonTimeZone=syminfo.timezone) =>
not na(time(timeframe.period, LondonTime, SessionZone))
InNewYork(NewYorkTime, NewYorkTimeZone=syminfo.timezone) =>
not na(time(timeframe.period, NewYorkTime, SessionZone))
InSydney(SydneyTime, SydneyTimeZone=syminfo.timezone) =>
not na(time(timeframe.period, SydneyTime, SessionZone))

// Creating variables Session High, Low, Open and Session Boxes, Lines and Texts
var AsianHighPrice = 0.0, var AsianLowPrice = 0.0, var AsianOpenPrice
= 0.0, var box AsianBox = na, var line AsianLine = na, var label
AsianLabel = na, var line AsianOC = na, var string AsianText =
str.tostring(stringAsian)
var LondonHighPrice = 0.0, var LondonLowPrice = 0.0, var LondonOpenPrice
= 0.0, var box LondonBox = na, var line LondonLine = na, var label
LondonLabel = na, var line LondonOC = na, var string LondonText =
str.tostring(stringLondon)
var NewYorkHighPrice = 0.0, var NewYorkLowPrice = 0.0, var NewYorkOpenPrice
= 0.0, var box NewYorkBox = na, var line NewYorkLine = na, var label
NewYorkLabel = na, var line NewYorkOC = na, var string NewYorkText =
str.tostring(stringNewYork)
var SydneyHighPrice = 0.0, var SydneyLowPrice = 0.0, var SydneyOpenPrice
= 0.0, var box SydneyBox = na, var line SydneyLine = na, var label
SydneyLabel = na, var line SydneyOC = na, var string SydneyText =
str.tostring(stringSydney)

// Checking if session is active/has started


inAsian = InAsian(AsianTime, SessionZone) and timeframe.isintraday
AsianStart = inAsian and not inAsian[1]
inLondon = InLondon(LondonTime, SessionZone) and timeframe.isintraday
LondonStart = inLondon and not inLondon[1]
inNewYork = InNewYork(NewYorkTime, SessionZone) and timeframe.isintraday
NewYorkStart = inNewYork and not inNewYork[1]
inSydney = InSydney(SydneyTime, SessionZone) and timeframe.isintraday
SydneyStart = inSydney and not inSydney[1]

// Settings high, low, open at the beggining of the session


if AsianStart
AsianHighPrice := high
AsianLowPrice := low
AsianOpenPrice := open
if LondonStart
LondonHighPrice := high
LondonLowPrice := low
LondonOpenPrice := open
if NewYorkStart
NewYorkHighPrice := high
NewYorkLowPrice := low
NewYorkOpenPrice := open
if SydneyStart
SydneyHighPrice := high
SydneyLowPrice := low
SydneyOpenPrice := open

// Track session's max high and max low during the session
else if inAsian
AsianHighPrice := math.max(AsianHighPrice, high)
AsianLowPrice := math.min(AsianLowPrice, low)
else if inLondon
LondonHighPrice := math.max(LondonHighPrice, high)
LondonLowPrice := math.min(LondonLowPrice, low)
else if inNewYork
NewYorkHighPrice := math.max(NewYorkHighPrice, high)
NewYorkLowPrice := math.min(NewYorkLowPrice, low)
else if inSydney
SydneyHighPrice := math.max(SydneyHighPrice, high)
SydneyLowPrice := math.min(SydneyLowPrice, low)

// Plotting session boxes at the beginning of each session


if AsianStart and showAsian and inRange
AsianBox := displayType=='Boxes' ? box.new(left=bar_index, top=na,
right=na, bottom=na, border_width=borderWidth, bgcolor = colorBoxes ? AsianCol :
na, border_style = lineStyle(borderStyle), border_color=color.new(AsianCol, 40)) :
na
AsianLine := halfline ? line.new(x1=bar_index, y1=na, x2=na, y2=na,
style=lineStyle(levelsStyle), color = color.new(AsianCol, 40)) : na
AsianLabel := showLabels ? label.new(x=na, y=na, text=AsianText,
textcolor=color.new(AsianCol, 40), color=color.rgb(0,0,0,100),
size=labelStyle(labelSize)) : na
AsianOC := sessionOC ? line.new(x1=bar_index, y1=AsianOpenPrice, x2=na,
y2=na, style=lineStyle(levelsStyle), color = color.new(AsianCol, 40)) : na
if LondonStart and showLondon and inRange
LondonBox := displayType=='Boxes' ? box.new(left=bar_index, top=na,
right=na, bottom=na, border_width=borderWidth, bgcolor = colorBoxes ? LondonCol :
na, border_style = lineStyle(borderStyle), border_color=color.new(LondonCol, 40)) :
na
LondonLine := halfline ? line.new(x1=bar_index, y1=na, x2=na, y2=na,
style=lineStyle(levelsStyle), color = color.new(LondonCol, 40)) : na
LondonLabel := showLabels ? label.new(x=na, y=na, text=LondonText,
textcolor=color.new(LondonCol, 40), color=color.rgb(0,0,0,100),
size=labelStyle(labelSize)) : na
LondonOC := sessionOC ? line.new(x1=bar_index, y1=LondonOpenPrice, x2=na,
y2=na, style=lineStyle(levelsStyle), color = color.new(LondonCol, 40)) : na
if NewYorkStart and showNewYork and inRange
NewYorkBox := displayType=='Boxes' ? box.new(left=bar_index, top=na,
right=na, bottom=na, border_width=borderWidth, bgcolor = colorBoxes ? NewYorkCol :
na, border_style = lineStyle(borderStyle), border_color=color.new(NewYorkCol,
40)) : na
NewYorkLine := halfline ? line.new(x1=bar_index, y1=na, x2=na, y2=na,
style=lineStyle(levelsStyle), color = color.new(NewYorkCol, 40)) : na
NewYorkLabel := showLabels ? label.new(x=na, y=na, text=NewYorkText,
textcolor=color.new(NewYorkCol, 40), color=color.rgb(0,0,0,100),
size=labelStyle(labelSize)) : na
NewYorkOC := sessionOC ? line.new(x1=bar_index, y1=NewYorkOpenPrice, x2=na,
y2=na, style=lineStyle(levelsStyle), color = color.new(NewYorkCol, 40)) : na
if SydneyStart and showSydney and inRange
SydneyBox := displayType=='Boxes' ? box.new(left=bar_index, top=na,
right=na, bottom=na, border_width=borderWidth, bgcolor = colorBoxes ? SydneyCol :
na, border_style = lineStyle(borderStyle), border_color=color.new(SydneyCol, 40)) :
na
SydneyLine := halfline ? line.new(x1=bar_index, y1=na, x2=na, y2=na,
style=lineStyle(levelsStyle), color = color.new(SydneyCol, 40)) : na
SydneyLabel := showLabels ? label.new(x=na, y=na, text=SydneyText,
textcolor=color.new(SydneyCol, 40), color=color.rgb(0,0,0,100),
size=labelStyle(labelSize)) : na
SydneyOC := sessionOC ? line.new(x1=bar_index, y1=SydneyOpenPrice, x2=na,
y2=na, style=lineStyle(levelsStyle), color = color.new(SydneyCol, 40)) : na

// Creating variables for alternative Sessions Box top and bottom (used for merging
sessions)
var float AsianHighM = 0, var float AsianLowM = 0, var float LondonHighM = 0,
var float LondonLowM = 0, var float NewYorkHighM = 0, var float NewYorkLowM = 0,
var float SydneyHighM = 0, var float SydneyLowM = 0

// Updating session boxes during sessions


if inAsian and inRange
AsianHighPrice := math.max(AsianHighPrice, high)
AsianLowPrice := math.min(AsianLowPrice, low)
box.set_top(AsianBox, AsianHighPrice)
box.set_bottom(AsianBox, AsianLowPrice)
box.set_right(AsianBox, bar_index + 1)
label.set_x(AsianLabel, (box.get_left(AsianBox)+box.get_right(AsianBox))/2)
label.set_y(AsianLabel, AsianHighPrice)
if sessionOC
line.set_x2(AsianOC, bar_index)
line.set_y2(AsianOC, close)
if halfline
line.set_y1(AsianLine, (AsianHighPrice+AsianLowPrice)/2)
line.set_y2(AsianLine, (AsianHighPrice+AsianLowPrice)/2)
line.set_x2(AsianLine, bar_index+1)
if merge and not inLondon and showLondon
AsianHighM := AsianHighPrice
AsianLowM := AsianLowPrice
if merge and inLondon and showLondon
box.set_top(AsianBox, AsianHighM)
box.set_bottom(AsianBox, AsianLowM)
label.set_y(AsianLabel, AsianHighM)
box.set_right(AsianBox, (box.get_left(LondonBox)))
line.set_x2(AsianLine, (box.get_left(LondonBox)))
label.set_x(AsianLabel, (box.get_left(AsianBox)+box.get_right(AsianBox))/2)
line.set_x2(AsianOC, (box.get_left(LondonBox)))
line.set_y2(AsianOC, LondonOpenPrice)
line.set_y1(AsianLine, (AsianHighM+AsianLowM)/2)
line.set_y2(AsianLine, (AsianHighM+AsianLowM)/2)
var float pips = 0
var float chg = 0
pips := changeType=='Session High/Low' ? ((AsianHighPrice - AsianLowPrice) /
syminfo.mintick / 10) : ((close - AsianOpenPrice) / syminfo.mintick / 10)
chg := changeType=='Session Open/Close' ? (100 * (close - AsianOpenPrice) /
AsianOpenPrice) : ((AsianHighPrice - AsianLowPrice) / AsianLowPrice * 100)
if percentChange and not pipChange
label.set_text(AsianLabel, str.tostring(AsianText) + ' (' +
str.tostring(chg, format.percent) + ')')
if pipChange and not percentChange
label.set_text(AsianLabel, str.tostring(AsianText) + ' (' +
str.tostring(pips) + ')')
if percentChange and pipChange
label.set_text(AsianLabel, str.tostring(AsianText) + ' ('+
str.tostring(chg, format.percent)+ ' • ' + str.tostring(pips) + ')')
if inLondon and inRange
LondonHighPrice := math.max(LondonHighPrice, high)
LondonLowPrice := math.min(LondonLowPrice, low)
box.set_top(LondonBox, LondonHighPrice)
box.set_bottom(LondonBox, LondonLowPrice)
box.set_right(LondonBox, bar_index+1)
label.set_x(LondonLabel, (box.get_left(LondonBox)+box.get_right(LondonBox))/2)
label.set_y(LondonLabel, LondonHighPrice)
if sessionOC
line.set_x2(LondonOC, bar_index)
line.set_y2(LondonOC, close)
if halfline
line.set_y1(LondonLine, (LondonHighPrice+LondonLowPrice)/2)
line.set_y2(LondonLine, (LondonHighPrice+LondonLowPrice)/2)
line.set_x2(LondonLine, bar_index+1)
if merge and not inNewYork and showNewYork
LondonHighM := LondonHighPrice
LondonLowM := LondonLowPrice
if merge and inNewYork and showNewYork
box.set_top(LondonBox, LondonHighM)
box.set_bottom(LondonBox, LondonLowM)
label.set_y(LondonLabel, LondonHighM)
box.set_right(LondonBox, (box.get_left(NewYorkBox)))
line.set_x2(LondonLine, (box.get_left(NewYorkBox)))
label.set_x(LondonLabel, (box.get_left(LondonBox)
+box.get_right(LondonBox))/2)
line.set_x2(LondonOC, (box.get_left(NewYorkBox)))
line.set_y2(LondonOC, NewYorkOpenPrice)
line.set_y1(LondonLine, (LondonHighM+LondonLowM)/2)
line.set_y2(LondonLine, (LondonHighM+LondonLowM)/2)
var float pips = 0
var float chg = 0
pips := changeType=='Session High/Low' ? ((LondonHighPrice - LondonLowPrice) /
syminfo.mintick / 10) : ((close - LondonOpenPrice) / syminfo.mintick / 10)
chg := changeType=='Session Open/Close' ? (100 * (close - LondonOpenPrice) /
LondonOpenPrice) : ((LondonHighPrice - LondonLowPrice) / LondonLowPrice * 100)
if percentChange and not pipChange
label.set_text(LondonLabel, str.tostring(LondonText) + ' (' +
str.tostring(chg, format.percent) + ')')
if pipChange and not percentChange
label.set_text(LondonLabel, str.tostring(LondonText) + ' (' +
str.tostring(pips) + ')')
if percentChange and pipChange
label.set_text(LondonLabel, str.tostring(LondonText) + ' ('+
str.tostring(chg, format.percent)+ ' • ' + str.tostring(pips) + ')')
if inNewYork and inRange
NewYorkHighPrice := math.max(NewYorkHighPrice, high)
NewYorkLowPrice := math.min(NewYorkLowPrice, low)
box.set_top(NewYorkBox, NewYorkHighPrice)
box.set_bottom(NewYorkBox, NewYorkLowPrice)
box.set_right(NewYorkBox, bar_index + 1)
label.set_x(NewYorkLabel, (box.get_left(NewYorkBox)
+box.get_right(NewYorkBox))/2)
label.set_y(NewYorkLabel, NewYorkHighPrice)
if sessionOC
line.set_x2(NewYorkOC, bar_index)
line.set_y2(NewYorkOC, close)
if halfline
line.set_y1(NewYorkLine, (NewYorkHighPrice+NewYorkLowPrice)/2)
line.set_y2(NewYorkLine, (NewYorkHighPrice+NewYorkLowPrice)/2)
line.set_x2(NewYorkLine, bar_index+1)
if merge and not inSydney and showSydney
NewYorkHighM := NewYorkHighPrice
NewYorkLowM := NewYorkLowPrice
if merge and inSydney and showSydney
box.set_top(NewYorkBox, NewYorkHighM)
box.set_bottom(NewYorkBox, NewYorkLowM)
label.set_y(NewYorkLabel, NewYorkHighM)
box.set_right(NewYorkBox, (box.get_left(SydneyBox)))
line.set_x2(NewYorkLine, (box.get_left(SydneyBox)))
label.set_x(NewYorkLabel, (box.get_left(NewYorkBox)
+box.get_right(NewYorkBox))/2)
line.set_x2(NewYorkOC, (box.get_left(SydneyBox)))
line.set_y2(NewYorkOC, SydneyOpenPrice)
line.set_y1(NewYorkLine, (NewYorkHighM+NewYorkLowM)/2)
line.set_y2(NewYorkLine, (NewYorkHighM+NewYorkLowM)/2)
var float pips = 0
var float chg = 0
pips := changeType=='Session High/Low' ? ((NewYorkHighPrice -
NewYorkLowPrice) / syminfo.mintick / 10) : ((close - NewYorkOpenPrice) /
syminfo.mintick / 10)
chg := changeType=='Session Open/Close' ? (100 * (close - NewYorkOpenPrice) /
NewYorkOpenPrice) : ((NewYorkHighPrice - NewYorkLowPrice) / NewYorkLowPrice * 100)
if percentChange and not pipChange
label.set_text(NewYorkLabel, str.tostring(NewYorkText) + ' (' +
str.tostring(chg, format.percent) + ')')
if pipChange and not percentChange
label.set_text(NewYorkLabel, str.tostring(NewYorkText) + ' (' +
str.tostring(pips) + ')')
if percentChange and pipChange
label.set_text(NewYorkLabel, str.tostring(NewYorkText) + ' ('+
str.tostring(chg, format.percent)+ ' • ' + str.tostring(pips) + ')')
if inSydney and inRange
SydneyHighPrice := math.max(SydneyHighPrice, high)
SydneyLowPrice := math.min(SydneyLowPrice, low)
box.set_top(SydneyBox, SydneyHighPrice)
box.set_bottom(SydneyBox, SydneyLowPrice)
box.set_right(SydneyBox, bar_index + 1)
label.set_x(SydneyLabel, (box.get_left(SydneyBox)+box.get_right(SydneyBox))/2)
label.set_y(SydneyLabel, SydneyHighPrice)
if sessionOC
line.set_x2(SydneyOC, bar_index)
line.set_y2(SydneyOC, close)
if halfline
line.set_y1(SydneyLine, (SydneyHighPrice+SydneyLowPrice)/2)
line.set_y2(SydneyLine, (SydneyHighPrice+SydneyLowPrice)/2)
line.set_x2(SydneyLine, bar_index+1)
if merge and not inAsian and showAsian
SydneyHighM := SydneyHighPrice
SydneyLowM := SydneyLowPrice
if merge and inAsian and showAsian
box.set_top(SydneyBox, SydneyHighM)
box.set_bottom(SydneyBox, SydneyLowM)
label.set_y(SydneyLabel, SydneyHighM)
box.set_right(SydneyBox, (box.get_left(AsianBox)))
line.set_x2(SydneyLine, (box.get_left(AsianBox)))
label.set_x(SydneyLabel, (box.get_left(SydneyBox)
+box.get_right(SydneyBox))/2)
line.set_x2(SydneyOC, (box.get_left(AsianBox)))
line.set_y2(SydneyOC, AsianOpenPrice)
line.set_y1(SydneyLine, (SydneyHighM+SydneyLowM)/2)
line.set_y2(SydneyLine, (SydneyHighM+SydneyLowM)/2)
var float pips = 0
var float chg = 0
pips := changeType=='Session High/Low' ? ((SydneyHighPrice - SydneyLowPrice) /
syminfo.mintick / 10) : ((close - SydneyOpenPrice) / syminfo.mintick / 10)
chg := changeType=='Session Open/Close' ? (100 * (close - SydneyOpenPrice) /
SydneyOpenPrice) : ((SydneyHighPrice - SydneyLowPrice) / SydneyLowPrice * 100)
if percentChange and not pipChange
label.set_text(SydneyLabel, str.tostring(SydneyText) + ' (' +
str.tostring(chg, format.percent) + ')')
if pipChange and not percentChange
label.set_text(SydneyLabel, str.tostring(SydneyText) + ' (' +
str.tostring(pips) + ')')
if percentChange and pipChange
label.set_text(SydneyLabel, str.tostring(SydneyText) + ' ('+
str.tostring(chg, format.percent)+ ' • ' + str.tostring(pips) + ')')

// Coloring candles
TKLO = showLondon ? (not inLondon) : true
LONY = showNewYork ? (not inNewYork) : true
NYSY = showSydney ? (not inSydney) : true
SYTK = showAsian ? (not inAsian) : true
barcolor((colorcandles or displayType=='Candles') and not merge and showAsian
and inAsian and inRange ? color.new(AsianCol, 40) : na, editable =
false)
barcolor((colorcandles or displayType=='Candles') and not merge and showLondon
and inLondon and inRange ? color.new(LondonCol, 40) : na, editable =
false)
barcolor((colorcandles or displayType=='Candles') and not merge and showNewYork
and inNewYork and inRange ? color.new(NewYorkCol, 40) : na, editable =
false)
barcolor((colorcandles or displayType=='Candles') and not merge and showSydney
and inNewYork and inRange ? color.new(SydneyCol, 40) : na, editable =
false)
barcolor((colorcandles or displayType=='Candles') and merge and showAsian
and inAsian and TKLO and inRange ? color.new(AsianCol, 40) : na, editable =
false)
barcolor((colorcandles or displayType=='Candles') and merge and showLondon
and inLondon and LONY and inRange ? color.new(LondonCol, 40) : na, editable =
false)
barcolor((colorcandles or displayType=='Candles') and merge and showNewYork
and inNewYork and NYSY and inRange ? color.new(NewYorkCol, 40) : na, editable =
false)
barcolor((colorcandles or displayType=='Candles') and merge and showSydney
and inSydney and SYTK and inRange ? color.new(SydneyCol, 40) : na, editable =
false)

// Coloring background if displayType=='Zones'


AsianT = time(timeframe.period, AsianTime)
LondonT = time(timeframe.period, LondonTime)
NewYorkT = time(timeframe.period, NewYorkTime)
SydneyT = time(timeframe.period, SydneyTime)
bgcolor(displayType == 'Zones' and not merge and showAsian and inRange and time
== AsianT ? AsianCol : na, editable = false)
bgcolor(displayType == 'Zones' and not merge and showLondon and inRange and time
== LondonT ? LondonCol : na, editable = false)
bgcolor(displayType == 'Zones' and not merge and showNewYork and inRange and time
== NewYorkT ? NewYorkCol : na, editable = false)
bgcolor(displayType == 'Zones' and not merge and showSydney and inRange and time
== SydneyT ? SydneyCol : na, editable = false)
bgcolor(displayType == 'Zones' and merge and not inLondon and showAsian and
inRange and time == AsianT ? AsianCol : na, editable = false)
bgcolor(displayType == 'Zones' and merge and not inNewYork and showLondon and
inRange and time == LondonT ? LondonCol : na, editable = false)
bgcolor(displayType == 'Zones' and merge and not inSydney and showNewYork and
inRange and time == NewYorkT ? NewYorkCol : na, editable = false)
bgcolor(displayType == 'Zones' and merge and not inAsian and showSydney and
inRange and time == SydneyT ? SydneyCol : na, editable = false)

// Plotting sessions in Timeline form


plotshape(displayType=='Timeline' and (merge and showLondon ? (showAsian and
inAsian and not inLondon) : showAsian and inAsian), style=shape.square,
color=AsianCol, location = location.bottom, size=size.auto)
plotshape(displayType=='Timeline' and (merge and showNewYork ? (showLondon and
inLondon and not inNewYork) : showLondon and inLondon), style=shape.square,
color=LondonCol, location = location.bottom, size=size.auto)
plotshape(displayType=='Timeline' and (merge and showSydney ? (showNewYork and
inNewYork and not inSydney) : showNewYork and inNewYork), style=shape.square,
color=NewYorkCol, location = location.bottom, size=size.auto)
plotshape(displayType=='Timeline' and (merge and showAsian ? (showSydney and
inSydney and not inAsian) : showSydney and inSydney), style=shape.square,
color=SydneyCol, location = location.bottom, size=size.auto)

// Creating alerts
//alertcondition(inAsian and not inAsian[1], 'Asian Open', 'The Asian Session has
started')
//alertcondition(inLondon and not inLondon[1], 'London Open', 'The London Session
has started')
//alertcondition(inNewYork and not inNewYork[1], 'New York Open', 'The New York
Session has started')
//alertcondition(inSydney and not inSydney[1], 'Sydney Open', 'The Sydney Session
has started')
//alertcondition(high > AsianHighPrice[0] and inAsian, 'Asian Session - New
High', 'New High in Asian Session')
//alertcondition(high > LondonHighPrice[0] and inLondon, 'London Session - New
High', 'New High in London Session')
//alertcondition(high > NewYorkHighPrice[0] and inNewYork, 'New York Session - New
High', 'New High in New York Session')
//alertcondition(high > SydneyHighPrice[0] and inSydney, 'Sydney Session - New
High', 'New High in Sydney Session')
//alertcondition(low > AsianLowPrice[0] and inAsian, 'Asian Session - New
Low', 'New Low in Asian Session')
//alertcondition(low > LondonLowPrice[0] and inLondon, 'London Session - New
Low', 'New Low in London Session')
//alertcondition(low > NewYorkLowPrice[0] and inNewYork, 'New York Session - New
Low', 'New Low In New York Session')
//alertcondition(low > SydneyLowPrice[0] and inSydney, 'Sydney Session - New
Low', 'New Low In Sydney Session')

//------------------------------------------------------------------------------
//Breaker Blocks Settings
//-----------------------------------------------------------------------------{
bblength = input.int(10, 'Swing Lookback' , minval = 3, group = 'Breaker
Blocks')
showBull = input.int(3, 'Show Last Bullish OB', minval = 0, group = 'Breaker
Blocks')
showBear = input.int(3, 'Show Last Bearish OB', minval = 0, group = 'Breaker
Blocks')
useBody = input(false, 'Use Candle Body', group = 'Breaker Blocks')

//Style
bullCss = input(color.new(#2962ff, 85), 'Bullish OB' , inline = 'bullcss',
group = 'Breaker Blocks')
bullBreakCss = input(color.new(#e20061, 85), 'Bullish Break', inline = 'bullcss',
group = 'Breaker Blocks')

bearCss = input(color.new(#e20061, 85), 'Bearish OB' , inline = 'bearcss',


group = 'Breaker Blocks')
bearBreakCss = input(color.new(#2962ff, 85), 'Bearish Break', inline = 'bearcss',
group = 'Breaker Blocks')

bbshowLabels = input(false, 'Show Historical Polarity Changes', group = 'Breaker


Blocks')

//-----------------------------------------------------------------------------}
//UDT's
//-----------------------------------------------------------------------------{
type ob
float top = na
float btm = na
int loc = bar_index
bool breaker = false
int break_loc = na

type swing
float y = na
int x = na
bool crossed = false

//-----------------------------------------------------------------------------}
//Functions
//-----------------------------------------------------------------------------{
bbswings(len)=>
var os = 0
var swing top = swing.new(na, na)
var swing btm = swing.new(na, na)

upper = ta.highest(len)
lower = ta.lowest(len)
os := high[len] > upper ? 0
: low[len] < lower ? 1 : os

if os == 0 and os[1] != 0
top := swing.new(high[bblength], bar_index[bblength])

if os == 1 and os[1] != 1
btm := swing.new(low[bblength], bar_index[bblength])

[top, btm]

method notransp(color css) => color.rgb(color.r(css), color.g(css), color.b(css))

method display(ob id, css, break_css)=>


if id.breaker
box.new(id.loc, id.top, id.break_loc, id.btm,color.new(css.notransp(),60)
, bgcolor = css
, xloc = xloc.bar_time)

box.new(id.break_loc, id.top, time+5, id.btm,


color.new(break_css.notransp(),60)
, bgcolor = break_css
, extend = extend.right
, xloc = xloc.bar_time)

//line.new(id.loc, id.top, id.break_loc, id.top, xloc.bar_time, color =


color.new(css.notransp(),50))
//line.new(id.loc, id.btm, id.break_loc, id.btm, xloc.bar_time, color =
color.new(css.notransp(),50))
//line.new(id.break_loc, id.top, time+5, id.top, xloc.bar_time, color =
color.new(break_css.notransp(),50))//, line.style_dashed)
//line.new(id.break_loc, id.btm, time+5, id.btm, xloc.bar_time, color =
color.new(break_css.notransp(),50))//, line.style_dashed)
else
box.new(id.loc, id.top, time+5, id.btm, color.new(css.notransp(),65)
, bgcolor = css
, extend = extend.right
, xloc = xloc.bar_time)

//line.new(id.loc, id.top, time, id.top, xloc.bar_time, color =


color.new(css.notransp(),50))
//line.new(id.loc, id.btm, time, id.btm, xloc.bar_time, color =
color.new(css.notransp(),50))

//-----------------------------------------------------------------------------}
//Detect bbswings
//-----------------------------------------------------------------------------{
//n = bar_index

[bbtop, bbbtm] = bbswings(bblength)


max = useBody ? math.max(close, open) : high
min = useBody ? math.min(close, open) : low

//-----------------------------------------------------------------------------}
//Bullish OB
//-----------------------------------------------------------------------------{
var bullish_ob = array.new<ob>(0)
bull_break_conf = 0
if close > bbtop.y and not bbtop.crossed
bbtop.crossed := true

minima = max[1]
maxima = min[1]
loc = time[1]

for i = 1 to (n - bbtop.x)-1
minima := math.min(min[i], minima)
maxima := minima == min[i] ? max[i] : maxima
loc := minima == min[i] ? time[i] : loc

bullish_ob.unshift(ob.new(maxima, minima, loc))

if bullish_ob.size() > 0
for i = bullish_ob.size()-1 to 0
element = bullish_ob.get(i)

if not element.breaker
if math.min(close, open) < element.btm
element.breaker := true
element.break_loc := time
else
if close > element.top
bullish_ob.remove(i)
else if i < showBull and bbtop.y < element.top and bbtop.y >
element.btm
bull_break_conf := 1

//Set label
if bull_break_conf > bull_break_conf[1] and bbshowLabels
label.new(bbtop.x, bbtop.y, '▼', color = na
, textcolor = bearCss.notransp()
, style = label.style_label_down
, size = size.tiny)

//-----------------------------------------------------------------------------}
//Bearish OB
//-----------------------------------------------------------------------------{
var bearish_ob = array.new<ob>(0)
bear_break_conf = 0

if close < bbbtm.y and not bbbtm.crossed


bbbtm.crossed := true

minima = min[1]
maxima = max[1]
loc = time[1]

for i = 1 to (n - bbbtm.x)-1
maxima := math.max(max[i], maxima)
minima := maxima == max[i] ? min[i] : minima
loc := maxima == max[i] ? time[i] : loc

bearish_ob.unshift(ob.new(maxima, minima, loc))

if bearish_ob.size() > 0
for i = bearish_ob.size()-1 to 0
element = bearish_ob.get(i)
if not element.breaker
if math.max(close, open) > element.top
element.breaker := true
element.break_loc := time
else
if close < element.btm
bearish_ob.remove(i)
else if i < showBear and bbbtm.y > element.btm and bbbtm.y <
element.top
bear_break_conf := 1

//Set label
if bear_break_conf > bear_break_conf[1] and bbshowLabels
label.new(bbbtm.x, bbbtm.y, '▲', color = na
, textcolor = bullCss.notransp()
, style = label.style_label_up
, size = size.tiny)

//-----------------------------------------------------------------------------}
//Set Order Blocks
//-----------------------------------------------------------------------------{
//for bx in box.all
// bx.delete()

//for l in line.all
// l.delete()

if barstate.islast
//Bullish
if showBull > 0
for i = 0 to math.min(showBull-1, bullish_ob.size())
get_ob = bullish_ob.get(i)
get_ob.display(bullCss, bullBreakCss)

//Bearish
if showBear > 0
for i = 0 to math.min(showBear-1, bearish_ob.size())
get_ob = bearish_ob.get(i)
get_ob.display(bearCss, bearBreakCss)

//------------------------------------------------------------------------------
//Settings
//-----------------------------------------------------------------------------{
liqGrp = 'Liquidity Detection'
liqLen = input.int (7, title = 'Detection Length', minval = 3, maxval = 13,
inline = 'LIQ', group = liqGrp)
liqMar = 10 / input.float (6.9, 'Margin', minval = 4, maxval = 9, step = 0.1,
inline = 'LIQ', group = liqGrp)

liqBuy = input.bool (true, 'Buyside Liquidity Zones, Margin', inline = 'Buyside',


group = liqGrp)
marBuy = input.float(2, '', minval = 1.5, maxval = 10, step = .1, inline =
'Buyside', group = liqGrp)
cLIQ_B = input.color (color.new(#ffffff, 93), '', inline = 'Buyside', group =
liqGrp)
liqSel = input.bool (true, 'Sellside Liquidity Zones, Margin', inline = 'Sellside',
group = liqGrp)
marSel = input.float(2, '', minval = 1.5, maxval = 10, step = .1, inline =
'Sellside', group = liqGrp)
cLIQ_S = input.color (color.new(#ffffff, 93), '', inline = 'Sellside', group =
liqGrp)

lqVoid = input.bool (false, 'Liquidity Voids, Bullish', inline = 'void', group =


liqGrp)
cLQV_B = input.color (color.new(#4caf50, 0), '', inline = 'void', group = liqGrp)
cLQV_S = input.color (color.new(#f23645, 0), 'Bearish', inline = 'void', group =
liqGrp)
lqText = input.bool (false, 'Label', inline = 'void', group = liqGrp)

liqmode = input.string('Present', title = 'liqmode', options =['Present',


'Historical'], inline = 'MOD', group = liqGrp)
visLiq = input.int (3, ' # Visible Levels', minval = 1, maxval = 50, inline =
'MOD', group = liqGrp)

//-----------------------------------------------------------------------------}
//General Calculations
//-----------------------------------------------------------------------------{
maxSize = 50
atr10 = ta.atr(10)
//atr200 = ta.atr(200)
per = liqmode == 'Present' ? last_bar_index - bar_index <= 500 : true

//-----------------------------------------------------------------------------}
//User Defined Types
//-----------------------------------------------------------------------------{
// @type used to store pivot high/low data
//
// @field d (array<int>) The array where the trend direction is to be
maintained
// @field x (array<int>) The array where the bar index value of pivot high/low
is to be maintained
// @field y (array<float>) The array where the price value of pivot high/low is
to be maintained

type ZZ
int [] d
int [] x
float [] y

// @type bar properties with their values


//
// @field o (float) open price of the bar
// @field h (float) high price of the bar
// @field l (float) low price of the bar
// @field c (float) close price of the bar
// @field i (int) index of the bar

type bar
float o = open
float h = high
float l = low
float c = close
int i = bar_index
// @type liquidity object definition
//
// @field bx (box) box maitaing the liquity level margin extreme levels
// @field bxz (box) box maitaing the liquity zone margin extreme levels
// @field bxt (box) box maitaing the labels
// @field brZ (bool) mainains broken zone status
// @field brL (bool) mainains broken level status
// @field ln (line) maitaing the liquity level line
// @field lne (line) maitaing the liquity extended level line

type liq
box bx
box bxz
box bxt
bool brZ
bool brL
line ln
line lne

//-----------------------------------------------------------------------------}
//Variables
//-----------------------------------------------------------------------------{
var ZZ aZZ = ZZ.new(
array.new <int> (maxSize, 0),
array.new <int> (maxSize, 0),
array.new <float>(maxSize, na)
)

bar b = bar.new()

var liq[] b_liq_B = array.new<liq> (1, liq.new(box(na), box(na), box(na), false,


false, line(na), line(na)))
var liq[] b_liq_S = array.new<liq> (1, liq.new(box(na), box(na), box(na), false,
false, line(na), line(na)))

var b_liq_V = array.new_box()

var int dir = na, var int x1 = na, var float y1 = na, var int x2 = na, var float y2
= na

//-----------------------------------------------------------------------------}
//Functions/methods
//-----------------------------------------------------------------------------{
// @function maintains arrays
// it prepends a `value` to the arrays and removes their oldest
element at last position
// @param aZZ (UDT<array<int>, array<int>, array<float>>) The UDT obejct of
arrays
// @param _d (array<int>) The array where the trend direction is maintained
// @param _x (array<int>) The array where the bar index value of pivot
high/low is maintained
// @param _y (array<float>) The array where the price value of pivot
high/low is maintained
//
// @returns none

method in_out(ZZ aZZ, int _d, int _x, float _y) =>
aZZ.d.unshift(_d), aZZ.x.unshift(_x), aZZ.y.unshift(_y), aZZ.d.pop(),
aZZ.x.pop(), aZZ.y.pop()
// @function (build-in) sets the maximum number of bars that is available
for historical reference

max_bars_back(time, 1000)

//-----------------------------------------------------------------------------}
//Calculations
//-----------------------------------------------------------------------------{
x2 := b.i - 1
ph = ta.pivothigh(liqLen, 1)
pl = ta.pivotlow (liqLen, 1)

if ph
dir := aZZ.d.get(0)
x1 := aZZ.x.get(0)
y1 := aZZ.y.get(0)
y2 := nz(b.h[1])

if dir < 1
aZZ.in_out(1, x2, y2)
else
if dir == 1 and ph > y1
aZZ.x.set(0, x2), aZZ.y.set(0, y2)

if per
count = 0
st_P = 0.
st_B = 0
minP = 0.
maxP = 10e6

for i = 0 to maxSize - 1
if aZZ.d.get(i) == 1
if aZZ.y.get(i) > ph + (atr10 / liqMar)
break
else
if aZZ.y.get(i) > ph - (atr10 / liqMar) and aZZ.y.get(i) < ph +
(atr10 / liqMar)
count += 1
st_B := aZZ.x.get(i)
st_P := aZZ.y.get(i)
if aZZ.y.get(i) > minP
minP := aZZ.y.get(i)
if aZZ.y.get(i) < maxP
maxP := aZZ.y.get(i)

if count > 2
getB = b_liq_B.get(0)

if st_B == getB.bx.get_left()
getB.bx.set_top(math.avg(minP, maxP) + (atr10 / liqMar))
getB.bx.set_rightbottom(b.i + 10, math.avg(minP, maxP) - (atr10 /
liqMar))
else
b_liq_B.unshift(
liq.new(
box.new(st_B, math.avg(minP, maxP) + (atr10 / liqMar), b.i + 10,
math.avg(minP, maxP) - (atr10 / liqMar), bgcolor=color(na),
border_color=color(na)),
box.new(na, na, na, na, bgcolor = color(na), border_color =
color(na)),
box.new(st_B, st_P, b.i + 10, st_P, text = 'Buyside liquidity',
text_size = size.small, text_halign = text.align_left, text_valign =
text.align_bottom, text_color = color.new(cLIQ_B, 25), bgcolor = color(na),
border_color = color(na)),
false,
false,
line.new(st_B , st_P, b.i - 1, st_P, color = color.new(cLIQ_B,
60)),
line.new(b.i - 1, st_P, na , st_P, color = color.new(cLIQ_B,
60), style = line.style_dotted))
)

alert('buyside liquidity level detected/updated for ' +


syminfo.ticker)

if b_liq_B.size() > visLiq


getLast = b_liq_B.pop()
getLast.bx.delete()
getLast.bxz.delete()
getLast.bxt.delete()
getLast.ln.delete()
getLast.lne.delete()

if pl
dir := aZZ.d.get (0)
x1 := aZZ.x.get (0)
y1 := aZZ.y.get (0)
y2 := nz(b.l[1])

if dir > -1
aZZ.in_out(-1, x2, y2)
else
if dir == -1 and pl < y1
aZZ.x.set(0, x2), aZZ.y.set(0, y2)

if per
count = 0
st_P = 0.
st_B = 0
minP = 0.
maxP = 10e6

for i = 0 to maxSize - 1
if aZZ.d.get(i) == -1
if aZZ.y.get(i) < pl - (atr10 / liqMar)
break
else
if aZZ.y.get(i) > pl - (atr10 / liqMar) and aZZ.y.get(i) < pl +
(atr10 / liqMar)
count += 1
st_B := aZZ.x.get(i)
st_P := aZZ.y.get(i)
if aZZ.y.get(i) > minP
minP := aZZ.y.get(i)
if aZZ.y.get(i) < maxP
maxP := aZZ.y.get(i)

if count > 2
getB = b_liq_S.get(0)

if st_B == getB.bx.get_left()
getB.bx.set_top(math.avg(minP, maxP) + (atr10 / liqMar))
getB.bx.set_rightbottom(b.i + 10, math.avg(minP, maxP) - (atr10 /
liqMar))
else
b_liq_S.unshift(
liq.new(
box.new(st_B, math.avg(minP, maxP) + (atr10 / liqMar), b.i + 10,
math.avg(minP, maxP) - (atr10 / liqMar), bgcolor=color(na),
border_color=color(na)),
box.new(na, na, na, na, bgcolor=color(na),
border_color=color(na)),
box.new(st_B, st_P, b.i + 10, st_P, text = 'Sellside liquidity',
text_size = size.small, text_halign = text.align_left, text_valign =
text.align_top, text_color = color.new(cLIQ_S, 25), bgcolor=color(na),
border_color=color(na)),
false,
false,
line.new(st_B , st_P, b.i - 1, st_P, color = color.new(cLIQ_S,
60)),
line.new(b.i - 1, st_P, na , st_P, color = color.new(cLIQ_S,
60), style = line.style_dotted))
)

alert('sellside liquidity level detected/updated for ' +


syminfo.ticker)

if b_liq_S.size() > visLiq


getLast = b_liq_S.pop()
getLast.bx.delete()
getLast.bxz.delete()
getLast.bxt.delete()
getLast.ln.delete()
getLast.lne.delete()

for i = 0 to b_liq_B.size() - 1
x = b_liq_B.get(i)

if not x.brL
x.lne.set_x2(b.i)

if b.h > x.bx.get_top()


x.brL := true
x.brZ := true
alert('buyside liquidity level breached for ' + syminfo.ticker)

x.bxz.set_lefttop(b.i - 1, math.min(x.ln.get_y1() + marBuy * (atr10),


b.h))
x.bxz.set_rightbottom(b.i + 1, x.ln.get_y1())
x.bxz.set_bgcolor(color.new(cLIQ_B, liqBuy ? 73 : 100))

else if x.brZ
if b.l > x.ln.get_y1() - marBuy * (atr10) and b.h < x.ln.get_y1() + marBuy
* (atr10)
x.bxz.set_right(b.i + 1)
x.bxz.set_top(math.max(b.h, x.bxz.get_top()))
if liqBuy
x.lne.set_x2(b.i + 1)
else
x.brZ := false

for i = 0 to b_liq_S.size() - 1
x = b_liq_S.get(i)

if not x.brL
x.lne.set_x2(b.i)

if b.l < x.bx.get_bottom()


x.brL := true
x.brZ := true
alert('sellside liquidity level breached for ' + syminfo.ticker)

x.bxz.set_lefttop(b.i - 1, x.ln.get_y1())
x.bxz.set_rightbottom(b.i + 1, math.max(x.ln.get_y1() - marSel *
(atr10), b.l))
x.bxz.set_bgcolor(color.new(cLIQ_S, liqSel ? 73 : 100))

else if x.brZ
if b.l > x.ln.get_y1() - marSel * (atr10) and b.h < x.ln.get_y1() + marSel
* (atr10)
x.bxz.set_rightbottom(b.i + 1, math.min(b.l, x.bxz.get_bottom()))
if liqSel
x.lne.set_x2(b.i + 1)
else
x.brZ := false

if lqVoid and per


bull = b.l - b.h[2] > atr and b.l > b.h[2] and b.c[1] > b.h[2]
bear = b.l[2] - b.h > atr and b.h < b.l[2] and b.c[1] < b.l[2]

if bull
l = 13
if bull[1]
st = math.abs(b.l - b.l[1]) / l
for i = 0 to l - 1
array.push(b_liq_V, box.new(b.i - 2, b.l[1] + i * st, b.i, b.l[1] +
(i + 1) * st, border_color = na, bgcolor = color.new(cLQV_B, 90) ))
else
st = math.abs(b.l - b.h[2]) / l
for i = 0 to l - 1
if lqText and i == 0
array.push(b_liq_V, box.new(b.i - 2, b.h[2] + i * st, b.i,
b.h[2] + (i + 1) * st, text = 'Liquidity Void ', text_size = size.tiny,
text_halign = text.align_right, text_valign = text.align_bottom, text_color = na,
border_color = na, bgcolor = color.new(cLQV_B, 90) ))
else
array.push(b_liq_V, box.new(b.i - 2, b.h[2] + i * st, b.i,
b.h[2] + (i + 1) * st, border_color = na, bgcolor = color.new(cLQV_B, 90) ))

if bear
l = 13
if bear[1]
st = math.abs(b.h[1] - b.h) / l
for i = 0 to l - 1
array.push(b_liq_V, box.new(b.i - 2, b.h + i * st, b.i, b.h + (i +
1) * st, border_color = na, bgcolor = color.new(cLQV_S, 90) ))
else
st = math.abs(b.l[2] - b.h) / l
for i = 0 to l - 1
if lqText and i == l - 1
array.push(b_liq_V, box.new(b.i - 2, b.h + i * st, b.i, b.h +
(i + 1) * st, text = 'Liquidity Void ', text_size = size.tiny, text_halign =
text.align_right, text_valign = text.align_top, text_color = na, border_color = na,
bgcolor = color.new(cLQV_S, 90) ))
else
array.push(b_liq_V, box.new(b.i - 2, b.h + i * st, b.i, b.h +
(i + 1) * st, border_color = na, bgcolor = color.new(cLQV_S, 90) ))

if b_liq_V.size() > 0
qt = b_liq_V.size()
for bn = qt - 1 to 0
if bn < b_liq_V.size()
cb = b_liq_V.get(bn)
ba = math.avg(cb.get_bottom(), cb.get_top())

if math.sign(b.c[1] - ba) != math.sign(b.c - ba) or math.sign(b.c[1] -


ba) != math.sign(b.l - ba) or math.sign(b.c[1] - ba) != math.sign(b.h - ba)
b_liq_V.remove(bn)
else
cb.set_right(b.i + 1)

if b.i - cb.get_left() > 21


cb.set_text_color(color.new(color.gray, 25))

//-----------------------------------------------------------------------------}

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

//@version=5
// Pulu's Moving Averages
// Release version 1.68, date 2021-12-05
//indicator(title='Pulu\'s Moving Averages', shorttitle='PMA', overlay=true)

strRoundValue(num) =>
strv = ''
if num >= 100000
strv := str.tostring(num/1000, '#K')
else if (num < 100000) and (num >= 100)
strv := str.tostring(num, '#')
else if (num < 100) and (num >= 1)
strv := str.tostring(num, '#.##')
else if (num < 1) and (num >= 0.01)
strv := str.tostring(num, '#.####')
else if (num < 0.01) and (num >= 0.0001)
strv := str.tostring(num, '#.######')
else if (num < 0.0001) and (num >= 0.000001)
strv := str.tostring(num, '#.########')
(strv)
defaultFunction(func, src, len, alma_offst, alma_sigma) =>
has_len = false
ma = ta.swma(close)
if func == 'ALMA'
ma := ta.alma(src, len, alma_offst, alma_sigma)
has_len := true
has_len
else if func == 'EMA'
ma := ta.ema(src, len)
has_len := true
has_len
else if func == 'RMA'
ma := ta.rma(src, len)
has_len := true
has_len
else if func == 'SMA'
ma := ta.sma(src, len)
has_len := true
has_len
else if func == 'SWMA'
ma := ta.swma(src)
has_len := false
has_len
else if func == 'VWAP'
ma := ta.vwap(src)
has_len := false
has_len
else if func == 'VWMA'
ma := ta.vwma(src, len)
has_len := true
has_len
else if func == 'WMA'
ma := ta.wma(src, len)
has_len := true
has_len
[ma, has_len]

def_fn = input.string(title='Default moving average', defval='EMA',


options=['ALMA', 'EMA', 'RMA', 'SMA', 'SWMA', 'VWAP', 'VWMA', 'WMA'])

ma1_on = input.bool(inline='MA1', title='Enable moving average 1', defval=true)


ma2_on = input.bool(inline='MA2', title='Enable moving average 2', defval=true)
ma3_on = input.bool(inline='MA3', title='Enable moving average 3', defval=true)
ma4_on = input.bool(inline='MA4', title='Enable moving average 4', defval=true)
ma5_on = input.bool(inline='MA5', title='Enable moving average 5', defval=true)
ma6_on = input.bool(inline='MA6', title='Enable moving average 6', defval=true)
ma7_on = input.bool(inline='MA7', title='Enable moving average 7', defval=true)

ma1_fn = input.string(inline='MA1', title='', defval='default', options=['default',


'ALMA', 'EMA', 'RMA', 'SMA', 'SWMA', 'VWAP', 'VWMA', 'WMA'])
ma2_fn = input.string(inline='MA2', title='', defval='default', options=['default',
'ALMA', 'EMA', 'RMA', 'SMA', 'SWMA', 'VWAP', 'VWMA', 'WMA'])
ma3_fn = input.string(inline='MA3', title='', defval='default', options=['default',
'ALMA', 'EMA', 'RMA', 'SMA', 'SWMA', 'VWAP', 'VWMA', 'WMA'])
ma4_fn = input.string(inline='MA4', title='', defval='default', options=['default',
'ALMA', 'EMA', 'RMA', 'SMA', 'SWMA', 'VWAP', 'VWMA', 'WMA'])
ma5_fn = input.string(inline='MA5', title='', defval='default', options=['default',
'ALMA', 'EMA', 'RMA', 'SMA', 'SWMA', 'VWAP', 'VWMA', 'WMA'])
ma6_fn = input.string(inline='MA6', title='', defval='default', options=['default',
'ALMA', 'EMA', 'RMA', 'SMA', 'SWMA', 'VWAP', 'VWMA', 'WMA'])
ma7_fn = input.string(inline='MA7', title='', defval='default', options=['default',
'ALMA', 'EMA', 'RMA', 'SMA', 'SWMA', 'VWAP', 'VWMA', 'WMA'])

ma1_len = input.int(inline='MA1', title='', defval=8, minval=1)


ma2_len = input.int(inline='MA2', title='', defval=20, minval=1)
ma3_len = input.int(inline='MA3', title='', defval=30, minval=1)
ma4_len = input.int(inline='MA4', title='', defval=144, minval=1)
ma5_len = input.int(inline='MA5', title='', defval=169, minval=1)
ma6_len = input.int(inline='MA6', title='', defval=576, minval=1)
ma7_len = input.int(inline='MA7', title='', defval=676, minval=1)

ma1_clr = input.color(inline='MA1', title='', defval=color.new(color.fuchsia,65))


ma2_clr = input.color(inline='MA2', title='', defval=color.new(color.aqua,65))
ma3_clr = input.color(inline='MA3', title='', defval=color.new(color.yellow,65))
ma4_clr = input.color(inline='MA4', title='', defval=color.new(color.aqua,65))
ma5_clr = input.color(inline='MA5', title='', defval=color.new(color.orange,65))
ma6_clr = input.color(inline='MA6', title='', defval=color.new(color.green,65))
ma7_clr = input.color(inline='MA7', title='', defval=color.new(color.red,65))

ma1_len_indx = ma1_len - 1
ma2_len_indx = ma2_len - 1
ma3_len_indx = ma3_len - 1
ma4_len_indx = ma4_len - 1
ma5_len_indx = ma5_len - 1
ma6_len_indx = ma6_len - 1
ma7_len_indx = ma7_len - 1

// Moving average 1 other parameters


alma1_offst = input.float(group='MA1 other settings', inline='MA11', title='ALMA
offset', defval=0.85, minval=-1, maxval=1, step=0.01)
alma1_sigma = input.float(group='MA1 other settings', inline='MA11', title=',
sigma', defval=6, minval=0, maxval=100, step=0.01)
ma1_src = input.source(group='MA1 other settings', inline='MA12', title='Source',
defval=close)
ma1_plt_offst = input.int(group='MA1 other settings', inline='MA12', title=', plot
offset', defval=0, minval=-500, maxval=500)

// Moving average 2 other parameters


alma2_offst = input.float(group='MA2 other settings', inline='MA21', title='ALMA
Offset', defval=0.85, minval=-1, maxval=1, step=0.01)
alma2_sigma = input.float(group='MA2 other settings', inline='MA21', title='Sigma',
defval=6, minval=0, maxval=100, step=0.01)
ma2_src = input.source(group='MA2 other settings', inline='MA22', title='Source',
defval=close)
ma2_plt_offst = input.int(group='MA2 other settings', inline='MA22', title='Polt
offset', defval=0, minval=-500, maxval=500)

// Moving average 3 other parameters


alma3_offst = input.float(group='MA3 other settings', inline='MA31', title='ALMA
Offset', defval=0.85, minval=-1, maxval=1, step=0.01)
alma3_sigma = input.float(group='MA3 other settings', inline='MA31', title='Sigma',
defval=6, minval=0, maxval=100, step=0.01)
ma3_src = input.source(group='MA3 other settings', inline='MA32', title='Source',
defval=close)
ma3_plt_offst = input.int(group='MA3 other settings', inline='MA32', title='Plot
offset', defval=0, minval=-500, maxval=500)
// Moving average 4 other parameters
alma4_offst = input.float(group='MA4 other settings', inline='MA41', title='ALMA
Offset', defval=0.85, minval=-1, maxval=1, step=0.01)
alma4_sigma = input.float(group='MA4 other settings', inline='MA41', title='Sigma',
defval=6, minval=0, maxval=100, step=0.01)
ma4_src = input.source(group='MA4 other settings', inline='MA42', title='Source',
defval=close)
ma4_plt_offst = input.int(group='MA4 other settings', inline='MA42', title='Plot
offset', defval=0, minval=-500, maxval=500)

// Moving average 5 other parameters


alma5_offst = input.float(group='MA5 other settings', inline='MA51', title='ALMA
Offset', defval=0.85, minval=-1, maxval=1, step=0.01)
alma5_sigma = input.float(group='MA5 other settings', inline='MA51', title='Sigma',
defval=6, minval=0, maxval=100, step=0.01)
ma5_src = input.source(group='MA5 other settings', inline='MA52', title='Source',
defval=close)
ma5_plt_offst = input.int(group='MA5 other settings', inline='MA52', title='Plot
offset', defval=0, minval=-500, maxval=500)

// Moving average 6 other parameters


alma6_offst = input.float(group='MA6 other settings', inline='MA61', title='ALMA
Offset', defval=0.85, minval=-1, maxval=1, step=0.01)
alma6_sigma = input.float(group='MA6 other settings', inline='MA61', title='Sigma',
defval=6, minval=0, maxval=100, step=0.01)
ma6_src = input.source(group='MA6 other settings', inline='MA62', title='Source',
defval=close)
ma6_plt_offst = input.int(group='MA6 other settings', inline='MA62', title='Plot
offset', defval=0, minval=-500, maxval=500)

// Moving average 7 other parameters


alma7_offst = input.float(group='MA7 other settings', inline='MA71', title='ALMA
Offset', defval=0.85, minval=-1, maxval=1, step=0.01)
alma7_sigma = input.float(group='MA7 other settings', inline='MA71', title='Sigma',
defval=6, minval=0, maxval=100, step=0.01)
ma7_src = input.source(group='MA7 other settings', inline='MA72', title='Source',
defval=close)
ma7_plt_offst = input.int(group='MA7 other settings', inline='MA72', title='Plot
offset', defval=0, minval=-500, maxval=500)

// Background fills between MAs


fill_12_on = input.bool(group='Background fills between MAs', inline='FILL1',
title='MA1-2', defval=true)
fill_23_on = input.bool(group='Background fills between MAs', inline='FILL2',
title='MA2-3', defval=true)
fill_34_on = input.bool(group='Background fills between MAs', inline='FILL3',
title='MA3-4', defval=false)
fill_45_on = input.bool(group='Background fills between MAs', inline='FILL4',
title='MA4-5', defval=true)
fill_56_on = input.bool(group='Background fills between MAs', inline='FILL5',
title='MA5-6', defval=false)
fill_67_on = input.bool(group='Background fills between MAs', inline='FILL6',
title='MA6-7', defval=true)

fill_12_trans = input.int(group='Background fills between MAs', inline='FILL1',


title=', transparency', defval=90, minval=0, maxval=100)
fill_23_trans = input.int(group='Background fills between MAs', inline='FILL2',
title=', transparency', defval=90, minval=0, maxval=100)
fill_34_trans = input.int(group='Background fills between MAs', inline='FILL3',
title=', transparency', defval=90, minval=0, maxval=100)
fill_45_trans = input.int(group='Background fills between MAs', inline='FILL4',
title=', transparency', defval=90, minval=0, maxval=100)
fill_56_trans = input.int(group='Background fills between MAs', inline='FILL5',
title=', transparency', defval=90, minval=0, maxval=100)
fill_67_trans = input.int(group='Background fills between MAs', inline='FILL6',
title=', transparency', defval=90, minval=0, maxval=100)

// Initial moving averages


[ma1, ma1_has_len] = defaultFunction(def_fn, ma1_src, ma1_len, alma1_offst,
alma1_sigma)
[ma2, ma2_has_len] = defaultFunction(def_fn, ma2_src, ma2_len, alma2_offst,
alma2_sigma)
[ma3, ma3_has_len] = defaultFunction(def_fn, ma3_src, ma3_len, alma3_offst,
alma3_sigma)
[ma4, ma4_has_len] = defaultFunction(def_fn, ma4_src, ma4_len, alma4_offst,
alma4_sigma)
[ma5, ma5_has_len] = defaultFunction(def_fn, ma5_src, ma5_len, alma5_offst,
alma5_sigma)
[ma6, ma6_has_len] = defaultFunction(def_fn, ma6_src, ma6_len, alma6_offst,
alma6_sigma)
[ma7, ma7_has_len] = defaultFunction(def_fn, ma7_src, ma7_len, alma7_offst,
alma7_sigma)

if ma1_fn != 'default' // if MA1 does not use default function


if ma1_fn == 'ALMA'
ma1 := ta.alma(ma1_src, ma1_len, alma1_offst, alma1_sigma)
ma1_has_len := true
else if ma1_fn == 'EMA'
ma1 := ta.ema(ma1_src, ma1_len)
ma1_has_len := true
else if ma1_fn == 'RMA'
ma1 := ta.rma(ma1_src, ma1_len)
ma1_has_len := true
else if ma1_fn == 'SMA'
ma1 := ta.sma(ma1_src, ma1_len)
ma1_has_len := true
else if ma1_fn == 'SWMA'
ma1 := ta.swma(ma1_src)
ma1_has_len := false
else if ma1_fn == 'VWAP'
ma1 := ta.vwap(ma1_src)
ma1_has_len := false
else if ma1_fn == 'VWMA'
ma1 := ta.vwma(ma1_src, ma1_len)
ma1_has_len := true
else if ma1_fn == 'WMA'
ma1 := ta.wma(ma1_src, ma1_len)
ma1_has_len := true

if ma2_fn != 'default' // if MA2 does not use default function


if ma2_fn == 'ALMA'
ma2 := ta.alma(ma2_src, ma2_len, alma2_offst, alma2_sigma)
ma2_has_len := true
else if ma2_fn == 'EMA'
ma2 := ta.ema(ma2_src, ma2_len)
ma2_has_len := true
else if ma2_fn == 'RMA'
ma2 := ta.rma(ma2_src, ma2_len)
ma2_has_len := true
else if ma2_fn == 'SMA'
ma2 := ta.sma(ma2_src, ma2_len)
ma2_has_len := true
else if ma2_fn == 'SWMA'
ma2 := ta.swma(ma2_src)
ma2_has_len := false
else if ma2_fn == 'VWAP'
ma2 := ta.vwap(ma2_src)
ma2_has_len := false
else if ma2_fn == 'VWMA'
ma2 := ta.vwma(ma2_src, ma1_len)
ma2_has_len := true
else if ma2_fn == 'WMA'
ma2 := ta.wma(ma2_src, ma2_len)
ma2_has_len := true

if ma3_fn != 'default' // if MA3 does not use default function


if ma3_fn == 'ALMA'
ma3 := ta.alma(ma3_src, ma3_len, alma3_offst, alma3_sigma)
ma3_has_len := true
else if ma3_fn == 'EMA'
ma3 := ta.ema(ma3_src, ma3_len)
ma3_has_len := true
else if ma3_fn == 'RMA'
ma3 := ta.rma(ma3_src, ma3_len)
ma3_has_len := true
else if ma3_fn == 'SMA'
ma3 := ta.sma(ma3_src, ma3_len)
ma3_has_len := true
else if ma3_fn == 'SWMA'
ma3 := ta.swma(ma3_src)
ma3_has_len := false
else if ma3_fn == 'VWAP'
ma3 := ta.vwap(ma3_src)
ma3_has_len := false
else if ma3_fn == 'VWMA'
ma3 := ta.vwma(ma3_src, ma3_len)
ma3_has_len := true
else if ma3_fn == 'WMA'
ma3 := ta.wma(ma3_src, ma3_len)
ma3_has_len := true

if ma4_fn != 'default' // if MA4 does not use default function


if ma4_fn == 'ALMA'
ma4 := ta.alma(ma4_src, ma4_len, alma4_offst, alma4_sigma)
ma4_has_len := true
else if ma4_fn == 'EMA'
ma4 := ta.ema(ma4_src, ma4_len)
ma4_has_len := true
else if ma4_fn == 'RMA'
ma4 := ta.rma(ma4_src, ma4_len)
ma4_has_len := true
else if ma4_fn == 'SMA'
ma4 := ta.sma(ma4_src, ma4_len)
ma4_has_len := true
else if ma4_fn == 'SWMA'
ma4 := ta.swma(ma4_src)
ma4_has_len := false
else if ma4_fn == 'VWAP'
ma4 := ta.vwap(ma4_src)
ma4_has_len := false
else if ma4_fn == 'VWMA'
ma4 := ta.vwma(ma4_src, ma4_len)
ma4_has_len := true
else if ma4_fn == 'WMA'
ma4 := ta.wma(ma4_src, ma4_len)
ma4_has_len := true

if ma5_fn != 'default' // if MA5 does not use default function


if ma5_fn == 'ALMA'
ma5 := ta.alma(ma5_src, ma5_len, alma5_offst, alma5_sigma)
ma5_has_len := true
else if ma5_fn == 'EMA'
ma5 := ta.ema(ma5_src, ma5_len)
ma5_has_len := true
else if ma5_fn == 'RMA'
ma5 := ta.rma(ma5_src, ma5_len)
ma5_has_len := true
else if ma5_fn == 'SMA'
ma5 := ta.sma(ma5_src, ma5_len)
ma5_has_len := true
else if ma5_fn == 'SWMA'
ma5 := ta.swma(ma5_src)
ma5_has_len := false
else if ma5_fn == 'VWAP'
ma5 := ta.vwap(ma5_src)
ma5_has_len := false
else if ma5_fn == 'VWMA'
ma5 := ta.vwma(ma5_src, ma5_len)
ma5_has_len := true
else if ma5_fn == 'WMA'
ma5 := ta.wma(ma5_src, ma5_len)
ma5_has_len := true

if ma6_fn != 'default' // if MA6 does not use default function


if ma6_fn == 'ALMA'
ma6 := ta.alma(ma6_src, ma6_len, alma6_offst, alma6_sigma)
ma6_has_len := true
else if ma6_fn == 'EMA'
ma6 := ta.ema(ma6_src, ma6_len)
ma6_has_len := true
else if ma6_fn == 'RMA'
ma6 := ta.rma(ma6_src, ma6_len)
ma6_has_len := true
else if ma6_fn == 'SMA'
ma6 := ta.sma(ma6_src, ma6_len)
ma6_has_len := true
else if ma6_fn == 'SWMA'
ma6 := ta.swma(ma6_src)
ma6_has_len := false
else if ma6_fn == 'VWAP'
ma6 := ta.vwap(ma6_src)
ma6_has_len := false
else if ma6_fn == 'VWMA'
ma6 := ta.vwma(ma6_src, ma6_len)
ma6_has_len := true
else if ma6_fn == 'WMA'
ma6 := ta.wma(ma6_src, ma6_len)
ma6_has_len := true

if ma7_fn != 'default' // if MA7 does not use default function


if ma7_fn == 'ALMA'
ma7 := ta.alma(ma6_src, ma7_len, alma7_offst, alma7_sigma)
ma7_has_len := true
else if ma7_fn == 'EMA'
ma7 := ta.ema(ma7_src, ma7_len)
ma7_has_len := true
else if ma7_fn == 'RMA'
ma7 := ta.rma(ma7_src, ma7_len)
ma7_has_len := true
else if ma7_fn == 'SMA'
ma7 := ta.sma(ma7_src, ma7_len)
ma7_has_len := true
else if ma7_fn == 'SWMA'
ma7 := ta.swma(ma7_src)
ma7_has_len := false
else if ma7_fn == 'VWAP'
ma7 := ta.vwap(ma7_src)
ma7_has_len := false
else if ma7_fn == 'VWMA'
ma7 := ta.vwma(ma7_src, ma7_len)
ma7_has_len := true
else if ma7_fn == 'WMA'
ma7 := ta.wma(ma7_src, ma7_len)
ma7_has_len := true

// Plot MA curves
p1 = plot(series=ma1_on and switch_ema ? ma1 : na, color=ma1_clr, trackprice=false,
offset=ma1_plt_offst)
p2 = plot(series=ma2_on and switch_ema ? ma2 : na, color=ma2_clr, trackprice=false,
offset=ma2_plt_offst)
p3 = plot(series=ma3_on and switch_ema ? ma3 : na, color=ma3_clr, trackprice=false,
offset=ma3_plt_offst)
p4 = plot(series=ma4_on and switch_ema ? ma4 : na, color=ma4_clr, trackprice=false,
offset=ma4_plt_offst)
p5 = plot(series=ma5_on and switch_ema ? ma5 : na, color=ma5_clr, trackprice=false,
offset=ma5_plt_offst)
p6 = plot(series=ma6_on and switch_ema ? ma6 : na, color=ma6_clr, trackprice=false,
offset=ma6_plt_offst)
p7 = plot(series=ma7_on and switch_ema ? ma7 : na, color=ma7_clr, trackprice=false,
offset=ma7_plt_offst)

// Background fills between MAs


fill(p1, p2, color.new((ma1 > ma2 ? ma1_clr : ma2_clr), (ma1_on and ma2_on and
fill_12_on ? fill_12_trans : 100)))
fill(p2, p3, color.new((ma2 > ma3 ? ma2_clr : ma3_clr), (ma2_on and ma3_on and
fill_23_on ? fill_23_trans : 100)))
fill(p3, p4, color.new((ma3 > ma4 ? ma3_clr : ma4_clr), (ma3_on and ma4_on and
fill_34_on ? fill_34_trans : 100)))
fill(p4, p5, color.new((ma4 > ma5 ? ma4_clr : ma5_clr), (ma4_on and ma5_on and
fill_45_on ? fill_45_trans : 100)))
fill(p5, p6, color.new((ma5 > ma6 ? ma5_clr : ma6_clr), (ma5_on and ma6_on and
fill_56_on ? fill_56_trans : 100)))
fill(p6, p7, color.new((ma6 > ma7 ? ma6_clr : ma7_clr), (ma6_on and ma7_on and
fill_67_on ? fill_67_trans : 100)))
// This work is licensed under a Attribution-NonCommercial-ShareAlike 4.0
International (CC BY-NC-SA 4.0) https://creativecommons.org/licenses/by-nc-sa/4.0/
// © LuxAlgo
//@version=5

//indicator("Reversal Signals [LuxAlgo]", "LuxAlgo - Reversal Signals", true,


max_labels_count = 500, max_bars_back = 5000)

//------------------------------------------------------------------------------
// Settings
//-----------------------------------------------------------------------------{

bGR = 'Momentum Phase'


bTP = 'Momentum phase provides an indication of the initial trend\'s momentum and
identifies a point of a likely top or bottom in the ranging markets\n\n' +
'Completed - dislays only completed momentum phases\n' +
'Detailed - displays all counting process of the momentum phases\nNone -
disables the display of the momentum phases'

bSh = string('Completed')
srL = bool(false)
ptLT = string('Step Line w/ Diamonds')
rsB = bool(false)
ptSR = string('Circles')

eGR = 'Trend Exhaustion Phase'


eTP = 'Trend exhaustion phase aims to identify when the trend is fading/exhausting
and possibly starting to reverse. The trend exhaustion phase starts only if a
momentum phase is already established\n\n' +
'Completed - dislays only completed trend exhaustion phases\n' +
'Detailed - displays all counting process of the trend exhaustion phases\
nNone - disables the display of the trend exhaustion phases'
eSh = string('Completed')
rsE = bool(false)
ttE = bool(false)

tGR = 'Trade Setups'

tTP = 'All phase specific trade setups, presented as options, are triggered once
the selected phase is completed and folowed by a price flip in the direction of the
trade setup. Please pay attention to the phase specific risk levels as well as the
overall trend direction\n' +
'⚠️ Trading is subject to high risk, look first then leap\n\n' +
'Tips : \n' +
' - Momentum trade setups are not recommended setups, and in case applied
they best fit in ranging market\n' +
' a trade signal, followed immediately by a warning indication can be
assumed as continuation of the underlying trend and can be traded in the opposite
direction of the suggested signal\n\n' +
' - Exhaustion / Qualified trade setups best fits in trending market\n' +
' Exhaustion, suggested type of trade setup, buy (sell) when buy (sell)
trend exhaustion phase is complete\n' +
' Qualified, trend exhaustion phase followed by momentum phase is assumed
as qualified trade setup'

tso = string('None')
war = bool(false)
//-----------------------------------------------------------------------------}
// General Calculations
//-----------------------------------------------------------------------------{

var BnoShw = false


Bcmpltd = bSh == 'Completed'
BnoShw := bSh == 'None' ? false : true

var noShw = false


cmpltd = eSh == 'Completed'
noShw := eSh == 'None' ? false : true

//-----------------------------------------------------------------------------}
// User Defined Types
//-----------------------------------------------------------------------------{

// @type bar properties with their values


//
// @field o (float) open price of the bar
// @field h (float) high price of the bar
// @field l (float) low price of the bar
// @field c (float) close price of the bar
// @field i (int) index of the bar

//type bar
// float o = open
// float h = high
// float l = low
// float c = close
// int i = bar_index

// @type momentum phase varaibles


//
// @field bSC (int) bullish momentum phase count
// @field bSH (float) bullish momentum phase high price value
// @field bSL (float) bullish momentum phase lowest price value
//
// @field sSC (int) bearish momentum phase count
// @field sSH (float) bearish momentum phase highest price value
// @field sSL (float) bearish momentum phase low price value

type trb
int bSC
float bSH
float bSL

int sSC
float sSH
float sSL

// @type trend exhaustion phase varaibles


//
// @field bCC (int) bullish trend exhaustion phase count
// @field bC8 (float) bullish trend exhaustion phase 8 count's condition
// @field bCHt (float) bullish trend exhaustion phase highest price value
// @field bCH (float) bullish trend exhaustion phase high price value
// @field bCL (float) bullish trend exhaustion phase low price value
// @field bCLt (float) bullish trend exhaustion phase lowest price value
// @field bCD (float) bullish trend exhaustion phase risk price value
//
// @field sCC (int) bearish trend exhaustion phase count
// @field sC8 (float) bearish trend exhaustion phase 8 count's condition
// @field sCHt (float) bearish trend exhaustion phase highest price value
// @field sCH (float) bearish trend exhaustion phase high price value
// @field sCL (float) bearish trend exhaustion phase low price value
// @field sCLt (float) bearish trend exhaustion phase lowest price value
// @field sCT (float) bearish trend exhaustion phase target price value

type tre
int bCC
float bC8
float bCHt
float bCH
float bCL
float bCLt
float bCD

int sCC
float sC8
float sCHt
float sCH
float sCL
float sCLt
float sCT

//-----------------------------------------------------------------------------}
// Variables
//-----------------------------------------------------------------------------{

bar snb = bar.new()


var trb snS = trb.new()
var tre snC = tre.new()

noC = #00000000
rdC = #f23645
gnC = #089981
whC = #ffffff
blC = #2962ff
grC = #787b86
bgC = #00bcd4

shpD = shape.labeldown
shpU = shape.labelup
locA = location.abovebar
locB = location.belowbar
dspN = false
pltL = plot.style_circles
pltS = size.tiny

//-----------------------------------------------------------------------------}
// Functions / Methods
//-----------------------------------------------------------------------------{

// @function alert function detecting crosses


//
// @param _p (float) price value
// @param _l (float) checked level value
//
// return (bool) true if condition mets, false otherwise

f_xLX(_p, _l) =>


(_l > _p and _l < _p[1]) or (_l < _p and _l > _p[1])

// @function plot style function


//
// @param _p (string) input string value
//
// return returns enumarated plot style value

f_lnS(_s) =>
s = switch _s
'Circles' => plot.style_circles
'Step Line' => plot.style_steplinebr
'Step Line w/ Diamonds' => plot.style_steplinebr

//-----------------------------------------------------------------------------}
// Calculations
//-----------------------------------------------------------------------------{

ptLB = f_lnS(ptLT)
ptRS = f_lnS(ptSR)

//-----------------------------------------------------------------------------}
// Momentum Phase
//-----------------------------------------------------------------------------{

con = snb.c < snb.c[4]

if con
snS.bSC := snS.bSC == 9 ? 1 : snS.bSC + 1
snS.sSC := 0
else
snS.sSC := snS.sSC == 9 ? 1 : snS.sSC + 1
snS.bSC := 0

pbS = (snb.l <= snb.l[3] and snb.l <= snb.l[2]) or (snb.l[1] <= snb.l[3] and
snb.l[1] <= snb.l[2])

plotshape(switch_Reversal and BnoShw and snS.bSC == 9 and pbS, 'Perfect Bullish


Momentum Phases', shpU, locB, color.new(gnC, 25), 0, 'ᵖ', whC, not dspN, pltS)

bC8 = snS.bSC[1] == 8 and snS.sSC == 1

sR = ta.highest(9)
bSR = 0.0
bSR := snS.bSC == 9 or bC8 ? sR : snb.c > bSR[1] ? 0 : bSR[1]

if snS.bSC == 1
snS.bSL := snb.l

if snS.bSC > 0
snS.bSL := math.min(snb.l, snS.bSL)

if snb.l == snS.bSL
snS.bSH := snb.h
bSD = 0.0
bSD := snS.bSC == 9 ? 2 * snS.bSL - snS.bSH : snb.c < bSD[1] or snS.sSC == 9 ? 0 :
bSD[1]

psS = (snb.h >= snb.h[3] and snb.h >= snb.h[2]) or (snb.h[1] >= snb.h[3] and
snb.h[1] >= snb.h[2])
plotshape(switch_Reversal and BnoShw and snS.sSC == 9 and psS, 'Perfect Bearish
Momentum Phases' , shpD, locA, color.new(rdC, 25), 0, 'ᵖ', whC, not dspN, pltS)

//////////////////////////////////////////////////////
//vector candles
/////////////////////////////////////////////////////

// Indicator Settings

pvsra_group="██████████ PVSRA ██████████"

var overideCandleColours = input.bool(title='Override Candles with PVSRA Colour',


defval=true, tooltip="Indicator must be dragged to the top of the Object Tree to
display correctly", group=pvsra_group)

var bool override_imnt = input.bool(defval=false, title="Overide Symbol",


group=pvsra_group, inline="0")
var string pvsra_sym = input.symbol(title="", defval="BINANCE:BTCUSDTPERP",
group=pvsra_group, inline="0")

var Bull200CandleColor = input.color(color.new(color.lime, 0), title="200% Volume",


group=pvsra_group, inline="1")
var Bear200CandleColor = input.color(color.new(color.red, 0), title="",
group=pvsra_group, inline = "1")

var Bull150CandleColor = input.color(color.new(color.blue, 0), title="150% Volume",


group=pvsra_group, inline="2")
var Bear150CandleColor = input.color(color.new(color.fuchsia, 0), title="",
group=pvsra_group, inline="2")

var BullNormCandleColor = input.color(color.new(#999999, 0), title="Norm Volume",


group=pvsra_group, inline="3")
var BearNormCandleColor = input.color(color.new(#4d4d4d, 0), title="",
group=pvsra_group, inline="3")

var color candleColor = na


var color imbalanceColor = na
var color imbalancedLineColor = na

var color NO_COLOR = na

var bool chartIs120MinOrMore = false

// Logic to reference another Instruments Volume Profile


pvsra_imnt(sresolution,sseries) => request.security(override_imnt ? pvsra_sym :
syminfo.tickerid ,sresolution,sseries, barmerge.gaps_off,barmerge.lookahead_off)
volume_imnt = override_imnt == true? pvsra_imnt("",volume): volume
high_imnt = override_imnt == true? pvsra_imnt("",high): high
low_imnt = override_imnt == true? pvsra_imnt("",low): low
close_imnt = override_imnt == true? pvsra_imnt("",close): close
open_imnt = override_imnt == true? pvsra_imnt("",open): open

av = ta.sma(volume_imnt, 10)//sum_2 = math.sum(volume, 10)


value2 = volume_imnt * (high_imnt - low_imnt)
hivalue2 = ta.highest(value2, 10)
imnt_override_pvsra_calc_part2 = volume_imnt >= av * 1.5 ? 2 : 0
va = volume_imnt >= av * 2 or value2 >= hivalue2 ? 1 :
imnt_override_pvsra_calc_part2

// Bull or bear Candle Colors


isBull = close_imnt > open_imnt

var bool is200Bull = na


var bool is150Bull = na
var bool is100Bull = na
var bool is200Bear = na
var bool is150Bear = na
var bool is100Bear = na

if isBull
if va == 1
candleColor := Bull200CandleColor
is200Bull := true
else
if va == 2
candleColor := Bull150CandleColor
is150Bull := true
else
is200Bull := false
is150Bull := false
candleColor := BullNormCandleColor
imbalanceColor := na
imbalancedLineColor := na
else
if va == 1
candleColor := Bear200CandleColor
is200Bear := true
else
if va == 2
candleColor := Bear150CandleColor
is150Bear := true
else
is200Bear := false
is150Bear := false
candleColor := BearNormCandleColor
imbalanceColor := na
imbalancedLineColor := na
barcolor(overideCandleColours and switch_pvsra ? candleColor : NO_COLOR)
plotcandle(open, high, low, close, color=(overideCandleColours and switch_pvsra ?
candleColor : NO_COLOR), wickcolor=(overideCandleColours and switch_pvsra?
candleColor : NO_COLOR), bordercolor=(overideCandleColours and switch_pvsra?
candleColor : NO_COLOR), display = display.all)

/////////////////////////////////////////////
/////////// Half Trend
////////////////////////////////////////////

ht_group = "██████████ HalfTrend ██████████"


amplitude = input(title='Amplitude', defval=2,group=ht_group)
channelDeviation = input(title='Channel Deviation', defval=2,group=ht_group)
showArrows = input(title='Show Arrows', defval=true,group=ht_group)
showChannels = input(title='Show Channels', defval=false,group=ht_group)

var int ht_trend = 0


var int nextTrend = 0
var float maxLowPrice = nz(low[1], low)
var float minHighPrice = nz(high[1], high)

var float ht_up = 0.0


var float ht_down = 0.0
float atrHigh = 0.0
float atrLow = 0.0
float arrowUp = na
float arrowDown = na

ht_atr2 = ta.atr(100) / 2
ht_dev = channelDeviation * ht_atr2

highPrice = high[math.abs(ta.highestbars(amplitude))]
lowPrice = low[math.abs(ta.lowestbars(amplitude))]
highma = ta.sma(high, amplitude)
lowma = ta.sma(low, amplitude)

if nextTrend == 1
maxLowPrice := math.max(lowPrice, maxLowPrice)

if highma < maxLowPrice and close < nz(low[1], low)


ht_trend := 1
nextTrend := 0
minHighPrice := highPrice
minHighPrice
else
minHighPrice := math.min(highPrice, minHighPrice)

if lowma > minHighPrice and close > nz(high[1], high)


ht_trend := 0
nextTrend := 1
maxLowPrice := lowPrice
maxLowPrice

if ht_trend == 0
if not na(ht_trend[1]) and ht_trend[1] != 0
ht_up := na(ht_down[1]) ? ht_down : ht_down[1]
arrowUp := ht_up - ht_atr2
arrowUp
else
ht_up := na(ht_up[1]) ? maxLowPrice : math.max(maxLowPrice, ht_up[1])
ht_up
atrHigh := ht_up + ht_dev
atrLow := ht_up - ht_dev
atrLow
else
if not na(ht_trend[1]) and ht_trend[1] != 1
ht_down := na(ht_up[1]) ? ht_up : ht_up[1]
arrowDown := ht_down + ht_atr2
arrowDown
else
ht_down := na(ht_down[1]) ? minHighPrice : math.min(minHighPrice,
ht_down[1])
ht_down
atrHigh := ht_down + ht_dev
atrLow := ht_down - ht_dev
atrLow

ht = ht_trend == 0 ? ht_up : ht_down

var color buyColor = color.blue


var color sellColor = color.red

htColor = ht_trend == 0 ? buyColor : sellColor


htPlot = plot(switch_halftrend ? ht:na, title='HalfTrend', linewidth=1,
color=htColor)

atrHighPlot = plot(showChannels ? atrHigh : na, title='ATR High',


style=plot.style_circles, color=color.new(sellColor, 0))
atrLowPlot = plot(showChannels ? atrLow : na, title='ATR Low',
style=plot.style_circles, color=color.new(buyColor, 0))

fill(htPlot, atrHighPlot, title='ATR High Ribbon', color=color.new(sellColor, 90))


fill(htPlot, atrLowPlot, title='ATR Low Ribbon', color=color.new(buyColor, 90))

halftrend_long = not na(arrowUp) and ht_trend == 0 and ht_trend[1] == 1


halftrend_short = not na(arrowDown) and ht_trend == 1 and ht_trend[1] == 0

plotshape(switch_halftrend and showArrows and halftrend_long ? atrLow : na,


title="Arrow Up", style=shape.triangleup, location=location.absolute,
size=size.tiny, color=buyColor)
plotshape(switch_halftrend and showArrows and halftrend_short ? atrHigh : na,
title="Arrow Down", style=shape.triangledown, location=location.absolute,
size=size.tiny, color=sellColor)

//halftrend_long = ht_trend == 0
//halftrend_short = ht_trend != 0

You might also like