// This source code is subject to the terms of the Mozilla Public License 2.
0 at
https://mozilla.org/MPL/2.0/
// © LeviathanCapital
//@version=5
indicator("Gaps + Imbalances + Wicks (MTF) - By Leviathan", overlay=true,
max_boxes_count = 500, max_lines_count = 500)
// General Settings
boxtype = input.string('Imbalance', 'Zone Type ', options=['Imbalance',
'Gap', 'Wick'], group = 'General Settings', inline='1')
tfinput = input.timeframe('', ' - ', group = 'General Settings',
inline='1')
showmiddleline = input.bool(true, 'Middle Line ', inline='ln', group = 'General
Settings')
showbottomline = input.bool(false, 'Bottom Line ', inline='ln', group = 'General
Settings')
showtopline = input.bool(false, 'Top Line ', inline='ln', group = 'General
Settings')
showup = input.bool(true, 'UP Zones ', inline='appup', group =
'General Settings')
showdown = input.bool(true, 'DOWN Zones ', inline='appdown', group =
'General Settings')
upcol1 = input.color(color.rgb(0, 0, 0, 95), ' ', inline='appup', group =
'General Settings')
upbordercol = input.color(color.rgb(0, 0, 0, 100), '', inline='appup', group =
'General Settings')
uptextcol = input.color(color.rgb(0, 0, 0, 100), '', inline='appup', group =
'General Settings')
downcol1 = input.color(color.rgb(0, 0, 0, 95), ' ', inline='appdown', group
= 'General Settings')
downbordercol = input.color(color.rgb(0, 0, 0, 100), '', inline='appdown', group
= 'General Settings')
downtextcol = input.color(color.rgb(0, 0, 0, 100), '', inline='appdown', group
= 'General Settings')
extendtilfilled = input.bool(true, '', group = 'General Settings', inline='fill')
filledtype = input.string('Half Fill', 'Fill Condition ',
options=['Touch', 'Full Fill', 'Half Fill'], group = 'General Settings',
inline='fill')
lookback = input.bool(true, '', inline='lb', group = 'General Settings')
daysBack = input.float(1000, 'Lookback (D) ', group = 'General
Settings',inline='lb')
hidefilled = input.bool(true, 'Hide Filled Levels', inline='hd',
group='General Settings')
showboxes = input.bool(true, 'Show Boxes', inline='hd', group='General
Settings')
conditiontype = input.string('None', 'Filter Type ', options=['Percentage',
'ATR', 'None'], group = 'Filter Settings')
atrlength = input.int(25, 'ATR Length + Mult.', step=1, group = 'Filter
Settings', inline='atr')
atrmult = input.float(1, '', step=0.1, group = 'Filter Settings',
inline='atr')
pctcond = input.float(0.30, 'Percentage + Mult.', step=0.1, group = 'Filter
Settings', inline='pct')
pctmult = input.float(1, '', step=0.1, group = 'Filter Settings',
inline='pct')
showboxtext = input.bool(false, ' ', group = 'Zone Labels', inline='txt')
textType = input.string('Labels + Timeframe', '', group = 'Zone Labels',
options = ['Labels', 'Volume','Labels + Timeframe', 'Labels + Timeframe + Volume'],
inline='txt')
textsize = input.string('Size: Tiny', '', options = ['Size: Normal','Size:
Large', 'Size: Small', 'Size: Tiny', 'Size: Auto' ], inline='txt', group = 'Zone
Labels' )
textvalign = input.string('Center','Position ', options = ['Center', 'Top',
'Bottom'], inline='pos', group = 'Zone Labels')
texthalign = input.string('Middle','', options = ['Middle', 'Right', 'Left'],
inline='pos', group = 'Zone Labels')
imbtext = input.string("IMB", title='Imbalance Label', group = 'Zone
Labels')
gaptext = input.string("GAP", title='Gap Label', group = 'Zone Labels')
wicktext = input.string('WICK', title='Wick Label', group = 'Zone Labels')
actionbool = input.bool(false, '', inline='act', group='Other Settings')
actiondel = input.string('Stop Zone','', options = ['Stop Zone', 'Delete
Zone'], inline='act', group='Other Settings')
nmbars = input.int(3500, 'after', inline='act', group='Other Settings',
tooltip = 'Delete/Stop Zone after X number of candles')
linestyle = input.string('Solid', 'Line Style', ['Solid', 'Dashed',
'Dotted'], inline='l', group='Other Settings')
lineCol = input.color(color.rgb(255, 153, 0, 50), '', inline='l',
group='Other Settings')
nbars = input.int(4, 'Zone Length', group='Other Settings', tooltip =
'Length of the zone (in bars) if Fill Condition is turned off')
maxBoxes = input.int(499, 'Max Zones', minval=1, maxval=500, group = 'Other
Settings')
buy_alert = input.bool(title='Buy Signal', defval=true, group='Alerts', tooltip='An
alert will be sent when price goes below the top of a bullish order block.')
sell_alert = input.bool(title='Sell Signal', defval=true, group='Alerts',
tooltip='An alert will be sent when price goes above the bottom of a bearish order
block.')
// 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)
tvol = request.security(syminfo.tickerid, tfinput, volume)
atr = request.security(syminfo.tickerid, tfinput, ta.atr(atrlength))
bool new = ta.change(time(tfinput))
// Distances in %
upimbdist = (l-h2) / h2 * 100
downimbdist = (l2-h) / h * 100
upgapdist = (l-h1) / h1 * 100
downgapdist = (l1-h) / h * 100
upwickdist = (h1-math.max(o1, c1)) / math.max(o1, c1) * 100
downwickdist = (math.min(o1, c1)-l1) / l1 * 100
// Candle body size and the size of lower&upper wicks
bodysize = math.abs(o1-c1)
upperWickSize = h1 - math.max(o1, c1)
lowerWickSize = math.min(o1, c1) - l1
// Hide boxes (transparency to 100)
clear = color.rgb(0,0,0,100)
color upcol = showboxes ? upcol1 : clear
color downcol = showboxes ? downcol1 : clear
// Volume
float labeltype = 0
if boxtype=='Imbalance' or boxtype=='Wick'
labeltype := tfinput==timeframe.period ? tvol[1] : tvol[2]
if boxtype=='Gap'
labeltype := tfinput==timeframe.period ? tvol[0] : tvol[1]
// Calculating inRange, used for lookback in days
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 = lookback ? (daysLeft < daysBack) : 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' => '1H'
'120' => '2H'
'240' => '4H'
'480' => '8H'
'720' => '12H'
=> tfinput
// Box Text
var string imbboxtext = na, var string gapboxtext = na, var string wickboxtext
= na
if showboxtext and textType == 'Labels'
imbboxtext := str.tostring(imbtext)
gapboxtext := str.tostring(gaptext)
wickboxtext := str.tostring(wicktext)
if showboxtext and textType == 'Volume'
imbboxtext := str.tostring(labeltype, format.volume)
gapboxtext := str.tostring(labeltype, format.volume)
wickboxtext := str.tostring(labeltype, format.volume)
if showboxtext and textType == 'Labels + Timeframe'
imbboxtext := str.tostring(imbtext) + ' • ' +
str.tostring(timeframelabel(tfinput))
gapboxtext := str.tostring(gaptext) + ' • ' +
str.tostring(timeframelabel(tfinput))
wickboxtext := str.tostring(wicktext) + ' • ' +
str.tostring(timeframelabel(tfinput))
if showboxtext and textType == 'Labels + Timeframe + Volume'
imbboxtext := str.tostring(imbtext) + ' • ' +
str.tostring(timeframelabel(tfinput)) + ' • ' + str.tostring(labeltype,
format.volume)
gapboxtext := str.tostring(gaptext) + ' • ' +
str.tostring(timeframelabel(tfinput)) + ' • ' + str.tostring(labeltype,
format.volume)
wickboxtext := str.tostring(wicktext) + ' • ' +
str.tostring(timeframelabel(tfinput)) + ' • ' + str.tostring(labeltype,
format.volume)
// Line style and text label appearance
lineStyle(x) =>
switch x
'Solid' => line.style_solid
'Dashed' => line.style_dashed
'Dotted' => line.style_dotted
switchhalign(texthalign) =>
switch texthalign
'Middle' => text.align_center
'Right' => text.align_right
'Left' => text.align_left
switchvalign(textvalign) =>
switch textvalign
'Center' => text.align_center
'Top' => text.align_top
'Bottom' => text.align_bottom
switchtextsize(textsize) =>
switch textsize
'Size: Normal' => size.normal
'Size: Small' => size.small
'Size: Tiny' => size.tiny
'Size: Auto' => size.auto
'Size: Large' => size.large
// 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 == 'Percentage'
condition := upimbdist>(pctcond*pctmult)
condition2 := downimbdist>(pctcond*pctmult)
condition3 := upgapdist>(pctcond*pctmult)
condition4 := downgapdist>(pctcond*pctmult)
condition5 := upwickdist>(pctcond*pctmult)
condition6 := downwickdist>(pctcond*pctmult)
if conditiontype == 'ATR'
condition := (l-h2)>(atrmult*atr)
condition2 := (l2-h)>(atrmult*atr)
condition3 := (l-h1)>(atrmult*atr)
condition4 := (l1-h)>(atrmult*atr)
condition5 := (h1-math.max(o1, c1))>(atrmult*atr)
condition6 := (math.min(o1, c1)-l1)>(atrmult*atr)
if conditiontype == 'None'
condition := true
condition2 := true
condition3 := true
condition4 := true
condition5 := true
condition6 := true
// Drawing Boxes and Lines
var criado = false
var boxes = array.new_box(), var topLines = array.new_line(), var
middleLines = array.new_line(), var bottomLines = array.new_line()
if boxtype == 'Imbalance' and (l > h2) and showup and condition and inRange and new
imbboxUP = box.new(t[2], l, time, h2, bgcolor = upcol,
border_color=upbordercol,border_width = 1, text=imbboxtext, text_size =
switchtextsize(textsize), text_halign = switchhalign(texthalign), text_valign =
switchvalign(textvalign), text_color = uptextcol,xloc = xloc.bar_time)
topLine = showtopline ? line.new(t[2], l, time, l, color=lineCol,
style=lineStyle(linestyle), xloc = xloc.bar_time) : na
bottomLine = showbottomline ? line.new(t[2], h2, time, h2, color=lineCol,
style=lineStyle(linestyle), xloc = xloc.bar_time) : na
middleLine = showmiddleline ? line.new(t[2], (l + h2)/2, time, (l + h2)/2,
color=lineCol, style=lineStyle(linestyle), xloc = xloc.bar_time) : na
criado := true
array.push(topLines, topLine)
array.push(middleLines, middleLine)
array.push(bottomLines, bottomLine)
array.push(boxes, imbboxUP)
if boxtype == 'Imbalance' and (h < l2) and showdown and condition2 and inRange and
new
imbboxDOWN = box.new(t[2], h, time, l2, bgcolor = downcol,
border_color=downbordercol,border_width = 1, text=imbboxtext, text_size =
switchtextsize(textsize), text_halign = switchhalign(texthalign), text_valign =
switchvalign(textvalign), text_color = downtextcol, xloc = xloc.bar_time)
topLine = showtopline ? line.new(t[2], l2, time, l2, color=lineCol,
style=lineStyle(linestyle), xloc = xloc.bar_time) : na
bottomLine = showbottomline ? line.new(t[2], h, time, h, color=lineCol,
style=lineStyle(linestyle), xloc = xloc.bar_time) : na
middleLine = showmiddleline ? line.new(t[2], (h+l2)/2, time, (h+l2)/2,
color=lineCol, style=lineStyle(linestyle), xloc = xloc.bar_time) : na
criado := true
array.push(topLines, topLine)
array.push(middleLines, middleLine)
array.push(bottomLines, bottomLine)
array.push(boxes, imbboxDOWN)
if boxtype == 'Gap' and l > h1 and showup and condition3 and inRange and new
gapboxUP = box.new(t[1], l, time, h1, bgcolor = upcol,
border_color=upbordercol, border_width = 1, text=gapboxtext, text_size =
switchtextsize(textsize), text_halign = switchhalign(texthalign), text_valign =
switchvalign(textvalign), text_color = uptextcol, xloc = xloc.bar_time)
topLine = showtopline ? line.new(t[1], l, time, l, color=lineCol,
style=lineStyle(linestyle), xloc = xloc.bar_time) : na
bottomLine = showbottomline ? line.new(t[1], h1, time, h1, color=lineCol,
style=lineStyle(linestyle), xloc = xloc.bar_time) : na
middleLine = showmiddleline ? line.new(t[1], (l+h1)/2, time, (l+h1)/2,
color=lineCol, style=lineStyle(linestyle), xloc = xloc.bar_time) : na
array.push(topLines, topLine)
array.push(middleLines, middleLine)
array.push(bottomLines, bottomLine)
array.push(boxes, gapboxUP)
if boxtype == 'Gap' and h < l1 and showdown and condition4 and inRange and new
gapboxDOWN = box.new(t[1], l1, time, h, bgcolor = downcol,
border_color=downbordercol,border_width = 1, text=gapboxtext, text_size =
switchtextsize(textsize), text_halign = switchhalign(texthalign), text_valign =
switchvalign(textvalign), text_color = downtextcol, xloc = xloc.bar_time)
topLine = showtopline ? line.new(t[1], l1, time, l1, color=lineCol,
style=lineStyle(linestyle), xloc = xloc.bar_time) : na
bottomLine = showbottomline ? line.new(t[1], h, time, h, color=lineCol,
style=lineStyle(linestyle), xloc = xloc.bar_time) : na
middleLine = showmiddleline ? line.new(t[1], (h+l1)/2, time, (h+l1)/2,
color=lineCol, style=lineStyle(linestyle), xloc = xloc.bar_time) : na
array.push(topLines, topLine)
array.push(middleLines, middleLine)
array.push(bottomLines, bottomLine)
array.push(boxes, gapboxDOWN)
if boxtype == 'Wick' and upperWickSize>(bodysize/6) and showup and condition5 and
inRange and new
wickboxUP = box.new(t[1], h1, time, math.max(o1, c1), bgcolor = upcol,
border_color=upbordercol,border_width = 1, text=wickboxtext, text_size =
switchtextsize(textsize), text_halign = switchhalign(texthalign), text_valign =
switchvalign(textvalign), text_color = uptextcol, xloc = xloc.bar_time)
topLine = showtopline ? line.new(t[1], math.max(h1, math.max(o1, c1)),
time, math.max(h1, math.max(o1, c1)), color=lineCol, style=lineStyle(linestyle),
xloc = xloc.bar_time) : na
bottomLine = showbottomline ? line.new(t[1], math.min(h1, math.max(o1, c1)),
time, math.min(h1, math.max(o1, c1)), color=lineCol, style=lineStyle(linestyle),
xloc = xloc.bar_time) : na
middleLine = showmiddleline ? line.new(t[1], (h1+math.max(o1, c1))/2, time,
(h1+math.max(o1, c1))/2, color=lineCol, style=lineStyle(linestyle), xloc =
xloc.bar_time) : na
array.push(topLines, topLine)
array.push(middleLines, middleLine)
array.push(bottomLines, bottomLine)
array.push(boxes, wickboxUP)
if boxtype == 'Wick' and lowerWickSize>(bodysize/6) and showdown and condition6 and
inRange and new
wickboxDOWN = box.new(t[1], math.min(o1, c1), time, l1, bgcolor = downcol,
border_color=downbordercol,border_width = 1, text=wickboxtext, text_size =
switchtextsize(textsize), text_halign = switchhalign(texthalign), text_valign =
switchvalign(textvalign), text_color = downtextcol, xloc = xloc.bar_time)
topLine = showtopline ? line.new(t[1], math.max(l1, math.min(o1, c1)),
time, math.max(l1, math.min(o1, c1)), color=lineCol, style=lineStyle(linestyle),
xloc = xloc.bar_time) : na
bottomLine = showbottomline ? line.new(t[1], math.min(l1, math.min(o1, c1)),
time, math.min(l1, math.min(o1, c1)), color=lineCol, style=lineStyle(linestyle),
xloc = xloc.bar_time) : na
middleLine = showmiddleline ? line.new(t[1], (l1+math.min(o1, c1))/2, time,
(l1+math.min(o1, c1))/2, color=lineCol, style=lineStyle(linestyle), xloc =
xloc.bar_time) : na
array.push(topLines, topLine)
array.push(middleLines, middleLine)
array.push(bottomLines, bottomLine)
array.push(boxes, wickboxDOWN)
// 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)
for gapboxUP in boxes
filled := (high > level2 and low < level2)
for gapboxDOWN in boxes
filled := (high > level and low < level)
for wickboxUP in boxes
filled := (high > level2 and low < level2)
for wickboxDOWN 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, time+1)
line.set_x2(topLine, time+1)
line.set_x2(middleLine, time+1)
line.set_x2(bottomLine, time+1)
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)
if not filled and actionbool and actiondel == 'Delete Zone' and
((box.get_right(box)-box.get_left(box)) > nmbars)
line.delete(topLine)
line.delete(middleLine)
line.delete(bottomLine)
box.delete(box)
if not filled and actionbool and actiondel == 'Stop Zone' and
((box.get_right(box)-box.get_left(box)) > nmbars)
array.remove(boxes, j)
array.remove(topLines, j)
array.remove(middleLines, j)
array.remove(bottomLines, j)
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
size2 = array.size(boxes)
if size2 > 0
var condicao = false
for i = 0 to size2 - 1
j2 = size2 - 1 - i
box2 = array.get(boxes, j2)
level2 = box.get_bottom(box2)
level22 = box.get_top(box2)
if (high > level2 and low < level2) or (high > level22 and low < level22)
alert("Imbalance atingido", alert.freq_once_per_bar)