0% found this document useful (0 votes)
26 views

New Text Document

The document outlines a trading strategy involving the use of indicators such as ZigZag, FVG (Fair Value Gaps), and EMA (Exponential Moving Average) across different timeframes. It includes a code snippet for a custom ZigZag indicator that displays retracement levels and integrates FVG analysis. The strategy emphasizes trading against the trend with high volume and provides customization options for various parameters in the indicator settings.

Uploaded by

H-M Channel
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)
26 views

New Text Document

The document outlines a trading strategy involving the use of indicators such as ZigZag, FVG (Fair Value Gaps), and EMA (Exponential Moving Average) across different timeframes. It includes a code snippet for a custom ZigZag indicator that displays retracement levels and integrates FVG analysis. The strategy emphasizes trading against the trend with high volume and provides customization options for various parameters in the indicator settings.

Uploaded by

H-M Channel
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/ 35

https://www.mql5.com/en/market/product/134117?

source=Site+Profile+Seller

3 Etry ;

1 break co BOS vaf co ca FVG (BOS + FVG)

2 EMA 35 - 90 , time chart va time x4 chart. ve 90 co nen rau ngan + x4 chart ve


35

3 ORder Block + Dinh Day Ziig Zag

Cam: Di nguoc Trend voi Volume to

// -------------------------------------------------------------------------------

// -------------- Code 2 2 indi zigzag and fvgg ifvg

//@version=6
indicator('ZigZag with Retracement Levels', overlay = true, max_bars_back = 500,
max_lines_count = 300)
prd = input.int(defval = 10, title = 'ZigZag Period', minval = 2, maxval = 50)
showzigzag = input(defval = true, title = 'Show Zig Zag')
showfibo = input(defval = true, title = 'Show Retracement Ratios')
labelcol = input(defval = color.white, title = 'Text Color for Levels')
fibolinecol = input(defval = color.white, title = 'Line Color for Levels')
showcurrent = input(defval = true, title = 'Show Retracement Ratios based on latest
pivot')
labelcol2 = input(defval = color.yellow, title = 'Text Color for Current Levels')
fibolinecol2 = input(defval = color.yellow, title = 'Line Color for Current
Levels')
upcol = input.color(defval = color.lime, title = 'Zigzag Colors', inline = 'zzcol')
dncol = input.color(defval = color.red, title = '', inline = 'zzcol')
labelloc = input.string(defval = 'Left', title = 'Label Location', options =
['Left', 'Right'])

// Modified from © LonesomeTheBlue origial code, added options to


enable/disable/customize levels ------------------------------------
enable1 = input(defval = true, title = 'Enable Level 1', inline = 'level1')
level1 = input.float(defval = 0.236, title = '', inline = 'level1')
enable2 = input(defval = true, title = 'Enable Level 2', inline = 'level2')
level2 = input.float(defval = 0.382, title = '', inline = 'level2')
enable3 = input(defval = true, title = 'Enable Level 3', inline = 'level3')
level3 = input.float(defval = 0.500, title = '', inline = 'level3')
enable4 = input(defval = true, title = 'Enable Level 4', inline = 'level4')
level4 = input.float(defval = 0.618, title = '', inline = 'level4')
enable5 = input(defval = true, title = 'Enable Level 5', inline = 'level5')
level5 = input.float(defval = 0.786, title = '', inline = 'level5')

var fibo_ratios = array.new_float(0)


var shownlevels = 1
if barstate.isfirst
array.push(fibo_ratios, 0.0)
if enable1
array.push(fibo_ratios, level1)
shownlevels := shownlevels + 1
shownlevels
if enable2
array.push(fibo_ratios, level2)
shownlevels := shownlevels + 1
shownlevels
if enable3
array.push(fibo_ratios, level3)
shownlevels := shownlevels + 1
shownlevels
if enable4
array.push(fibo_ratios, level4)
shownlevels := shownlevels + 1
shownlevels
if enable5
array.push(fibo_ratios, level5)
shownlevels := shownlevels + 1
shownlevels
// for x = 1 to 5 by 1
// array.push(fibo_ratios, x)
// array.push(fibo_ratios, x + 0.272)
// array.push(fibo_ratios, x + 0.414)
// array.push(fibo_ratios, x + 0.618)
array.push(fibo_ratios, 1.0)
//
-------------------------------------------------------------------------------

float ph = ta.highestbars(high, prd) == 0 ? high : na


float pl = ta.lowestbars(low, prd) == 0 ? low : na
var dir = 0
iff_1 = bool(pl) and na(ph) ? -1 : dir
dir := bool(ph) and na(pl) ? 1 : iff_1
var max_array_size = 10
var zigzag = array.new_float(0)
oldzigzag = array.copy(zigzag)

add_to_zigzag(value, bindex) =>


array.unshift(zigzag, bindex)
array.unshift(zigzag, value)
if array.size(zigzag) > max_array_size
array.pop(zigzag)
array.pop(zigzag)

update_zigzag(value, bindex) =>


if array.size(zigzag) == 0
add_to_zigzag(value, bindex)
else
if dir == 1 and value > array.get(zigzag, 0) or dir == -1 and value <
array.get(zigzag, 0)
array.set(zigzag, 0, value)
array.set(zigzag, 1, bindex)
0.

bool dirchanged = dir != dir[1]


if bool(ph) or bool(pl)
if dirchanged
add_to_zigzag(dir == 1 ? ph : pl, bar_index)
else
update_zigzag(dir == 1 ? ph : pl, bar_index)
if showzigzag and array.size(zigzag) >= 4 and array.size(oldzigzag) >= 4
var line zzline = na
if array.get(zigzag, 0) != array.get(oldzigzag, 0) or array.get(zigzag, 1) !=
array.get(oldzigzag, 1)
if array.get(zigzag, 2) == array.get(oldzigzag, 2) and array.get(zigzag, 3)
== math.round(array.get(oldzigzag, 3))
line.delete(zzline)
zzline := line.new(x1 = math.round(array.get(zigzag, 1)), y1 =
array.get(zigzag, 0), x2 = math.round(array.get(zigzag, 3)), y2 = array.get(zigzag,
2), color = dir == 1 ? upcol : dncol, width = 2)
zzline

var fibolines = array.new_line(0)


var fibolabels = array.new_label(0)

// Addition to © LonesomeTheBlue origial code ------------------------------------


var fibolines2 = array.new_line(0)
var fibolabels2 = array.new_label(0)
// -------------------------------------------------------------------------------

if showfibo and array.size(zigzag) >= 6 and barstate.islast


if array.size(fibolines) > 0
for x = 0 to array.size(fibolines) - 1 by 1
line.delete(array.get(fibolines, x))
label.delete(array.get(fibolabels, x))
if array.size(fibolines2) > 0
for x = 0 to array.size(fibolines2) - 1 by 1
line.delete(array.get(fibolines2, x))
label.delete(array.get(fibolabels2, x))

diff = array.get(zigzag, 4) - array.get(zigzag, 2)


stopit = false
for x = 0 to array.size(fibo_ratios) - 1 by 1
if stopit and x > shownlevels
break
array.unshift(fibolines, line.new(x1 = math.round(array.get(zigzag, 5)), y1
= array.get(zigzag, 2) + diff * array.get(fibo_ratios, x), x2 = bar_index, y2 =
array.get(zigzag, 2) + diff * array.get(fibo_ratios, x), color = fibolinecol,
extend = extend.right, width = 2))
label_x_loc = labelloc == 'Left' ? math.round(array.get(zigzag, 5)) - 1 :
bar_index + 15
array.unshift(fibolabels, label.new(x = label_x_loc, y = array.get(zigzag,
2) + diff * array.get(fibo_ratios, x), text = str.tostring(array.get(fibo_ratios,
x), '#.###') + '(' + str.tostring(math.round_to_mintick(array.get(zigzag, 2) + diff
* array.get(fibo_ratios, x))) + ')', textcolor = labelcol, style =
label.style_none))
if dir == 1 and array.get(zigzag, 2) + diff * array.get(fibo_ratios, x) >
array.get(zigzag, 0) or dir == -1 and array.get(zigzag, 2) + diff *
array.get(fibo_ratios, x) < array.get(zigzag, 0)
stopit := true
stopit

// Addition to © LonesomeTheBlue origial code ------------------------------------


if showcurrent and array.size(zigzag) >= 6 and barstate.islast
diff2 = array.get(zigzag, 0) - array.get(zigzag, 2)
stopit2 = false
for x = 0 to array.size(fibo_ratios) - 1 by 1
if stopit2 and x > shownlevels
break
array.unshift(fibolines2, line.new(x1 = math.round(array.get(zigzag, 3)),
y1 = array.get(zigzag, 2) + diff2 * (1 - array.get(fibo_ratios, x)), x2 =
bar_index, y2 = array.get(zigzag, 2) + diff2 * (1 - array.get(fibo_ratios, x)),
color = fibolinecol2, extend = extend.right))
label_x_loc2 = labelloc == 'Left' ? math.round(array.get(zigzag, 3)) - 1 :
bar_index + 15
array.unshift(fibolabels2, label.new(x = label_x_loc2, y =
array.get(zigzag, 2) + diff2 * (1 - array.get(fibo_ratios, x)), text =
str.tostring(array.get(fibo_ratios, x), '#.###') + '(' +
str.tostring(math.round_to_mintick(array.get(zigzag, 2) + diff2 * (1 -
array.get(fibo_ratios, x)))) + ')', textcolor = labelcol2, style =
label.style_none))
if dir == 1 and array.get(zigzag, 2) + diff2 * array.get(fibo_ratios, x) >
array.get(zigzag, 0) or dir == -1 and array.get(zigzag, 2) + diff2 *
array.get(fibo_ratios, x) < array.get(zigzag, 0)
stopit2 := true
stopit2

// indicator('Inverse FVG with Quadrants [Modified]', 'FVG/IFVG Q/O', true)

// -------------------------------------------------- Inputs
--------------------------------------------------
var g_SET = 'Settings'
show_rfvg = input.bool(true, 'Show Regular FVG', inline = 'RFVG', group = g_SET)
show_ifvg = input.bool(true, 'Show Inverse FVG', inline = 'IFVG', group = g_SET)
extend_right = input.bool(true, 'Extend Boxes', group = g_SET)

rfvg_color = input.color(color.new(#2962ff, 60), '', inline = 'RFVG', group =


g_SET)
ifvg_color = input.color(color.new(#f23645, 60), '', inline = 'IFVG', group =
g_SET)

// Add automatic timeframe selection option


auto_tf = input.bool(false, 'Auto Timeframe Selection', tooltip = 'Automatically
selects higher timeframe based on current chart timeframe', group = g_SET)
tf = input.timeframe('', 'Manual Timeframe (ignored if Auto TF is enabled)', group
= g_SET)

disp_x = input.int(3, 'Displacement', 1, 10, tooltip = 'Larger Displacement will


require larger FVGs', group = g_SET)
disp_limit = input.int(10, 'Display Limit', 1, 50, tooltip = 'The maximum amount of
FVGs and IFVGs to display', group = g_SET)

session = input.session('0000-0000', 'Session', tooltip = 'FVGs will only be saved


if they are created within this time period', group = g_SET)
// -------------------------------------------------- Inputs
--------------------------------------------------

// -------------------------------------------------- Auto Timeframe Logic


--------------------------------------------------
// Function to determine the appropriate higher timeframe based on current
timeframe
get_auto_timeframe() =>
current_tf = timeframe.period
auto_selected_tf = ''
if current_tf == '1'
auto_selected_tf := '15'
else if current_tf == '3'
auto_selected_tf := '30'
else if current_tf == '5'
auto_selected_tf := '60'
else if current_tf == '15'
auto_selected_tf := '240'
else if current_tf == '60'
auto_selected_tf := '1D'
else if current_tf == '240'
auto_selected_tf := '1W'
else
// Default to daily for other timeframes
auto_selected_tf := '1D'

auto_selected_tf

// Use auto timeframe or manual input


used_tf = auto_tf ? get_auto_timeframe() : tf
// -------------------------------------------------- Auto Timeframe Logic
--------------------------------------------------

// -------------------------------------------------- Logic
--------------------------------------------------
t = not na(time(used_tf, session, 'America/New_York'))

[o, h, l, c, ti] = request.security(syminfo.tickerid, used_tf, [open[1], high[1],


low[1], close[1], time[1]], lookahead = barmerge.lookahead_on, gaps =
barmerge.gaps_off)

var tf_o = array.new_float()


var tf_h = array.new_float()
var tf_l = array.new_float()
var tf_c = array.new_float()
var tf_time = array.new_int()
var tf_t = array.new_bool()

var reg_fvg = array.new_box()


var reg_fvg_ce = array.new_line()
var reg_fvg_side = array.new_string()
var reg_fvg_labels = array.new_label()

var inv_fvg = array.new_box()


var inv_fvg_ce = array.new_line()
var inv_fvg_side = array.new_string()
var inv_fvg_labels = array.new_label()

solid_color(color x) =>
color.new(x, 0)

avg_over(array<float> h, array<float> l, int len) =>


sum = 0.0
for i = 0 to math.min(len - 1, h.size() - 1) by 1
sum := sum + h.get(i) - l.get(i)
sum
result = sum / math.min(len, h.size())
result
var tf_new = false

if timeframe.change(used_tf) and timeframe.in_seconds(used_tf) >=


timeframe.in_seconds(timeframe.period)
tf_o.unshift(o)
tf_h.unshift(h)
tf_l.unshift(l)
tf_c.unshift(c)
tf_t.unshift(t[1])
tf_time.unshift(ti)

tf_new := true

if tf_o.size() > 300


tf_o.pop()
tf_h.pop()
tf_l.pop()
tf_c.pop()
tf_t.pop()
tf_time.pop()

// Update right end of boxes and lines + labels


if not extend_right
if reg_fvg.size() > 0
for i = 0 to reg_fvg.size() - 1 by 1
reg_fvg.get(i).set_right(time)
reg_fvg_ce.get(i).set_x2(time)
if i < reg_fvg_labels.size()
reg_fvg_labels.get(i).set_x(time)

if inv_fvg.size() > 0
for i = 0 to inv_fvg.size() - 1 by 1
inv_fvg.get(i).set_right(time)
inv_fvg_ce.get(i).set_x2(time)
if i < inv_fvg_labels.size()
inv_fvg_labels.get(i).set_x(time)

// Check if we have enough data before processing


if tf_o.size() >= 3 and tf_new
// Safe array access with bounds checking
o0 = tf_o.size() > 0 ? tf_o.get(0) : na
o1 = tf_o.size() > 1 ? tf_o.get(1) : na
o2 = tf_o.size() > 2 ? tf_o.get(2) : na

h0 = tf_h.size() > 0 ? tf_h.get(0) : na


h1 = tf_h.size() > 1 ? tf_h.get(1) : na
h2 = tf_h.size() > 2 ? tf_h.get(2) : na

l0 = tf_l.size() > 0 ? tf_l.get(0) : na


l1 = tf_l.size() > 1 ? tf_l.get(1) : na
l2 = tf_l.size() > 2 ? tf_l.get(2) : na

c0 = tf_c.size() > 0 ? tf_c.get(0) : na


c1 = tf_c.size() > 1 ? tf_c.get(1) : na
c2 = tf_c.size() > 2 ? tf_c.get(2) : na

t0 = tf_t.size() > 0 ? tf_t.get(0) : false


t1 = tf_t.size() > 1 ? tf_t.get(1) : false
t2 = tf_t.size() > 2 ? tf_t.get(2) : false

time0 = tf_time.size() > 0 ? tf_time.get(0) : na


time1 = tf_time.size() > 1 ? tf_time.get(1) : na
time2 = tf_time.size() > 2 ? tf_time.get(2) : na

bull = c1 > o1
fvg = bull ? h2 < l0 and l1 <= h2 and h1 >= l0 : l2 > h0 and l1 <= h0 and l2 <=
h1
fvg_len = bull ? l0 - h2 : l2 - h0

// Make sure we have enough data for ATR calculation


atr_check = tf_h.size() >= 20 and tf_l.size() >= 20 ? fvg_len > avg_over(tf_h,
tf_l, 20) * disp_x / 10 : false

if t2 and fvg and atr_check and not na(time1)


full_top = bull ? l0 : l2
full_bottom = bull ? h2 : h0
ce_level = math.avg(full_top, full_bottom)

// For bullish patterns, show only upper half (ce_level to top)


// For bearish patterns, show only lower half (bottom to ce_level)
top = bull ? full_top : ce_level
bottom = bull ? ce_level : full_bottom

// Create the FVG box (only showing the relevant quadrant + CE), CE line,
and label
reg_fvg.unshift(box.new(time1, top, time, bottom, xloc = xloc.bar_time,
extend = extend_right ? extend.right : extend.none, bgcolor = show_rfvg ?
rfvg_color : na, border_color = na))
reg_fvg_ce.unshift(line.new(time1, ce_level, time, ce_level, xloc =
xloc.bar_time, extend = extend_right ? extend.right : extend.none, color =
show_rfvg ? solid_color(rfvg_color) : na, style = line.style_dashed))
reg_fvg_side.unshift(bull ? 'bull' : 'bear')

// Add label for quadrant reference - position it at the non-CE edge of the
box
quadrant_text = bull ? "FVG+ " + used_tf : "FVG- " + used_tf
label_pos = bull ? top : bottom // Place at the extreme edge (top for
bullish, bottom for bearish)

// Only show the label if show_rfvg is true


reg_label = label.new(time, label_pos, quadrant_text, xloc = xloc.bar_time,
style = label.style_none,
textcolor = show_rfvg ? solid_color(rfvg_color) : na,
size = size.small, textalign = text.align_right,
text_font_family = font.family_monospace)
reg_fvg_labels.unshift(reg_label)

tf_new := false
tf_new

// Check for overlapping FVGs and handle them


if reg_fvg.size() > 1
for i = 0 to reg_fvg.size() - 2 by 1
for j = i + 1 to reg_fvg.size() - 1 by 1
if i < reg_fvg.size() and j < reg_fvg.size() and i <
reg_fvg_side.size() and j < reg_fvg_side.size()
box1 = reg_fvg.get(i)
box2 = reg_fvg.get(j)

// Check if boxes overlap


overlap = not (box1.get_top() < box2.get_bottom() or
box1.get_bottom() > box2.get_top())

if overlap
// Keep the most recent FVG (which is the one with lower
index in our array)
// We'll adjust its visual style to indicate it represents
multiple FVGs
box1.set_border_color(#000000ce)
box1.set_border_width(2)

// Remove the older one


box.delete(box2)
line.delete(reg_fvg_ce.get(j))
if j < reg_fvg_labels.size()
label.delete(reg_fvg_labels.get(j))

reg_fvg.remove(j)
reg_fvg_ce.remove(j)
reg_fvg_side.remove(j)
if j < reg_fvg_labels.size()
reg_fvg_labels.remove(j)

// Update the indices


j = j - 1

if reg_fvg.size() > 0
for i = reg_fvg.size() - 1 to 0 by 1
if i < reg_fvg.size() and i < reg_fvg_side.size() // Safe bounds
checking
remove_bull = reg_fvg_side.get(i) == 'bull' and c0 <
reg_fvg.get(i).get_bottom()
remove_bear = reg_fvg_side.get(i) == 'bear' and c0 >
reg_fvg.get(i).get_top()

if remove_bull or remove_bear
// Get the original FVG side (bull or bear)
original_is_bull = reg_fvg_side.get(i) == 'bull'

// Store the original FVG's top and bottom for reference


original_top = reg_fvg.get(i).get_top()
original_bottom = reg_fvg.get(i).get_bottom()

// Create inverse FVG from regular FVG - first, create a full


copy
inv_fvg.unshift(box.copy(reg_fvg.get(i)))
inv_fvg_ce.unshift(line.copy(reg_fvg_ce.get(i)))

// Set colors for inverse FVG


inv_fvg.get(0).set_bgcolor(show_ifvg ? ifvg_color : na)
inv_fvg_ce.get(0).set_color(show_ifvg ? solid_color(ifvg_color)
: na)

// Add the original condition to inv_fvg_side


inv_fvg_side.unshift(original_is_bull ? 'inv bull' : 'inv
bear')
// Get CE level for consistent quadrant display
ce_level = inv_fvg_ce.get(0).get_y1()

// CORRECTED: For IFVG+, show upper quadrant; for IFVG-, show


lower quadrant
var float label_pos = 0.0

// Get the original full FVG dimensions from which we'll create
our IFVG
full_top = original_is_bull ? original_top : ce_level * 2 -
original_bottom
full_bottom = original_is_bull ? ce_level * 2 - original_top :
original_bottom

if original_is_bull
// For inverse of bullish pattern (IFVG-), show lower half
inv_fvg.get(0).set_top(ce_level)
inv_fvg.get(0).set_bottom(full_bottom)
label_pos := full_bottom
else
// For inverse of bearish pattern (IFVG+), show upper half
inv_fvg.get(0).set_top(full_top)
inv_fvg.get(0).set_bottom(ce_level)
label_pos := full_top

// Create label for inverse FVG with consistent quadrant


reference
quadrant_text = original_is_bull ? "IFVG- " + used_tf : "IFVG+
" + used_tf

// Only show the label if show_ifvg is true


inv_label = label.new(time, label_pos, quadrant_text, xloc =
xloc.bar_time, style = label.style_none,
textcolor = show_ifvg ?
solid_color(ifvg_color) : na,
size = size.small, textalign =
text.align_right, text_font_family = font.family_monospace)
inv_fvg_labels.unshift(inv_label)

// Remove regular FVG


box.delete(reg_fvg.get(i))
line.delete(reg_fvg_ce.get(i))
if i < reg_fvg_labels.size()
label.delete(reg_fvg_labels.get(i))

reg_fvg.remove(i)
reg_fvg_ce.remove(i)
reg_fvg_side.remove(i)
if i < reg_fvg_labels.size()
reg_fvg_labels.remove(i)

// Enforce display limit


while reg_fvg.size() > disp_limit and reg_fvg.size() > 0
idx = reg_fvg.size() - 1
box.delete(reg_fvg.get(idx))
line.delete(reg_fvg_ce.get(idx))
if idx < reg_fvg_labels.size()
label.delete(reg_fvg_labels.get(idx))
reg_fvg.pop()
reg_fvg_ce.pop()
reg_fvg_side.pop()
if reg_fvg_labels.size() > 0
reg_fvg_labels.pop()

// Check for overlapping IFVGs and handle them


if inv_fvg.size() > 1
for i = 0 to inv_fvg.size() - 2 by 1
for j = i + 1 to inv_fvg.size() - 1 by 1
if i < inv_fvg.size() and j < inv_fvg.size() and i <
inv_fvg_side.size() and j < inv_fvg_side.size()
box1 = inv_fvg.get(i)
box2 = inv_fvg.get(j)

// Check if boxes overlap


overlap = not (box1.get_top() < box2.get_bottom() or
box1.get_bottom() > box2.get_top())

if overlap
// Keep the most recent IFVG (which is the one with lower
index in our array)
// We'll adjust its visual style to indicate it represents
multiple IFVGs
box1.set_border_color(color.new(#000000, 50))
box1.set_border_width(2)

// Remove the older one


box.delete(box2)
line.delete(inv_fvg_ce.get(j))
if j < inv_fvg_labels.size()
label.delete(inv_fvg_labels.get(j))

inv_fvg.remove(j)
inv_fvg_ce.remove(j)
inv_fvg_side.remove(j)
if j < inv_fvg_labels.size()
inv_fvg_labels.remove(j)

// Update the indices


j = j - 1

if inv_fvg.size() > 0
for i = inv_fvg.size() - 1 to 0 by 1
if i < inv_fvg.size() and i < inv_fvg_side.size() // Safe bounds
checking
remove_inv_bear = inv_fvg_side.get(i) == 'inv bear' and c0 <
inv_fvg.get(i).get_bottom()
remove_inv_bull = inv_fvg_side.get(i) == 'inv bull' and c0 >
inv_fvg.get(i).get_top()

if remove_inv_bear or remove_inv_bull
box.delete(inv_fvg.get(i))
line.delete(inv_fvg_ce.get(i))
if i < inv_fvg_labels.size()
label.delete(inv_fvg_labels.get(i))

inv_fvg.remove(i)
inv_fvg_ce.remove(i)
inv_fvg_side.remove(i)
if i < inv_fvg_labels.size()
inv_fvg_labels.remove(i)

// Enforce display limit


while inv_fvg.size() > disp_limit and inv_fvg.size() > 0
idx = inv_fvg.size() - 1
box.delete(inv_fvg.get(idx))
line.delete(inv_fvg_ce.get(idx))
if idx < inv_fvg_labels.size()
label.delete(inv_fvg_labels.get(idx))

inv_fvg.pop()
inv_fvg_ce.pop()
inv_fvg_side.pop()
if inv_fvg_labels.size() > 0
inv_fvg_labels.pop()

// Alert conditions for FVG and IFVG creation - modified to prevent errors
is_new_fvg = false
if tf_new and tf_o.size() >= 3 and tf_h.size() >= 3 and tf_l.size() >= 3 and
tf_t.size() > 2
if tf_t.get(2)
bull = tf_c.get(1) > tf_o.get(1)
fvg = bull ? tf_h.get(2) < tf_l.get(0) and tf_l.get(1) <= tf_h.get(2) and
tf_h.get(1) >= tf_l.get(0) :
tf_l.get(2) > tf_h.get(0) and tf_l.get(1) <= tf_h.get(0) and
tf_l.get(2) <= tf_h.get(1)
fvg_len = bull ? tf_l.get(0) - tf_h.get(2) : tf_l.get(2) - tf_h.get(0)
atr_check = tf_h.size() >= 20 ? fvg_len > avg_over(tf_h, tf_l, 20) * disp_x
/ 10 : false
is_new_fvg := fvg and atr_check

alertcondition(is_new_fvg, 'New FVG Created')


alertcondition(show_rfvg and reg_fvg.size() > 0 and reg_fvg.size() >
array.size(reg_fvg) - 1, 'New Regular FVG')
alertcondition(show_ifvg and inv_fvg.size() > 0 and inv_fvg.size() >
array.size(inv_fvg) - 1, 'New Inverse FVG')
// -------------------------------------------------- Logic
--------------------------------------------------

VErsion 5 dung hon nen hay giu lai

// 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('Smart Money Concepts [LuxAlgo]', 'LuxAlgo - Smart Money Concepts',
overlay = true, max_labels_count = 500, max_lines_count = 500, max_boxes_count =
500)
//---------------------------------------------------------------------------------
------------------------------------}
//CONSTANTS & STRINGS & INPUTS
//---------------------------------------------------------------------------------
------------------------------------{
BULLISH_LEG = 1
BEARISH_LEG = 0

BULLISH = +1
BEARISH = -1

GREEN = #089981
RED = #F23645
BLUE = #2157f3
GRAY = #878b94
MONO_BULLISH = #b2b5be
MONO_BEARISH = #5d606b

HISTORICAL = 'Historical'
PRESENT = 'Present'

COLORED = 'Colored'
MONOCHROME = 'Monochrome'

ALL = 'All'
BOS = 'BOS'
CHOCH = 'CHoCH'

TINY = size.tiny
SMALL = size.small
NORMAL = size.normal

ATR = 'Atr'
RANGE = 'Cumulative Mean Range'

CLOSE = 'Close'
HIGHLOW = 'High/Low'

SOLID = '⎯⎯⎯'
DASHED = '----'
DOTTED = '····'

SMART_GROUP = 'Smart Money Concepts'


INTERNAL_GROUP = 'Real Time Internal Structure'
SWING_GROUP = 'Real Time Swing Structure'
BLOCKS_GROUP = 'Order Blocks'
EQUAL_GROUP = 'EQH/EQL'
GAPS_GROUP = 'Fair Value Gaps'
LEVELS_GROUP = 'Highs & Lows MTF'
ZONES_GROUP = 'Premium & Discount Zones'

modeTooltip = 'Allows to display historical Structure or only


the recent ones'
styleTooltip = 'Indicator color theme'
showTrendTooltip = 'Display additional candles with a color
reflecting the current trend detected by structure'
showInternalsTooltip = 'Display internal market structure'
internalFilterConfluenceTooltip = 'Filter non significant internal structure
breakouts'
showStructureTooltip = 'Display swing market Structure'
showSwingsTooltip = 'Display swing point as labels on the chart'
showHighLowSwingsTooltip = 'Highlight most recent strong and weak high/low
points on the chart'
showInternalOrderBlocksTooltip = 'Display internal order blocks on the chart\n\
nNumber of internal order blocks to display on the chart'
showSwingOrderBlocksTooltip = 'Display swing order blocks on the chart\n\
nNumber of internal swing blocks to display on the chart'
orderBlockFilterTooltip = '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'
orderBlockMitigationTooltip = 'Select what values to use for order block
mitigation'
showEqualHighsLowsTooltip = 'Display equal highs and equal lows on the chart'
equalHighsLowsLengthTooltip = 'Number of bars used to confirm equal highs and
equal lows'
equalHighsLowsThresholdTooltip = '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'
showFairValueGapsTooltip = 'Display fair values gaps on the chart'
fairValueGapsThresholdTooltip = 'Filter out non significant fair value gaps'
fairValueGapsTimeframeTooltip = 'Fair value gaps timeframe'
fairValueGapsExtendTooltip = 'Determine how many bars to extend the Fair Value
Gap boxes on chart'
showPremiumDiscountZonesTooltip = 'Display premium, discount, and equilibrium zones
on chart'

modeInput = input.string( HISTORICAL, 'Mode',


group = SMART_GROUP, tooltip = modeTooltip, options = [HISTORICAL, PRESENT])
styleInput = input.string( COLORED, 'Style',
group = SMART_GROUP, tooltip = styleTooltip,options = [COLORED, MONOCHROME])
showTrendInput = input( false, 'Color Candles',
group = SMART_GROUP, tooltip = showTrendTooltip)

showInternalsInput = input( true, 'Show Internal


Structure', group = INTERNAL_GROUP, tooltip = showInternalsTooltip)
showInternalBullInput = input.string( ALL, 'Bullish Structure',
group = INTERNAL_GROUP, inline = 'ibull', options = [ALL,BOS,CHOCH])
internalBullColorInput = input( GREEN, '',
group = INTERNAL_GROUP, inline = 'ibull')
showInternalBearInput = input.string( ALL, 'Bearish Structure' ,
group = INTERNAL_GROUP, inline = 'ibear', options = [ALL,BOS,CHOCH])
internalBearColorInput = input( RED, '',
group = INTERNAL_GROUP, inline = 'ibear')
internalFilterConfluenceInput = input( false, 'Confluence Filter',
group = INTERNAL_GROUP, tooltip = internalFilterConfluenceTooltip)
internalStructureSize = input.string( TINY, 'Internal Label Size',
group = INTERNAL_GROUP, options = [TINY,SMALL,NORMAL])

showStructureInput = input( true, 'Show Swing Structure',


group = SWING_GROUP, tooltip = showStructureTooltip)
showSwingBullInput = input.string( ALL, 'Bullish Structure',
group = SWING_GROUP, inline = 'bull', options = [ALL,BOS,CHOCH])
swingBullColorInput = input( GREEN, '',
group = SWING_GROUP, inline = 'bull')
showSwingBearInput = input.string( ALL, 'Bearish Structure',
group = SWING_GROUP, inline = 'bear', options = [ALL,BOS,CHOCH])
swingBearColorInput = input( RED, '',
group = SWING_GROUP, inline = 'bear')
swingStructureSize = input.string( SMALL, 'Swing Label Size',
group = SWING_GROUP, options = [TINY,SMALL,NORMAL])
showSwingsInput = input( false, 'Show Swings Points',
group = SWING_GROUP, tooltip = showSwingsTooltip,inline = 'swings')
swingsLengthInput = input.int( 50, '',
group = SWING_GROUP, minval = 10, inline = 'swings')
showHighLowSwingsInput = input( true, 'Show Strong/Weak
High/Low',group = SWING_GROUP, tooltip = showHighLowSwingsTooltip)

showInternalOrderBlocksInput = input( true, 'Internal Order Blocks'


, group = BLOCKS_GROUP, tooltip = showInternalOrderBlocksTooltip, inline =
'iob')
internalOrderBlocksSizeInput = input.int( 5, '',
group = BLOCKS_GROUP, minval = 1, maxval = 20, inline = 'iob')
showSwingOrderBlocksInput = input( false, 'Swing Order Blocks',
group = BLOCKS_GROUP, tooltip = showSwingOrderBlocksTooltip, inline = 'ob')
swingOrderBlocksSizeInput = input.int( 5, '',
group = BLOCKS_GROUP, minval = 1, maxval = 20, inline = 'ob')
orderBlockFilterInput = input.string( 'Atr', 'Order Block Filter',
group = BLOCKS_GROUP, tooltip = orderBlockFilterTooltip, options = [ATR,
RANGE])
orderBlockMitigationInput = input.string( HIGHLOW, 'Order Block
Mitigation', group = BLOCKS_GROUP, tooltip = orderBlockMitigationTooltip,
options = [CLOSE,HIGHLOW])
internalBullishOrderBlockColor = input.color(color.new(#3179f5, 80), 'Internal
Bullish OB', group = BLOCKS_GROUP)
internalBearishOrderBlockColor = input.color(color.new(#f77c80, 80), 'Internal
Bearish OB', group = BLOCKS_GROUP)
swingBullishOrderBlockColor = input.color(color.new(#1848cc, 80), 'Bullish OB',
group = BLOCKS_GROUP)
swingBearishOrderBlockColor = input.color(color.new(#b22833, 80), 'Bearish OB',
group = BLOCKS_GROUP)

showEqualHighsLowsInput = input( true, 'Equal High/Low',


group = EQUAL_GROUP, tooltip = showEqualHighsLowsTooltip)
equalHighsLowsLengthInput = input.int( 3, 'Bars Confirmation',
group = EQUAL_GROUP, tooltip = equalHighsLowsLengthTooltip, minval = 1)
equalHighsLowsThresholdInput = input.float( 0.1, 'Threshold',
group = EQUAL_GROUP, tooltip = equalHighsLowsThresholdTooltip, minval = 0,
maxval = 0.5, step = 0.1)
equalHighsLowsSizeInput = input.string( TINY, 'Label Size',
group = EQUAL_GROUP, options = [TINY,SMALL,NORMAL])

showFairValueGapsInput = input( false, 'Fair Value Gaps',


group = GAPS_GROUP, tooltip = showFairValueGapsTooltip)
fairValueGapsThresholdInput = input( true, 'Auto Threshold',
group = GAPS_GROUP, tooltip = fairValueGapsThresholdTooltip)
fairValueGapsTimeframeInput = input.timeframe('', 'Timeframe',
group = GAPS_GROUP, tooltip = fairValueGapsTimeframeTooltip)
fairValueGapsBullColorInput = input.color(color.new(#00ff68, 70), 'Bullish FVG'
, group = GAPS_GROUP)
fairValueGapsBearColorInput = input.color(color.new(#ff0008, 70), 'Bearish FVG'
, group = GAPS_GROUP)
fairValueGapsExtendInput = input.int( 1, 'Extend FVG',
group = GAPS_GROUP, tooltip = fairValueGapsExtendTooltip, minval = 0)

showDailyLevelsInput = input( false, 'Daily', group =


LEVELS_GROUP, inline = 'daily')
dailyLevelsStyleInput = input.string( SOLID, '', group =
LEVELS_GROUP, inline = 'daily', options = [SOLID,DASHED,DOTTED])
dailyLevelsColorInput = input( BLUE, '', group =
LEVELS_GROUP, inline = 'daily')
showWeeklyLevelsInput = input( false, 'Weekly', group =
LEVELS_GROUP, inline = 'weekly')
weeklyLevelsStyleInput = input.string( SOLID, '', group =
LEVELS_GROUP, inline = 'weekly', options = [SOLID,DASHED,DOTTED])
weeklyLevelsColorInput = input( BLUE, '', group =
LEVELS_GROUP, inline = 'weekly')
showMonthlyLevelsInput = input( false, 'Monthly', group =
LEVELS_GROUP, inline = 'monthly')
monthlyLevelsStyleInput = input.string( SOLID, '', group =
LEVELS_GROUP, inline = 'monthly', options = [SOLID,DASHED,DOTTED])
monthlyLevelsColorInput = input( BLUE, '', group =
LEVELS_GROUP, inline = 'monthly')

showPremiumDiscountZonesInput = input( false, 'Premium/Discount


Zones', group = ZONES_GROUP , tooltip = showPremiumDiscountZonesTooltip)
premiumZoneColorInput = input.color( RED, 'Premium Zone',
group = ZONES_GROUP)
equilibriumZoneColorInput = input.color( GRAY, 'Equilibrium Zone',
group = ZONES_GROUP)
discountZoneColorInput = input.color( GREEN, 'Discount Zone',
group = ZONES_GROUP)

//---------------------------------------------------------------------------------
------------------------------------}
//DATA STRUCTURES & VARIABLES
//---------------------------------------------------------------------------------
------------------------------------{
// @type UDT representing alerts as bool fields
// @field internalBullishBOS internal structure custom alert
// @field internalBearishBOS internal structure custom alert
// @field internalBullishCHoCH internal structure custom alert
// @field internalBearishCHoCH internal structure custom alert
// @field swingBullishBOS swing structure custom alert
// @field swingBearishBOS swing structure custom alert
// @field swingBullishCHoCH swing structure custom alert
// @field swingBearishCHoCH swing structure custom alert
// @field internalBullishOrderBlock internal order block custom alert
// @field internalBearishOrderBlock internal order block custom alert
// @field swingBullishOrderBlock swing order block custom alert
// @field swingBearishOrderBlock swing order block custom alert
// @field equalHighs equal high low custom alert
// @field equalLows equal high low custom alert
// @field bullishFairValueGap fair value gap custom alert
// @field bearishFairValueGap fair value gap custom alert
type alerts
bool internalBullishBOS = false
bool internalBearishBOS = false
bool internalBullishCHoCH = false
bool internalBearishCHoCH = false
bool swingBullishBOS = false
bool swingBearishBOS = false
bool swingBullishCHoCH = false
bool swingBearishCHoCH = false
bool internalBullishOrderBlock = false
bool internalBearishOrderBlock = false
bool swingBullishOrderBlock = false
bool swingBearishOrderBlock = false
bool equalHighs = false
bool equalLows = false
bool bullishFairValueGap = false
bool bearishFairValueGap = false
// @type UDT representing last swing extremes (top &
bottom)
// @field top last top swing price
// @field bottom last bottom swing price
// @field barTime last swing bar time
// @field barIndex last swing bar index
// @field lastTopTime last top swing time
// @field lastBottomTime last bottom swing time
type trailingExtremes
float top
float bottom
int barTime
int barIndex
int lastTopTime
int lastBottomTime

// @type UDT representing Fair Value Gaps


// @field top top price
// @field bottom bottom price
// @field bias bias (BULLISH or BEARISH)
// @field topBox top box
// @field bottomBox bottom box
type fairValueGap
float top
float bottom
int bias
box topBox
box bottomBox

// @type UDT representing trend bias


// @field bias BULLISH or BEARISH
type trend
int bias

// @type UDT representing Equal Highs Lows display


// @field l_ine displayed line
// @field l_abel displayed label
type equalDisplay
line l_ine = na
label l_abel = na

// @type UDT representing a pivot point (swing point)


// @field currentLevel current price level
// @field lastLevel last price level
// @field crossed true if price level is crossed
// @field barTime bar time
// @field barIndex bar index
type pivot
float currentLevel
float lastLevel
bool crossed
int barTime = time
int barIndex = bar_index

// @type UDT representing an order block


// @field barHigh bar high
// @field barLow bar low
// @field barTime bar time
// @field bias BULLISH or BEARISH
type orderBlock
float barHigh
float barLow
int barTime
int bias

// @variable current swing pivot high


var pivot swingHigh = pivot.new(na,na,false)
// @variable current swing pivot low
var pivot swingLow = pivot.new(na,na,false)
// @variable current internal pivot high
var pivot internalHigh = pivot.new(na,na,false)
// @variable current internal pivot low
var pivot internalLow = pivot.new(na,na,false)
// @variable current equal high pivot
var pivot equalHigh = pivot.new(na,na,false)
// @variable current equal low pivot
var pivot equalLow = pivot.new(na,na,false)
// @variable swing trend bias
var trend swingTrend = trend.new(0)
// @variable internal trend bias
var trend internalTrend = trend.new(0)
// @variable equal high display
var equalDisplay equalHighDisplay = equalDisplay.new()
// @variable equal low display
var equalDisplay equalLowDisplay = equalDisplay.new()
// @variable storage for fairValueGap UDTs
var array<fairValueGap> fairValueGaps = array.new<fairValueGap>()
// @variable storage for parsed highs
var array<float> parsedHighs = array.new<float>()
// @variable storage for parsed lows
var array<float> parsedLows = array.new<float>()
// @variable storage for raw highs
var array<float> highs = array.new<float>()
// @variable storage for raw lows
var array<float> lows = array.new<float>()
// @variable storage for bar time values
var array<int> times = array.new<int>()
// @variable last trailing swing high and low
var trailingExtremes trailing = trailingExtremes.new()
// @variable storage for orderBlock UDTs (swing
order blocks)
var array<orderBlock> swingOrderBlocks = array.new<orderBlock>()
// @variable storage for orderBlock UDTs (internal
order blocks)
var array<orderBlock> internalOrderBlocks = array.new<orderBlock>()
// @variable storage for swing order blocks boxes
var array<box> swingOrderBlocksBoxes = array.new<box>()
// @variable storage for internal order blocks boxes
var array<box> internalOrderBlocksBoxes = array.new<box>()
// @variable color for swing bullish structures
var swingBullishColor = styleInput == MONOCHROME ? MONO_BULLISH :
swingBullColorInput
// @variable color for swing bearish structures
var swingBearishColor = styleInput == MONOCHROME ? MONO_BEARISH :
swingBearColorInput
// @variable color for bullish fair value gaps
var fairValueGapBullishColor = styleInput == MONOCHROME ?
color.new(MONO_BULLISH,70) : fairValueGapsBullColorInput
// @variable color for bearish fair value gaps
var fairValueGapBearishColor = styleInput == MONOCHROME ?
color.new(MONO_BEARISH,70) : fairValueGapsBearColorInput
// @variable color for premium zone
var premiumZoneColor = styleInput == MONOCHROME ? MONO_BEARISH :
premiumZoneColorInput
// @variable color for discount zone
var discountZoneColor = styleInput == MONOCHROME ? MONO_BULLISH :
discountZoneColorInput
// @variable bar index on current script iteration
varip int currentBarIndex = bar_index
// @variable bar index on last script iteration
varip int lastBarIndex = bar_index
// @variable alerts in current bar
alerts currentAlerts = alerts.new()
// @variable time at start of chart
var initialTime = time

// we create the needed boxes for displaying order blocks at the first execution
if barstate.isfirst
if showSwingOrderBlocksInput
for index = 1 to swingOrderBlocksSizeInput
swingOrderBlocksBoxes.push(box.new(na,na,na,na,xloc =
xloc.bar_time,extend = extend.right))
if showInternalOrderBlocksInput
for index = 1 to internalOrderBlocksSizeInput
internalOrderBlocksBoxes.push(box.new(na,na,na,na,xloc =
xloc.bar_time,extend = extend.right))

// @variable source to use in bearish order blocks


mitigation
bearishOrderBlockMitigationSource = orderBlockMitigationInput == CLOSE ? close :
high
// @variable source to use in bullish order blocks
mitigation
bullishOrderBlockMitigationSource = orderBlockMitigationInput == CLOSE ? close :
low
// @variable default volatility measure
atrMeasure = ta.atr(200)
// @variable parsed volatility measure by user settings
volatilityMeasure = orderBlockFilterInput == ATR ? atrMeasure :
ta.cum(ta.tr)/bar_index
// @variable true if current bar is a high volatility bar
highVolatilityBar = (high - low) >= (2 * volatilityMeasure)
// @variable parsed high
parsedHigh = highVolatilityBar ? low : high
// @variable parsed low
parsedLow = highVolatilityBar ? high : low

// we store current values into the arrays at each bar


parsedHighs.push(parsedHigh)
parsedLows.push(parsedLow)
highs.push(high)
lows.push(low)
times.push(time)

//---------------------------------------------------------------------------------
------------------------------------}
//USER-DEFINED FUNCTIONS
//---------------------------------------------------------------------------------
------------------------------------{
// @function Get the value of the current leg, it can be 0 (bearish) or
1 (bullish)
// @returns int
leg(int size) =>
var leg = 0
newLegHigh = high[size] > ta.highest( size)
newLegLow = low[size] < ta.lowest( size)

if newLegHigh
leg := BEARISH_LEG
else if newLegLow
leg := BULLISH_LEG
leg

// @function Identify whether the current value is the start of a new


leg (swing)
// @param leg (int) Current leg value
// @returns bool
startOfNewLeg(int leg) => ta.change(leg) != 0

// @function Identify whether the current level is the start of a new


bearish leg (swing)
// @param leg (int) Current leg value
// @returns bool
startOfBearishLeg(int leg) => ta.change(leg) == -1

// @function Identify whether the current level is the start of a new


bullish leg (swing)
// @param leg (int) Current leg value
// @returns bool
startOfBullishLeg(int leg) => ta.change(leg) == +1

// @function create a new label


// @param labelTime bar time coordinate
// @param labelPrice price coordinate
// @param tag text to display
// @param labelColor text color
// @param labelStyle label style
// @returns label ID
drawLabel(int labelTime, float labelPrice, string tag, color labelColor, string
labelStyle) =>
var label l_abel = na

if modeInput == PRESENT
l_abel.delete()

l_abel :=
label.new(chart.point.new(labelTime,na,labelPrice),tag,xloc.bar_time,color=color(na
),textcolor=labelColor,style = labelStyle,size = size.small)

// @function create a new line and label representing an EQH or EQL


// @param p_ivot starting pivot
// @param level price level of current pivot
// @param size how many bars ago was the current pivot detected
// @param equalHigh true for EQH, false for EQL
// @returns label ID
drawEqualHighLow(pivot p_ivot, float level, int size, bool equalHigh) =>
equalDisplay e_qualDisplay = equalHigh ? equalHighDisplay : equalLowDisplay

string tag = 'EQL'


color equalColor = swingBullishColor
string labelStyle = label.style_label_up

if equalHigh
tag := 'EQH'
equalColor := swingBearishColor
labelStyle := label.style_label_down

if modeInput == PRESENT
line.delete( e_qualDisplay.l_ine)
label.delete( e_qualDisplay.l_abel)

e_qualDisplay.l_ine :=
line.new(chart.point.new(p_ivot.barTime,na,p_ivot.currentLevel),
chart.point.new(time[size],na,level), xloc = xloc.bar_time, color = equalColor,
style = line.style_dotted)
labelPosition = math.round(0.5*(p_ivot.barIndex + bar_index - size))
e_qualDisplay.l_abel := label.new(chart.point.new(na,labelPosition,level),
tag, xloc.bar_index, color = color(na), textcolor = equalColor, style = labelStyle,
size = equalHighsLowsSizeInput)

// @function store current structure and trailing swing points, and also
display swing points and equal highs/lows
// @param size (int) structure size
// @param equalHighLow (bool) true for displaying current highs/lows
// @param internal (bool) true for getting internal structures
// @returns label ID
getCurrentStructure(int size,bool equalHighLow = false, bool internal = false) =>
currentLeg = leg(size)
newPivot = startOfNewLeg(currentLeg)
pivotLow = startOfBullishLeg(currentLeg)
pivotHigh = startOfBearishLeg(currentLeg)

if newPivot
if pivotLow
pivot p_ivot = equalHighLow ? equalLow : internal ? internalLow :
swingLow

if equalHighLow and math.abs(p_ivot.currentLevel - low[size]) <


equalHighsLowsThresholdInput * atrMeasure
drawEqualHighLow(p_ivot, low[size], size, false)

p_ivot.lastLevel := p_ivot.currentLevel
p_ivot.currentLevel := low[size]
p_ivot.crossed := false
p_ivot.barTime := time[size]
p_ivot.barIndex := bar_index[size]

if not equalHighLow and not internal


trailing.bottom := p_ivot.currentLevel
trailing.barTime := p_ivot.barTime
trailing.barIndex := p_ivot.barIndex
trailing.lastBottomTime := p_ivot.barTime

if showSwingsInput and not internal and not equalHighLow


drawLabel(time[size], p_ivot.currentLevel, p_ivot.currentLevel <
p_ivot.lastLevel ? 'LL' : 'HL', swingBullishColor, label.style_label_up)
else
pivot p_ivot = equalHighLow ? equalHigh : internal ? internalHigh :
swingHigh

if equalHighLow and math.abs(p_ivot.currentLevel - high[size]) <


equalHighsLowsThresholdInput * atrMeasure
drawEqualHighLow(p_ivot,high[size],size,true)

p_ivot.lastLevel := p_ivot.currentLevel
p_ivot.currentLevel := high[size]
p_ivot.crossed := false
p_ivot.barTime := time[size]
p_ivot.barIndex := bar_index[size]

if not equalHighLow and not internal


trailing.top := p_ivot.currentLevel
trailing.barTime := p_ivot.barTime
trailing.barIndex := p_ivot.barIndex
trailing.lastTopTime := p_ivot.barTime

if showSwingsInput and not internal and not equalHighLow


drawLabel(time[size], p_ivot.currentLevel, p_ivot.currentLevel >
p_ivot.lastLevel ? 'HH' : 'LH', swingBearishColor, label.style_label_down)

// @function draw line and label representing a structure


// @param p_ivot base pivot point
// @param tag test to display
// @param structureColor base color
// @param lineStyle line style
// @param labelStyle label style
// @param labelSize text size
// @returns label ID
drawStructure(pivot p_ivot, string tag, color structureColor, string lineStyle,
string labelStyle, string labelSize) =>
var line l_ine = line.new(na,na,na,na,xloc = xloc.bar_time)
var label l_abel = label.new(na,na)

if modeInput == PRESENT
l_ine.delete()
l_abel.delete()

l_ine := line.new(chart.point.new(p_ivot.barTime,na,p_ivot.currentLevel),
chart.point.new(time,na,p_ivot.currentLevel), xloc.bar_time, color=structureColor,
style=lineStyle)
l_abel :=
label.new(chart.point.new(na,math.round(0.5*(p_ivot.barIndex+bar_index)),p_ivot.cur
rentLevel), tag, xloc.bar_index, color=color(na), textcolor=structureColor,
style=labelStyle, size = labelSize)

// @function delete order blocks


// @param internal true for internal order blocks
// @returns orderBlock ID
deleteOrderBlocks(bool internal = false) =>
array<orderBlock> orderBlocks = internal ? internalOrderBlocks :
swingOrderBlocks

for [index,eachOrderBlock] in orderBlocks


bool crossedOderBlock = false

if bearishOrderBlockMitigationSource > eachOrderBlock.barHigh and


eachOrderBlock.bias == BEARISH
crossedOderBlock := true
if internal
currentAlerts.internalBearishOrderBlock := true
else
currentAlerts.swingBearishOrderBlock := true
else if bullishOrderBlockMitigationSource < eachOrderBlock.barLow and
eachOrderBlock.bias == BULLISH
crossedOderBlock := true
if internal
currentAlerts.internalBullishOrderBlock := true
else
currentAlerts.swingBullishOrderBlock := true
if crossedOderBlock
orderBlocks.remove(index)

// @function fetch and store order blocks


// @param p_ivot base pivot point
// @param internal true for internal order blocks
// @param bias BULLISH or BEARISH
// @returns void
storeOrdeBlock(pivot p_ivot,bool internal = false,int bias) =>
if (not internal and showSwingOrderBlocksInput) or (internal and
showInternalOrderBlocksInput)

array<float> a_rray = na
int parsedIndex = na

if bias == BEARISH
a_rray := parsedHighs.slice(p_ivot.barIndex,bar_index)
parsedIndex := p_ivot.barIndex + a_rray.indexof(a_rray.max())
else
a_rray := parsedLows.slice(p_ivot.barIndex,bar_index)
parsedIndex := p_ivot.barIndex + a_rray.indexof(a_rray.min())

orderBlock o_rderBlock =
orderBlock.new(parsedHighs.get(parsedIndex), parsedLows.get(parsedIndex),
times.get(parsedIndex),bias)
array<orderBlock> orderBlocks = internal ? internalOrderBlocks :
swingOrderBlocks

if orderBlocks.size() >= 100


orderBlocks.pop()
orderBlocks.unshift(o_rderBlock)

// @function draw order blocks as boxes


// @param internal true for internal order blocks
// @returns void
drawOrderBlocks(bool internal = false) =>
array<orderBlock> orderBlocks = internal ? internalOrderBlocks :
swingOrderBlocks
orderBlocksSize = orderBlocks.size()

if orderBlocksSize > 0
maxOrderBlocks = internal ?
internalOrderBlocksSizeInput : swingOrderBlocksSizeInput
array<orderBlock> parsedOrdeBlocks = orderBlocks.slice(0,
math.min(maxOrderBlocks,orderBlocksSize))
array<box> b_oxes = internal ? internalOrderBlocksBoxes :
swingOrderBlocksBoxes

for [index,eachOrderBlock] in parsedOrdeBlocks


orderBlockColor = styleInput == MONOCHROME ? (eachOrderBlock.bias ==
BEARISH ? color.new(MONO_BEARISH,80) : color.new(MONO_BULLISH,80)) : internal ?
(eachOrderBlock.bias == BEARISH ? internalBearishOrderBlockColor :
internalBullishOrderBlockColor) : (eachOrderBlock.bias == BEARISH ?
swingBearishOrderBlockColor : swingBullishOrderBlockColor)

box b_ox = b_oxes.get(index)

b_ox.set_top_left_point( chart.point.new(eachOrderBlock.barTime,na,eachOrderBloc
k.barHigh))

b_ox.set_bottom_right_point(chart.point.new(last_bar_time,na,eachOrderBlock.barLow)
)
b_ox.set_border_color( internal ? na : orderBlockColor)
b_ox.set_bgcolor( orderBlockColor)

// @function detect and draw structures, also detect and store order
blocks
// @param internal true for internal structures or order blocks
// @returns void
displayStructure(bool internal = false) =>
var bullishBar = true
var bearishBar = true

if internalFilterConfluenceInput
bullishBar := high - math.max(close, open) > math.min(close, open - low)
bearishBar := high - math.max(close, open) < math.min(close, open - low)

pivot p_ivot = internal ? internalHigh : swingHigh


trend t_rend = internal ? internalTrend : swingTrend

lineStyle = internal ? line.style_dashed : line.style_solid


labelSize = internal ? internalStructureSize : swingStructureSize

extraCondition = internal ? internalHigh.currentLevel !=


swingHigh.currentLevel and bullishBar : true
bullishColor = styleInput == MONOCHROME ? MONO_BULLISH : internal ?
internalBullColorInput : swingBullColorInput

if ta.crossover(close,p_ivot.currentLevel) and not p_ivot.crossed and


extraCondition
string tag = t_rend.bias == BEARISH ? CHOCH : BOS

if internal
currentAlerts.internalBullishCHoCH := tag == CHOCH
currentAlerts.internalBullishBOS := tag == BOS
else
currentAlerts.swingBullishCHoCH := tag == CHOCH
currentAlerts.swingBullishBOS := tag == BOS

p_ivot.crossed := true
t_rend.bias := BULLISH
displayCondition = internal ? showInternalsInput and (showInternalBullInput
== ALL or (showInternalBullInput == BOS and tag != CHOCH) or (showInternalBullInput
== CHOCH and tag == CHOCH)) : showStructureInput and (showSwingBullInput == ALL or
(showSwingBullInput == BOS and tag != CHOCH) or (showSwingBullInput == CHOCH and
tag == CHOCH))

if displayCondition

drawStructure(p_ivot,tag,bullishColor,lineStyle,label.style_label_down,labelSize)

if (internal and showInternalOrderBlocksInput) or (not internal and


showSwingOrderBlocksInput)
storeOrdeBlock(p_ivot,internal,BULLISH)

p_ivot := internal ? internalLow : swingLow


extraCondition := internal ? internalLow.currentLevel != swingLow.currentLevel
and bearishBar : true
bearishColor = styleInput == MONOCHROME ? MONO_BEARISH : internal ?
internalBearColorInput : swingBearColorInput

if ta.crossunder(close,p_ivot.currentLevel) and not p_ivot.crossed and


extraCondition
string tag = t_rend.bias == BULLISH ? CHOCH : BOS

if internal
currentAlerts.internalBearishCHoCH := tag == CHOCH
currentAlerts.internalBearishBOS := tag == BOS
else
currentAlerts.swingBearishCHoCH := tag == CHOCH
currentAlerts.swingBearishBOS := tag == BOS

p_ivot.crossed := true
t_rend.bias := BEARISH

displayCondition = internal ? showInternalsInput and (showInternalBearInput


== ALL or (showInternalBearInput == BOS and tag != CHOCH) or (showInternalBearInput
== CHOCH and tag == CHOCH)) : showStructureInput and (showSwingBearInput == ALL or
(showSwingBearInput == BOS and tag != CHOCH) or (showSwingBearInput == CHOCH and
tag == CHOCH))

if displayCondition

drawStructure(p_ivot,tag,bearishColor,lineStyle,label.style_label_up,labelSize)

if (internal and showInternalOrderBlocksInput) or (not internal and


showSwingOrderBlocksInput)
storeOrdeBlock(p_ivot,internal,BEARISH)

// @function draw one fair value gap box (each fair value gap has two
boxes)
// @param leftTime left time coordinate
// @param rightTime right time coordinate
// @param topPrice top price level
// @param bottomPrice bottom price level
// @param boxColor box color
// @returns box ID
fairValueGapBox(leftTime,rightTime,topPrice,bottomPrice,boxColor) =>
box.new(chart.point.new(leftTime,na,topPrice),chart.point.new(rightTime +
fairValueGapsExtendInput * (time-time[1]),na,bottomPrice), xloc=xloc.bar_time,
border_color = boxColor, bgcolor = boxColor)

// @function delete fair value gaps


// @returns fairValueGap ID
deleteFairValueGaps() =>
for [index,eachFairValueGap] in fairValueGaps
if (low < eachFairValueGap.bottom and eachFairValueGap.bias == BULLISH) or
(high > eachFairValueGap.top and eachFairValueGap.bias == BEARISH)
eachFairValueGap.topBox.delete()
eachFairValueGap.bottomBox.delete()
fairValueGaps.remove(index)

// @function draw fair value gaps


// @returns fairValueGap ID
drawFairValueGaps() =>
[lastClose, lastOpen, lastTime, currentHigh, currentLow, currentTime,
last2High, last2Low] = request.security(syminfo.tickerid,
fairValueGapsTimeframeInput, [close[1], open[1], time[1], high[0], low[0], time[0],
high[2], low[2]],lookahead = barmerge.lookahead_on)

barDeltaPercent = (lastClose - lastOpen) / (lastOpen * 100)


newTimeframe = timeframe.change(fairValueGapsTimeframeInput)
threshold = fairValueGapsThresholdInput ?
ta.cum(math.abs(newTimeframe ? barDeltaPercent : 0)) / bar_index * 2 : 0

bullishFairValueGap = currentLow > last2High and lastClose > last2High and


barDeltaPercent > threshold and newTimeframe
bearishFairValueGap = currentHigh < last2Low and lastClose < last2Low and -
barDeltaPercent > threshold and newTimeframe

if bullishFairValueGap
currentAlerts.bullishFairValueGap := true

fairValueGaps.unshift(fairValueGap.new(currentLow,last2High,BULLISH,fairValueGapBox
(lastTime,currentTime,currentLow,math.avg(currentLow,last2High),fairValueGapBullish
Color),fairValueGapBox(lastTime,currentTime,math.avg(currentLow,last2High),last2Hig
h,fairValueGapBullishColor)))
if bearishFairValueGap
currentAlerts.bearishFairValueGap := true

fairValueGaps.unshift(fairValueGap.new(currentHigh,last2Low,BEARISH,fairValueGapBox
(lastTime,currentTime,currentHigh,math.avg(currentHigh,last2Low),fairValueGapBearis
hColor),fairValueGapBox(lastTime,currentTime,math.avg(currentHigh,last2Low),last2Lo
w,fairValueGapBearishColor)))

// @function get line style from string


// @param style line style
// @returns string
getStyle(string style) =>
switch style
SOLID => line.style_solid
DASHED => line.style_dashed
DOTTED => line.style_dotted

// @function draw MultiTimeFrame levels


// @param timeframe base timeframe
// @param sameTimeframe true if chart timeframe is same as base timeframe
// @param style line style
// @param levelColor line and text color
// @returns void
drawLevels(string timeframe, bool sameTimeframe, string style, color levelColor) =>
[topLevel, bottomLevel, leftTime, rightTime] =
request.security(syminfo.tickerid, timeframe, [high[1], low[1], time[1],
time],lookahead = barmerge.lookahead_on)

float parsedTop = sameTimeframe ? high : topLevel


float parsedBottom = sameTimeframe ? low : bottomLevel

int parsedLeftTime = sameTimeframe ? time : leftTime


int parsedRightTime = sameTimeframe ? time : rightTime

int parsedTopTime = time


int parsedBottomTime = time

if not sameTimeframe
int leftIndex = times.binary_search_rightmost(parsedLeftTime)
int rightIndex =
times.binary_search_rightmost(parsedRightTime)

array<int> timeArray = times.slice(leftIndex,rightIndex)


array<float> topArray = highs.slice(leftIndex,rightIndex)
array<float> bottomArray = lows.slice(leftIndex,rightIndex)

parsedTopTime := timeArray.size() > 0 ?


timeArray.get(topArray.indexof(topArray.max())) : initialTime
parsedBottomTime := timeArray.size() > 0 ?
timeArray.get(bottomArray.indexof(bottomArray.min())) : initialTime

var line topLine = line.new(na, na, na, na, xloc = xloc.bar_time, color
= levelColor, style = getStyle(style))
var line bottomLine = line.new(na, na, na, na, xloc = xloc.bar_time, color
= levelColor, style = getStyle(style))
var label topLabel = label.new(na, na, xloc = xloc.bar_time, text =
str.format('P{0}H',timeframe), color=color(na), textcolor = levelColor, size =
size.small, style = label.style_label_left)
var label bottomLabel = label.new(na, na, xloc = xloc.bar_time, text =
str.format('P{0}L',timeframe), color=color(na), textcolor = levelColor, size =
size.small, style = label.style_label_left)

topLine.set_first_point( chart.point.new(parsedTopTime,na,parsedTop))
topLine.set_second_point( chart.point.new(last_bar_time + 20 * (time-
time[1]),na,parsedTop))
topLabel.set_point( chart.point.new(last_bar_time + 20 * (time-
time[1]),na,parsedTop))

bottomLine.set_first_point( chart.point.new(parsedBottomTime,na,parsedBottom))
bottomLine.set_second_point(chart.point.new(last_bar_time + 20 * (time-
time[1]),na,parsedBottom))
bottomLabel.set_point( chart.point.new(last_bar_time + 20 * (time-
time[1]),na,parsedBottom))

// @function true if chart timeframe is higher than provided timeframe


// @param timeframe timeframe to check
// @returns bool
higherTimeframe(string timeframe) => timeframe.in_seconds() >
timeframe.in_seconds(timeframe)

// @function update trailing swing points


// @returns int
updateTrailingExtremes() =>
trailing.top := math.max(high,trailing.top)
trailing.lastTopTime := trailing.top == high ? time : trailing.lastTopTime
trailing.bottom := math.min(low,trailing.bottom)
trailing.lastBottomTime := trailing.bottom == low ? time :
trailing.lastBottomTime

// @function draw trailing swing points


// @returns void
drawHighLowSwings() =>
var line topLine = line.new(na, na, na, na, color = swingBearishColor,
xloc = xloc.bar_time)
var line bottomLine = line.new(na, na, na, na, color = swingBullishColor,
xloc = xloc.bar_time)
var label topLabel = label.new(na, na, color=color(na), textcolor =
swingBearishColor, xloc = xloc.bar_time, style = label.style_label_down, size =
size.tiny)
var label bottomLabel = label.new(na, na, color=color(na), textcolor =
swingBullishColor, xloc = xloc.bar_time, style = label.style_label_up, size =
size.tiny)

rightTimeBar = last_bar_time + 20 * (time - time[1])

topLine.set_first_point( chart.point.new(trailing.lastTopTime, na,


trailing.top))
topLine.set_second_point( chart.point.new(rightTimeBar, na, trailing.top))
topLabel.set_point( chart.point.new(rightTimeBar, na, trailing.top))
topLabel.set_text( swingTrend.bias == BEARISH ? 'Strong High' : 'Weak
High')

bottomLine.set_first_point( chart.point.new(trailing.lastBottomTime, na,


trailing.bottom))
bottomLine.set_second_point(chart.point.new(rightTimeBar, na, trailing.bottom))
bottomLabel.set_point( chart.point.new(rightTimeBar, na, trailing.bottom))
bottomLabel.set_text( swingTrend.bias == BULLISH ? 'Strong Low' : 'Weak
Low')

// @function draw a zone with a label and a box


// @param labelLevel price level for label
// @param labelIndex bar index for label
// @param top top price level for box
// @param bottom bottom price level for box
// @param tag text to display
// @param zoneColor base color
// @param style label style
// @returns void
drawZone(float labelLevel, int labelIndex, float top, float bottom, string tag,
color zoneColor, string style) =>
var label l_abel = label.new(na,na,text = tag, color=color(na),textcolor =
zoneColor, style = style, size = size.small)
var box b_ox = box.new(na,na,na,na,bgcolor =
color.new(zoneColor,80),border_color = color(na), xloc = xloc.bar_time)

b_ox.set_top_left_point( chart.point.new(trailing.barTime,na,top))
b_ox.set_bottom_right_point(chart.point.new(last_bar_time,na,bottom))

l_abel.set_point( chart.point.new(na,labelIndex,labelLevel))
// @function draw premium/discount zones
// @returns void
drawPremiumDiscountZones() =>
drawZone(trailing.top, math.round(0.5*(trailing.barIndex + last_bar_index)),
trailing.top, 0.95*trailing.top + 0.05*trailing.bottom, 'Premium',
premiumZoneColor, label.style_label_down)

equilibriumLevel = math.avg(trailing.top, trailing.bottom)


drawZone(equilibriumLevel, last_bar_index, 0.525*trailing.top +
0.475*trailing.bottom, 0.525*trailing.bottom + 0.475*trailing.top, 'Equilibrium',
equilibriumZoneColorInput, label.style_label_left)

drawZone(trailing.bottom, math.round(0.5*(trailing.barIndex + last_bar_index)),


0.95*trailing.bottom + 0.05*trailing.top, trailing.bottom, 'Discount',
discountZoneColor, label.style_label_up)

//---------------------------------------------------------------------------------
------------------------------------}
//MUTABLE VARIABLES & EXECUTION
//---------------------------------------------------------------------------------
------------------------------------{
parsedOpen = showTrendInput ? open : na
candleColor = internalTrend.bias == BULLISH ? swingBullishColor : swingBearishColor
plotcandle(parsedOpen,high,low,close,color = candleColor, wickcolor = candleColor,
bordercolor = candleColor)

if showHighLowSwingsInput or showPremiumDiscountZonesInput
updateTrailingExtremes()

if showHighLowSwingsInput
drawHighLowSwings()

if showPremiumDiscountZonesInput
drawPremiumDiscountZones()

if showFairValueGapsInput
deleteFairValueGaps()

getCurrentStructure(swingsLengthInput,false)
getCurrentStructure(5,false,true)

if showEqualHighsLowsInput
getCurrentStructure(equalHighsLowsLengthInput,true)

if showInternalsInput or showInternalOrderBlocksInput or showTrendInput


displayStructure(true)

if showStructureInput or showSwingOrderBlocksInput or showHighLowSwingsInput


displayStructure()

if showInternalOrderBlocksInput
deleteOrderBlocks(true)

if showSwingOrderBlocksInput
deleteOrderBlocks()

if showFairValueGapsInput
drawFairValueGaps()
if barstate.islastconfirmedhistory or barstate.islast
if showInternalOrderBlocksInput
drawOrderBlocks(true)

if showSwingOrderBlocksInput
drawOrderBlocks()

lastBarIndex := currentBarIndex
currentBarIndex := bar_index
newBar = currentBarIndex != lastBarIndex

if barstate.islastconfirmedhistory or (barstate.isrealtime and newBar)


if showDailyLevelsInput and not higherTimeframe('D')

drawLevels('D',timeframe.isdaily,dailyLevelsStyleInput,dailyLevelsColorInput)

if showWeeklyLevelsInput and not higherTimeframe('W')

drawLevels('W',timeframe.isweekly,weeklyLevelsStyleInput,weeklyLevelsColorInput)

if showMonthlyLevelsInput and not higherTimeframe('M')

drawLevels('M',timeframe.ismonthly,monthlyLevelsStyleInput,monthlyLevelsColorInput)

//---------------------------------------------------------------------------------
------------------------------------}
//ALERTS
//---------------------------------------------------------------------------------
------------------------------------{
alertcondition(currentAlerts.internalBullishBOS, 'Internal Bullish BOS',
'Internal Bullish BOS formed')
alertcondition(currentAlerts.internalBullishCHoCH, 'Internal Bullish CHoCH',
'Internal Bullish CHoCH formed')
alertcondition(currentAlerts.internalBearishBOS, 'Internal Bearish BOS',
'Internal Bearish BOS formed')
alertcondition(currentAlerts.internalBearishCHoCH, 'Internal Bearish CHoCH',
'Internal Bearish CHoCH formed')

alertcondition(currentAlerts.swingBullishBOS, 'Bullish BOS',


'Internal Bullish BOS formed')
alertcondition(currentAlerts.swingBullishCHoCH, 'Bullish CHoCH',
'Internal Bullish CHoCH formed')
alertcondition(currentAlerts.swingBearishBOS, 'Bearish BOS',
'Bearish BOS formed')
alertcondition(currentAlerts.swingBearishCHoCH, 'Bearish CHoCH',
'Bearish CHoCH formed')

alertcondition(currentAlerts.internalBullishOrderBlock, 'Bullish Internal OB


Breakout', 'Price broke bullish internal OB')
alertcondition(currentAlerts.internalBearishOrderBlock, 'Bearish Internal OB
Breakout', 'Price broke bearish internal OB')
alertcondition(currentAlerts.swingBullishOrderBlock, 'Bullish Swing OB
Breakout', 'Price broke bullish swing OB')
alertcondition(currentAlerts.swingBearishOrderBlock, 'Bearish Swing OB
Breakout', 'Price broke bearish swing OB')

alertcondition(currentAlerts.equalHighs, 'Equal Highs',


'Equal highs detected')
alertcondition(currentAlerts.equalLows, 'Equal Lows',
'Equal lows detected')

alertcondition(currentAlerts.bullishFairValueGap, 'Bullish FVG',


'Bullish FVG formed')
alertcondition(currentAlerts.bearishFairValueGap, 'Bearish FVG',
'Bearish FVG formed')

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

var GRP1 = "Settings"


showLines = input(title='Show Lines ?', defval=true, group=GRP1)
showBackground = input(title='Show Background ?', defval=true, group=GRP1)
showMiddleLine = input(title='Show Middle Line ?', defval=true, group=GRP1)
extendLines = input(title='Extend Lines ?', defval=true, group=GRP1)
rangeTime = input.session(title='Session Time', defval='1700-0259', group=GRP1)
extendTime = input.session(title='Extended Lines Time', defval='0300-1659',
group=GRP1)

var GRP2 = "Styles"


linesWidth = input.int(2, 'Box And Lines Width ?', minval=1, maxval=4, group=GRP2)
boxLineColor = input(color.blue, 'Box and H/L Line Color', group=GRP2)
middleLineColor = input(color.red, 'Middle Line Color', group=GRP2)
backgroundColor = input(color.new(color.aqua, 90), 'Box Background Color',
group=GRP2)

inSession = not na(time(timeframe.period, rangeTime))


inExtend = not na(time(timeframe.period, extendTime))

startTime = 0
startTime := inSession and not inSession[1] ? time : startTime[1]

//Box lines
var line lowHLine = na
var line topHLine = na
var line leftVLine = na
var line rightVLine = na
var line middleHLine = na
var box bgBox = na

var low_val = 0.0


var high_val = 0.0
if inSession and not inSession[1]
low_val := low
high_val := high
high_val

// Plot lines
if inSession and timeframe.isintraday
if inSession[1]
line.delete(lowHLine)
line.delete(topHLine)
line.delete(leftVLine)
line.delete(rightVLine)
line.delete(middleHLine)
box.delete(bgBox)

if low < low_val


low_val := low
low_val
if high > high_val
high_val := high
high_val

//Create Box
//x1, y1, x2, y2
if showBackground
bgBox := box.new(startTime, high_val, time, low_val, xloc=xloc.bar_time,
bgcolor=backgroundColor, border_width=0)

if showLines
lowHLine := line.new(startTime, low_val, time, low_val, xloc=xloc.bar_time,
color=boxLineColor, style=line.style_solid, width=linesWidth)
topHLine := line.new(startTime, high_val, time, high_val,
xloc=xloc.bar_time, color=boxLineColor, style=line.style_solid, width=linesWidth)
leftVLine := line.new(startTime, high_val, startTime, low_val,
xloc=xloc.bar_time, color=boxLineColor, style=line.style_solid, width=linesWidth)
rightVLine := line.new(time, high_val, time, low_val, xloc=xloc.bar_time,
color=boxLineColor, style=line.style_solid, width=linesWidth)

//Create Middle line


if showMiddleLine
middleHLine := line.new(startTime, (high_val + low_val) / 2, time,
(high_val + low_val) / 2, xloc=xloc.bar_time, color=middleLineColor,
style=line.style_dotted, width=linesWidth)

else
if inExtend and extendLines and not inSession and timeframe.isintraday
time1 = line.get_x1(lowHLine)
time2 = line.get_x2(lowHLine)
price = line.get_y1(lowHLine)
line.delete(lowHLine)
lowHLine := line.new(time1, price, time, price, xloc=xloc.bar_time,
color=boxLineColor, style=line.style_solid, width=linesWidth)

time1 := line.get_x1(topHLine)
time2 := line.get_x2(topHLine)
price := line.get_y1(topHLine)
line.delete(topHLine)
topHLine := line.new(time1, price, time, price, xloc=xloc.bar_time,
color=boxLineColor, style=line.style_solid, width=linesWidth)

time1 := line.get_x1(middleHLine)
time2 := line.get_x2(middleHLine)
price := line.get_y1(middleHLine)
line.delete(middleHLine)
middleHLine := line.new(time1, price, time, price, xloc=xloc.bar_time,
color=middleLineColor, style=line.style_dotted, width=linesWidth)
middleHLine

// Define EMAs
ema20_close = ta.ema(close, 20)
ema34_close = ta.ema(close, 34)
ema34_high = ta.ema(high, 34)
ema34_low = ta.ema(low, 34)
ema50_close = ta.ema(close, 50)
ema200_high = ta.ema(high, 200)
ema200_low = ta.ema(low, 200)
ema13_close = ta.ema(close, 13)
ema10_close = ta.ema(close, 10)
ema65_close = ta.ema(close, 65)
ema89_close = ta.ema(close, 89)
ema200_close = ta.ema(close, 200)
ema630_close = ta.ema(close,630)
sma5 = ta.sma(close,5)
sma50 = ta.sma(close,50)
sma89 = ta.sma(close,89)
ema5_close = ta.ema(close, 5)
ema100_close = ta.ema(close, 100)

// Plot EMAs
plot(ema20_close, color = #ef8688eb, title = "ema20_close", linewidth = 1)
plot(ema34_close, color = color.rgb(149, 218, 239, 8), title = "ema34_close",
linewidth = 1)
plot(ema50_close, color = color.rgb(109, 109, 232, 8), title = "ema50_close",
linewidth = 1)
plot(ema5_close, color = color.rgb(149, 218, 239, 8), title = "ema5_close",
linewidth = 1)
plot(ema100_close, color = color.rgb(149, 218, 239, 8), title = "ema100_close",
linewidth = 1)

plot(ema34_high, color = color.rgb(134, 207, 239, 8), title = "ema34_high",


linewidth = 1)
plot(ema34_low, color = color.rgb(134, 216, 239, 8), title = "ema34_low", linewidth
= 1)

plot(ema200_high, color = #c389f2eb, title = "ema200_high", linewidth = 1)


plot(ema200_low, color = #c389f2eb, title = "ema200_low", linewidth = 1)
plot(ema13_close, color = color.rgb(155, 149, 149, 8) , title = "EMA 13 Close",
linewidth =1)
plot(ema10_close, color = color.rgb(155, 149, 149, 8) , title = "EMA 10 Close",
linewidth =1)

plot(ema65_close, color = color.rgb(64, 44, 239), title = "EMA 65 Close", linewidth


= 1)
plot(ema89_close, color = #efbb2c, title = "EMA 89 Close", linewidth = 1)
plot(ema200_close, color = color.rgb(209, 99, 237), title = "EMA 200 Close",
linewidth = 1)
plot(ema630_close, color = color.rgb(85, 84,86, 12), title = "EMA 630 Close",
linewidth = 1)
plot(sma5, color = color.rgb(85, 84, 86, 12), title = "SMA 5", linewidth = 1)
plot(sma50, color = #5364e8e0, title = "SMA 50", linewidth = 1)
plot(sma89, color = #edd410e0, title = "SMA 89", linewidth = 1)

// bolinger band

maType = input.string(title="Moving Average Type BB1", defval="SMA",


options=["SMA", "EMA"])
length1 = input(20, title="Length")
mult1 = input(2.0, title="Multiplier")
basis1 = maType == "SMA" ? ta.sma(close, length1) : ta.ema(close, length1)
// basis1 = ta.sma(close, length1)
dev = mult1*ta.stdev(close, length1)
upper = basis1 + dev
lower = basis1 - dev
// Vẽ Bollinger Bands
plot(upper, color=#eca1a1, title="Upper BB")
plot(lower, color=#eca1a1, title="Lower BB")
plot(basis1, color = #eca1a1, title = "basis1 BB")

// bolinger band 2

maType2 = input.string(title="Moving Average Type BB2", defval="SMA",


options=["SMA", "EMA"])
length2 = input(20, title="Length2")
mult2 = input(2.0, title="Multiplier2")
basis2 = maType2 == "SMA" ? ta.sma(close, length2) : ta.ema(close, length2)
// basis2 = ta.sma(close, length2)
dev2 = mult2*ta.stdev(close, length2)
upper2 = basis2 + dev2
lower2 = basis2 - dev2
// Vẽ Bollinger Bands
plot(upper2, color=#eca1a1, title="Upper BB2")
plot(lower2, color=#eca1a1, title="Lower BB2")
plot(basis2, color = #eca1a1, title = "basis2 BB")

// PIVOT ORDER BLOCK


//Titles
inputGroupTitle = "=== Pivots ==="
plotGroupTitle = "=== Plots ==="

//Inputs
source = input.string("Wicks", options=['Wicks','Bodys'],
title="Source", group=inputGroupTitle)

leftLenH = input.int(title="Pivot High", defval=25, minval=1,


inline="Pivot High", group=inputGroupTitle)
rightLenH = input.int(title="/", defval=25, minval=1, inline="Pivot
High", group=inputGroupTitle)

leftLenL = input.int(title="Pivot Low", defval=25, minval=1,


inline="Pivot Low", group=inputGroupTitle)
rightLenL = input.int(title="/", defval=25, minval=1, inline="Pivot Low",
group=inputGroupTitle)

bullBoxColor = input.color(color.new(#00E600,90), title="Bullish Color",


group=plotGroupTitle, inline="1")
bearBoxColor = input.color(color.new(#FF0000,90), title="Bearish Color",
group=plotGroupTitle, inline="1")
closedBoxColor = input.color(color.new(color.gray,90), title="Closed",
group=plotGroupTitle, inline="1")

extendBox = input.bool(true, title="Extend Boxes", group=plotGroupTitle,


tooltip="Extend boxes until price hits them")
boxLength = input.int(30, title="Box Size", tooltip="if Extend boxes is
off, boxes will be drawn this long", group=plotGroupTitle)

//Wick / Body option


phOption = source == "Wicks" ? high : close
plOption = source == "Wicks" ? low : close

ph = ta.pivothigh(phOption,leftLenH, rightLenH)
pl = ta.pivotlow(plOption,leftLenL, rightLenL)
//Variables
var leftBull = bar_index
var rightBull = bar_index
var topBull = close
var bottomBull = close

var leftBear = bar_index


var rightBear = bar_index
var topBear = close
var bottomBear = close

var box[] _bearBoxes = array.new_box()


var box[] _bullBoxes = array.new_box()

//Bear Box Calc


if (not na(ph))
leftBear := bar_index-leftLenH
rightBear := bar_index-(leftLenH-boxLength)
topBear := source == "Bodys" ? (close[leftLenL]>open[leftLenL] ?
close[leftLenH] : open[leftLenH]) : high[leftLenL]
bottomBear := source == "Bodys" ? (close[leftLenL]>open[leftLenL] ?
open[leftLenH] : close[leftLenH]) : close[leftLenL] > open[leftLenL] ?
close[leftLenL] : open[leftLenL]

//Bull Box Calc


if (not na(pl))
leftBull := bar_index-leftLenL
rightBull := bar_index-(leftLenL-boxLength)
topBull := source == "Bodys" ? (close[leftLenL]>open[leftLenL] ?
close[leftLenL] : open[leftLenL]) : close[leftLenL] > open[leftLenL] ?
open[leftLenL] : close[leftLenL]
bottomBull := source == "Bodys" ? (close[leftLenL]>open[leftLenL] ?
open[leftLenL] : close[leftLenL]) : low[leftLenL]

if (not na(pl))
array.push(_bullBoxes, box.new(left=leftBull, right=rightBull, top=topBull,
bottom=bottomBull, bgcolor=color.new(bullBoxColor,80), border_color=bullBoxColor))

if (not na(ph))
array.push(_bearBoxes, box.new(left=leftBear, right=rightBear, top=topBear,
bottom=bottomBear, bgcolor=color.new(bearBoxColor,80), border_color=bearBoxColor))

extend_boxes(_array, _type)=>
if array.size(_array)>0
for i = 0 to array.size(_array)-1
_box = array.get(_array,i)
_boxLow = box.get_bottom(_box)
_boxHigh = box.get_top(_box)
_boxLeft = box.get_left(_box)
_boxRight = box.get_right(_box)

if _type=="bull" and _boxRight == bar_index


if low > _boxHigh
box.set_right(_box,bar_index+1)
else
box.set_bgcolor(_box, closedBoxColor)
box.set_border_color(_box, closedBoxColor)
box.set_text_color(_box, closedBoxColor)
box.set_right(_box,bar_index)

if _type=="bear" and _boxRight == bar_index


if high < _boxLow
box.set_right(_box,bar_index+1)
else
box.set_bgcolor(_box, closedBoxColor)
box.set_border_color(_box, closedBoxColor)
box.set_text_color(_box, closedBoxColor)
box.set_right(_box,bar_index)

if extendBox
extend_boxes(_bullBoxes,"bull")
extend_boxes(_bearBoxes,"bear")

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy